はじめに
incusの勉強中にincusのコンテナがネットワークに接続できない問題が発生した。今後同じ問題に遭遇した場合を考えて、ネットワーク接続問題の解決方法をメモしておく。
追記
公式FAQにネットワーク接続問題についての言及があった。Dockerを利用していると問題が発生するようだ。
まとめ
問題
incusのコンテナからインターネットに接続できなかった。コンテナとホストPC間ではパケットが到達していた。
原因
今回のネットワーク接続問題の原因は2つ
- コンテナに対するNATルールが作成されていなかった
- FORWARDチェーンのデフォルトポリシーがDROPに設定されていた
修正方法
NATルールの追加
コンテナから外部へのパケットはeth0
のIPアドレスに変換して通信する
sudo iptables -t nat -A POSTROUTING -s 10.107.73.0/24 ! -d 10.107.73.0/24 -o eth0 -j MASQUERADE
コマンド | 意味 |
---|---|
iptables | パケットフィルタリングとNATを設定するためのコマンド |
-t nat | NAT設定のためのテーブルを指定 |
-A POSTROUTING |
POSTROUTING チェーンにルールを追加。パケット送信元アドレスを変更 |
-s 10.107.73.0/24 | 送信元アドレスが10.107.73.0/24 のパケットに適用 |
! -d 10.107.73.0/24 | 宛先が10.107.73.0/24 以外のパケットに適用 |
-o eth0 | 出力インターフェースeth0 を介するパケットに適用 |
-j MASQUERADE | 送信元IPをeth0 のIPアドレスに変換して通信 |
FORWARDチェーンのデフォルトポリシーを変更
FORWARDチェーンのポリシーをACCEPTに変更します。これにより、コンテナからインターネットへのトラフィックが許可されるようになる。
sudo iptables -P FORWARD ACCEPT
ネットワークが繋がらない問題の調査方法
コンテナの状況を確認
IPv4のIPアドレスは10.107.73.0/24
だと確認できる
incus list
+----------------+---------+----------------------+---------------------------------------------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+----------------+---------+----------------------+---------------------------------------------+-----------+-----------+
| first | RUNNING | 10.107.73.58 (eth0) | fd42:8159:b94:458:216:3eff:fea5:9726 (eth0) | CONTAINER | 0 |
+----------------+---------+----------------------+---------------------------------------------+-----------+-----------+
| noble | RUNNING | 10.107.73.227 (eth0) | fd42:8159:b94:458:216:3eff:feb9:d5c4 (eth0) | CONTAINER | 0 |
+----------------+---------+----------------------+---------------------------------------------+-----------+-----------+
| remote-desktop | STOPPED | | | CONTAINER | 0 |
+----------------+---------+----------------------+---------------------------------------------+-----------+-----------+
パケットの到達状況を確認
ping
コマンドを使った下記の結果からホストPCとコンテナ間はパケットが届いているが、コンテナから外部ネットワークへパケットが届いていないことが確認できた。
- ホストPCからコンテナ
noble
にパケットが届くかを確認する [OK] - ホストPCから
8.8.8.8
にパケットが届くかを確認する [OK] - コンテナ
noble
からホストPCにパケットが届くかを確認する [OK] - コンテナ
noble
から8.8.8.8
にパケットが届くかを確認する [NG]
ping 10.107.73.227
ping 8.8.8.8
incus exec noble -- ping 192.168.1.113
incus exec noble -- ping 8.8.8.8
NAT (Network Address Translation) 設定やIPフォワーディングに関連していると推察される。
NATの設定を確認する
iptables
を使って、ホストがコンテナからのトラフィックをインターネットに向けてNAT(アドレス変換)しているか確認する。
sudo iptables -t nat -L -n -v
オプション | 意味 |
---|---|
-t nat | NATテーブルを対象にする |
-L | 現在のルールをリスト形式で表示する |
-n | 数値形式で出力する |
-v | 詳細モードで表示する |
Chain PREROUTING (policy ACCEPT 8485 packets, 1168K bytes)
pkts bytes target prot opt in out source destination
4010 265K DOCKER 0 -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 3901 packets, 971K bytes)
pkts bytes target prot opt in out source destination
1 278 DOCKER 0 -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT 3896 packets, 970K bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE 0 -- * !docker0 172.17.0.0/16 0.0.0.0/0
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN 0 -- docker0 * 0.0.0.0/0 0.0.0.0/0
現在のiptablesの設定を見ると、POSTROUTINGチェーンでMASQUERADEルールが存在するが、このルールはDockerのネットワーク (172.17.0.0/16) に対して適用されている。Incusのコンテナは別のサブネット (10.107.73.0/24) を使用しているため、これが適用されていないと考えられる。
NATルールの追加
コンテナが属するネットワーク (10.107.73.0/24) に対してもNATのMASQUERADEルールを追加する。
sudo iptables -t nat -A POSTROUTING -s 10.107.73.0/24 ! -d 10.107.73.0/24 -o eth0 -j MASQUERADE
iptables
コマンドでNATルールを追加した結果を確認する。
sudo iptables -t nat -L -n -v
...
Chain POSTROUTING (policy ACCEPT 3897 packets, 971K bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE 0 -- * !docker0 172.17.0.0/16 0.0.0.0/0
0 0 MASQUERADE 0 -- * eth0 10.107.73.0/24 !10.107.73.0/24
...
設定したルールが適用されていることが確認できた。
残念ながらNATのルールを追加しただけでは ping が通らなかった。そこでポリシールールを確認する。
iptables
のポリシールールの確認
sudo iptables -L -v
オプション | 意味 |
---|---|
-L | 現在のルールをリスト表示する |
-v | 詳細モード |
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy DROP 900 packets, 56584 bytes)
pkts bytes target prot opt in out source destination
900 56584 DOCKER-USER all -- any any anywhere anywhere
900 56584 DOCKER-ISOLATION-STAGE-1 all -- any any anywhere anywhere
0 0 ACCEPT all -- any docker0 anywhere anywhere ctstate RELATED,ESTABLISHED
0 0 DOCKER all -- any docker0 anywhere anywhere
0 0 ACCEPT all -- docker0 !docker0 anywhere anywhere
0 0 ACCEPT all -- docker0 docker0 anywhere anywhere
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain DOCKER (1 references)
pkts bytes target prot opt in out source destination
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
pkts bytes target prot opt in out source destination
0 0 DOCKER-ISOLATION-STAGE-2 all -- docker0 !docker0 anywhere anywhere
900 56584 RETURN all -- any any anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (1 references)
pkts bytes target prot opt in out source destination
0 0 DROP all -- any docker0 anywhere anywhere
0 0 RETURN all -- any any anywhere anywhere
Chain DOCKER-USER (1 references)
pkts bytes target prot opt in out source destination
900 56584 RETURN all -- any any anywhere anywhere
iptablesの出力を見ると、Chain FORWARD (policy DROP 900 packets, 56584 bytes)
のようにFORWARDチェーンのデフォルトポリシーがDROPに設定されている。これが原因でIncusコンテナからのトラフィックがインターネットに到達しない可能性が高い。コンテナからインターネットに出て行くパケットがこのFORWARDチェーンでドロップされているため、pingが通らない状態だと考えられる。
FORWARDチェーンのポリシーを変更
FORWARDチェーンのポリシーをACCEPTに変更する
sudo iptables -P FORWARD ACCEPT
ポリシーの変更を確認する
sudo iptables -L -v
...
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
900 56584 DOCKER-USER all -- any any anywhere anywhere
900 56584 DOCKER-ISOLATION-STAGE-1 all -- any any anywhere
...
FORWARDのpolicayがACCEPTに修正された
パケットの到達を確認する
コンテナからインターネットへのパケット到達を確認する
incus exec noble -- ping -c 4 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=4.20 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=57 time=4.47 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=57 time=4.25 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=57 time=4.24 ms
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 4.198/4.289/4.466/0.104 ms