はじめに
この記事はAmazon EKS Advent Calendar 2019 11日目の記事です。
- Amazon VPC CNI plugin for KubernetesのソースコードリーディングでEKSのネットワーキングについて理解を深める #1 (イマココ)
- Amazon VPC CNI plugin for KubernetesのソースコードリーディングでEKSのネットワーキングについて理解を深める #2
- Amazon VPC CNI plugin for KubernetesのソースコードリーディングでEKSのネットワーキングについて理解を深める #3
巷ではEKSにNodeGroupを作成するAPIが追加されたり、FargateがGAになったりと新機能が話題ですが、
今回はそんな新機能には全く触れず、原点に立ち返って、EKSのネットワークの特徴でもある、Amazon VPC CNIプラグイン(amazon-vpc-cni-k8s)について見ていきたいと思います。
自分は長らくEKSでKubernetesを触っていましたが、正直ネットワーク周りをあまり理解していませんでした。
ただKubernetesを触る以上そろそろネットワークのこともちゃんと知っておかないとと思い、改めてEKSのネットワーキングについてまとめたいと思います。
また先に謝らせていただくと、長くなったので実際にソースコードを見ていくのは#2で行います。
CNIプラグインのソースコードまで目を通してみると、Operator SDKや自前のコントローラーがあったり、RWMutexでインメモリデータストアが実装されていたりなど、ネットワークだけでなく色々と発見があって面白いです。
そんな感じでまとまるか少々不安ですが、少しでもどなたかのご参考になれば幸いです。
Amazon VPC CNI pluginの概要
まずはEKSのドキュメントから。
ポッドネットワーキング (CNI)
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/pod-networking.html
Amazon EKS は、Amazon VPC CNI plugin for Kubernetes を経由してネイティブな VPC ネットワーキングをサポートします。この CNI プラグインを使用すると、Kubernetes ポッドは VPC ネットワーク上と同じ IP アドレスをポッド内に持つことができます。この CNI プラグインは、GitHub で管理されているオープンソースのプロジェクトです。
正式名称は「Amazon VPC CNI plugin for Kubernetes」。
Githubのリポジトリはこちら→ https://github.com/aws/amazon-vpc-cni-k8s
Amazon VPC CNIプラグインはEKSのデフォルトCNIプラグインですが、EKS以外にも利用することが可能です。
Creating a single control-plane cluster with kubeadm
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/#tabs-pod-install-1
AWS VPC CNI provides native AWS VPC networking to Kubernetes clusters.
自分も一度kubeadmで構築したことがあります。以前はバグに当たったりなどHard wayな印象でしたが、EKSのネットワークに興味ある人は是非。
ただ、そんなところに興味もなかった昔の自分は、
「ENIのセカンダリIPなるものがPodに割り振られるらしい。だからクラスタ外からもPodのIPに直接繋がるらしい。」
そんな程度の理解でした。
ENIのセカンダリIPについて
ところでENIって意外と何者かわからなくないでしょうか(少なくとも自分はわかりませんでした)
しかもENIのセカンダリIPについては、特にネット上の情報が少ない印象です。
複数の IP アドレス
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/MultipleIP.html
ENIはEC2等にアタッチ可能な仮想ネットワークインターフェースです。実態はよく分かりませんが、MACアドレスを動的に割り当てる仕組みなのでしょうか。
ENIには複数のIPアドレスを割り当てることが可能で、1つのプライマリIPと、複数のセカンダリIPを持つことができます。
このようなENIの特徴のうち、Amazon VPC CNIプラグインにとって重要なことは、「ENIのセカンダリIPはEC2内で割り振り直すことができる」ということです。これを利用することで、VPCネイティブなPodネットワーキングを実現しています。
セカンダリプライベート IPv4 アドレスを認識するようにインスタンスのオペレーティングシステムを設定する
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/MultipleIP.html
セカンダリプライベート IPv4 アドレスをインスタンスに割り当てたら、セカンダリプライベート IP アドレスを認識するようにインスタンスのオペレーティングシステムを設定する必要があります。
ネットワークインターフェイスに割り当てられているセカンダリプライベート IPv4 アドレスは、明示的に許可された場合、別のネットワークインターフェイスに割り当て直すことができます。
ENIやセカンダリIPはEC2インスタンスタイプごとに割り当て可能な量に違いがあります。そのためEKSのノードで動かせるPod数は、CPUやメモリといったリソースのほかに、IPアドレス数の制限を受けます。
CNIプラグインのコンポーネント
次にCNIプラグインがどのような構成なのか見ていきます。
先ほどのEKSのドキュメントの続きをみます。
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/pod-networking.html
CNI プラグインは、Kubernetes ノードに VPC IP アドレスを割り当て、各ノードのポッドに必要なネットワークを設定します。このプラグインは 2 つの主なコンポーネントで構成されています。
- L-IPAM デーモンは、インスタンスへの Elastic Network Interface の接続、Elastic Network Interface へのセカンダリ IP アドレスの割り当て、スケジュールされた際に Kubernetes ポッドに割り当てるために各ノードにおける IP アドレスの「ウォームプール」の維持を行います。
- CNI プラグインは、ホストネットワークの接続 (例: インターフェイスと仮想イーサネットペアの設定) とポッド名前空間への正しいインターフェイスの追加を行います。
L-IPAMデーモン
(Local IP Address Manager Daemon、ipamdとの記載もあります)は、各ノードでaws-node
というdaemonsetのPodで起動します。L-IPAMは内部にデータストアをもち、IPアドレスの管理やPodへのアサインを行っています。gRPCサーバの機能ももち、CNIプラグインからのPodの追加/削除リクエストに応えます。
CNIプラグイン
は、その名の通り、CNIの仕様に沿って実行されるモジュールで、gRPCでL-IPAMと通信してIPを取得し、ネットワーク設定を行います。以下、公式のイメージを引用します。
Inter-process communication between CNI-plugin and L-IPAM
https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md#inter-process-communication--between-cni-plugin-and-l-ipam
(Officeでちょろっと作ったような図ですよね・・・笑)
そもそもCNIって・・・という方には以下の記事が参考になります。
CNCF CNI プラグイン
https://qiita.com/hichihara/items/54ff9aeff476bf463509
EKSクラスター作成時の状態
それでは実際にEKSの状態を見ていきましょう。
クラスターの状態
まずはkubectlでクラスターの状態から。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-10-110-10-171.ap-northeast-1.compute.internal Ready <none> 8h v1.14.7-eks-1861c5
ip-10-110-10-233.ap-northeast-1.compute.internal Ready <none> 9d v1.14.7-eks-1861c5
ip-10-110-20-254.ap-northeast-1.compute.internal Ready <none> 8d v1.14.7-eks-1861c5
$ kubectl get all -n kube-system -l k8s-app=aws-node -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/aws-node-2gl8m 1/1 Running 0 16h 10.110.10.171 ip-10-110-10-171.ap-northeast-1.compute.internal <none> <none>
pod/aws-node-v8w76 1/1 Running 0 9d 10.110.10.233 ip-10-110-10-233.ap-northeast-1.compute.internal <none> <none>
pod/aws-node-xpqxv 1/1 Running 0 9d 10.110.20.254 ip-10-110-20-254.ap-northeast-1.compute.internal <none> <none>
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
daemonset.apps/aws-node 3 3 3 3 3 <none> 14d aws-node 602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni:v1.5.3 k8s-app=aws-node
$ kubectl describe daemonset.apps/aws-node -n kube-system
Name: aws-node
Selector: k8s-app=aws-node
Node-Selector: <none>
Labels: k8s-app=aws-node
Annotations: deprecated.daemonset.template.generation: 1
kubectl.kubernetes.io/last-applied-configuration:{}
Desired Number of Nodes Scheduled: 3
Current Number of Nodes Scheduled: 3
Number of Nodes Scheduled with Up-to-date Pods: 3
Number of Nodes Scheduled with Available Pods: 3
Number of Nodes Misscheduled: 0
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: k8s-app=aws-node
Service Account: aws-node
Containers:
aws-node:
Image: 602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni:v1.5.3
Port: 61678/TCP
Host Port: 61678/TCP
Requests:
cpu: 10m
Environment:
AWS_VPC_K8S_CNI_LOGLEVEL: DEBUG
MY_NODE_NAME: (v1:spec.nodeName)
Mounts:
/host/etc/cni/net.d from cni-net-dir (rw)
/host/opt/cni/bin from cni-bin-dir (rw)
/host/var/log from log-dir (rw)
/var/run/docker.sock from dockersock (rw)
Volumes:
cni-bin-dir:
Type: HostPath (bare host directory volume)
Path: /opt/cni/bin
HostPathType:
cni-net-dir:
Type: HostPath (bare host directory volume)
Path: /etc/cni/net.d
HostPathType:
log-dir:
Type: HostPath (bare host directory volume)
Path: /var/log
HostPathType:
dockersock:
Type: HostPath (bare host directory volume)
Path: /var/run/docker.sock
HostPathType:
Events: <none>
aws-node
というdaemonsetが起動します。いつも見るやつですね。
この中でL-IPAMが動いています。
このPodのIPは各ノードのプライマリIPとなっており、HostPathでいくつかホスト上のディレクトリをマウントしていることがわかります。
また、CRDが1つ作成されています。
$ kubectl api-resources # 抜粋
NAME SHORTNAMES APIGROUP NAMESPACED KIND
eniconfigs crd.k8s.amazonaws.com false ENIConfig
これは、Podのネットワークに、同じVPC内にある別のセキュリティグループまたはサブネットを使用したい場合にオプションで利用します。
今回は詳しく触れませんので、公式ドキュメントを貼っておきます。
CNI カスタムネットワーク
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/cni-custom-network.html
ノードの状態
ノードにログインして、先ほど確認した、aws-node
にHostPathでマウントしているディレクトリを見ていきましょう。
cni-bin-dir:
cniで利用される実行ファイルが配置されたディレクトリです。kubeletの起動オプションで変えられた気がしますが、マウントされているのはデフォルトで利用されるディレクトリです。
EKSのドキュメントに記載のあったCNIプラグインがaws-cni
というモジュールです。
CNIの仕様に沿って実行され、ipamdとgRPCで通信します。
$ ll /opt/cni/bin
合計 69688
-rwxr-xr-x 1 root root 15863452 11月 28 00:12 aws-cni <---------- これ
-rwxr-xr-x 1 root root 3110 11月 28 00:12 aws-cni-support.sh
-rwxr-xr-x 1 root root 4028260 3月 15 2019 bridge
-rwxr-xr-x 1 root root 2775211 8月 17 2017 cnitool
-rwxr-xr-x 1 root root 10232415 3月 15 2019 dhcp
-rwxr-xr-x 1 root root 2856252 3月 15 2019 flannel
-rwxr-xr-x 1 root root 3127363 3月 15 2019 host-device
-rwxr-xr-x 1 root root 3036768 3月 15 2019 host-local
-rwxr-xr-x 1 root root 3572685 3月 15 2019 ipvlan
-rwxr-xr-x 1 root root 3084347 3月 15 2019 loopback
-rwxr-xr-x 1 root root 3613497 3月 15 2019 macvlan
-rwxr-xr-x 1 root root 2606733 8月 17 2017 noop
-rwxr-xr-x 1 root root 3470464 11月 28 00:12 portmap
-rwxr-xr-x 1 root root 3993428 3月 15 2019 ptp
-rwxr-xr-x 1 root root 2641877 3月 15 2019 sample
-rwxr-xr-x 1 root root 2850029 3月 15 2019 tuning
-rwxr-xr-x 1 root root 3568537 3月 15 2019 vlan
なお、aws-cni-support.sh
はデバッグ用の情報収集ツールです。Githubにほんの少しドキュメントがあります。
Troubleshooting Tips
https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/troubleshooting.md
collecting node level tech-support bundle for offline troubleshooting
[root@ip-192-168-188-7 aws-routed-eni]# /opt/cni/bin/aws-cni-support.sh
// download
/var/log/aws-routed-eni/aws-cni-support.tar.gz
cni-net-dir:
CNIの設定を記載したConfigファイルを配置するディレクトリです。
このディレクトリにConfigファイルを配置することで、NodeStatus が Ready になります。
中身には、先ほどのaws-cni
をCNIプラグインとして使うことなどが記載されています。
$ ll /etc/cni/net.d
合計 4
-rw-r--r-- 1 root root 235 11月 28 00:12 10-aws.conflist
$ cat /etc/cni/net.d/10-aws.conflist
{
"name": "aws-cni",
"plugins": [
{
"name": "aws-cni",
"type": "aws-cni",
"vethPrefix": "eni"
},
{
"type": "portmap",
"capabilities": {"portMappings": true},
"snat": true
}
]
}
log-dir:
ipamdやCNIプラグインのログが出力されています。
1時間ごと1日24ファイルも作っているんですね・・・
$ ll /var/log/aws-routed-eni/
合計 14992
-rw-r--r-- 1 root root 628617 12月 7 00:59 ipamd.log.2019-12-07-00
-rw-r--r-- 1 root root 629027 12月 7 01:59 ipamd.log.2019-12-07-01
-rw-r--r-- 1 root root 629018 12月 7 02:59 ipamd.log.2019-12-07-02
-rw-r--r-- 1 root root 629020 12月 7 03:59 ipamd.log.2019-12-07-03
-rw-r--r-- 1 root root 628943 12月 7 04:59 ipamd.log.2019-12-07-04
-rw-r--r-- 1 root root 629025 12月 7 05:59 ipamd.log.2019-12-07-05
-rw-r--r-- 1 root root 629041 12月 7 06:59 ipamd.log.2019-12-07-06
-rw-r--r-- 1 root root 628617 12月 7 07:59 ipamd.log.2019-12-07-07
-rw-r--r-- 1 root root 629048 12月 7 08:59 ipamd.log.2019-12-07-08
-rw-r--r-- 1 root root 629023 12月 7 09:59 ipamd.log.2019-12-07-09
-rw-r--r-- 1 root root 629024 12月 7 10:59 ipamd.log.2019-12-07-10
-rw-r--r-- 1 root root 628920 12月 7 11:59 ipamd.log.2019-12-07-11
-rw-r--r-- 1 root root 629033 12月 7 12:59 ipamd.log.2019-12-07-12
-rw-r--r-- 1 root root 629013 12月 7 13:59 ipamd.log.2019-12-07-13
-rw-r--r-- 1 root root 628607 12月 7 14:59 ipamd.log.2019-12-07-14
-rw-r--r-- 1 root root 629030 12月 7 15:59 ipamd.log.2019-12-07-15
-rw-r--r-- 1 root root 181262 12月 7 16:17 ipamd.log.2019-12-07-16
-rw-r--r-- 1 root root 1718 11月 28 00:21 plugin.log.2019-11-28-00
-rw-r--r-- 1 root root 4585 11月 28 04:32 plugin.log.2019-11-28-04
-rw-r--r-- 1 root root 3253 12月 5 01:13 plugin.log.2019-12-05-01
dockersock:
Dockerのsocketですね。
ENIを通してPodが繋がる仕組み
EC2内でどのようなルーティング設定を行っているのかは、Githubにドキュメントがあります。
Proposal: CNI plugin for Kubernetes networking over AWS VPC
https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md
Pod to Pod Communication
https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md#pod-to-pod-communication
ホスト側でvethを作成し、Podのネットワーク名前空間のeth0に紐づけています。
そしてPodに割り当てたENIのセカンダリIPにきた通信が、vethに流れるようにルーティングテーブルを設定することで、Podに繋がるようになっています。
Life of a Pod to Pod Ping Packet
https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md#life-of-a-pod-to-external-packet
Podから外への通信は、Podのネットワーク名前空間のデフォルトゲートウェイからvethに流れるようにして実現しているようです。
Pod起動時の状態
実際にPodを起動してノードの中身を見てみます。
何度目の引用かわかりませんが、実際のネットワーク設定が書いてある貴重なドキュメントなので、これに沿って見ていきます。
Pod to Pod Communication
inside-a-pod
https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md#inside-a-pod
on-host-side
https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md#on-host-side
Podとしてnetshootを起動しました。PodのIPは 10.110.10.109
です。
nicolaka/netshoot
https://github.com/nicolaka/netshoot
$ kubectl get po tmp-shell -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
tmp-shell 1/1 Running 0 13h 10.110.10.109 ip-10-110-10-171.ap-northeast-1.compute.internal <none> <none>
ノードにログインして動いているdockerコンテナを確認します。
このノードで動いているのは、kube-proxyとaws-nodeと各pauseコンテナをのぞいて、netshootのコンテナだけです。
(pauseコンテナは、Podのネットワーク名前空間を保持するコンテナです。仮にアプリのコンテナが再起動してもネットワーク名前空間が再利用できるよう存在します。)
[ec2-user@ip-10-110-10-171 ~]$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e49972815e64 932520758690.dkr.ecr.ap-northeast-1.amazonaws.com/nicolaka/netshoot "tail -f /dev/null" 13 hours ago Up 13 hours k8s_tmp-shell_tmp-shell_kube-system_de9cb72e-1a90-11ea-a80c-0efdaea6eca6_0 <---------- これと
373b7e98b5a1 602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/eks/pause-amd64:3.1 "/pause" 13 hours ago Up 13 hours k8s_POD_tmp-shell_kube-system_de9cb72e-1a90-11ea-a80c-0efdaea6eca6_0 <---------- これ
13e3eed03049 602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/amazon-k8s-cni "/bin/sh -c /app/ins…" 3 days ago Up 3 days k8s_aws-node_aws-node-2gl8m_kube-system_b0160f05-1806-11ea-b040-0adab48a968a_0
9fec891354e8 602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/eks/kube-proxy "kube-proxy --v=2 --…" 3 days ago Up 3 days k8s_kube-proxy_kube-proxy-6wjkw_kube-system_b0169b30-1806-11ea-b040-0adab48a968a_0
4bfccfc27c3d 602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/eks/pause-amd64:3.1 "/pause" 3 days ago Up 3 days k8s_POD_aws-node-2gl8m_kube-system_b0160f05-1806-11ea-b040-0adab48a968a_0
0b6435826e81 602401143452.dkr.ecr.ap-northeast-1.amazonaws.com/eks/pause-amd64:3.1 "/pause" 3 days ago Up 3 days k8s_POD_kube-proxy-6wjkw_kube-system_b0169b30-1806-11ea-b040-0adab48a968a_0
[ec2-user@ip-10-110-10-171 ~]$
このノードにはENIが2つアタッチされていました。
一番最後のネットワークインターフェースがPod用のvethです。
[ec2-user@ip-10-110-10-171 ~]$ ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 06:a3:0c:9d:99:5e brd ff:ff:ff:ff:ff:ff
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 06:ed:bb:fd:5a:d8 brd ff:ff:ff:ff:ff:ff
6: enie5da25cfd1a@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default <---------- Podのveth
link/ether 02:5b:59:7b:c9:f7 brd ff:ff:ff:ff:ff:ff link-netnsid 0
[ec2-user@ip-10-110-10-171 ~]$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
link/ether 06:a3:0c:9d:99:5e brd ff:ff:ff:ff:ff:ff
inet 10.110.10.171/24 brd 10.110.10.255 scope global dynamic eth0 <---------- ENI(eth0)プライマリIP
valid_lft 3339sec preferred_lft 3339sec
inet6 fe80::4a3:cff:fe9d:995e/64 scope link
valid_lft forever preferred_lft forever
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000
link/ether 06:ed:bb:fd:5a:d8 brd ff:ff:ff:ff:ff:ff
inet 10.110.10.167/24 brd 10.110.10.255 scope global eth1 <---------- ENI(eth1)のプライマリIP
valid_lft forever preferred_lft forever
inet6 fe80::4ed:bbff:fefd:5ad8/64 scope link
valid_lft forever preferred_lft forever
6: enie5da25cfd1a@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
link/ether 02:5b:59:7b:c9:f7 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet6 fe80::5b:59ff:fe7b:c9f7/64 scope link
valid_lft forever preferred_lft forever
次にルーティング設定を見てみます。
ルールを確認すると、10.110.10.109
への通信はmainルートテーブルを見なさいとあります。
[ec2-user@ip-10-110-10-171 ~]$ ip rule
0: from all lookup local
512: from all to 10.110.10.109 lookup main
1024: from all fwmark 0x80/0x80 lookup main
32766: from all lookup main
32767: from all lookup default
mainルートテーブルをみます。
10.110.10.109
はenie5da25cfd1a
を使いなさいとあります。
これがPodのvethですね。その他の通信はeth0を使うようになっています。
[ec2-user@ip-10-110-10-171 ~]$ ip route show table main
default via 10.110.10.1 dev eth0
10.110.10.0/24 dev eth0 proto kernel scope link src 10.110.10.171
10.110.10.109 dev enie5da25cfd1a scope link
169.254.169.254 dev eth0
先ほどのネットワークインタフェースを見るとvethのMACアドレスが02:5b:59:7b:c9:f7
とあります。
[ec2-user@ip-10-110-10-171 ~]$ ip link
〜〜
6: enie5da25cfd1a@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP mode DEFAULT group default
link/ether 02:5b:59:7b:c9:f7 brd ff:ff:ff:ff:ff:ff link-netnsid 0
それでは次にコンテナ内のネットワーク設定をみてみます。
コンテナのネットワーク名前空間内のeth0のipアドレスが、10.110.10.109
になっていることがわかります。
[ec2-user@ip-10-110-10-171 ~]$ sudo docker exec e49972815e64 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
3: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
link/ether 62:18:cc:40:63:a8 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.110.10.109/32 brd 10.110.10.109 scope global eth0
コンテナ内のルーティングテーブルは169.254.1.1
がデフォルトゲートウェイになっています。
[ec2-user@ip-10-110-10-171 ~]$ sudo docker exec e49972815e64 ip route
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link
最後に、arpテーブルを見ると、169.254.1.1
がホスト側のvethのMACアドレス02:5b:59:7b:c9:f7
に紐づいていることがわかります。
[ec2-user@ip-10-110-10-171 ~]$ sudo docker exec e49972815e64 ip neigh
169.254.1.1 dev eth0 lladdr 02:5b:59:7b:c9:f7 PERMANENT
最後に
ひとまず今回はドキュメントや実際のクラスターの状態から、ネットワークの基本的な内容を整理しました。
次回はCNIプラグインのソースコードを見ていきますが、ネットワーク周りだけでなくGoの面白そうなところをピックアップしていきたいと思います。