
ネットワークの疎通確認・経路確認などのテストにDockerコンテナを活用する方式を検討している。テストの際に大量のPCを用意するのは非効率なため、軽量・スピーディなDockerコンテナを活用していきたい。
イメージしている構成は以下の通り。802.1Q VLANタグでホストNICを分離して、各VLAN(セグメント)にDockerコンテナをぶら下げて、相互にPing・Tracerouteにより疎通確認・経路確認ができるようにする。

最終的には、以下のような一連の作業をタスク化し、ネットワークテスト自動化環境を構築したい。
- VLAN Tagネットワーク生成
- コンテナ起動
- テスト実行
- 結果評価
参考にした情報
要素技術として以下の情報を参考にさせていただきました。ありがとうございます。
Dockerマルチホストネットワーク knowledge.sakura.ad.jp
Docker with Open vSwitch blog.kamabokonet.com Open vSwitchではなく、シンプルなネットワーク構成としたい。
Docker Docs docs.docker.com
MACVLAN notes
macvlan_ipvlan_driver_notes.md · GitHub
こちらの図がわかりやすかったです。
前提環境
vSphereのスタンドアロン環境で、NICはIntel ProなどVLANトランク対応していれば問題なし。標準vSwitchのポートグループでVLANトランクを選択して全VLANを802.1Qタグ付きで通している。また、無差別モード(Promiscuous)を有効にしている。
- HyperVisor: VMware ESXi6.5
- NIC: Broadcom NetXtreme BCM5722 Gigabit Ethernet
- Switch: Cisco Catalyst2960
- Router: Juniper vSRX
ゲストOS
CentOSでDockerをインストールして使用する。Dockerが動けば問題なし。Docker構築手順は割愛。
- CentOS Linux release 7.4.1708 (Core)
- Docker version 1.13.1, build 774336d/1.13.1
- docker-compose version 1.21.0, build 5920eb0
環境構築
冒頭の図のような環境を構築する。
Dockerネットワーク作成
MACVLANドライバを指定してDockerネットワークを作成する。parentのens192部分は環境に合わせる。
$ docker network create -d macvlan \
--subnet=192.168.20.0/24 \
--gateway=192.168.20.1 \
-o parent=ens192.20 vlan20
$ docker network create -d macvlan \
--subnet=192.168.30.0/24 \
--gateway=192.168.30.1 \
-o parent=ens192.30 vlan30
Dockerネットワークが作成された。
$ docker network ls NETWORK ID NAME DRIVER SCOPE 61b2b0b3706c bridge bridge local e14ebf55d626 host host local 112dc8a40c20 none null local cacbb0f62e7e vlan20 macvlan local 554515e7aa1a vlan30 macvlan local $ docker network inspect vlan20 [ { "Name": "vlan20", "Id": "cacbb0f62e7e971c34f9a556e153c367d81ca23eb7d22a2fce8ce35920f031d9", "Created": "2018-05-01T23:33:01.063894797-04:00", "Scope": "local", "Driver": "macvlan", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.20.0/24", "Gateway": "192.168.20.1" } ] }, "Internal": false, "Attachable": false, "Containers": {}, "Options": { "parent": "ens192.20" }, "Labels": {} } ] $ docker network inspect vlan30 [ { "Name": "vlan30", "Id": "554515e7aa1ad11d7df178ce3b6244f087cecf7ca19bb3792915f4f9f7f73de9", "Created": "2018-05-01T23:33:03.007612901-04:00", "Scope": "local", "Driver": "macvlan", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "192.168.30.0/24", "Gateway": "192.168.30.1" } ] }, "Internal": false, "Attachable": false, "Containers": {}, "Options": { "parent": "ens192.30" }, "Labels": {} } ]
DockerホストのCentOSのネットワークは以下のような状態になっている。(抜粋)
$ ip a
2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:3a:4c:62 brd ff:ff:ff:ff:ff:ff
4: ens192.10@ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
link/ether 00:0c:29:3a:4c:62 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.80/24 brd 192.168.1.255 scope global ens192.10
valid_lft forever preferred_lft forever
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 02:42:a6:4a:5b:fe brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:a6ff:fe4a:5bfe/64 scope link
valid_lft forever preferred_lft forever
19: ens192.20@ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 00:0c:29:3a:4c:62 brd ff:ff:ff:ff:ff:ff
20: ens192.30@ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 00:0c:29:3a:4c:62 brd ff:ff:ff:ff:ff:ff
Dockerコンテナ作成
作成したネットワーク、IPアドレスを指定してコンテナを作成する。Ping・Tracerouteができればよいので、Alpineを使用する。WARNINGが出るが今回は無視する。
$ docker run -it -d --rm \
--net=vlan20 \
--ip=192.168.20.201 \
--name container-vlan20 \
alpine /bin/sh
WARNING: IPv4 forwarding is disabled. Networking will not work.
4b5dd6ab28bdaa49b8a64221177b942a3754ae058854081318b14f6e79b9e038
$ docker run -it -d --rm \
--net=vlan30 \
--ip=192.168.30.201 \
--name container-vlan30 \
alpine /bin/sh
WARNING: IPv4 forwarding is disabled. Networking will not work.
c68efffc09fffb01f44054293bb71213db3f7fb7c72f85300771a5aa11cabb64
コンテナが作成された。
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c68efffc09ff alpine "/bin/sh" 3 seconds ago Up 2 seconds container-vlan30 4b5dd6ab28bd alpine "/bin/sh" 43 seconds ago Up 43 seconds container-vlan20
動作確認
それぞれのコンテナから疎通確認する。
$ docker exec -it container-vlan20 /bin/sh
/ # ip a
23: eth0@if19: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 02:42:c0:a8:14:c9 brd ff:ff:ff:ff:ff:ff
inet 192.168.20.201/24 scope global eth0
valid_lft forever preferred_lft forever
/ # ping 192.168.20.1
PING 192.168.20.1 (192.168.20.1): 56 data bytes
64 bytes from 192.168.20.1: seq=0 ttl=64 time=1.201 ms
64 bytes from 192.168.20.1: seq=1 ttl=64 time=0.295 ms
/ # ping 192.168.30.201
PING 192.168.30.201 (192.168.30.201): 56 data bytes
64 bytes from 192.168.30.201: seq=0 ttl=63 time=23.294 ms
64 bytes from 192.168.30.201: seq=1 ttl=63 time=0.521 ms
/ # traceroute 192.168.30.201
traceroute to 192.168.30.201 (192.168.30.201), 30 hops max, 46 byte packets
1 192.168.20.1 (192.168.20.1) 0.343 ms 0.157 ms 0.251 ms
2 192.168.30.201 (192.168.30.201) 0.323 ms 0.294 ms 0.238 ms
逆側からも疎通・経路確認。
$ docker exec -it container-vlan30 /bin/sh
/ # ip a
24: eth0@if20: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UNKNOWN
link/ether 02:42:c0:a8:1e:c9 brd ff:ff:ff:ff:ff:ff
inet 192.168.30.201/24 scope global eth0
valid_lft forever preferred_lft forever
/ # ping 192.168.30.1
PING 192.168.30.1 (192.168.30.1): 56 data bytes
64 bytes from 192.168.30.1: seq=0 ttl=64 time=0.281 ms
64 bytes from 192.168.30.1: seq=1 ttl=64 time=0.293 ms
/ # ping 192.168.20.201
PING 192.168.20.201 (192.168.20.201): 56 data bytes
64 bytes from 192.168.20.201: seq=0 ttl=63 time=0.392 ms
64 bytes from 192.168.20.201: seq=1 ttl=63 time=0.444 ms
/ # traceroute 192.168.20.201
traceroute to 192.168.20.201 (192.168.20.201), 30 hops max, 46 byte packets
1 192.168.30.1 (192.168.30.1) 0.240 ms 0.176 ms 0.303 ms
2 192.168.20.201 (192.168.20.201) 0.463 ms 0.216 ms 0.306 ms
/ #
SUCCEEDED!! 期待通り相互に疎通確認・経路確認ができている。Tracerouteの結果からわかる通り、ホストNICはVLANタグを透過して、外部ルータでVLAN間ルーティングされている。
まとめ - Dockerコンテナを外部ネットワークとVLAN Tag接続する
DockerのMACVLANネットワークドライバをすることで、Dockerコンテナを外部ネットワークと802.1Q VLAN Tag接続することができた。Dockerコンテナを活用することで、ネットワークのテストのために大量のPCを用意する必要がなくなる。
(追記) Docker-Composeはこちら
本記事と同内容をDocker-Composeで実装しました。