前回、Dockerでルータが動くようにできたので、今度はルータを使ってダイナミックルーティングをしようと思います。
kurochan-note.hatenablog.jp
使うもの
- ubuntu 15.04
- vyOSのコンテナ
- open vSwitch
作るネットワーク
以下の図のようなルータ3台のシンプルなネットワーク構成にしました。
RouterAとRouterB、RouterBとRouterCは直接接続されていて、RouterAとRouterCは直接接続されていないので、RouterBにルーティングをしてもらわないと通信ができません。
OSPFで経路情報を交換して、RouterAとRouterC間の疎通が取れるようにする事をゴールにしてみようと思います。
それぞれのRouterがコンテナで動いていて、コンテナ間の接続にopen vSwitchを使います。
イメージとしてはこんな感じです。
環境構築
Ubuntu15.04とdockerとopen vSwitchがあればOKです。
$ sudo aptitude install docker.io openvswitch-common openvswitch-switch
$ sudo service docker start
ovs-docker
dockerのインターフェイスを簡単にopen vSwitchに接続ためのシェルスクリプトです。
今回インストールしたopenvswitch-commonには入っていなかったので、Githubのリポジトリからダウンロードしてきます。
ovs/ovs-docker at master · openvswitch/ovs · GitHub
$ wget https://raw.githubusercontent.com/openvswitch/ovs/master/utilities/ovs-docker
$ chmod +x ovs-docker
ネットワークを作る
ルータを作る
ルータを3台用意します。
Ubuntuのカーネルモジュールを使用するため、特権コンテナにして、 /lib/modules
をマウントしてあげます。
NICは後で追加するので、 --net=none
で起動します。
$ sudo docker run -d --name RouterA --net=none --privileged -v /lib/modules:/lib/modules kurochan/vyos:1.1.6 /sbin/init
$ sudo docker run -d --name RouterB --net=none --privileged -v /lib/modules:/lib/modules kurochan/vyos:1.1.6 /sbin/init
$ sudo docker run -d --name RouterC --net=none --privileged -v /lib/modules:/lib/modules kurochan/vyos:1.1.6 /sbin/init
スイッチを作る
vSwitchを1つ作ります。
$ sudo ovs-vsctl add-br vswitch0
スイッチとルータを接続する
ovs-docker
を使ってコンテナのNICの作成、IPアドレスとサブネットマスクの設定、スイッチへの接続をします。
RouterBだけNICを2つ作成します。
$ sudo ./ovs-docker add-port vswitch0 eth0 RouterA --ipaddress=192.168.100.1/24
$ sudo ./ovs-docker add-port vswitch0 eth0 RouterB --ipaddress=192.168.100.2/24
$ sudo ./ovs-docker add-port vswitch0 eth1 RouterB --ipaddress=192.168.200.2/24
$ sudo ./ovs-docker add-port vswitch0 eth0 RouterC --ipaddress=192.168.200.1/24
ポートVLANを設定する
ルータの全ポートが同じスイッチに繋がっている状態なので、VLANを使ってネットワークを分割します。ポートとVLANの対応は以下の表のようになります。
Router |
port |
vlan |
RouterA |
eth0 |
100 |
RouterB |
eth0 |
100 |
RouterB |
eth1 |
200 |
RouterC |
eth0 |
200 |
$ sudo ./ovs-docker set-vlan vswitch0 eth0 RouterA 100
$ sudo ./ovs-docker set-vlan vswitch0 eth0 RouterB 100
$ sudo ./ovs-docker set-vlan vswitch0 eth1 RouterB 200
$ sudo ./ovs-docker set-vlan vswitch0 eth0 RouterC 200
ここまでの確認
ここまでの疎通確認をしてみます。
まだルーティングの設定をしていないので、状態は以下の表のようになるはずです。
Router |
Router |
ping |
RouterA |
RouterB |
◯ |
RouterB |
RouterC |
◯ |
RouterA |
RouterC |
☓ |
RouterAからRouterB
$ sudo docker exec -it RouterA ping -c 1 192.168.100.2
PING 192.168.100.2 (192.168.100.2) 56(84) bytes of data.
64 bytes from 192.168.100.2: icmp_req=1 ttl=64 time=0.309 ms
--- 192.168.100.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.309/0.309/0.309/0.000 ms
RouterBからRouterC
$ sudo docker exec -it RouterB ping -c 1 192.168.200.1
PING 192.168.200.1 (192.168.200.1) 56(84) bytes of data.
64 bytes from 192.168.200.1: icmp_req=1 ttl=64 time=0.998 ms
--- 192.168.200.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.998/0.998/0.998/0.000 ms
RouterAからRouterC
$ sudo docker exec -it RouterA ping -c 1 192.168.200.1
connect: Network is unreachable
ルータの設定をする
各ルータにOSPFの設定をして、経路情報を交換してルーティングできるようにします。
RouterA
$ sudo docker exec -it RouterA /bin/vbash
vbash-4.1# su - vyos
vyos@vyos:~$ configure
vyos@vyos# set interfaces loopback lo address 1.1.1.1/32
vyos@vyos# set protocols ospf area 0 network 192.168.0.0/16
vyos@vyos# set protocols ospf parameters router-id 1.1.1.1
vyos@vyos# commit
vyos@vyos# exit
vyos@vyos:~$ exit
vbash-4.1# exit
RouterB
$ sudo docker exec -it RouterB /bin/vbash
vbash-4.1# su - vyos
vyos@vyos:~$ configure
vyos@vyos# set interfaces loopback lo address 2.2.2.2/32
vyos@vyos# set protocols ospf area 0 network 192.168.0.0/16
vyos@vyos# set protocols ospf parameters router-id 2.2.2.2
vyos@vyos# commit
vyos@vyos# exit
vyos@vyos:~$ exit
vbash-4.1# exit
RouterC
$ sudo docker exec -it RouterC /bin/vbash
vbash-4.1# su - vyos
vyos@vyos:~$ configure
vyos@vyos# set interfaces loopback lo address 3.3.3.3/32
vyos@vyos# set protocols ospf area 0 network 192.168.0.0/16
vyos@vyos# set protocols ospf parameters router-id 3.3.3.3
vyos@vyos# commit
vyos@vyos# exit
vyos@vyos:~$ exit
vbash-4.1# exit
再び確認
再び疎通確認をしてみます。
OSPFできちんと経路交換をしてルーティングされていれば、状態は以下の表のようになるはずです。
Router |
Router |
ping |
RouterA |
RouterB |
◯ |
RouterB |
RouterC |
◯ |
RouterA |
RouterC |
◯ |
RouterAからRouterB
$ sudo docker exec -it RouterA ping -c 1 192.168.100.2
PING 192.168.100.2 (192.168.100.2) 56(84) bytes of data.
64 bytes from 192.168.100.2: icmp_req=1 ttl=64 time=0.215 ms
--- 192.168.100.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.215/0.215/0.215/0.000 ms
RouterBからRouterC
$ sudo docker exec -it RouterB ping -c 1 192.168.200.1
PING 192.168.200.1 (192.168.200.1) 56(84) bytes of data.
64 bytes from 192.168.200.1: icmp_req=1 ttl=64 time=0.238 ms
--- 192.168.200.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.238/0.238/0.238/0.000 ms
RouterAからRouterC
$ sudo docker exec -it RouterA ping -c 1 192.168.200.1
PING 192.168.200.1 (192.168.200.1) 56(84) bytes of data.
64 bytes from 192.168.200.1: icmp_req=1 ttl=63 time=0.280 ms
--- 192.168.200.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.280/0.280/0.280/0.000 ms
RouterAからRouterCの通信ができるようになりましたね!
せっかくなのでルーティングテーブルも確認
RouterAのルーティングテーブルを確認してみます。
$ sudo docker exec -it RouterA /bin/vbash
vbash-4.1# su - vyos
vyos@vyos:~$ show ip route
WARNING: terminal is not fully functional
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
I - ISIS, B - BGP, > - selected route, * - FIB route
C>* 1.1.1.1/32 is directly connected, lo
C>* 127.0.0.0/8 is directly connected, lo
O 192.168.100.0/24 [110/10] is directly connected, eth0, 00:10:38
C>* 192.168.100.0/24 is directly connected, eth0
O>* 192.168.200.0/24 [110/20] via 192.168.100.2, eth0, 00:05:33
さいごに
ルータをコンテナで動かして、実際にルーティングするところまでやってみました。
コンテナで動いているため、ノートPC1台あればルータを10台くらい立てたりできると思うので、ネットワークの勉強をするための環境にはよいかもしれません。
今更ですが、ポートVLANを使わなくてもvSwitchをもう一つ作った方が分かりやすかった気がしてきました(笑)