본문 바로가기
AWS/EKS

[AEWS2] 2-1. AWS VPC CNI 소개

by okms1017 2024. 3. 16.
728x90

✍ Posted by Immersive Builder  Seong
 

1. 기본 인프라 배포 

AWS CloudFormation 원클릭 배포 

AWS CloudFormation을 이용하여 하기 아키텍처와 같이 VPC 1, Public Subnet 3, Private Subnet 3, EKS Cluster(Control Plane), Managed node group(EC2 3), Add-on(kube-proxy, coredns, aws vpn cni) 구성으로 원클릭 배포합니다.  
 

이후 실습에서 원클릭 배포를 활용할 예정입니다. 
EKS 클러스터 배포 시간은 약 20분 정도 소요됩니다. 
 

AWS CloudFormation - 기본 인프라 원클릭 배포

 

인프라 배포 확인 

작업용 EC2 인스턴스에 접속하여 기본 구성 정보를 확인합니다. 
그리고 각 Worker Node로의 접속 여부를 확인합니다. 
 

# 디폴트 네임스페이스 적용
$ kubectl ns default 
Context "admin@myeks.ap-northeast-2.eksctl.io" modified.
Active namespace is "default".

# 설치 확인
$ kubectl cluster-info
Kubernetes control plane is running at https://E7CBCE6208A87AE437A37D8A7BBADD03.gr7.ap-northeast-2.eks.amazonaws.com
CoreDNS is running at https://E7CBCE6208A87AE437A37D8A7BBADD03.gr7.ap-northeast-2.eks.amazonaws.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
$ eksctl get cluster
NAME    REGION          EKSCTL CREATED
myeks   ap-northeast-2  True
$ eksctl get nodegroup --cluster $CLUSTER_NAME
CLUSTER NODEGROUP       STATUS  CREATED                 MIN SIZE        MAX SIZE        DESIRED CAPACITY        INSTANCE TYPE            IMAGE ID                                        ASG NAME   TYPE
myeks   ng1             ACTIVE  2024-03-15T06:50:04Z    3               3               3                       t3.mediumAL2_x86_64      eks-ng1-74c7206f-f695-e2c2-41b8-6b8729d48645    managed\

# 환경변수 확인 
$ export | egrep 'ACCOUNT|AWS_|CLUSTER|KUBERNETES|VPC|Subnet'
declare -x ACCOUNT_ID="732659419746"
declare -x AWS_ACCESS_KEY_ID="AK**********"
declare -x AWS_DEFAULT_REGION="ap-northeast-2"
declare -x AWS_PAGER=""
declare -x AWS_SECRET_ACCESS_KEY="im**********"
declare -x CLUSTER_NAME="myeks"
declare -x KUBERNETES_VERSION="1.28"
declare -x PrivateSubnet1="subnet-015044dcfd918b35f"
declare -x PrivateSubnet2="subnet-0c34acaa5d9b67fa3"
declare -x PrivateSubnet3="subnet-047888b674d065c11"
declare -x PubSubnet1="subnet-0d9345f2ab41fc086"
declare -x PubSubnet2="subnet-067a05fd80d637d20"
declare -x PubSubnet3="subnet-0f7d9ff0ce5d3332d"
declare -x VPCID="vpc-01297db718988b5d9"

# Node Info 확인
$ kubectl get node --label-columns=node.kubernetes.io/instance-type,ekmazonaws.com/capacityType,topology.kubernetes.io/zone
NAME                                               STATUS   ROLES    AGE   VERSION               INSTANCE-TYPE   CAPACITYTYPE   ZONE
ip-192-168-1-213.ap-northeast-2.compute.internal   Ready    <none>   67m   v1.28.5-eks-5e0fdde   t3.medium       ON_DEMAND      ap-northeast-2a
ip-192-168-2-49.ap-northeast-2.compute.internal    Ready    <none>   67m   v1.28.5-eks-5e0fdde   t3.medium       ON_DEMAND      ap-northeast-2b
ip-192-168-3-134.ap-northeast-2.compute.internal   Ready    <none>   67m   v1.28.5-eks-5e0fdde   t3.medium       ON_DEMAND      ap-northeast-2c

# Node IP 조회 및 Node Private IP 환경변수 설정 
$ aws ec2 describe-instances --query "Reservations[*].Instances[*].{PublicIPAdd:PublicIpAddress,PrivateIPAdd:PrivateIpAddress,InstanceName:Tags[?Key=='Name']|[0].Value,Status:State.Name}" --filters Name=instance-state-name,Values=running --output table
-------------------------------------------------------------------
|                        DescribeInstances                        |
+--------------------+-----------------+---------------+----------+
|    InstanceName    |  PrivateIPAdd   |  PublicIPAdd  | Status   |
+--------------------+-----------------+---------------+----------+
|  myeks-ng1-Node    |  192.168.3.134  |  3.34.134.187 |  running |
|  myeks-bastion-EC2 |  192.168.1.100  |  43.202.68.90 |  running |
|  myeks-ng1-Node    |  192.168.1.213  |  15.165.18.64 |  running |
|  myeks-ng1-Node    |  192.168.2.49   |  3.38.171.151 |  running |
+--------------------+-----------------+---------------+----------+
$ N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
$ N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})
$ N3=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
$ echo "export N1=$N1" >> /etc/profile
$ echo "export N2=$N2" >> /etc/profile
$ echo "export N3=$N3" >> /etc/profile
$ echo $N1, $N2, $N3 
192.168.1.213, 192.168.2.49, 192.168.3.134

# Security Group Rule 추가 
$ NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=*ng1* --query "SecurityGroups[*].[GroupId]" --output text)
$ echo $NGSGID 
sg-0cd1a10ce5df2b0d6
$ echo "export NGSGID=$NGSGID" >> /etc/profile
$ aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.100/32
{
    "Return": true,
    "SecurityGroupRules": [
        {
            "SecurityGroupRuleId": "sgr-012249e55ad2eba82",
            "GroupId": "sg-0cd1a10ce5df2b0d6",
            "GroupOwnerId": "732659419746",
            "IsEgress": false,
            "IpProtocol": "-1",
            "FromPort": -1,
            "ToPort": -1,
            "CidrIpv4": "192.168.1.100/32"
        }
    ]
}

# 작업용 EC2 -> Worker Nodes (ICMP)
$ ping -c 1 $N1
PING 192.168.1.213 (192.168.1.213) 56(84) bytes of data.
64 bytes from 192.168.1.213: icmp_seq=1 ttl=255 time=0.576 ms
$ ping -c 1 $N2 
PING 192.168.2.49 (192.168.2.49) 56(84) bytes of data.
64 bytes from 192.168.2.49: icmp_seq=1 ttl=255 time=3.26 ms
$ ping -c 1 $N3
PING 192.168.3.134 (192.168.3.134) 56(84) bytes of data.
64 bytes from 192.168.3.134: icmp_seq=1 ttl=255 time=1.48 ms

# 작업용 EC2 -> Worker Nodes (SSH) 
$ for node in $N1 $N2 $N3; do ssh -i ~/.ssh/id_rsa ec2-user@$node hostname; done 
ip-192-168-1-213.ap-northeast-2.compute.internal
ip-192-168-2-49.ap-northeast-2.compute.internal
ip-192-168-3-134.ap-northeast-2.compute.internal

 
Amazone EKS 콘솔 화면의 추가 기능 항목에서 Add-on 정보를 확인할 수 있습니다. 
Add-on 최신 버전으로 설치하기 위해 매니페스트(yaml)에 'version: latest'을 선언합니다.  
 

Amazon EKS - 추가 기능

# 모든 파드의 컨테이너 이미지 정보 확인 
$ kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" | tr -s '[[:space:]]' '\n' | sort | uniq -c
    3 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon/aws-network-policy-agent:v1.0.8-eksbuild.1
    3 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon-k8s-cni:v1.16.4-eksbuild.2
    2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/coredns:v1.10.1-eksbuild.7
    3 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/kube-proxy:v1.28.6-minimal-eksbuild.2

