Ssoon

[9주차] AWS EKS : VPC CNI : 네트워크 정보 본문

쿠버네티스 네트워크 스터디 3기

[9주차] AWS EKS : VPC CNI : 네트워크 정보

구구달스 2024. 10. 28. 20:06
CloudNet@ 가시다님이 진행하는 쿠버네티스 네트워크 스터디 3기

 

 AWS VPC CNI

https://aws.amazon.com/ko/blogs/opensource/vpc-cni-plugin-v1-1-available/

  • Kubernetes 클러스터에서 Pod의 네트워크를 관리하기 위해 만들어진 네트워크 인터페이스 플러그인으로, Kubernetes가 클러스터 내에서 통신할 때 AWS VPC 네트워크와 직접 연동할 수 있도록 지원합니다.
  • Amazon EKS 클러스터는 기본적으로 이 VPC CNI 플러그인을 사용하여 네트워크를 설정하며, Pod가 VPC 내에서 고유 IP를 받아 AWS의 다른 리소스와 쉽게 통신할 수 있게 합니다.

  • Pod별 고유 IP 제공:
    • VPC CNI 플러그인은 각 Pod에 AWS VPC의 IP 주소를 할당하여 AWS 내 다른 서비스와 동일한 네트워크 범위 안에서 통신할 수 있게 해줍니다.
    • 이를 통해 네트워크 보안 규칙과 접근 제어가 더 간단해집니다. 예를 들어, Security Group을 활용해 VPC 내에서 Pod 단위로 세부적인 통신 제어가 가능합니다.
  • 고성능 네트워킹:
    • Pod에 직접 ENI(Elastic Network Interface)를 연결하여 AWS 인프라 내에서 고성능 네트워킹을 구현합니다.
    • 특히 데이터 집약적인 작업이 필요한 경우 AWS 네트워크의 높은 대역폭을 그대로 사용할 수 있습니다.
  • 네트워크 보안 및 격리:
    • VPC CNI는 AWS 보안 기능을 그대로 활용하므로 각 Pod에 대한 보안 관리가 강화됩니다.
    • 네트워크 ACL, 보안 그룹과 같은 VPC 내 보안 정책을 사용하여 Pod의 통신 범위를 제어할 수 있습니다.
  • 노드 풀의 IP 관리:
    • AWS VPC CNI는 노드 풀의 ENI를 사용하여 Pod에 IP를 할당합니다. 기본적으로 각 ENI는 여러 개의 보조 IP를 가질 수 있으며, 이는 하나의 ENI가 다수의 Pod에 IP를 제공할 수 있음을 의미합니다.
    • 이를 통해 IP 자원을 효율적으로 사용할 수 있습니다.

 

AWS VPC CNI 플러그인은 EKS 클러스터의 각 워커 노드에 설치되며, Pod가 스케줄될 때마다 다음과 같은 방식으로 네트워크 연결을 관리합니다:

  1. ENI 할당: 각 워커 노드는 하나 이상의 ENI를 가질 수 있으며, ENI에는 여러 개의 IP가 할당됩니다.
  2. IP 할당: 새로운 Pod가 생성되면, VPC CNI 플러그인은 해당 노드의 ENI에서 사용 가능한 IP를 Pod에 할당합니다.
  3. Pod와 ENI 연결: 할당된 IP는 Pod가 네트워크에 연결되는 데 사용되며, Pod는 이를 통해 AWS 리소스와 통신할 수 있습니다.

🧿 L-IPAM (Local IP Address Manager)

  • Pod에게 IP 주소를 할당할 때 서브넷의 IP 자원을 효율적으로 관리할 수 있도록 돕는 IP 관리 기능입니다.
  • L-IPAM은 Amazon VPC CNI(네트워크 플러그인)와 함께 사용되며, IP 자원이 부족한 경우에도 Pod에 IP를 유연하게 할당할 수 있도록 설계된 IP 관리 모드입니다.

  • 노드 간 IP 주소 재활용:
    • L-IPAM은 서브넷 내에서 가용한 IP 자원을 재활용하고 효율적으로 배분하여, Pod가 많은 환경에서도 IP 자원 부족 문제를 최소화할 수 있도록 합니다.
  • ENI 할당 절약:
    • 기존의 VPC CNI 플러그인에서는 Pod가 배치될 때마다 Elastic Network Interface(ENI)가 필요합니다. 그러나 L-IPAM을 사용하면 Pod에 ENI를 추가로 할당할 필요 없이 IP를 할당할 수 있습니다.
    • 이를 통해 ENI 자원의 소모를 줄이고, 한 노드에서 더 많은 Pod를 운영할 수 있습니다.
  • 서브넷 IP 자원의 효율적 사용:
    • L-IPAM은 기존 방식보다 서브넷의 IP 주소를 효율적으로 사용할 수 있도록 최적화되어 있어, 한정된 IP 풀을 가진 서브넷에서도 더 많은 Pod에 IP를 할당할 수 있습니다.

