kubernetes連携時の動作2

前回に引き続き、contrailとkubernetesを組み合わせた場合の動作の確認となる。
https://github.com/Juniper/contrail-controller/wiki/Kubernetes

ingress

ingress はservice と違い、L7でのロードバランスを行う仕組みとなる。
contrail 使用時は、各スレーブノード内にhaproxyが起動し、振り分けを行う動作となる。

サンプルのyamlは以下を参照。
https://github.com/tnaganawa/contrail-k8s-tutorial/tree/master/yml/3_contrail-cni-features/3_ingress

順に定義していくと、以下のように、ingresssvc に対してアタッチされる動作となる。

root@ip-172-31-3-97:~# kubectl get pod -o wide
NAME                                READY     STATUS    RESTARTS   AGE       IP              NODE
cirros-pod                          1/1       Running   1          1d        10.47.255.252   ip-172-31-6-143
nginx-deployment-1286893921-hjkth   1/1       Running   0          6m        10.47.255.252   ip-172-31-6-143
nginx-deployment-1286893921-tbkhk   1/1       Running   0          6m        10.47.255.251   ip-172-31-15-186

root@ip-172-31-3-97:~# kubectl get deployment -o wide
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINER(S)   IMAGE(S)      SELECTOR
nginx-deployment   2         2         2            2           6m        nginx          nginx:1.7.9   app=nginx-deployment

root@ip-172-31-3-97:~# kubectl get svc -o wide
NAME         CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE       SELECTOR
kubernetes   10.96.0.1              443/TCP   21d       
nginx-svc    10.97.170.21           80/TCP    6m        app=nginx-deployment

root@ip-172-31-3-97:~# kubectl get ing -o wide
NAME            HOSTS     ADDRESS         PORTS     AGE
nginx-ingress   *         10.47.255.250   80        6m

pod内にログインして、curl実行することで、urlが提供されていることが分かる。

root@ip-172-31-3-97:~# kubectl exec -it cirros-pod sh
/ # 
/ # curl 10.47.255.250
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
(snip)

なお、ルーティングテーブルを確認してみると、該当のIPは各スレーブノードへの経路が配布されており、行き先は、特定のlinux namespaceとなっている。
f:id:aaabbb_200904:20171106003752p:plain
f:id:aaabbb_200904:20171106003759p:plain

スレーブノードにログインして確認 (agentのdocker内でnetnsが作成されている) してみると、以下のようにhaproxyが起動されていることが分かる。

root@ip-172-31-15-186(agent):/# ip netns                                                                                   
RTNETLINK answers: Invalid argument
RTNETLINK answers: Invalid argument
vrouter-8e2c207e-8799-4422-8f3c-631635e67e03:aab44187-c1f9-11e7-8cc3-06b5b8f5fd22
root@ip-172-31-15-186(agent):/#    

root@ip-172-31-15-186(agent):/# ps -ef | cat
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 07:12 ?        00:00:00 /lib/systemd/systemd systemd.unit=multi-user.target
root        19     1  0 07:12 ?        00:00:00 /lib/systemd/systemd-journald
root       814     1  2 07:12 ?        00:00:37 /usr/bin/contrail-vrouter-agent
contrail   821     1  0 07:12 ?        00:00:05 /usr/bin/python /usr/bin/contrail-nodemgr --nodetype=contrail-vrouter
message+   920     1  0 07:12 ?        00:00:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
haproxy   2898     1  0 07:19 ?        00:00:00 haproxy -f /var/lib/contrail/loadbalancer/haproxy/aab44187-c1f9-11e7-8cc3-06b5b8f5fd22/haproxy.conf -p /var/lib/contrail/loadbalancer/haproxy/aab44187-c1f9-11e7-8cc3-06b5b8f5fd22/haproxy.pid -sf 2887
root      3451     0  0 07:34 ?        00:00:00 bash
root      3802  3451  0 07:43 ?        00:00:00 ps -ef
root      3803  3451  0 07:43 ?        00:00:00 cat
root@ip-172-31-15-186(agent):/# 

haproxy自体は各スレーブノードで起動されているようなので、スレーブノードが全て停止しない限り、ingressは継続出来るようである。

namespace

通常、kubernetes でnamespace を設定した場合、

  • kubectl の表示対象を分離する
  • kube-dnsドメイン名としてnamespace の名前が使用される

等の違いはあるが、ネットワーク的には分離されない状況となる。

contrail 使用時も、この動作に変化はないが、追加の機能として、namespace 作成時に以下のannotation を設定することで、互いに疎通が取れないnamespace を作成することが出来るようになる。
※ 内部的には namespace の名前を持つ仮想ネットワークが作成される

  annotations: {
   "opencontrail.org/isolation" : "true"
  }

yamlのサンプルは以下を参照。
https://github.com/tnaganawa/contrail-k8s-tutorial/tree/master/yml/3_contrail-cni-features/4_namespace

作成を行うと、以下のようにnamespaceが作成される。

root@ip-172-31-3-97:~# kubectl get ns -o wide
NAME          STATUS    AGE
default       Active    21d
kube-public   Active    21d
kube-system   Active    21d
myns1         Active    8m
myns2         Active    6m

root@ip-172-31-3-97:~# kubectl get pod -n myns1 -o wide
NAME           READY     STATUS    RESTARTS   AGE       IP              NODE
cirros-myns1   1/1       Running   0          2m        10.47.255.252   ip-172-31-15-186
root@ip-172-31-3-97:~# kubectl get pod -n myns2 -o wide
NAME           READY     STATUS    RESTARTS   AGE       IP              NODE
cirros-myns2   1/1       Running   0          11s       10.47.255.250   ip-172-31-6-143
root@ip-172-31-3-97:~# 

※ namespace内にpodを作る場合、以下のように、作成時にnamespaceを指定する必要があるので注意

# kubectl create -n myns1 -f cirros-myns1.yaml 
pod "cirros-myns1" created


この状態で、myns1内のpodに入り、myns2内のpodにpingを打つと、pingが飛ばず、ネットワークが分離されていることが確認できる。
複数のシステムを扱い、システム間で互いに疎通できないようにしたい場合に、活用できるのではなかろうか。

root@ip-172-31-3-97:~# kubectl exec -it -n myns1 cirros-myns1 sh
/ # ping 10.47.255.250
PING 10.47.255.250 (10.47.255.250): 56 data bytes
^C
--- 10.47.255.250 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss