2015/09/30

lxcコンテナへのNAT設定もsystemdで

昨夜久しぶりにホストをリブートした。そしたらlxcコンテナへのNAT設定が消滅した。永続化してなかったので、当然です。そうかと軽く考えて

iptable設定永続化パッケージインストール
$ sudo apt-get install iptables-persistent

で、コンテナへのNAT設定を保存し、ホスト再起動してみたら、あらあら、
Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  10.0.3.0/24         !10.0.3.0/24
MASQUERADE  all  --  10.0.3.0/24         !10.0.3.0/24
lxcbr0の設定がダブってしまうじゃありませんか。なるほど。lxcのネットワーク設定とiptables-persistentの設定の両方が効いてしまうからでしょうか。

Enable LXC neworking in Debian Jessie, Fedora 21 and others
には、/usr/lib/x86_64-linux-gnu/lxc/lxc-net ファイルに追加設定する方法があったり

Tips for LXC: Creation, Autostart, OpenVPN and Port Forwarding to Containersには、iptables-persistentでいいが、起動に問題があるのでちょっとゴニョゴニョするとか

それぞれのアプローチ方法は参考にはなるが、ちょっと好きになれない感じ。
自分なりの解決方法としては、iptables-persistentをやめて、前記事と同じsystemdを使って設定することにした。

ただ、今回はホストでの設定だし、ユーザモードで実行するものでもないので、普通のsystemdサービスユニット。それと追加変更がし易い形にはしようと思う。

サービスユニットファイル
~/.config/systemd/system/lxc-nat.service として作成。どこでもいいと思うが、ユーザモードの場合 ~/.config/systemd/user以下に置く流れに沿ってみた。内容は以下のとおり
[Unit]
Description=LXC NAT network setup
After=lxc-net.service

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/home/ubuntu/bin/lxc-nat start
ExecStop=/home/ubuntu/bin/lxc-nat stop

[Install]
WantedBy=multi-user.target
登録 (/etc/systemd/systemへシンボリックリンク作成)
$ sudo systemctl enable ~/.config/systemd/system/lxc-nat.service

自分でインストール先へ直接ln -sしてもいいかもしれないけど、systemctlにやってもらいます。

確認
$ sudo systemctl list-unit-files | grep lxc
lxc-nat.service                        enabled
lxc-net.service                        enabled
lxc.service                            enabled
lxcfs.service                          enabled

/home/ubuntu/bin/lxc-nat の中身の例
#!/bin/sh -

nat()
{
    iptables -t nat $1 PREROUTING -p tcp -d 192.168.1.10/32 --dport 80 -j DNAT --to 10.0.3.10:80
    iptables -t nat $1 PREROUTING -p tcp --dport 8000 -j DNAT --to 10.0.3.11:80
}

case "$1" in
    start)
        nat -A
    ;;
    stop)
        nat -D
    ;;
    *)
        echo "Usage: $0 {start|stop}"
        exit 2
esac
exit $?
nat()関数で-A/-D切り替えできるように(start/stop両方に書かないで済むように)。
後は、nat()内のiptables記述を増やすなり編集するなりするだけ。

例の場合の、10.0.3.10 のコンテナも自動起動するようにコンテナ設定ファイルに
lxc.start.auto = 1
としておくと尚良し。

余談ちゃ余談ですが、80ポートをNATするときには若干注意が必要だった。

最初、
iptables -t nat $1 PREROUTING -p tcp --dport 80 -j DNAT --to 10.0.3.10:80
ってしていたら、lxcコンテナからの apt-get update が出来なくなってしまった。

最初原因が分からなくて、lxc.networkのgateway設定とか、dnsmasqのルーター設定とか迷宮にのめり込みそうだったが、何の事はない。

コンテナからの80ポートアクセスがブリッジからホストネットワークを通るときに80がポートフォワードされていたというオチ。destinationがanywhereだったのが原因。

ということで、destinationをホストアドレスに限定した設定
iptables -t nat $1 PREROUTING -p tcp -d 192.168.1.10/32 --dport 80 -j DNAT --to 10.0.3.10:80

とすることで、ホストへの80ポートアクセスのみNATが効くようにして、解決。

0 件のコメント:

コメントを投稿