ネットワークの疎通確認・経路確認などのテストに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で実装しました。