1
1

incusのコンテナがネットワークに接続できない問題の調査と解決方法: NAT設定の手順とトラブルシューティング

Last updated at Posted at 2024-08-27

はじめに

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
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 詳細モードで表示する
sudo iptables -t 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
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 詳細モード
sudo iptables -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
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
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
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1