🧿 Warm IP Pool

Warm IP Pool은 Local-IPAM 설정에서 관리하는 사전에 확보된 IP 주소 풀입니다. 이는 새로운 Pod가 생성될 때마다 IP를 할당받는 시간을 줄이기 위해 미리 IP를 확보해 두는 방식으로, 새로운 Pod 생성 시 빠르게 IP를 제공할 수 있도록 돕습니다.

  • 미리 확보된 IP 풀:
    • Local-IPAM을 사용할 때, Warm IP Pool에 미리 IP를 확보해둠으로써 Pod 생성 시 IP 주소 할당 속도가 빨라집니다.
  • IP 자원 관리 최적화:
    • IP를 미리 준비해두므로, Pod가 빠르게 생성되거나 삭제되는 상황에서도 IP를 안정적으로 할당할 수 있어 IP 자원을 효율적으로 사용할 수 있습니다.
  • 자동 조정:
    • 사용 가능한 IP가 충분하지 않을 경우, Warm IP Pool은 동적으로 IP를 추가 확보하거나 줄여 가용성을 유지합니다.

🧿 K8S Calico CNI 와 AWS VPC CNI 차이

  • 네트워크 통신의 최적화(성능, 지연)를 위해서 노드와 파드의 네트워크 대역을 동일하게 설정함
  • 네트워크 대역을 동일하게 설정하면, 파드와 노드 간 통신이 같은 네트워크 대역 내에서 이루어져 추가적인 라우팅 경로가 필요 없게 됩니다. 이렇게 설정할 경우, 데이터가 전달되는 경로가 짧아지기 때문에 전송 속도가 빨라지고 지연(latency)도 줄어듭니다.

  • 파드간 통신 시 일반적으로 K8S CNI는 오버레이(VXLAN, IP-IP 등) 통신을 하고, AWS VPC CNI는 동일 대역으로 직접 통신을 한다


✅ 배포 확인

🧿 노드 IP 확인 및 PrivateIP 변수 지정

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# 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})
ile
echo "export N3=$N3" >> /etc/profile
echo $N1, $N2, $N3(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topologne=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# 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})
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# echo "export N1=$N1" >> /etc/profile
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# echo "export N2=$N2" >> /etc/profile
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# echo "export N3=$N3" >> /etc/profile
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# echo $N1, $N2, $N3
192.168.1.111, 192.168.2.59, 192.168.3.215​

🧿 보안 그룹 ID를 환경 변수로 설정하고, 이를 시스템 전역 환경 변수로 유지

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=*ng1* --query "SecurityGroups[*].[GroupId]" --output text)
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# echo $NGSGID
sg-003a5e48e50354739
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# echo "export NGSGID=$NGSGID" >> /etc/profile

