13
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Kubernetes ネットワークの仕組み (Azure)

Last updated at Posted at 2018-05-09

Kubernetes のネットワークがどの様に実現されているか知りたかったので調べてメモしました。ここに書いているのは...

  • コンテナ (POD) のIPアドレスがどのようにルーティングされるか
  • SERVICE の Cluster-IP が、複数いる POD の IPアドレスにどうルーティングされるか
  • コンテナ (POD) 内のDNS名前解決はどうされるか

普通の Docker のネットワークについては こちら

Kubernetes ネットワークの仕組み (GKE) は こちら 。ほぼ同じです。

検証環境

Azure Container Service です。GKE ではありません。

2台の Agent Node と、1台の Master Node。

# kubectl get nodes

NAME                    STATUS    AGE       VERSION
k8s-agent-XXXXXXXX-0    Ready     4h        v1.7.7
k8s-agent-XXXXXXXX-1    Ready     4h        v1.7.7
k8s-master-XXXXXXXX-0   Ready     4h        v1.7.7

特に何も追加でデプロイはしませんでした。Kubernetes 標準の POD kube-dns が、いい感じに2台いて SERVICE で分散されているので、これを題材にします。

# kubectl get pods --namespace=kube-system

NAME                                READY     STATUS    RESTARTS   AGE
kube-dns-v20-3003781527-lc299       3/3       Running   0          4h
kube-dns-v20-3003781527-njvzk       3/3       Running   0          4h
...
# kubectl get services --namespace=kube-system

NAME               CLUSTER-IP    EXTERNAL-IP   PORT(S)         AGE
kube-dns           10.0.0.10     <none>        53/UDP,53/TCP   4h
...

まとめ

まずはまとめから。↓は Azure Container Service の場合で GKE はまたちょっと違うと思います。

Agent Node のみ。Master Node は省略。

Kubernetes (Azure).png

主要な3つのネットワーク範囲があります。

  • 物理ホストのネットワークが 10.240.0.0/16
  • それぞれの物理ホスト上に、コンテナのネットワーク 10.244.X.0/24 がある
    • Agent Node #0 には 10.244.0.0/24
    • Agent Node #1 には 10.244.1.0/24
  • SERVICE の Cluster-IP は 10.0.0.0/16 の範囲で振られる

コンテナのネットワーク。別々のホスト上にいるコンテナはこう↓ルーティングされます。

  • Destination=10.244.0.0/16 へのアクセスは Default Gateway 10.240.0.1 へ送信されます
  • 物理ゲートウェイのルートテーブルで物理ホストのIPアドレスへルーティングされます
    • 例えば、Destination=10.244.1.0/24 → Next Hop=10.240.0.5
  • 物理ホストに到達すると、ホストOSのルートテーブルで仮想NIC cbr0 に送信
  • 仮想NIC cbr0 の先に、宛先のコンテナのNICがあります

SERVICE の Cluster-IP 宛に送信すると...

  • 10.0.0.0/16 は全て ホストOSの iptables で解決されます (このアドレス範囲に該当する NIC はない)
  • 宛先 10.0.0.0/16DNAT で宛先 10.244.X.0/24 (コンテナIP) に書き換えられます
  • コンテナ (POD) が複数いる時は random probability 0... でランダムに選択されます

また、コンテナ内の /etc/resolv.conf を見ると nameserver は固定で 10.0.0.10 です。
これは kube-dns SERVICE の Cluster-IP です。

実際に追ってみた編

書いてあるIPとかは 今回たまたまこうだった です。

Gateway (10.240.0.1) のルートテーブル

コンテナネットワーク 10.244.X.0/24 へのアクセスが、そのネットワークが存在する物理ホスト宛にルーティングされています。

NAME ADDRESS PREFIX NEXT HOP
k8s-agent-154d19d7-0 10.244.0.0/24 10.240.0.4
k8s-agent-154d19d7-1 10.244.1.0/24 10.240.0.5
k8s-master-154d19d7-0 10.244.2.0/24 10.240.255.5

ホスト (Agent Node) のネットワーク

ifconfig の結果。

  • cbr0 ... この仮想NICの先にコンテナのNICがあります
  • docker0 ... Docker 標準のNICだけど Kubernetes 環境では使われていない?
  • eth0 ... ホストOSの物理NICです
  • vethXXXX ... ホストNIC→コンテナNIC間の仮想Ethernetケーブル
# ifconfig

cbr0      Link encap:Ethernet  HWaddr 0a:58:0a:f4:00:01  
          inet addr:10.244.0.1  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::808c:97ff:feb1:3bd5/64 Scope:Link
          UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
          RX packets:187644 errors:0 dropped:0 overruns:0 frame:0
          TX packets:228056 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:17175759 (17.1 MB)  TX bytes:150372583 (150.3 MB)

docker0   Link encap:Ethernet  HWaddr 02:42:bf:91:4b:33  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:bfff:fe91:4b33/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:424 (424.0 B)  TX bytes:508 (508.0 B)