# Add-on 정보 확인 
$ eksctl get addon --cluster $CLUSTER_NAME
NAME            VERSION                 STATUS  ISSUES  IAMROLE                                                         UPDATE AVAILABLE CONFIGURATION VALUES
coredns         v1.10.1-eksbuild.7      ACTIVE  0
kube-proxy      v1.28.6-eksbuild.2      ACTIVE  0
vpc-cni         v1.16.4-eksbuild.2      ACTIVE  0       arn:aws:iam::732659419746:role/eksctl-myeks-addon-vpc-cni-Role1-3q8Ta2vx4FTX                             enableNetworkPolicy: "true"

# K8s 버전별 Add-on 지원 
# Count: v1.28 > v1.29 
$ eksctl utils describe-addon-versions --kubernetes-version 1.29 | grep AddonName | wc -l
11
$ eksctl utils describe-addon-versions --kubernetes-version 1.28 | grep AddonName | wc -l
23

 


2. AWS VPC CNI 

K8s CNI 란? 

CNI(Container Network Interface)는 컨테이너 간 네트워크를 제어할 수 있는 플러그인입니다. 
K8s 환경에서는 파드 간 통신을 구현하기 위해 사용합니다.
K8s CNI의 종류로는 Flannel, Weavenet, Calico, NSX 등 다양한 플러그인이 있습니다. 
 

AWS VPC CNI 란?

Amazon EKS에서 지원하는 유일한 CNI 플러그인입니다. 
 