🧿 EC2 보안 그룹에 대해 특정 IP 주소 ( 192.168.1.100/32 ) 에서의 모든 트래픽(All traffic)을 허용하도록 인바운드 규칙을 추가

  • aws ec2 authorize-security-group-ingress
    AWS CLI를 사용하여 EC2 보안 그룹의 인바운드 규칙을 추가하는 명령어입니다.
  • --group-id $NGSGID
    대상 보안 그룹의 ID를 지정합니다. $NGSGID 변수에 저장된 값은 이전에 조회한 보안 그룹 ID(sg-003a5e48e50354739)입니다.
  • --protocol '-1'
    -1 프로토콜은 모든 프로토콜을 의미하며, 트래픽 유형에 상관없이 모든 트래픽을 허용합니다.
  • --cidr 192.168.1.100/32
    인바운드 트래픽을 허용할 IP 주소 범위를 지정합니다. 192.168.1.100/32은 단일 IP인 192.168.1.100만을 의미합니다.
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.100/32
{
    "Return": true,
    "SecurityGroupRules": [
        {
            "SecurityGroupRuleId": "sgr-0ec3c2f3e53f735be",
            "GroupId": "sg-003a5e48e50354739",
            "GroupOwnerId": "992382835044",
            "IsEgress": false,
            "IpProtocol": "-1",
            "FromPort": -1,
            "ToPort": -1,
            "CidrIpv4": "192.168.1.100/32"
        }
    ]
}

🧿myeks-bastion 에서 노드의IP ( 192.168.1.111, 192.168.2.59, 192.168.3.215 ) 로 ping 테스트

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# ping -c 1 $N1
PING 192.168.1.111 (192.168.1.111) 56(84) bytes of data.
64 bytes from 192.168.1.111: icmp_seq=1 ttl=255 time=0.859 ms

--- 192.168.1.111 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.859/0.859/0.859/0.000 ms
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# ping -c 1 $N2
PING 192.168.2.59 (192.168.2.59) 56(84) bytes of data.
64 bytes from 192.168.2.59: icmp_seq=1 ttl=255 time=1.00 ms

--- 192.168.2.59 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.000/1.000/1.000/0.000 ms
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# ping -c 1 $N3
PING 192.168.3.215 (192.168.3.215) 56(84) bytes of data.
64 bytes from 192.168.3.215: icmp_seq=1 ttl=255 time=1.36 ms

--- 192.168.3.215 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.362/1.362/1.362/0.000 ms

🧿  각 노드 로 SSH 연결을 시도하여 원격 호스트의 호스트명을 출력

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# for node in $N1 $N2 $N3; do ssh -o StrictHostKeyChecking=no ec2-user@$node hostname; done
Warning: Permanently added '192.168.1.111' (ECDSA) to the list of known hosts.
ip-192-168-1-111.ap-northeast-2.compute.internal
Warning: Permanently added '192.168.2.59' (ECDSA) to the list of known hosts.
ip-192-168-2-59.ap-northeast-2.compute.internal
Warning: Permanently added '192.168.3.215' (ECDSA) to the list of known hosts.
ip-192-168-3-215.ap-northeast-2.compute.internal

🧿 각 노드에 SSH 접속확인 

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# ssh ec2-user@$N1
Last login: Thu Oct 24 01:21:33 2024 from 54.240.230.184
   ,     #_
   ~\_  ####_        Amazon Linux 2
  ~~  \_#####\
  ~~     \###|       AL2 End of Life is 2025-06-30.
  ~~       \#/ ___
   ~~       V~' '->
    ~~~         /    A newer version of Amazon Linux is available!
      ~~._.   _/
         _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
       _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/

[ec2-user@ip-192-168-1-111 ~]$ exit
logout
Connection to 192.168.1.111 closed.
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# ssh ec2-user@$N2
Last login: Thu Oct 24 01:21:33 2024 from 54.240.230.184
   ,     #_
   ~\_  ####_        Amazon Linux 2
  ~~  \_#####\
  ~~     \###|       AL2 End of Life is 2025-06-30.
  ~~       \#/ ___
   ~~       V~' '->
    ~~~         /    A newer version of Amazon Linux is available!
      ~~._.   _/
         _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
       _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/

[ec2-user@ip-192-168-2-59 ~]$ exit
logout
Connection to 192.168.2.59 closed.
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# ssh ec2-user@$N3
Last login: Thu Oct 24 01:21:33 2024 from 54.240.230.184
   ,     #_
   ~\_  ####_        Amazon Linux 2
  ~~  \_#####\
  ~~     \###|       AL2 End of Life is 2025-06-30.
  ~~       \#/ ___
   ~~       V~' '->
    ~~~         /    A newer version of Amazon Linux is available!
      ~~._.   _/
         _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
       _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/

[ec2-user@ip-192-168-3-215 ~]$ exit
logout
Connection to 192.168.3.215 closed.

🧿 Add-on 정보확인


