目次
EKSのHybrid Nodesを、Calicoを利用したPodネットワークを構成してみました。
EKSのハイブリッド構成を試す際に、Pod ネットワークとして Calico を導入してみました。Calico は VXLAN を利用して Pod 間の通信を行うため、EC2 ノード同士のルーティングさえ正しく設定されていれば、VPC をまたいだ環境でもシームレスに Pod 間通信を行えます。(Pod用のルーティング設定が不要です)
今回、簡単に試せる環境として、上図の構成を作ってみました。2 つの VPC(左側がメインの EKS VPC、右側が「オンプレミス環境を模した」VPC)を用意し、それぞれの VPC に EKS ノードを配置しています。EKS はマネージドノードグループで構築し、Calico の CNI プラグインを導入することで、同一の Pod CIDRを両方の VPC 上のノードで共有しています。
コード
IaCのコードはこちらにあります。DevContainerを構成しているので、この記事の作業では、DevContainer上で作業を進めていきます。
AWS環境のデプロイ方法
設定ファイルの準備
まずは以下のように2つの設定ファイルを用意します。
- vars/env.tfvars.sample を参考にしてvars/env.tfvars ファイルを作成してください。
- vars/backend.tfvars.sample を参考にしてvars/backend.tfvars ファイルを作成してください。
Terraformの実行
以下のコマンドでTerraformで図の環境がデプロイ可能です。
$ make tf-apply-aws
EKS Hybrid NodeはEC2のuserdataを設定する以下の部分でインストールして、EKSに参加しています。
user_data = <<EOF
省略
--==BOUNDARY==
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
#cloud-config
write_files:
- path: /etc/nodeadm/nodeConfig.yaml
owner: root:root
permissions: '0644'
content: |
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
cluster:
name: eks-hybrid
region: ap-northeast-1
hybrid:
ssm:
activationCode: ${aws_ssm_activation.this.activation_code}
activationId: ${aws_ssm_activation.this.id}
runcmd:
- curl -OL 'https://hybrid-assets.eks.amazonaws.com/releases/latest/bin/linux/arm64/nodeadm'
- mv nodeadm /usr/bin/nodeadm
- chmod +x /usr/bin/nodeadm
- nodeadm install ${local.cluster_version} --credential-provider ssm
- nodeadm init -c file:///etc/nodeadm/nodeConfig.yaml
- nodeadm debug -c file:///etc/nodeadm/nodeConfig.yaml
--==BOUNDARY==--
EOF
EKSへのアクセス確認
awsコマンドでkubeconfigを更新します。
$ aws eks update-kubeconfig --profile your_profile --name eks-hybrid
Updated context arn:aws:eks:ap-northeast-1:012345678901:cluster/eks-hybrid in /home/vscode/.kube/config
以下がこの時点でのk9sの画面ですが、「ip-」 始まりがEKSのManaged Node Groupで起動されたEC2インスタンスです。
「mi-」始まりのものがUserdataの処理を利用して、Hybrid NodeとしてEKSに参加したNodeとなります。こちらはEKSからはEC2として認識されていないため、VPC CNIが適用されおらずNotReadyとなります。
Calicoの導入
CNI PluginとしてCalicoを適用します。手順はこちらの公式ドキュメントを参考にしています。
# AWS VPC CNIを削除します
$ kubectl delete daemonset -n kube-system aws-node
# Calicoをインストールします
$ kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.2/manifests/calico-vxlan.yaml
$ kubectl -n kube-system set env daemonset/calico-node FELIX_AWSSRCDSTCHECK=DoNothing
Calicoインストール後、既存のManaged Node Groupとして起動していたEC2は削除します。
これで新しいインスタンスがCalico CNIを利用して起動してきます。
PodネットワークでL3ルーティングを確認
L3ルーティングを確認するために、上図の赤枠のPodをデプロイします。
$ kubectl apply -f manifest/nw-check.yaml
namespace/nw-check created
deployment.apps/nw-check-managed created
deployment.apps/nw-check-hybrid created
Managed NodeとHybrid Nodeの両方にPodが配置されました。
$ kubectl get pod -n nw-check -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nw-check-hybrid-5854bbd794-tndpr 1/1 Running 0 39s 192.168.35.7 mi-06d5ac211e74887c1 <none> <none>
nw-check-managed-c7cd75cc6-bvf8x 1/1 Running 0 39s 192.168.231.3 ip-10-10-2-193.ap-northeast-1.compute.internal <none> <none>
Managed Node <-> Hybrid Node相互のPINGができることが確認できます。
# それぞれのNodeに配置されたPodが確認できます。
$ kubectl get pod -n nw-check -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nw-check-hybrid-5854bbd794-tndpr 1/1 Running 0 10m 192.168.35.7 mi-06d5ac211e74887c1 <none> <none>
nw-check-managed-c7cd75cc6-bvf8x 1/1 Running 0 10m 192.168.231.3 ip-10-10-2-193.ap-northeast-1.compute.internal <none> <none>
# Hybrid -> Managed
$ kubectl exec -n nw-check nw-check-hybrid-5854bbd794-tndpr -- ping -c3 192.168.231.3
PING 192.168.231.3 (192.168.231.3) 56(84) bytes of data.
64 bytes from 192.168.231.3: icmp_seq=1 ttl=125 time=1.87 ms
64 bytes from 192.168.231.3: icmp_seq=2 ttl=125 time=1.83 ms
64 bytes from 192.168.231.3: icmp_seq=3 ttl=125 time=1.81 ms
--- 192.168.231.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 1.813/1.839/1.872/0.024 ms
# Managed -> Hybrid
$ kubectl exec -n nw-check nw-check-managed-c7cd75cc6-bvf8x -- ping -c3 192.168.35.7
PING 192.168.35.7 (192.168.35.7) 56(84) bytes of data.
64 bytes from 192.168.35.7: icmp_seq=1 ttl=62 time=1.84 ms
64 bytes from 192.168.35.7: icmp_seq=2 ttl=62 time=1.81 ms
64 bytes from 192.168.35.7: icmp_seq=3 ttl=62 time=1.81 ms
--- 192.168.35.7 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 1.807/1.819/1.843/0.016 ms
当然、ここではPod NetworkのCIDRはAWSのルートテーブルには出てきていません。
Session ManagerでManaged Nodeに入ってコマンドで確認してみると、以下のようにHybrid Nodeへの通信はCalicoが構築してくれたVXLANで通信されていることがわかります。
$ ip route
default via 10.10.2.1 dev eth0
10.10.2.0/24 dev eth0 proto kernel scope link src 10.10.2.193
169.254.169.254 dev eth0
169.254.170.23 dev pod-id-link0
192.168.35.0/26 via 192.168.35.0 dev vxlan.calico onlink
blackhole 192.168.231.0/26 proto 80
192.168.231.3 dev cali9ce7ff61306 scope link
ALBを通して(オンプレを模した)VPCのPodにアクセス
最後にALBを通したHybrid Node上のPodへの通信を確認したいと思います。
$ kubectl apply -f manifest/sample.yaml
まずは、Podを通してService Networkを通した通信を確認してみます。
# sample-appがHybrid Nodeに配置されていることがわかります
$ kubectl get po -n sample -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
sample-app-7d5b76dcff-qjdmh 1/1 Running 0 3h9m 192.168.35.5 mi-06d5ac211e74887c1 <none> <none>
# 以下のようにNodePortとして登録されています
$ kubectl get svc -n sample
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
sample-svc NodePort 172.16.58.99 <none> 80:30080/TCP 3h5m
# Managed Node側からService Network経由で通信確認
$ kubectl exec -n nw-check nw-check-managed-c7cd75cc6-dlv6r -- curl -s 172.16.58.99:80
"Hello from Pod [sample-app-7d5b76dcff-qjdmh] !"
$ kubectl exec -n nw-check nw-check-managed-c7cd75cc6-dlv6r -- curl -s sample-svc.sample.svc.cluster.local
"Hello from Pod [sample-app-7d5b76dcff-qjdmh] !"
次にNodePortを通した通信確認もしてみます。
$ kubectl exec -n nw-check nw-check-managed-c7cd75cc6-dlv6r -- curl -s 10.10.1.14:30080
"Hello from Pod [sample-app-7d5b76dcff-qjdmh] !"
$ kubectl exec -n nw-check nw-check-managed-c7cd75cc6-dlv6r -- curl -s 10.90.1.182:30080
"Hello from Pod [sample-app-7d5b76dcff-qjdmh] !"
ALBに登録していきます。最初のTerraformでALBは登録済みなので、「eks-hybrid-alb」という名前のTarget Groupを探します。
Manged Node、Hybrid NodeそれぞれのEC2のIPを調べて登録します。
後はALBのURLに対してアクセスしてみると、Hybrid Nodeで動いているsample-appのPod名が返ってくることが確認できます。
$ curl eks-hybrid-alb-xxxxxx.ap-northeast-1.elb.amazonaws.com
"Hello from Pod [sample-app-7d5b76dcff-qjdmh] !"
片付け
最後に以下のコマンドでTerraformで作成したリソースを全て削除します。
$ make tf-destroy-aws
タイトルの構成を作成するIaCと手順の話でした。もし理解が薄い場合も環境さえ構築できれば、その中で試したり調査してみることができると思います。
最後に今回の範囲だと以下のような情報が大変参考になりましたので紹介させていただきます。


- カテゴリー
- タグ