AWS VPC CNI

  • 파드의 IP를 할당하며, 파드 간 통신을 구현합니다. 
  • VPC와 통합하여 VPC Flow Logs, VPC Routing Table, Security Group 등을 사용 가능합니다. 
  • VPC ENI(Elastic Network Interface)에 미리 할당된 IP(L-IPAM)을 파드에서 사용 가능합니다. 
  • GitHub에서 오픈 소스로 유지 관리되고 있습니다. (https://github.com/aws/amazon-vpc-cni-k8s)
 

GitHub - aws/amazon-vpc-cni-k8s: Networking plugin repository for pod networking in Kubernetes using Elastic Network Interfaces

Networking plugin repository for pod networking in Kubernetes using Elastic Network Interfaces on AWS - aws/amazon-vpc-cni-k8s

github.com

 

K8s Calico CNI  VS  AWS VPC CNI 

 

K8s Calico CNI와 AWS VPC CNI 간 네트워크 비교 1 (CloudNet@)
K8s Calico CNI와 AWS VPC CNI 간 네트워크 비교 2 (CloudNet@)

  • 일반적인 K8s CNI 플러그인은 파드와 Worker Node에 할당하는 네트워크 대역이 다른 반면, AWS VPC CNI 플러그인은 파드와 Worker Node에 할당하는 네트워크 대역이 동일합니다.
  • 파드 간 통신 시 K8s CNI 플러그인은 일반적으로 오버레이(VXLAN, IP-IP 등) 통신을 구현하고, AWS VPC CNI 플러그인은 직접 통신을 구현합니다. 오버레이란 패킷을 송수신할 때 원본 패킷의 헤더를 encapsulation/decapsulation 하는 것을 의미합니다. 
  • AWS VPC CNI 플러그인은 동일한 네트워크 대역을 사용하므로 오버레이 통신으로 인한 오버헤드가 발생하지 않으며, 파드 간 직접 통신하여 네트워크 통신을 최적화합니다. (latancy, Processing, Packet size ↓)

 

네트워크 기본 정보 확인 

aws-node, coredns, kube-proxy를 포함하여 총 8 개의 파드가 실행되고 있습니다. 
그리고 파드의 정보를 조회하여 파드와 Worker Node의 네트워크 대역이 동일함을 확인합니다. 
 

# 모니터링 
$ watch -d kubectl get pod -A
NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE
kube-system   aws-node-jpp6z             2/2     Running   0          8h
kube-system   aws-node-ks477             2/2     Running   0          8h
kube-system   aws-node-rbkng             2/2     Running   0          8h
kube-system   coredns-55474bf7b9-hgs8h   1/1     Running   0          8h
kube-system   coredns-55474bf7b9-tvt8p   1/1     Running   0          8h
kube-system   kube-proxy-bg7ts           1/1     Running   0          8h
kube-system   kube-proxy-h7rtp           1/1     Running   0          8h
kube-system   kube-proxy-lg7zv           1/1     Running   0          8h

# CNI 정보 확인
$ kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
amazon-k8s-cni-init:v1.16.4-eksbuild.2
amazon-k8s-cni:v1.16.4-eksbuild.2
amazon
$ for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i tree /var/log/aws-routed-eni; echo; done
>> node 192.168.1.213 <<
/var/log/aws-routed-eni
├── ebpf-sdk.log
├── egress-v6-plugin.log
├── ipamd.log
├── network-policy-agent.log
└── plugin.log
>> node 192.168.2.49 <<
/var/log/aws-routed-eni
├── ebpf-sdk.log
├── egress-v6-plugin.log
├── ipamd.log
├── network-policy-agent.log
└── plugin.log
>> node 192.168.3.134 <<
/var/log/aws-routed-eni
├── ebpf-sdk.log
├── egress-v6-plugin.log
├── ipamd.log
├── network-policy-agent.log
└── plugin.log
$ ssh ec2-user@$N1 sudo cat /var/log/aws-routed-eni/plugin.log | jq
```
  "level": "debug",
  "ts": "2024-03-15T06:54:02.888Z",
  "caller": "driver/driver.go:267",
  "msg": "Successfully deleted toContainer rule, containerAddr=192.168.1.217/32, rtTable=main"
```

# kube-proxy 모드 확인: iptables 
$ kubectl describe cm -n kube-system kube-proxy-config | grep mode
mode: "iptables"

# 파드 정보 조회
$ kubectl get pod -n kube-system -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase
NAME                       IP              STATUS
aws-node-jpp6z             192.168.3.134   Running
aws-node-ks477             192.168.1.213   Running
aws-node-rbkng             192.168.2.49    Running
coredns-55474bf7b9-hgs8h   192.168.3.203   Running
coredns-55474bf7b9-tvt8p   192.168.2.168   Running
kube-proxy-bg7ts           192.168.3.134   Running
kube-proxy-h7rtp           192.168.1.213   Running
kube-proxy-lg7zv           192.168.2.49    Running
$ kubectl get pod -A -o name
pod/aws-node-jpp6z
pod/aws-node-ks477
pod/aws-node-rbkng
pod/coredns-55474bf7b9-hgs8h
pod/coredns-55474bf7b9-tvt8p
pod/kube-proxy-bg7ts
pod/kube-proxy-h7rtp
pod/kube-proxy-lg7zv

# ENI & veth pair 정보 확인 => 호스트에서만 확인 가능, 파드 내에서 확인 불가 
$ for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -br -c addr; echo; done
>> node 192.168.1.213 <<
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             192.168.1.213/24 fe80::9d:f6ff:fed4:2383/64
>> node 192.168.2.49 <<
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             192.168.2.49/24 fe80::497:50ff:fe45:7293/64
enie35b64a4285@if3 UP             fe80::9c83:d2ff:fe96:8000/64
eth1             UP             192.168.2.88/24 fe80::4bc:6aff:fed3:24d7/64
>> node 192.168.3.134 <<
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             192.168.3.134/24 fe80::8b9:3fff:fe51:6629/64
eni6de0d96ce6f@if3 UP             fe80::caf:f8ff:fe69:129e/64
eth1             UP             192.168.3.77/24 fe80::8d9:58ff:fe18:b63d/64

# kube-proxy iptables 리스트 확인 
$ ssh ec2-user@$N1 sudo iptables -t nat -S 
```
-A KUBE-SEP-DS44B3D277JP66UB -s 192.168.3.203/32 -m comment --comment "kube-system/kube-dns:dns-tcp" -j KUBE-MARK-MASQ
-A KUBE-SEP-DS44B3D277JP66UB -p tcp -m comment --comment "kube-system/kube-dns:dns-tcp" -m tcp -j DNAT --to-destination 192.168.3.203:53
```

 
* ipamd 란?
- IP 주소를 할당하고 관리하는 데몬(서비스) 
 
* kube-proxy 모드로 IPVS가 아닌 iptables를 사용하는 이유? 
- 기본적으로 kube-proxy 모드로 iptables를 사용하여 이미 검증되어 있으며, 이전에 사용된 기술과의 호환성을 유지하기 위해서 입니다.  
- IPVS는 설정 내용을 해시테이블에 보존하거나 커널 모드에서 동작하여 iptables보다 빠른 속도로 동작합니다.
- 따라서 IPVS는 서비스 수가 10,000개를 초과하는 대규모 클러스터에 적합하며, 소규모 클러스터에서는 오히려 iptables가 적합할 수 있습니다. 
 

노드에서 기본 네트워크 정보 확인 

Woreker Node 2에서 ENI, Primary Private IP, Secondary Private IP, coredns 등 상세 네트워크 정보를 확인합니다. 

Worker Node 2 - 내부 네트워크 구성도

 

  • Network Namespace는 호스트(Root)와 파드별(Per Pod)로 구분됩니다. 
  • aws-node와 kube-proxy 파드는 호스트(Root)의 IP 주소를 그대로 사용합니다. (파드 옵션 'hostNetwork : true' 선언)
  • aws-node와 kube-proxy 파드는 포트를 구분하여 서비스합니다. 
  • coredns 파드는 veth으로 호스트(Root)와 eniY@ifN 인터페이스로 연결되어 있고, 파드와는 eth0으로 연결되어 있습니다. 

 

EC2 인스턴스 - Worker Node 2 ENI & Secondary Private IP

# coredns 파드 IP 조회 
$ kubectl get pod -n kube-system -l k8s-app=kube-dns -owide
NAME                       READY   STATUS    RESTARTS   AGE   IP              NODE                                               NOMINATED NODE   READINESS GATES
coredns-55474bf7b9-hgs8h   1/1     Running   0          10h   192.168.3.203   ip-192-168-3-134.ap-northeast-2.compute.internal   <none>           <none>
coredns-55474bf7b9-tvt8p   1/1     Running   0          10h   192.168.2.168   ip-192-168-2-49.ap-northeast-2.compute.internal    <none>           <none>

# Node IP 조회
$ kubectl get node -owide
NAME                                               STATUS   ROLES    AGE   VERSION               INTERNAL-IP     EXTERNAL-IP    OS-IMAGE         KERNEL-VERSION                  CONTAINER-RUNTIME
ip-192-168-1-213.ap-northeast-2.compute.internal   Ready    <none>   10h   v1.28.5-eks-5e0fdde   192.168.1.213   15.165.18.64   Amazon Linux 2   5.10.210-201.852.amzn2.x86_64   containerd://1.7.11
ip-192-168-2-49.ap-northeast-2.compute.internal    Ready    <none>   10h   v1.28.5-eks-5e0fdde   192.168.2.49    3.38.171.151   Amazon Linux 2   5.10.210-201.852.amzn2.x86_64   containerd://1.7.11
ip-192-168-3-134.ap-northeast-2.compute.internal   Ready    <none>   10h   v1.28.5-eks-5e0fdde   192.168.3.134   3.34.134.187   Amazon Linux 2   5.10.210-201.852.amzn2.x86_64   containerd://1.7.11

# 호스트 Routing Table 조회 -> veth coredns IP 일치 확인 
$ for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -c route; echo; done
>> node 192.168.1.213 <<
default via 192.168.1.1 dev eth0
169.254.169.254 dev eth0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.213
>> node 192.168.2.49 <<
default via 192.168.2.1 dev eth0
169.254.169.254 dev eth0
192.168.2.0/24 dev eth0 proto kernel scope link src 192.168.2.49
192.168.2.168 dev enie35b64a4285 scope link
>> node 192.168.3.134 <<
default via 192.168.3.1 dev eth0
169.254.169.254 dev eth0
192.168.3.0/24 dev eth0 proto kernel scope link src 192.168.3.134
192.168.3.203 dev eni6de0d96ce6f scope link

 

파드를 추가 생성하여 네트워크 구성 변경 확인 

AWS 콘솔에서 Worker Node의 현재 네트워크 구성 정보를 확인합니다. 
 

Worker Node 1 - ENI & Secondary Private IP (before)
Worker Node 2 - ENI & Secondary Private IP(before)
Worker Node 3 - ENI & Secondary Private IP (before)

 
그리고 각 Worker Node에 접속하여 현재 라우팅 테이블 정보를 확인합니다. 
 

Worker Node 1 - Routing Table (before)
Worker Node 2 - Routing Table (before)
Worker Node 3 - Routing Table (before)

이제 테스트용 파드를 하나 생성하여 네트워크 구성이 어떻게 변경되는지 확인합니다. 
 

# 테스트용 파드(netshoot-pod) 생성
$ cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: netshoot-pod
spec:
  replicas: 3
  selector:
    matchLabels:
      app: netshoot-pod
  template:
    metadata:
      labels:
        app: netshoot-pod
    spec:
      containers:
      - name: netshoot-pod
        image: nicolaka/netshoot
        command: ["tail"]
        args: ["-f", "/dev/null"]
      terminationGracePeriodSeconds: 0
EOF
deployment.apps/netshoot-pod created

# 파드 생성 확인 
$ kubectl get pod -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP              NODE                                               NOMINATED NODE   READINESS GATES
netshoot-pod-79b47d6c48-mv9dj   1/1     Running   0          96s   192.168.3.14    ip-192-168-3-134.ap-northeast-2.compute.internal   <none>           <none>
netshoot-pod-79b47d6c48-sn66z   1/1     Running   0          96s   192.168.2.29    ip-192-168-2-49.ap-northeast-2.compute.internal    <none>           <none>
netshoot-pod-79b47d6c48-zvnz9   1/1     Running   0          96s   192.168.1.202   ip-192-168-1-213.ap-northeast-2.compute.internal   <none>           <none>

# 호스트 Routing Table 조회 -> Worker Node 1 veth interface 생성 확인
$ for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -c route; echo; done
>> node 192.168.1.213 <<
default via 192.168.1.1 dev eth0
169.254.169.254 dev eth0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.213
192.168.1.202 dev eni2794f83090a scope link
>> node 192.168.2.49 <<
default via 192.168.2.1 dev eth0
169.254.169.254 dev eth0
192.168.2.0/24 dev eth0 proto kernel scope link src 192.168.2.49
192.168.2.29 dev eni44bd6003c77 scope link
192.168.2.168 dev enie35b64a4285 scope link
>> node 192.168.3.134 <<
default via 192.168.3.1 dev eth0
169.254.169.254 dev eth0
192.168.3.0/24 dev eth0 proto kernel scope link src 192.168.3.134
192.168.3.14 dev enida53b8a7dcf scope link
192.168.3.203 dev eni6de0d96ce6f scope link

 
Worker Node 1에 eth1이 추가되었습니다. 또한, 각 Worker Node에서 veth 인터페이스가 하나씩 생성되고 라우팅 테이블에는 새 파드(netshoot-pod)로 향하는 경로가 추가된 것을 확인할 수 있습니다. 
 

Worker Node 1 - Routing Table (after)
Worker Node 2 - Routing Table (after)
Worker Node 3 - Routing Table (after)

AWS 콘솔에서 Worker Node 1의 ENI(eth1)와 Secondary Private IP 5가 추가된 것을 확인할 수 있습니다. 
그 외 Worker Node 에서는 구성 변화가 없으나 미리 구성된 IP Pool에서 새 파드에 Secondary Private IP를 할당한 것을 알 수 있습니다. 
 

Worker Node 1 - ENI & Secondary Private IP (after)
Worker Node 2 - ENI & Secondary Private IP (after)
Worker Node 3 - ENI & Secondary Private IP (after)

 

노드 간 파드 통신 

파드(netshoot-pod)에 접속하여 파드 간 통신이 잘 되는지 확인합니다. 
 

# pod-1 (SSH)
$ kubectl exec -it netshoot-pod-79b47d6c48-zvnz9 -- zsh
$ ip -c addr
3: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
    link/ether 3a:f9:cb:9c:2c:fd brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.1.202/32 scope global eth0

# pod-1 -> pod-2 (ICMP)
$ ping -c 2 192.168.2.29
PING 192.168.2.29 (192.168.2.29) 56(84) bytes of data.
64 bytes from 192.168.2.29: icmp_seq=1 ttl=125 time=1.24 ms
64 bytes from 192.168.2.29: icmp_seq=2 ttl=125 time=0.986 ms

# Worker Node 1: tcpdump packet 확인
$ sudo tcpdump -i any -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
20:20:08.084158 IP 192.168.1.202 > 192.168.2.29: ICMP echo request, id 161, seq 1, length 64
20:20:08.084193 IP 192.168.1.202 > 192.168.2.29: ICMP echo request, id 161, seq 1, length 64
20:20:08.085358 IP 192.168.2.29 > 192.168.1.202: ICMP echo reply, id 161, seq 1, length 64
20:20:08.085386 IP 192.168.2.29 > 192.168.1.202: ICMP echo reply, id 161, seq 1, length 64

# Worker Node 2: tcpdump packet 확인
sudo tcpdump -i any -nn icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
20:20:08.084794 IP 192.168.1.202 > 192.168.2.29: ICMP echo request, id 161, seq 1, length 64
20:20:08.084970 IP 192.168.1.202 > 192.168.2.29: ICMP echo request, id 161, seq 1, length 64
20:20:08.084987 IP 192.168.2.29 > 192.168.1.202: ICMP echo reply, id 161, seq 1, length 64
20:20:08.085000 IP 192.168.2.29 > 192.168.1.202: ICMP echo reply, id 161, seq 1, length 64

# pod-1 DNS Sever 확인 
$ cat /etc/resolv.conf
search default.svc.cluster.local svc.cluster.local cluster.local ap-northeast-2.compute.internal
nameserver 10.100.0.10
options ndots:5

$ exit
$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.100.0.1   <none>        443/TCP   12h

 

파드에서 외부 통신 

파드에서 패키지를 다운로드하거나 업데이트가 필요한 경우 iptables의 SNAT를 통해 외부로 통신합니다. 
VPC CNI의 External source network address translation 설정에 따라 SNAT 하거나 혹은 SNAT 없이 외부와 통신할 수 있습니다. 
 

Life a Ping Packet(Pod to Internet)

파드에서 구글로 ping 테스트를 진행해보겠습니다. 
 

파드와 노드에서 각각 외부와 통신하는 공인 IP 주소가 동일함을 확인할 수 있습니다. 
 

 


[출처] 
1) CloudNet@, AEWS 실습 스터디 
2) https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/eks-add-ons.html

 