네트워크 기본 정보 확인

네트워크 네임스페이스는 호스트(Root)와 파드 별(Per Pod)로 구분된다

  • 네트워크 네임스페이스는 네트워크 자원(예: IP 주소, 라우팅 테이블 등)을 독립적으로 관리할 수 있게 해주는 기능입니다. Kubernetes에서 각 파드는 독립된 네트워크 네임스페이스를 가지며, 파드 내부 네트워크는 다른 파드와 분리됩니다.
  • 호스트 네임스페이스(Root)는 노드 자체의 네트워크 공간이고, 파드 별 네트워크 네임스페이스는 파드가 격리된 네트워크 환경에서 실행될 수 있도록 해줍니다.

특정한 파드(kube-proxy, aws-node)는 호스트(Root)의 IP를 그대로 사용한다

  • Kubernetes에서 kube-proxy aws-node와 같은 특정 파드들은 클러스터 내 노드의 네트워크 기능을 관리합니다.
  • 이 파드들은 노드 전체에 걸쳐 네트워크 트래픽을 제어해야 하므로, 별도의 파드 네임스페이스가 아닌 호스트 네임스페이스(Root)에서 직접 실행되어 호스트 IP를 그대로 사용합니다.

t3.medium 의 경우 ENI마다 최대 6개의 IP를 가질 수 있다

  • AWS의 t3.medium 인스턴스는 **ENI(Elastic Network Interface)**라는 네트워크 인터페이스를 사용합니다.
  • t3.medium 인스턴스는 ENI 하나당 최대 6개의 IP 주소를 가질 수 있습니다. 이 제한은 인스턴스 타입에 따라 달라지며, 이는 파드가 ENI를 통해 할당받을 수 있는 IP 수를 의미합니다.

ENI0, ENI1로 2개의 ENI는 자신의 IP 이외에 추가적으로 5개의 보조 프라이빗 IP를 가질 수 있다

  • 인스턴스에는 여러 개의 ENI를 장착할 수 있습니다. ENI0 ENI1은 첫 번째와 두 번째 ENI로, 각 ENI에는 하나의 기본 IP와 최대 5개의 추가 IP를 가질 수 있습니다.

coredns 파드는 veth으로 호스트에는 eniY@ifN 인터페이스와 파드에 eth0과 연결되어 있다

  • coredns 파드는 네임서버 역할을 하는 파드로, Kubernetes 클러스터에서 도메인 이름을 관리합니다.
  • 파드는 veth(Virtual Ethernet) 로 네트워크 인터페이스를 설정하여 노드의 네트워크와 연결됩니다. veth는 호스트 측 인터페이스(eniY@ifN)와 파드 내 인터페이스(eth0)를 쌍으로 연결합니다.

🧿 kube-system 네임스페이스에서 aws-node DaemonSet의 상세 정보

aws-node DaemonSet은 AWS의 네트워킹 컴포넌트로, 각 노드에 설치되는 AWS CNI(Container Network Interface) 플러그인 관련 설정을 가지고 있습니다.

  • amazon-k8s-cni-init:v1.18.5-eksbuild.1: 초기화 컨테이너 이미지
  • amazon-k8s-cni:v1.18.5-eksbuild.1: 실제 네트워킹 CNI 플러그인 컨테이너 이미지
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
amazon-k8s-cni-init:v1.18.5-eksbuild.1
amazon-k8s-cni:v1.18.5-eksbuild.1
amazon

🧿 Kubernetes 클러스터의 kube-proxy 설정을 확인

  • mode: "iptables"
    iptables 모드는 kube-proxy가 iptables를 사용하여 서비스와 관련된 네트워크 트래픽을 라우팅하도록 설정하는 모드입니다. 이는 패킷 필터링과 네트워크 주소 변환(NAT)을 위해 리눅스 커널에서 제공하는 네트워킹 기능을 활용합니다.
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# kubectl describe cm -n kube-system kube-proxy-config
...
mode: "iptables"
...

🧿 현재 실행 중(running)인 인스턴스에 대한 IP 주소와 인스턴스 이름 확인

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# 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.2.59   |  3.36.12.174    |  running |
|  myeks-ng1-Node|  192.168.3.215  |  13.124.252.15  |  running |
|  myeks-bastion |  192.168.1.100  |  43.203.232.16  |  running |
|  myeks-ng1-Node|  192.168.1.111  |  13.125.157.40  |  running |
+----------------+-----------------+-----------------+----------+