eth0      Link encap:Ethernet  HWaddr 00:0d:3a:51:da:e1  
          inet addr:10.240.0.4  Bcast:10.240.255.255  Mask:255.255.0.0
          inet6 addr: fe80::20d:3aff:fe51:dae1/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:853884 errors:0 dropped:0 overruns:0 frame:0
          TX packets:568944 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:891926509 (891.9 MB)  TX bytes:78778540 (78.7 MB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:164 errors:0 dropped:0 overruns:0 frame:0
          TX packets:164 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:12040 (12.0 KB)  TX bytes:12040 (12.0 KB)

veth16050088 Link encap:Ethernet  HWaddr be:b7:5f:05:e5:8e  
          inet6 addr: fe80::bcb7:5fff:fe05:e58e/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6741 errors:0 dropped:0 overruns:0 frame:0
          TX packets:12518 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:400888 (400.8 KB)  TX bytes:939070 (939.0 KB)

...

ルートテーブル。

  • 外部への通信は Default Gateway 10.240.0.1
  • 物理ホストへの通信は eth0 NIC に投げる
  • このホスト上にあるコンテナへの通信は cbr0 NIC に投げる
  • 別のホスト上にあるコンテナへの通信は Default Gateway 10.240.0.1
# route -n

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.240.0.1      0.0.0.0         UG    0      0        0 eth0
10.240.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0
10.244.0.0      0.0.0.0         255.255.255.0   U     0      0        0 cbr0
...

コンテナのネットワーク

ubuntu ベースのコンテナで試したので、ネットワークコマンドは apt-get install net-tools で入れました

ifconfig の結果。

  • eth0 ... コンテナのIPアドレスが振られている仮想NICです。この先にホストOSの cbr0 仮想NICがあります
# ifconfig

eth0      Link encap:Ethernet  HWaddr 0a:58:0a:f4:00:06  
          inet addr:10.244.0.6  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::c41c:2dff:fe41:4752/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:12441 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6701 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:934720 (912.8 KiB)  TX bytes:398536 (389.1 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

コンテナのIPは 10.244.{ホスト毎の連番}.{ホスト上のコンテナ毎の連番} になります

ルートテーブル。

  • 外部への通信は Gateway 10.244.0.1
  • 同じホスト上のコンテナへの通信は eth0 NIC へ
  • 違うホスト上のコンテナへの通信は Gateway 10.244.0.1
# route -n

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.244.0.1      0.0.0.0         UG    0      0        0 eth0
10.244.0.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0

SERVICE の Cluster-IP

題材として kube-dns SERVICE の Cluster-IP 10.0.0.10 に着目しました。ホストOSの iptables を見てみます。

# iptables -t nat -L -n -v
...

Chain KUBE-SERVICES (2 references)
 pkts bytes target                     prot opt in     out   source        destination
    ...
    0     0 KUBE-MARK-MASQ             tcp  --  *      *    !10.244.0.0/16  10.0.0.10    tcp dpt:53
    0     0 KUBE-SVC-ERIFXISQEP7F7OF4  tcp  --  *      *     0.0.0.0/0      10.0.0.10    tcp dpt:53

Chain KUBE-SVC-ERIFXISQEP7F7OF4. ランダムで別々のルールに転送される様になっています。今回は kube-dns POD は2台だったので、それぞれ 50% の確率が割り当てられていますね。

# iptables -t nat -L -n -v
...

Chain KUBE-SVC-ERIFXISQEP7F7OF4 (1 references)
 pkts bytes target                     prot opt in     out   source        destination
    ...
    0     0 KUBE-SEP-IT2ZTR26TO4XFPTO  all  --  *      *     0.0.0.0/0      0.0.0.0/0 statistic mode random probability 0.50000000000
    0     0 KUBE-SEP-BWHGELGX6BITPZVO  all  --  *      *     0.0.0.0/0      0.0.0.0/0

確率50% その1 --> Chain KUBE-SEP-IT2ZTR26TO4XFPTO. DNAT で宛先をコンテナ (POD) のIPアドレスに書き換え。

# iptables -t nat -L -n -v
...

Chain KUBE-SEP-IT2ZTR26TO4XFPTO (1 references)
 pkts bytes target                     prot opt in     out     source        destination
    0     0 KUBE-MARK-MASQ             all  --  *      *       10.244.0.2     0.0.0.0/0
    0     0 DNAT                       tcp  --  *      *       0.0.0.0/0      0.0.0.0/0 tcp to:10.244.0.2:53

確率50% その2 --> Chain KUBE-SEP-BWHGELGX6BITPZVO. これは その1 とは異なる物理ホスト上のコンテナIPを示しています。

# iptables -t nat -L -n -v
...

Chain KUBE-SEP-BWHGELGX6BITPZVO (1 references)
 pkts bytes target                     prot opt in     out     source        destination
    0     0 KUBE-MARK-MASQ             all  --  *      *       10.244.1.2     0.0.0.0/0
    0     0 DNAT                       tcp  --  *      *       0.0.0.0/0      0.0.0.0/0 tcp to:10.244.1.2:53

コンテナの DNS Nameserver

コンテナに入って /etc/resolv.conf を確認。

# cat /etc/resolv.conf

nameserver 10.0.0.10
search default.svc.cluster.local svc.cluster.local cluster.local tbshyrd11cuundvieskktqf3ib.lx.internal.cloudapp.net
options ndots:5

この 10.0.0.10 は前述の通り kube-dns SERVICE の Cluster-IP なので、2台の kube-dns POD のうちどちらかで名前解決されることになります。

13
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?