はじめに
Ubuntu 13.04
から Ubuntu 13.10
にアップデートして lxc
のバージョンも 1.0.0.alpha1
になったけど色々と困ったことが起きたのは前回。
改善を夢見て alpha2
にアップデートしたものの叶わずだったが、Debian 系のコンテナで IP が付与されない問題についてとりあえず解決したのでメモ。
メモ
ちなみに検証した環境は lxc 1.0.0.alpha1
から lxc 1.0.0.alpha2
にアップグレードした環境も利用している。
発生していた問題
Debian
系のコンテナを起動した場合に DHCP
で IP が取得出来ない状況が発生した。以下、起動メッセージの抜粋。
Configuring network interfaces...Internet Systems Consortium DHCP Client 4.1.1-P1 Copyright 2004-2010 Internet Systems Consortium. All rights reserved. For info, please visit https://www.isc.org/software/dhcp/ Listening on LPF/eth0/0e:eb:4f:74:8d:15 Sending on LPF/eth0/0e:eb:4f:74:8d:15 Sending on Socket/fallback DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 7 DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 11 DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 16 DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 7 DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 13 5 bad udp checksums in 5 packets DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 7 No DHCPOFFERS received. No working leases in persistent database - sleeping. done.
上記のようにコンテナ側から DHCPDISCOVER
をブロードキャストするものの DHCPOFFERS
を受信出来ない状況になっていた。入団を希望してドラフトで指名されないようなもんですな。(違うか)
解決の糸口
毎回手動で IP を設定するのも面倒なので調べていたら vagrant-lxc の issue に以下のような issue が上がっていた。
issue の一発目で...
This is due to dhclient checking the checksum of udp packets it receives, but checksums are not computed if the packets don't leave through a physical interface.
とあり DHCP
クライアント(コンテナ)が UDP
パケットのチェックサムを計算しない又はチェックサムのエラーで発生している...と解釈した。
ふむ。
そもそも DHCP
で DHCP
サーバーからクライアントに IP アドレスが付与される過程で UDP
パケットのチェックサムの計算が走るということを初めて知ったが、ざっとググると lxc
に限らず仮想環境においてクライアント(仮想マシン)に IP アドレスが付与されない現象というのは幾つか見られる。
- OpenStackのDHCP問題まとめ
- The challenge of the network
- Instances in OpenStack are not getting DHCP leases on ubuntu12.10
- lxc dhcp fails
- dhcp3-server reports many bad udp checksums to syslog using virtio NIC
- UDP checksum offload breaks DHCP on virtual machines
今回は OpenStack
は関係無いけど、上記の記事達がとても参考になった。
原因をそれなりに調べてみた
チェックサムの問題。確かに起動メッセージ内でも 5 bad udp checksums in 5 packets
と出力されているのでチェックサムの計算でコケて IP アドレスが付与されないのは解ったが、以下のような疑問が湧いてきたので調べてみた。
チェックサムの計算に失敗している状況を見たい
tcpdump
を使ってコンテナとの DHCP
のやりとりをキャプチャしてみた。
sudo tcpdump -n -vv -i lxcbr0 port bootps or port bootpc
以下のようにキャプチャ出来た。
10:15:53.015772 IP (tos 0xc0, ttl 64, id 48372, offset 0, flags [none], proto UDP (17), length 328) 10.0.3.1.67 > 10.0.3.129.68: [bad udp cksum 0x1bc7 -> 0x072b!] BOOTP/DHCP, Reply, length 300, xid 0x6ce6e42e, secs 6, Flags [none] (0x0000) Your-IP 10.0.3.129 Server-IP 10.0.3.1 Client-Ethernet-Address 0e:eb:4f:74:8d:15 Vendor-rfc1048 Extensions
[bad udp cksum 0x1bc7 -> 0x072b!]
がチェックサムの計算に失敗している部分。
なぜ チェックサムの計算に失敗するのか?
参考にさせて頂いた情報をまとめると以下のような状況でチェックサムの計算に失敗することがある。
vhost_net
カーネルモジュールが有効になっている場合- NIC にて
transmit checksum
オフロード処理が有効になっている場合
なぜ lxc
のバージョンアップ後に発生するようになったか?
- 引き続き調査
解決
解決策(1)
ホスト側にて transmit checksum
オフロード処理を無効にする。
sudo ethtool -K lxcbr0 tx off
以下のように表示される。
Actual changes: tx-checksumming: off tx-checksum-ip-generic: off tcp-segmentation-offload: off tx-tcp-segmentation: off [requested on] tx-tcp-ecn-segmentation: off [requested on] tx-tcp6-segmentation: off [requested on]
コンテナ側で IP
の取得を行ってみる。
sudo dhcpclient -v eth0
以下のように IP
の取得に成功している。
Internet Systems Consortium DHCP Client 4.1.1-P1 Copyright 2004-2010 Internet Systems Consortium. All rights reserved. For info, please visit https://www.isc.org/software/dhcp/ Listening on LPF/eth0/5a:65:24:87:b1:d3 Sending on LPF/eth0/5a:65:24:87:b1:d3 Sending on Socket/fallback DHCPREQUEST on eth0 to 255.255.255.255 port 67 DHCPNAK from 10.0.3.1 DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 3 DHCPOFFER from 10.0.3.1 DHCPREQUEST on eth0 to 255.255.255.255 port 67 DHCPACK from 10.0.3.1 bound to 10.0.3.243 -- renewal in 1384 seconds.
解決策(2)
こちらを参考にすると iptables
のmangle
テーブルに CHECKSUM
ターゲットを設定することで解決するようなので /etc/init/lxc-net.conf
を以下のように修正する。修正後にホストを再起動する。
--- lxc-net.conf 2013-10-26 07:56:13.071726566 +0900 +++ lxc-net.conf.fixed 2013-10-26 07:57:41.455722619 +0900 @@ -48,6 +48,10 @@ fi dnsmasq $LXC_DOMAIN_ARG -u lxc-dnsmasq --strict-order --bind-interfaces --pid-file=${varrun}/dnsmasq.pid --conf-file=${LXC_DHCP_CONFILE} --listen-address ${LXC_ADDR} --dhcp-range ${LXC_DHCP_RANGE} --dhcp-lease-max=${LXC_DHCP_MAX} --dhcp-no-override --except-interface=lo --interface=${LXC_BRIDGE} --dhcp-leasefile=/var/lib/misc/dnsmasq.${LXC_BRIDGE}.leases --dhcp-authoritative || cleanup touch ${varrun}/network_up + + ### + iptables -t mangle -A POSTROUTING -p udp --dport bootpc -s ${LXC_NETWORK} -j CHECKSUM --checksum-fill + end script post-stop script @@ -64,4 +68,8 @@ brctl delbr ${LXC_BRIDGE} fi rm -f ${varrun}/network_up + + ### + iptables -t mangle -D POSTROUTING -p udp --dport bootpc -s ${LXC_NETWORK} -j CHECKSUM --checksum-fill || true + end script
ホストを再起動後に以下のようにしてコンテナを起動する。
$ sudo lxc-start -n debian-master -d
以下のように IP
アドレスが付与されている。
$ sudo lxc-ls --fancy NAME STATE IPV4 IPV6 AUTOSTART --------------------------------------------------- debian-master RUNNING 10.0.3.243 - NO debian-test02 STOPPED - - NO test01 STOPPED - - NO ubuntu-master STOPPED - - NO
最後に
まだ残っている問題
- バージョンアップ(
lxc 0.9
tolxc 1.0.0
)に伴う挙動の変化について - コンソールからのデタッチで
Ctrl+a q
が使えない - LXC Web Panel が使えない