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にまとめる。
参考