🧿 kube-system 네임스페이스에 있는 모든 파드(Pod)들의 이름, IP 주소, 상태 정보

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# kubectl get pod -n kube-system -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase
NAME                       IP              STATUS
aws-node-6xgbq             192.168.2.59    Running
aws-node-gqkth             192.168.1.111   Running
aws-node-mqz2q             192.168.3.215   Running
coredns-6558b6db9c-7szh8   192.168.1.153   Running
coredns-6558b6db9c-bxhhq   192.168.3.40    Running
kube-proxy-gmscs           192.168.1.111   Running
kube-proxy-p28h8           192.168.3.215   Running
kube-proxy-ssmlp           192.168.2.59    Running

🧿 $N1, $N2, $N3로 지정된 각 노드에 대해 /var/log/aws-routed-eni 디렉터리의 파일 구조를 확인

/var/log/aws-routed-eni 디렉터리 내 로그 파일

이 디렉터리에는 VPC CNI 플러그인이 네트워크 인터페이스 및 IP를 관리하면서 생성한 다양한 로그 파일이 저장됩니다. 각 로그 파일은 다음과 같은 정보를 포함할 수 있습니다:

  • ebpf-sdk.log: eBPF와 관련된 네트워크 플러그인의 활동을 기록합니다.
  • ipamd.log: IP 주소 관리 데몬(IPAM)의 로그로, ENI 및 IP 주소 할당과 관련된 활동이 기록됩니다.
  • network-policy-agent.log: 네트워크 정책 에이전트의 로그로, 네트워크 정책과 관련된 설정 및 이벤트를 기록합니다.
  • egress-v6-plugin.log: IPv6 egress 플러그인과 관련된 활동이 기록됩니다.
  • plugin.log: VPC CNI 플러그인의 일반적인 활동을 기록하는 로그입니다.

이러한 로그를 통해 VPC CNI 플러그인의 상태를 확인하고, 네트워크 인터페이스 및 IP 할당과 관련된 문제를 디버깅할 수 있습니다.

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# 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.111 <<
/var/log/aws-routed-eni
├── ebpf-sdk.log
├── egress-v6-plugin.log
├── ipamd.log
├── network-policy-agent.log
└── plugin.log

0 directories, 5 files

>> node 192.168.2.59 <<
/var/log/aws-routed-eni
├── ebpf-sdk.log
├── ipamd.log
└── network-policy-agent.log

0 directories, 3 files

>> node 192.168.3.215 <<
/var/log/aws-routed-eni
├── ebpf-sdk.log
├── egress-v6-plugin.log
├── ipamd.log
├── network-policy-agent.log
└── plugin.log

0 directories, 5 files

🧿 $N1, $N2, $N3 IP 주소를 가진 각 노드에서 네트워크 인터페이스의 IP 주소와 상태를 확인

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# 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.111 <<
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             192.168.1.111/24 fe80::49:edff:fee4:61fd/64
enif1e092ddbf8@if3 UP             fe80::c8a8:caff:feca:a711/64
eth1             UP             192.168.1.170/24 fe80::64:d2ff:fe4a:c907/64

>> node 192.168.2.59 <<
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             192.168.2.59/24 fe80::4f8:8aff:fe79:9b03/64

>> node 192.168.3.215 <<
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0             UP             192.168.3.215/24 fe80::8f4:45ff:fe54:8751/64
enicb023416899@if3 UP             fe80::1cab:4aff:fea0:7576/64
eth1             UP             192.168.3.191/24 fe80::8e1:68ff:fe63:8191/64

🧿  각 노드에서 네트워크 라우팅 정보를 출력하여, 트래픽이 특정 목적지에 도달하기 위해 경유하는 경로와 네트워크 인터페이스

  • 192.168.1.111과 192.168.3.215에는 추가 인터페이스(enif 및 enic)로 연결된 네트워크 경로가 있습니다.
  • 192.168.1.153과 192.168.3.40에 대한 경로는 각각의 추가 인터페이스에 직접 연결됩니다. 이는 VPC CNI 플러그인이 Pod와 ENI 간 트래픽을 관리하기 위해 사용하는 네트워크 인터페이스입니다.
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -c route; echo; done
>> node 192.168.1.111 <<
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.111
192.168.1.153 dev enif1e092ddbf8 scope link

