Contrailクラスタ間で直接GRE接続するには

Contrailのクラスタが複数ある場合に、クラスタ間で直接GRE接続する方法についてまとめてみる。

通常、Contrailのクラスタは1つにしたいところなのだが、2サイトに分かれる場合など、複数クラスタに分かれてしまうケースも考えられる。
この場合もBGPを使ってcontroller間で経路配布を行うことで、クラスタ間で直接、GRE接続を行うことが出来る。
https://github.com/tonyliu0592/opencontrail/wiki/Gateway-MX
ただし、別クラスタで同じサブネットを払い出す場合、IPAMは共有されないため、IPが重複する可能性があるので注意

今回は、aws上に2セットのk8sを構築し、cirros間での疎通を行ってみた。

実施内容は以下となる。
1. BGPの設定
2. 仮想ネットワークの設定
3. cirrosの作成と疎通確認

設定時の出力内容は、以下となる。
> 1. BGPの設定
configure>networking>bgp routersから、対向のcontrollerノードを、External Control Node として追加する。

f:id:aaabbb_200904:20171106011102p:plain
f:id:aaabbb_200904:20171106011115p:plain

> 2. 仮想ネットワークの設定

2については、仮想ネットワークとして、最初から存在するcluster-network を使用した。
この後、ルートターゲットを設定する必要があるのだが、今回はクラスタが分かれているために、'router', 'policy' 等によるルートターゲットインポートを行うことは出来ない。
このため、今回は明示的にvrf-target を設定(65412:11 として、両側に設定)して、経路インポートを行うようにしている。(なお、同じクラスタ内でも、ルートターゲット設定で経路インポートを行うこともできる)
f:id:aaabbb_200904:20171106011230p:plain

> 3. cirrosの作成と疎通確認

クラスタにcirrosを作成する。
※ 一部のcirrosが同じipになってしまったので、別のipが出るまで複数作成している。

root@ip-172-31-3-97:~# kubectl get pod -o wide
NAME      READY     STATUS    RESTARTS   AGE       IP              NODE
cirros1   1/1       Running   0          1m        10.47.255.252   ip-172-31-6-143
cirros2   1/1       Running   0          1m        10.47.255.251   ip-172-31-15-186
cirros3   1/1       Running   0          40s       10.47.255.250   ip-172-31-6-143
root@ip-172-31-3-97:~# 

root@ip-172-31-12-54:~# kubectl get pod -o wide
NAME      READY     STATUS    RESTARTS   AGE       IP              NODE
cirros1   1/1       Running   0          1h        10.47.255.251   ip-172-31-7-27
root@ip-172-31-12-54:~# 

172.31.12.54側のクラスタのルーティングテーブルを確認すると、10.47.255.250 への経路(172.31.6.143, 24)が、BGPで配布されてきていることがわかる。

f:id:aaabbb_200904:20171106011307p:plain

この状態で、172.31.12.54側のcirros1にログインした後、sshで10.47.255.250 にログインし、/tmp/ 以下に適当なファイルを作っておく。

root@ip-172-31-12-54:~# kubectl exec -it cirros1 sh
/ # 
/ # ssh cirros@10.47.255.250

Host '10.47.255.250' is not in the trusted hosts file.
(fingerprint md5 03:b3:c9:16:e1:37:d0:67:9d:55:89:24:22:fa:51:ac)
Do you want to continue connecting? (y/n) y
cirros@10.47.255.250's password: 
$ ip -o a
1: lo:  mtu 65536 qdisc noqueue qlen 1\    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
1: lo    inet6 ::1/128 scope host \       valid_lft forever preferred_lft forever
15: eth0@if16:  mtu 1500 qdisc noqueue \    link/ether 02:7d:6d:99:f0:c2 brd ff:ff:ff:ff:ff:ff
15: eth0    inet 10.47.255.250/12 scope global eth0\       valid_lft forever preferred_lft forever
15: eth0    inet6 fe80::28f8:67ff:fe54:91e5/64 scope link \       valid_lft forever preferred_lft forever
$ echo aaa > /tmp/aaa
$ 

この後、172.31.3.97 (先ほどと別のk8sクラスタの、マスターサーバー) から該当のcirrosにログインし、先ほどのファイルが作成されていることを確認することが出来た。

root@ip-172-31-3-97:~# kubectl exec -it cirros3 sh
/ # cat /tmp/aaa 
aaa
/ # 

なお、今回はkubernetes間での疎通を行ったのだが、仕組み上は、k8s以外にvsphere, openstack 等との間でも経路やりとりができるはずである。
複数のオーケストレーター内でネットワーク分離を行いつつ、必要に応じて直接疎通を行う、という場合には、役に立つのではなかろうか。