Dockerコンテナでネットワーク検証環境を構築する
DockerコンテナとOpen vSwitchを組み合わせてネットワーク検証環境を用意する。
作りたいのはこれ。

各コンポーネントは、以下のようにする。
- ルータ
- vyos1
- ブリッジ
- vswitch1
- vswitch2
- サーバ
- centos1
- centos2
- centos3
- centos4
各サーバは、NATを使いインターネットに出ることができる。
Open vSwitchとDockerのインストールは省略。
Dockerイメージ作成、取得
VyOSとCentOSのDockerイメージを用意する。
VyOS
$ docker pull 2stacks/vyos:1.2.0-rc11
CentOS
$ cat Dockerfile FROM centos RUN yum update -y RUN yum install -y iproute iputils $ docker build -t togattti/centos .
仮想スイッチを作成する
# ovs-vsctl add-br vswitch1
# ovs-vsctl add-br vswitch2
# ovs-vsctl show
591945d1-a629-428b-bf23-c725386b4db0
Bridge "vswitch2"
Port "vswitch2"
Interface "vswitch2"
type: internal
Bridge "vswitch1"
Port "vswitch1"
Interface "vswitch1"
type: internal
ovs_version: "2.9.2"
VyOSを構築する
コンテナを起動する。
$ docker run -d --name vyos1 --privileged -v /lib/modules:/lib/modules 2stacks/vyos:1.2.0-rc11 /sbin/init
vyos1にインターフェイスを作成、ブリッジとつなぐ。
$ sudo ovs-docker add-port vswitch1 eth1 vyos1 --ipaddress=192.168.10.1/24 $ sudo ovs-docker add-port vswitch2 eth2 vyos1 --ipaddress=192.168.20.1/24
サーバを構築する
Dockerコンテナを起動する。
$ docker run -d --net=none --privileged --name centos1 togattti/centos /sbin/init $ docker run -d --net=none --privileged --name centos2 togattti/centos /sbin/init $ docker run -d --net=none --privileged --name centos3 togattti/centos /sbin/init $ docker run -d --net=none --privileged --name centos4 togattti/centos /sbin/init
各サーバにインターフェイスを作成、ブリッジとつなぐ。
$ sudo ovs-docker add-port vswitch1 eth0 centos1 --ipaddress=192.168.10.2/24 $ sudo ovs-docker add-port vswitch1 eth0 centos2 --ipaddress=192.168.10.3/24 $ sudo ovs-docker add-port vswitch2 eth0 centos3 --ipaddress=192.168.20.2/24 $ sudo ovs-docker add-port vswitch2 eth0 centos4 --ipaddress=192.168.20.3/24
ここまでで、インターフェイスの設定状況が次のようになる。
$ docker exec -it centos1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
229: eth0@if230: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether be:97:47:c6:64:28 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.10.2/24 scope global eth0
valid_lft forever preferred_lft forever
$ docker exec -it centos2 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
231: eth0@if232: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether ce:40:67:95:a2:93 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.10.3/24 scope global eth0
valid_lft forever preferred_lft forever
$ docker exec -it centos3 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
233: eth0@if234: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 02:0e:68:d2:c6:59 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.20.2/24 scope global eth0
valid_lft forever preferred_lft forever
$ docker exec -it centos4 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
235: eth0@if236: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether e6:6b:b2:5f:38:cc brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.20.3/24 scope global eth0
valid_lft forever preferred_lft forever
ここまでの動作確認
centos1 -> centos2は、ネットワークが同一なので接続できるが、centos1 -> centos3は、別ネットワークにあるので、接続できない。
同様に、インターネットにも出れない。
$ docker exec -it centos1 ping -c 1 192.168.10.3 PING 192.168.10.3 (192.168.10.3) 56(84) bytes of data. 64 bytes from 192.168.10.3: icmp_seq=1 ttl=64 time=0.097 ms --- 192.168.10.3 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.097/0.097/0.097/0.000 ms $ docker exec -it centos1 ping -c 1 192.168.20.2 connect: Network is unreachable [root@a31c1ed4247a /]# ping -c 1 8.8.8.8 connect: Network is unreachable
デフォルトゲートウェイを設定する
centos1とcentos3のような別ネットワークにあるサーバ同士を接続する場合は、 お互いのデフォルトゲートウェイをvyos1に向ける必要がある。
行きと戻りのパケットの経路が必要なので、片道の経路だけでは疎通できないことに注意する。
$ docker exec -it centos1 ip route add default via 192.168.10.1 $ docker exec -it centos2 ip route add default via 192.168.10.1 $ docker exec -it centos3 ip route add default via 192.168.20.1 $ docker exec -it centos4 ip route add default via 192.168.20.1
設定状況は、以下のようになる。
$ docker exec -it centos1 ip r default via 192.168.10.1 dev eth0 192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.2 $ docker exec -it centos2 ip r default via 192.168.10.1 dev eth0 192.168.10.0/24 dev eth0 proto kernel scope link src 192.168.10.3 $ docker exec -it centos3 ip r default via 192.168.20.1 dev eth0 192.168.20.0/24 dev eth0 proto kernel scope link src 192.168.20.2 $ docker exec -it centos4 ip r default via 192.168.20.1 dev eth0 192.168.20.0/24 dev eth0 proto kernel scope link src 192.168.20.3
これで、centos1~4は、互いに疎通できる。
$ docker exec -it centos1 ping -c 1 192 .168.20.2 PING 192.168.20.2 (192.168.20.2) 56(84) bytes of data. 64 bytes from 192.168.20.2: icmp_seq=1 ttl=63 time=1.25 ms --- 192.168.20.2 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 1.257/1.257/1.257/0.000 ms
ただし、インターネットには出れないままなので、NATを設定する。
$ docker exec -it centos1 ping -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms
NATを設定する
vyos1にNATの設定を追加する。
$ docker exec -it vyos1 /bin/vbash
# su - minion
$ configure
# set interfaces loopback lo address 1.1.1.1/32
# set nat source rule 1 translation address masquerade
# set nat source rule 1 source address 192.168.0.0/16
# set nat source rule 1 outbound-interface eth0
# set nat source rule 1 description 'nat global 1'
# show
+interfaces {
+ loopback lo {
+ address 1.1.1.1/32
+ }
+}
+nat {
+ source {
+ rule 1 {
+ description "nat global 1"
+ outbound-interface eth0
+ source {
+ address 192.168.0.0/16
+ }
+ translation {
+ address masquerade
+ }
+ }
+ }
+}
# commit
# save
これで、vyos1のeth0を通してインターネットに出れる。
$ docker exec -it centos1 ping -c 1 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=50 time=2.27 ms --- 8.8.8.8 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 2.276/2.276/2.276/0.000 ms
あとで、作成した検証環境の構成をdocker-compose.ymlにまとめる。
参考