EKS Hybrid NodesをVPC Peering上にCalico使って構成してみた

この記事を書いたメンバー:

大友 佑介

EKS Hybrid NodesをVPC Peering上にCalico使って構成してみた

目次

 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上で作業を進めていきます。



GitHub - yomon8/eks-hybrid-calico-vpc-peering: VPC PeeringでEKS Hybrid Nodesを試す環境

VPC PeeringでEKS Hybrid Nodesを試す環境. Contribute to yomon8/eks-hybrid-calico-vpc-peering development by creating an account on GitHub.

github.com

og_img


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と手順の話でした。もし理解が薄い場合も環境さえ構築できれば、その中で試したり調査してみることができると思います。

最後に今回の範囲だと以下のような情報が大変参考になりましたので紹介させていただきます。


Kubernetes Network Deep Dive!

cndjp第4回勉強会の前半分の資料です。

speakerdeck.com

og_img



Kubernetes Network Deep Dive (NodePort, ClusterIP, Flannel) - Qiita

Kubernetes Network Deep Dive (NodePort, ClusterIP, Flannel)初めにKubernetes には、Kubeadmをはじめとした半自動インスト…

qiita.com

og_img




カテゴリー
タグ

Pick upピックアップ

Search記事を探す

キーワード

SAPシステムや基幹システムのクラウド移行・構築・保守、
DXに関して
お気軽にご相談ください

03-6260-6240 (受付時間 平日9:30〜18:00)