Dockerのブリッジネットは他のブリッジネットワーク通信できません。 コンテナのIPフォワーディングを使って擬似的にルーターの役割をもたせブリッジネットワーク間で通信してみます。
コンテナのIPフォワーディングを使用して2つのブリッジネットワークに配置したコンテナ間で通信します。
routeコマンドについてはこちらのEC2インスタンスのルーティングテーブル
を参照してください。
EC2(Ubuntu 22.04.1 LTS)にDocker version 20.10.20をインストールして作業しました。
// 172.27.0.0/16
$ sudo docker network create network1
// 172.28.0.0/16
$ sudo docker network create network2
Ubuntuコンテナをnetwork1とnetwork2に配置します。
// 172.27.0.2
$ sudo docker run -itd --name container1 --privileged --net=network1 ubuntu:latest
// 172.28.0.2
$ sudo docker run -itd --name container2 --privileged --net=network2 ubuntu:latest
今回はコンテナにルートを追加するので--privileged
を付与して作成します。
続いてルータの役割をするコンテナを作成します。 このコンテナはnetwork1およびnetwork2に配置します。
// network1に接続
// 172.27.0.3
$ sudo docker run -itd --name router --sysctl net.ipv4.ip_forward=1 --net=network1 ubuntu:latest
// network2に接続
// 172.28.0.3
$ sudo docker network connect network2 router
カーネルパラメータはコンテナ内から変更できないので、IPフォワーディングを有効にするために--sysctl net.ipv4.ip_forward=1
を付与します。
コンテナに接続してパッケージをインストールします。
# apt update && apt install -y iproute2 iputils-ping net-tools tcpdump traceroute
container1にnetwork2へのルートを追加します。
追加前のルートテーブルを確認します。
container1# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.27.0.1 0.0.0.0 UG 0 0 0 eth0
172.27.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
network2(172.28.0.0/16)へのルートを追加します。
container1# route add -net 172.28.0.0 netmask 255.255.0.0 gw 172.27.0.3 eth0
追加後のルートテーブルを確認します。
container1# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.27.0.1 0.0.0.0 UG 0 0 0 eth0
172.27.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
172.28.0.0 172.27.0.3 255.255.0.0 UG 0 0 0 eth0
container2にnetwork1へのルートを追加します。
追加前のルートテーブルを確認します。
container2# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.28.0.1 0.0.0.0 UG 0 0 0 eth0
172.27.0.0 172.28.0.3 255.255.0.0 UG 0 0 0 eth0
network2(172.28.0.0/16)へのルートを追加します。
container2# route add -net 172.27.0.0 netmask 255.255.0.0 gw 172.28.0.3 eth0
追加後のルートテーブルを確認します。
container2# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 172.28.0.1 0.0.0.0 UG 0 0 0 eth0
172.27.0.0 172.28.0.3 255.255.0.0 UG 0 0 0 eth0
172.28.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
container1(172.27.0.2)からcontainer2(172.28.0.2)にpingを発行して通信を確認します。
container1
container1# sudo docker exec -it container1 ping 172.28.0.2
PING 172.28.0.2 (172.28.0.2) 56(84) bytes of data.
64 bytes from 172.28.0.2: icmp_seq=1 ttl=63 time=0.111 ms
64 bytes from 172.28.0.2: icmp_seq=2 ttl=63 time=0.093 ms
64 bytes from 172.28.0.2: icmp_seq=3 ttl=63 time=0.097 ms
64 bytes from 172.28.0.2: icmp_seq=4 ttl=63 time=0.089 ms
--- 172.28.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3060ms
router
host$ sudo docker exec -it router tcpdump -tnl -i eth0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
IP 172.27.0.2 > 172.28.0.2: ICMP echo request, id 4, seq 1, length 64
IP 172.28.0.2 > 172.27.0.2: ICMP echo reply, id 4, seq 1, length 64
IP 172.27.0.2 > 172.28.0.2: ICMP echo request, id 4, seq 2, length 64
IP 172.28.0.2 > 172.27.0.2: ICMP echo reply, id 4, seq 2, length 64
IP 172.27.0.2 > 172.28.0.2: ICMP echo request, id 4, seq 3, length 64
IP 172.28.0.2 > 172.27.0.2: ICMP echo reply, id 4, seq 3, length 64
IP 172.27.0.2 > 172.28.0.2: ICMP echo request, id 4, seq 4, length 64
IP 172.28.0.2 > 172.27.0.2: ICMP echo reply, id 4, seq 4, length 64
container2
host$ sudo docker exec -it container2 tcpdump -tnl -i eth0 icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
IP 172.27.0.2 > 172.28.0.2: ICMP echo request, id 4, seq 1, length 64
IP 172.28.0.2 > 172.27.0.2: ICMP echo reply, id 4, seq 1, length 64
IP 172.27.0.2 > 172.28.0.2: ICMP echo request, id 4, seq 2, length 64
IP 172.28.0.2 > 172.27.0.2: ICMP echo reply, id 4, seq 2, length 64
IP 172.27.0.2 > 172.28.0.2: ICMP echo request, id 4, seq 3, length 64
IP 172.28.0.2 > 172.27.0.2: ICMP echo reply, id 4, seq 3, length 64
IP 172.27.0.2 > 172.28.0.2: ICMP echo request, id 4, seq 4, length 64
IP 172.28.0.2 > 172.27.0.2: ICMP echo reply, id 4, seq 4, length 64