Ssoon
[9주차] AWS EKS : VPC CNI : 네트워크 정보 본문
CloudNet@ 가시다님이 진행하는 쿠버네티스 네트워크 스터디 3기
✅ AWS VPC CNI
- 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가 스케줄될 때마다 다음과 같은 방식으로 네트워크 연결을 관리합니다:
- ENI 할당: 각 워커 노드는 하나 이상의 ENI를 가질 수 있으며, ENI에는 여러 개의 IP가 할당됩니다.
- IP 할당: 새로운 Pod가 생성되면, VPC CNI 플러그인은 해당 노드의 ENI에서 사용 가능한 IP를 Pod에 할당합니다.
- 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
'쿠버네티스 네트워크 스터디 3기' 카테고리의 다른 글
[9주차] AWS EKS : VPC CNI : Service & AWS LoadBalancer Controller / Ingress (2) | 2024.10.28 |
---|---|
[9주차] AWS EKS : VPC CNI : 노드 간 파드 통신 / 파드에서 외부 통신 / 노드에 파드 생성 갯수 제한 (0) | 2024.10.28 |
[8주차] Cilium CNI : Bandwidth Manager (0) | 2024.10.21 |
[8주차] Cilium CNI : Network Policy (L3, L4, L7) (0) | 2024.10.21 |
[8주차] Cilium CNI : 서비스 통신 확인 (0) | 2024.10.21 |
Comments