OSPFによる動的ルーティングをdocker container間で動かす
ひとつのVM内でdocker containerを複数立ち上げ,その間でOSPFを動かす.
pingを通すだけでなく,動的に経路が切り替わるのを確認する. コードはこちら.
ホストの立ち上げから必要な設定の注入に関しては以下のサイトにとても丁寧に書いてある. 今回の設定については,ほんの数行なのでgithubを参照してください. qiita.com
環境
- ホストマシン Ubuntu 20.04.1 LTS
- ルータ FRRouting/frr v8.8.2
- ホスト jonlabelle/docker-network-tools
ネットワーク構成
large/docker-compose.yamlの通りです.
動作
1. コンテナの立ち上げ
$ git clone https://github.com/kkti4216/docker-ospf.git $ cd docker-ospf/large $ docker-compose up -d
2. h1からh2への経路を確認
h1 -> frr1 -> frr2 -> h2となっている.
$ docker container exec -it h1 bash bash-5.1# traceroute -n 192.168.2.12 traceroute to 192.168.2.12 (192.168.2.12), 30 hops max, 46 byte packets 1 192.168.1.11 0.004 ms 0.002 ms 0.002 ms 2 192.168.11.22 0.003 ms 0.003 ms 0.002 ms 3 192.168.2.12 0.002 ms 0.002 ms 0.003 ms
3. frr1 - frr2のリンクのコストを大きく
沼に嵌った話はおまけへ.
frr1-eth1 (frr2側のインターフェース) のコストを編集.
$ docker container exec -it frr1 bash bash-5.1# vtysh Hello, this is FRRouting (version 8.2.2_git). Copyright 1996-2005 Kunihiro Ishiguro, et al. frr1# conf frr1(config)# int eth1 frr1(config-if)# ip ospf cost 100
frr2-eth0も同様にコストを編集.
$ docker container exec -it frr2 bash bash-5.1# vtysh Hello, this is FRRouting (version 8.2.2_git). Copyright 1996-2005 Kunihiro Ishiguro, et al. frr2# conf frr2(config)# int eth0 frr2(config-if)# ip ospf cost 100
再びh1からh2への経路を確認. frr3を経由するようになった.
$ docker container exec -it h1 bash bash-5.1# traceroute -n 192.168.2.12 traceroute to 192.168.2.12 (192.168.2.12), 30 hops max, 46 byte packets 1 192.168.1.11 0.005 ms 0.002 ms 0.002 ms 2 192.168.33.33 0.001 ms 0.002 ms 0.002 ms 3 192.168.22.22 0.002 ms 0.003 ms 0.002 ms 4 192.168.2.12 0.002 ms 0.003 ms 0.003 ms
この時のh1のルーティングテーブルは以下のようになる.
$ docker container exec -it frr1 bash frr1# show ip ospf route ============ OSPF network routing table ============ N 192.168.1.0/24 [10] area: 0.0.0.0 directly attached to eth0 N 192.168.2.0/24 [30] area: 0.0.0.0 via 192.168.33.33, eth2 N 192.168.3.0/24 [20] area: 0.0.0.0 via 192.168.33.33, eth2 N 192.168.11.0/24 [100] area: 0.0.0.0 directly attached to eth1 N 192.168.22.0/24 [20] area: 0.0.0.0 via 192.168.33.33, eth2 N 192.168.33.0/24 [10] area: 0.0.0.0 directly attached to eth2 ============ OSPF router routing table ============= ============ OSPF external routing table ===========
4. frr2-eth2をdownさせる
frr3 - frr2の接続が切れるため,h1 -> h2のパケットはコストの大きいリンクを通ることになる.
$ docker container exec -it frr2 bash bash-5.1# ip link set eth2 down
h1から再びtraceroute
すると,たしかにfrr3を経由しない経路へ戻った.
$ docker container exec -it f1 bash bash-5.1# traceroute -n 192.168.2.12 traceroute to 192.168.2.12 (192.168.2.12), 30 hops max, 46 byte packets 1 192.168.1.11 0.004 ms 0.003 ms 0.003 ms 2 192.168.11.22 0.003 ms 0.002 ms 0.003 ms 3 192.168.2.12 0.002 ms 0.003 ms 0.002 ms
この時のfrr1のルーティングテーブルは以下.
192.168.2.0/24
へのコストが大きくなっている.
$ docker container exec -it frr1 bash frr1# show ip ospf route ============ OSPF network routing table ============ N 192.168.1.0/24 [10] area: 0.0.0.0 directly attached to eth0 N 192.168.2.0/24 [110] area: 0.0.0.0 via 192.168.11.22, eth1 N 192.168.3.0/24 [20] area: 0.0.0.0 via 192.168.33.33, eth2 N 192.168.11.0/24 [100] area: 0.0.0.0 directly attached to eth1 N 192.168.22.0/24 [20] area: 0.0.0.0 via 192.168.33.33, eth2 N 192.168.33.0/24 [10] area: 0.0.0.0 directly attached to eth2 ============ OSPF router routing table ============= ============ OSPF external routing table ===========
また,frr3のルーティングテーブルを確認すると,h2 (192.168.2.0/24
) への経路がfrr1経由となっておりdownさせたリンクを迂回できている.
$ docker container exec -it frr3 bash bash-5.1# vtysh Hello, this is FRRouting (version 8.2.2_git). Copyright 1996-2005 Kunihiro Ishiguro, et al. frr3# show ip ospf route ============ OSPF network routing table ============ N 192.168.1.0/24 [20] area: 0.0.0.0 via 192.168.33.11, eth2 N 192.168.2.0/24 [120] area: 0.0.0.0 via 192.168.33.11, eth2 N 192.168.3.0/24 [10] area: 0.0.0.0 directly attached to eth1 N 192.168.11.0/24 [110] area: 0.0.0.0 via 192.168.33.11, eth2 N 192.168.22.0/24 [10] area: 0.0.0.0 directly attached to eth0 N 192.168.33.0/24 [10] area: 0.0.0.0 directly attached to eth2 ============ OSPF router routing table ============= ============ OSPF external routing table ===========
5. まとめ
実際に経路が切り替わるのはネットワークを弄れている実感が湧いて楽しい. docker network や docker-compose などdockerまわりのいい勉強にもなった.
おまけ
コストを大きくする際,片方のインターフェースのみしか編集しておらず沼に嵌った.
3. frr1 - frr2のリンクのコストを大きくから分岐.
frr1のeth1 (frr2と接続しているinterface) のコストを大きくする.
$ docker container exec -it frr1 bash bash-5.1# vtysh frr1# conf frr1(config)# interface eth1 frr1(config-if)# ip ospf cost 100
再びh1からh2への経路を確認. frr3を経由するようになっている.
$ docker container exec -it h1 bash bash-5.1# traceroute -n 192.168.2.12 traceroute to 192.168.2.12 (192.168.2.12), 30 hops max, 46 byte packets 1 192.168.1.11 0.004 ms 0.002 ms 0.002 ms 2 192.168.33.33 0.002 ms 0.002 ms 0.003 ms 3 192.168.11.22 0.001 ms 0.002 ms 0.002 ms 4 192.168.2.12 0.002 ms 0.002 ms 0.003 ms
ただし,3 192.168.11.22 0.001 ms 0.002 ms 0.002 ms
のルータのアドレスが 192.168.22.22
になっていない.
試しにfrr2-eth0をdownさせてみる.
$ docker container exec -it frr2 bash bash-5.1# ip link set eth0 down
もう一度経路を確認.
$ docker container exec -it h1 bash bash-5.1# traceroute -n 192.168.2.12 traceroute to 192.168.2.12 (192.168.2.12), 30 hops max, 46 byte packets 1 192.168.1.11 0.004 ms 0.002 ms 0.003 ms 2 192.168.33.33 0.001 ms 0.002 ms 0.003 ms 3 192.168.22.22 0.002 ms 0.002 ms 0.003 ms 4 192.168.2.12 0.002 ms 0.003 ms 0.003 ms
正しく192.168.22.22
を経由できている.
traceroute
はTTL値をインクリメントしながら送信し,返ってくるICMPパケットを見る.
frr2でTTL=0
となるパケットの経路がfrr2-eth0経由となったのが原因と考えられる.
本来一番最初にするべきであるルーティングテーブルを確認. frr2では,
$ docker container exec -it frr2 bash frr2# show ip ospf route ============ OSPF network routing table ============ N 192.168.1.0/24 [20] area: 0.0.0.0 via 192.168.11.11, eth0 N 192.168.2.0/24 [10] area: 0.0.0.0 directly attached to eth1 N 192.168.3.0/24 [20] area: 0.0.0.0 via 192.168.22.33, eth2 N 192.168.11.0/24 [10] area: 0.0.0.0 directly attached to eth0 N 192.168.22.0/24 [10] area: 0.0.0.0 directly attached to eth2 N 192.168.33.0/24 [20] area: 0.0.0.0 via 192.168.11.11, eth0 via 192.168.22.33, eth2 ============ OSPF router routing table ============= ============ OSPF external routing table ===========
h1(192.168.1.12
)へのパケットはコストを100に設定したはずのfrr1-eth1を経由することになっている(通常のインターフェースのコストは10).
インターフェースにコストを設定した場合,送信する側のコストのみが影響する様子?
調べてみると一般的には受信側のコストで計算されるらしいがよくわからず...
frr1のルーティングテーブルも確認してみると,192.168.11.0/24
への経路はfrr1 -> frr3 -> frr2 -> となっている.
$ docker container exec -it frr1 bash bash-5.1# vtysh frr1# show ip ospf route ============ OSPF network routing table ============ N 192.168.1.0/24 [10] area: 0.0.0.0 directly attached to eth0 N 192.168.2.0/24 [30] area: 0.0.0.0 via 192.168.33.33, eth2 N 192.168.3.0/24 [20] area: 0.0.0.0 via 192.168.33.33, eth2 N 192.168.11.0/24 [30] area: 0.0.0.0 via 192.168.33.33, eth2 N 192.168.22.0/24 [20] area: 0.0.0.0 via 192.168.33.33, eth2 N 192.168.33.0/24 [10] area: 0.0.0.0 directly attached to eth2 ============ OSPF router routing table ============= ============ OSPF external routing table ===========
frr2で
TTL=0
となるパケットの経路がfrr2-eth0経由となったのが原因と考えられる.
で正しそう. 本当はfrr1-eth1でtcpdumpとかすれば良さそう.
ここでfrr2-eth0のコストもfrr-eth1と同様にコストを高くする.
$ docker container exec -it frr2 bash frr2:/# ip link set eth0 up frr2:/# vtysh frr2# conf frr2(config)# int eth0 frr2(config-if)# ip ospf cost 100
経路を確認.
traceroute to 192.168.2.12 (192.168.2.12), 30 hops max, 46 byte packets 1 192.168.1.11 0.005 ms 0.002 ms 0.002 ms 2 192.168.33.33 0.024 ms 0.002 ms 0.002 ms 3 192.168.22.22 0.002 ms 0.002 ms 0.002 ms 4 192.168.2.12 0.004 ms 0.002 ms 0.002 ms
正しく192.168.22.22
を経由してくれるようになった.
おまけここまで