>> node 192.168.2.59 <<
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.59

>> node 192.168.3.215 <<
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.215
192.168.3.40 dev enicb023416899 scope link

 

🧿 netshoot-pod라는 이름의 Deployment를 생성하여 네트워크 진단 및 디버깅 작업을 위해 사용되는 netshoot 이미지를 배포

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# cat <<EOF | kubectl apply -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

🧿 라우팅 테이블 정보

  •  각 ENI는 특정 IP에 연결되어 있으며, 이 구성은 Kubernetes의 VPC CNI 플러그인이 네트워크 인터페이스를 사용하여 Pod 간 네트워크 트래픽을 처리하도록 설정된 방식
[ROUTE TABLE]
192.168.1.153   0.0.0.0         255.255.255.255 UH    0      0        0 enif1e092ddbf8
192.168.1.187   0.0.0.0         255.255.255.255 UH    0      0        0 eni89edfeecc39


[ROUTE TABLE]
192.168.2.172   0.0.0.0         255.255.255.255 UH    0      0        0 enieaae9400137


[ROUTE TABLE]
192.168.3.40    0.0.0.0         255.255.255.255 UH    0      0        0 enicb023416899

🧿 netshoot-pod이라는 애플리케이션 레이블을 가진 Pod 세 개의 이름을 각각 변수에 저장

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# PODNAME1=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[0].metadata.name})
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# PODNAME2=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[1].metadata.name})
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# PODNAME3=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[2].metadata.name})

🧿 파드 확인

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# kubectl get pod -o wide
NAME                            READY   STATUS    RESTARTS   AGE    IP              NODE                                               NOMINATED NODE   READINESS GATES
netshoot-pod-74b7555dc7-4jzzz   1/1     Running   0          2m8s   192.168.3.104   ip-192-168-3-215.ap-northeast-2.compute.internal   <none>           <none>
netshoot-pod-74b7555dc7-7xcn5   1/1     Running   0          2m8s   192.168.2.172   ip-192-168-2-59.ap-northeast-2.compute.internal    <none>           <none>
netshoot-pod-74b7555dc7-n9tjg   1/1     Running   0          2m8s   192.168.1.187   ip-192-168-1-111.ap-northeast-2.compute.internal   <none>           <none>

🧿 각 노드가 연결된 네트워크 인터페이스(ENI)와 특정 IP 주소들 간의 직접 연결을 설정한 내용

  • 첫 번째 노드 (192.168.1.111)
    • 기본 게이트웨이: 192.168.1.1 (eth0 인터페이스를 통해 라우팅)
    • 메타데이터 서버: 169.254.169.254
    • 로컬 서브넷: 192.168.1.0/24 네트워크에 연결
    • 192.168.1.153와 192.168.1.187 IP는 각각 enif1e092ddbf8와 eni89edfeecc39 ENI를 통해 연결됩니다.
  • 두 번째 노드 (192.168.2.59)
    • 기본 게이트웨이: 192.168.2.1 (eth0 인터페이스를 통해 라우팅)
    • 메타데이터 서버: 169.254.169.254
    • 로컬 서브넷: 192.168.2.0/24 네트워크에 연결
    • 192.168.2.172 IP는 enieaae9400137 ENI를 통해 연결됩니다.
  • 세 번째 노드 (192.168.3.215)
    • 기본 게이트웨이: 192.168.3.1 (eth0 인터페이스를 통해 라우팅)
    • 메타데이터 서버: 169.254.169.254
    • 로컬 서브넷: 192.168.3.0/24 네트워크에 연결
    • 192.168.3.40와 192.168.3.104 IP는 각각 enicb023416899와 eni3ef89bef356 ENI를 통해 연결됩니다.
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# for i in $N1 $N2 $N3; do echo ">> node $i <<"; ssh ec2-user@$i sudo ip -c route; echo; done
>> node 192.168.1.111 <<
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.111
192.168.1.153 dev enif1e092ddbf8 scope link
192.168.1.187 dev eni89edfeecc39 scope link

