#
ドキュメント

Document

自分のための備忘録です。

複数のブリッジネットワークを接続

Dockerのブリッジネットは他のブリッジネットワーク通信できません。 コンテナのIPフォワーディングを使って擬似的にルーターの役割をもたせブリッジネットワーク間で通信してみます。

Untitled (1)

ゴール

コンテナのIPフォワーディングを使用して2つのブリッジネットワークに配置したコンテナ間で通信します。

routeコマンド

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にルートを追加

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にルートを追加

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