Amazon EKS 추가 기능 - Amazon EKS

Amazon EKS 추가 기능 추가 기능은 Kubernetes 애플리케이션에 대한 지원 운영 기능을 제공하는 소프트웨어이지만 애플리케이션에만 국한되지는 않습니다. 여기에는 기본 AWS 리소스를 사용하여 네트

docs.aws.amazon.com

3) AWS SA 강인호, Amazon EKS 마이그레이션 요점 정리.pdf 
4) https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/managing-vpc-cni.html

 

Amazon VPC CNI plugin for Kubernetes Amazon EKS 추가 기능을 사용한 작업 - Amazon EKS

Amazon VPC CNI plugin for Kubernetes 버전 v1.16.0~v1.16.1은 Kubernetes 버전 1.23 이하와의 호환성을 제거했습니다. VPC CNI 버전 v1.16.2는 Kubernetes 버전 1.23 이하 및 CNI 사양 v0.4.0과의 호환성을 복원합니다.

docs.aws.amazon.com

5) https://aws.github.io/aws-eks-best-practices/networking/vpc-cni/

 

Amazon VPC CNI - EKS Best Practices Guides

Amazon VPC CNI Amazon EKS implements cluster networking through the Amazon VPC Container Network Interface(VPC CNI) plugin. The CNI plugin allows Kubernetes Pods to have the same IP address as they do on the VPC network. More specifically, all containers i

aws.github.io

6) https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md
 

728x90