>> node 192.168.2.59 <<
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.59
192.168.2.172 dev enieaae9400137 scope link

>> node 192.168.3.215 <<
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.215
192.168.3.40 dev enicb023416899 scope link
192.168.3.104 dev eni3ef89bef356 scope link

🧿 테스트용 파드 eniY 정보 확인

  • lo: 루프백 인터페이스로 기본 127.0.0.1 IP를 가집니다.
  • eth0@if5: eth0 인터페이스는 IP 192.168.3.104/32와 링크 로컬 주소를 가지고 있습니다.

  • default via 169.254.1.1 dev eth0: 기본 경로가 eth0 인터페이스를 통해 169.254.1.1로 지정되어 있습니다.
  • 169.254.1.1 dev eth0 scope link: 169.254.1.1 IP는 링크 스코프 내에서 접근이 가능합니다.
[ec2-user@ip-192-168-3-215 ~]$ sudo lsns -o PID,COMMAND -t net | awk 'NR>2 {print $1}' | tail -n 1
10839

[ec2-user@ip-192-168-3-215 ~]$ MyPID=$(sudo lsns -o PID,COMMAND -t net | awk 'NR>2 {print $1}' | tail -n 1)

[ec2-user@ip-192-168-3-215 ~]$ sudo nsenter -t $MyPID -n ip -c 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
3: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
    link/ether 16:75:39:45:0f:c1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.3.104/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::1475:39ff:fe45:fc1/64 scope link
       valid_lft forever preferred_lft forever

[ec2-user@ip-192-168-3-215 ~]$ sudo nsenter -t $MyPID -n ip -c route
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link

 

 

 


🧿 테스트용 파드 접속(exec) 

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# kubectl exec -it $PODNAME1 -- zsh
                    dP            dP                           dP
                    88            88                           88
88d888b. .d8888b. d8888P .d8888b. 88d888b. .d8888b. .d8888b. d8888P
88'  `88 88ooood8   88   Y8ooooo. 88'  `88 88'  `88 88'  `88   88
88    88 88.  ...   88         88 88    88 88.  .88 88.  .88   88
dP    dP `88888P'   dP   `88888P' dP    dP `88888P' `88888P'   dP

Welcome to Netshoot! (github.com/nicolaka/netshoot)
Version: 0.13





 netshoot-pod-74b7555dc7-4jzzz  ~ 

🧿 네트워크 정보 확인

  •  eth0 인터페이스가 연결된 ENI는 AWS 네트워크와의 통신을 관리하며, Pod 트래픽이 클러스터 외부로 나갈 때 169.254.1.1 게이트웨이를 통해 전달됩니다. 이는 AWS의 네트워크 아키텍처에서 EKS Pod들이 VPC 서브넷 내에서 직접적으로 IP를 할당받아 사용하게 하며, 이를 통해 다른 VPC 리소스와 상호 작용할 수 있습니다.
netshoot-pod-74b7555dc7-4jzzz  ~  ip -c 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
3: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
    link/ether 16:75:39:45:0f:c1 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.3.104/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::1475:39ff:fe45:fc1/64 scope link
       valid_lft forever preferred_lft forever

 netshoot-pod-74b7555dc7-4jzzz  ~  ip -c route
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link

 netshoot-pod-74b7555dc7-4jzzz  ~  route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         169.254.1.1     0.0.0.0         UG    0      0        0 eth0
169.254.1.1     0.0.0.0         255.255.255.255 UH    0      0        0 eth0

🧿 네트워크 정보 확인

(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# kubectl exec -it $PODNAME2 -- ip -c 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
3: eth0@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default
    link/ether 0e:59:a7:c9:9e:64 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.2.172/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::c59:a7ff:fec9:9e64/64 scope link
       valid_lft forever preferred_lft forever
(iam-root-account@myeks:N/A) [root@myeks-bastion ~]# kubectl exec -it $PODNAME3 -- ip -br -c addr
lo               UNKNOWN        127.0.0.1/8 ::1/128
eth0@if5         UP             192.168.1.187/32 fe80::b05b:9aff:fecd:95d6/64
Comments