-
[eks 스터디 2주차] - EKS NetworkingAWS 2023. 5. 6. 15:05
참고 링크
더보기AWS Docs - AWS_CNI VPC CNI prefix assignment mode VPC CNI add-on External SNAT
0. 실습 환경 배포
Amazon EKS 윈클릭 배포 & 기본 설정
더보기# YAML 파일 다운로드 curl -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/eks-oneclick.yaml # CloudFormation 스택 배포 # aws cloudformation deploy --template-file eks-oneclick.yaml --stack-name myeks --parameter-overrides KeyName=<My SSH Keyname> SgIngressSshCidr=<My Home Public IP Address>/32 MyIamUserAccessKeyID=<IAM User의 액세스키> MyIamUserSecretAccessKey=<IAM User의 시크릿 키> ClusterBaseName='<eks 이름>' --region ap-northeast-2 예시) aws cloudformation deploy --template-file eks-oneclick.yaml --stack-name myeks --parameter-overrides KeyName=kp-gasida SgIngressSshCidr=$(curl -s ipinfo.io/ip)/32 MyIamUserAccessKeyID=AKIA5... MyIamUserSecretAccessKey='CVNa2...' ClusterBaseName=myeks --region ap-northeast-2 # CloudFormation 스택 배포 완료 후 작업용 EC2 IP 출력 aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text # 마스터노드 SSH 접속 ssh -i ~/.ssh/kp-gasida.pem ec2-user@$(aws cloudformation describe-stacks --stack-name myeks --query 'Stacks[*].Outputs[0].OutputValue' --output text)
기본 설정
# default 네임스페이스 적용 kubectl ns default # 노드 정보 확인 kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone eksctl get iamidentitymapping --cluster myeks # 노드 IP 확인 및 PrivateIP 변수 지정 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 # 노드 보안그룹 ID 확인 NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=*ng1* --query "SecurityGroups[*].[GroupId]" --output text) aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.100/32 # 워커 노드 SSH 접속 ssh ec2-user@$N1 hostname ssh ec2-user@$N2 hostname ssh ec2-user@$N3 hostname
설치 정보 확인
# 이미지 정보 확인 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-k8s-cni:v1.12.6-eksbuild.1 2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/coredns:v1.9.3-eksbuild.3 3 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/kube-proxy:v1.24.10-minimal-eksbuild.2 # eksctl 설치/업데이트 addon 확인 eksctl get addon --cluster $CLUSTER_NAME NAME VERSION STATUS ISSUES IAMROLE coredns v1.9.3-eksbuild.3 ACTIVE 0 kube-proxy v1.24.10-eksbuild.2 ACTIVE 0 vpc-cni v1.12.6-eksbuild.1 ACTIVE 0 arn:aws:iam::911283464785:role/eksctl-myeks-addon-vpc-cni-Role1-1TZPXJONK9XGE
1. AWS VPC CNI 소개
K8S CNI : Container Network Interface 는 k8s 네트워크 환경을 구성해준다 - 링크, 다양한 플러그인이 존재 - 링크
AWS VPC CNI : 파드의 IP를 할당해준다, 파드의 IP 네트워크 대역과 노드(워커)의 IP 대역이 같아서 직접 통신이 가능하다 - AWS_CNI Github Proposal
- Amazon EKS supports native VPC networking with the Amazon VPC Container Network Interface (CNI) plugin for Kubernetes.
- VPC 와 통합 : VPC Flow logs , VPC 라우팅 정책, 보안 그룹(Security group) 을 사용 가능함
- This plugin assigns an IP address from your VPC to each pod.
- VPC ENI 에 미리 할당된 IP를 파드에서 사용할 수 있음
K8S Calico CNI 와 AWS VPC CNI 차이
- 네트워크 통신의 최적화(성능, 지연)를 위해서 노드와 파드의 네트워크 대역을 동일하게 설정함
- 파드간 통신 시 일반적으로 K8S CNI는 오버레이(VXLAN, IP-IP 등) 통신을 하고, AWS VPC CNI는 동일 대역으로 직접 통신을 한다
워커 노드에 생성 가능한 최대 파드 갯수
- Secondary IPv4 addresses : 인스턴스 유형에 최대 ENI 갯수와 할당 가능 IP 수를 조합하여 선정
- IPv4 Prefix Delegation : IPv4 28bit 서브넷(prefix)를 위임하여 할당 가능 IP 수와 인스턴스 유형에 권장하는 최대 갯수로 선정
2. AWS VPC CNI - 파드 기본 통신
실습 환경 소개
- AWS EKS 클러스터, 관리형 노드 그룹(t3.medium, 노드 2대
👉🏻 실습 사용 버전 : EKS(K8S) v1.21.2 , AWS VPC CNI v1.7.5 , kube-ops-view
(옵션) kube-ops-view 설치 - 링크
더보기# 설치 curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash helm repo add stable https://charts.helm.sh/stable helm install kube-ops-view stable/kube-ops-view --set service.type=LoadBalancer --set rbac.create=True --namespace kube-system # 접속 URL 확인 kubectl get svc kube-ops-view -n kube-system | tail -n 1 | awk '{ print "Kube-ops-view URL = http://"$4 }'
2.1 워커 노드 기본 정보 확인
워커노드1 기본 네트워크 구성 : 워커노드2는 구성이 유사하여 생략
- Network 네임스페이스는 호스트(Root)와 파드 별(Per Pod)로 구분된다
- 특정한 파드(kube-proxy, aws-node)는 호스트(Root)의 IP를 그대로 사용한다
- t3.medium 의 경우 ENI 에 최대 6개의 IP를 가질 수 있다
- ENI0, ENI1 으로 2개의 ENI는 자신의 IP 이외에 추가적으로 5개의 보조 프라이빗 IP를 가질수 있다
- coredns 파드는 veth 으로 호스트에는 eniY@ifN 인터페이스와 파드에 eth0 과 연결되어 있다
워커 노드1 인스턴스의 네트워크 정보 확인 : 프라이빗 IP와 보조 프라이빗 IP 확인
kubectl , aws cli 등 정보 확인
더보기# 노드 정보 확인 kubectl get node ... NAME STATUS ROLES AGE VERSION ip-192-168-1-64.ap-northeast-2.compute.internal Ready <none> 117m v1.21.2-eks-55daa9d ip-192-168-2-235.ap-northeast-2.compute.internal Ready <none> 117m v1.21.2-eks-55daa9d ... 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-ng-b760da78-Node | 192.168.1.64 | 3.34.127.206 | running | | myeks-ng-b760da78-Node | 192.168.2.235 | 54.180.85.80 | running | +-------------------------+----------------+----------------+-----------+ ... # 파드 정보(IP) 확인 kubectl get pod -n kube-system -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase ... NAME IP STATUS aws-node-5fzgw 192.168.1.64 Running aws-node-w9b6m 192.168.2.235 Running coredns-6dbb778559-ddwzr 192.168.1.235 Running kube-ops-view-5557846b44-dh74l 192.168.2.171 Running kube-proxy-6hpj7 192.168.1.64 Running kube-proxy-xvdsj 192.168.2.235 Running ... [워커노드1]에서 확인 docker ps --format 'table {{.Names}}\t{{.Status}}' | grep -v POD ... NAMES STATUS k8s_coredns_coredns-6dbb778559-ddwzr_kube-system_0f29c550-f412-4a73-879d-82a2b892d4bc_0 Up 2 hours k8s_aws-node_aws-node-5fzgw_kube-system_c8404b73-a683-476d-b06e-87171d693fe5_0 Up 2 hours k8s_kube-proxy_kube-proxy-6hpj7_kube-system_e0c71d53-43d5-445e-86db-b805168cdec8_0 Up 2 hours ... [워커노드2]에서 확인 docker ps --format 'table {{.Names}}\t{{.Status}}' | grep -v POD ... NAMES STATUS k8s_kube-ops-view_kube-ops-view-5557846b44-dh74l_kube-system_c2549f52-2740-4709-ad64-6e509247dd9a_0 Up 2 hours k8s_aws-node_aws-node-w9b6m_kube-system_7a324f78-1ff2-4efb-96ae-755e82955ddf_0 Up 2 hours k8s_kube-proxy_kube-proxy-xvdsj_kube-system_d268e74d-58bd-4e2e-8e45-a373e25ca7f3_0 Up 2 hours ... # 노드에서 네트워크 인터페이스 정보 확인 ip -br -c addr ip -c link ip -c addr ip route # 혹은 route -n [워커노드1]에서 확인 ip -br -c addr ... lo UNKNOWN 127.0.0.1/8 ::1/128 eth0 UP 192.168.1.64/24 fe80::7d:8bff:fe4f:10a6/64 eni4bae37b3559@if3 UP fe80::c03:12ff:fe56:dfb0/64 eth1 UP 192.168.1.65/24 fe80::ed:35ff:fe37:f35a/64 ... # eni4bae37b3559@if3 는 pod network 네임스페이스와 veth pair # if3 은 nsenter 로 파드 내부에서 ip a 확인 시 NIC 의 number (3번) 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 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000 link/ether 02:7d:8b:4f:10:a6 brd ff:ff:ff:ff:ff:ff inet 192.168.1.64/24 brd 192.168.1.255 scope global dynamic eth0 valid_lft 2519sec preferred_lft 2519sec inet6 fe80::7d:8bff:fe4f:10a6/64 scope link valid_lft forever preferred_lft forever 4: eni4bae37b3559@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default link/ether 0e:03:12:56:df:b0 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::c03:12ff:fe56:dfb0/64 scope link valid_lft forever preferred_lft forever 5: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc mq state UP group default qlen 1000 link/ether 02:ed:35:37:f3:5a brd ff:ff:ff:ff:ff:ff inet 192.168.1.65/24 brd 192.168.1.255 scope global eth1 valid_lft forever preferred_lft forever inet6 fe80::ed:35ff:fe37:f35a/64 scope link valid_lft forever preferred_lft forever ... # 노드에 생성된 파드는 host 라우팅 정보로 파드로 직접 통신 route -n ... Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 169.254.169.254 0.0.0.0 255.255.255.255 UH 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 192.168.1.235 0.0.0.0 255.255.255.255 UH 0 0 0 eni4bae37b3559 ... # 파드의 네트워크 정보 확인 # 네임스페이스 정보 출력 -t net(네트워크 타입) : pause(컨테이너) 확인, PID 1 을 제외 lsns -o PID,COMMAND -t net | awk 'NR>2 {print $1}' ... 4399 ... # 변수 지정 MyPID1=<위 출력된 PID> MyPID1=4399 # nsenter(=namespace enter) 로 격리된 namespace 에 enter 하는 명령어 (-n 명령어 실행) # IP 확인(/32bit)! , if4 는 호스트 네트워크 정보 (ip a) 확인 시 NIC 의 number (4번) nsenter -t $MyPID1 -n ip a ... 3: eth0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default link/ether ce:00:5b:24:2d:6a brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.1.235/32 scope global eth0 valid_lft forever preferred_lft forever ... # 169.254.1.1 디폴트 루트가 잡혀있다 nsenter -t $MyPID1 -n ip route ... default via 169.254.1.1 dev eth0 169.254.1.1 dev eth0 scope link ...
[실습] 보조 IPv4 주소를 파드가 사용하는지 확인
더보기# 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-6777fcd775-57k77 1/1 Running 0 70m 192.168.1.142 ip-192-168-1-251.ap-northeast-2.compute.internal <none> <none> coredns-6777fcd775-cvqsb 1/1 Running 0 70m 192.168.2.75 ip-192-168-2-34.ap-northeast-2.compute.internal <none> <none> # 노드의 라우팅 정보 확인 >> EC2 네트워크 정보의 '보조 프라이빗 IPv4 주소'와 비교해보자 ssh ec2-user@$N1 sudo ip -c route ssh ec2-user@$N2 sudo ip -c route ssh ec2-user@$N3 sudo ip -c route
2.2 테스트용 파드 생성 및 확인
테스트용 파드 생성 - nicolaka/netshoot
더보기# 워커 노드 - 모니터링 watch -d "ip link | egrep 'eth|eni' ;echo;echo "[ROUTE TABLE]"; route -n | grep eni" # 작업용 EC2 - 파드 2개 생성 cat <<EOF | kubectl create -f - apiVersion: v1 kind: Pod metadata: name: pod-1 labels: app: pod spec: containers: - name: netshoot-pod image: nicolaka/netshoot command: ["tail"] args: ["-f", "/dev/null"] terminationGracePeriodSeconds: 0 --- apiVersion: v1 kind: Pod metadata: name: pod-2 labels: app: pod spec: containers: - name: netshoot-pod image: nicolaka/netshoot command: ["tail"] args: ["-f", "/dev/null"] terminationGracePeriodSeconds: 0 EOF # 파드 확인 kubectl get pod -o wide ... NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-1 1/1 Running 0 20m 192.168.2.63 ip-192-168-2-235.ap-northeast-2.compute.internal <none> <none> pod-2 1/1 Running 0 20m 192.168.1.249 ip-192-168-1-64.ap-northeast-2.compute.internal <none> <none> ... kubectl get pod -o=custom-columns=NAME:.metadata.name,IP:.status.podIP
파드가 생성되면, 워커 노드에 eniY@ifN 추가되고 라우팅 테이블에도 정보가 추가된다
테스트용 파드 eniY 정보 확인 - 워커 노드 EC2
더보기# 노드에서 네트워크 인터페이스 정보 확인 ip -br -c addr show ip -c link ip -c addr ip route # 혹은 route -n # 마지막 생성된 네임스페이스 정보 출력 -t net(네트워크 타입) lsns -o PID,COMMAND -t net | awk 'NR>2 {print $1}' | tail -n 1 28596 # 마지막 생성된 네임스페이스 net PID 정보 출력 -t net(네트워크 타입)를 변수 지정 MyPID2=$(lsns -o PID,COMMAND -t net | awk 'NR>2 {print $1}' | tail -n 1) # 파드 정보 확인 nsenter -t $MyPID2 -n ip a ... 3: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc noqueue state UP group default link/ether c6:94:16:91:74:9e brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.1.249/32 scope global eth0 valid_lft forever preferred_lft forever ... nsenter -t $MyPID2 -n ip route
2.3 파드간 통신
파드간 통신 흐름 : 별도의 오버레이(Overlay) 통신 기술 없이, VPC Native 하게 파드간 직접 통신이 가능하다
pod-2(192.168.1.249) → pod-1(192.168.2.63) 으로 통신 확인
파드간 통신 시 과정 참고
https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md
파드간 통신 테스트 및 확인
더보기# 작업용 EC2 kubectl get pod -o=custom-columns=NAME:.metadata.name,IP:.status.podIP kubectl exec -it pod-2 -- zsh ip a route ping -c 2 192.168.2.63 exit # pod-1 Shell 실행 kubectl exec -it pod-1 -- zsh # 아래부터는 pod-1 Shell 에서 실행 : 파드 통신 확인, 외부 통신 확인 ---------------------------- ip a route ping -c 1 <pod-2 IP> # 아래 tcpdump 시 실행 exit ---------------------------- # (옵션) nsenter 를 사용해서 통신 테스트 가능 nsenter -t $MyPID2 -n ping -c 2 8.8.8.8 [root@ip-192-168-1-251 ~]# nsenter -t $MyPID1 -n "ping -c 2 8.8.8.8" 64 bytes from 8.8.8.8: icmp_seq=1 ttl=100 time=32.1 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=100 time=32.0 ms # 워커 노드 EC2 # 각 개별 PID 값으로 lsns -t net 으로 -n ip a 명령어 실행 for PID in $(lsns -o PID,COMMAND -t net | awk 'NR>2 {print $1}'); do nsenter -t $PID -n ip a | grep eth0@ -A2; echo "-----------"; done # TCPDUMP 확인 : eth1 은 패킷 덤프에서 출력되지 않는다 yum -y install tcpdump tcpdump -i any -nn icmp tcpdump -i eth0 -nn icmp tcpdump -i eth1 -nn icmp [워커 노드1] # routing policy database management 확인 ip rule 0: from all lookup local 512: from all to 192.168.1.235 lookup main 512: from all to 192.168.1.249 lookup main 1024: from all fwmark 0x80/0x80 lookup main 32766: from all lookup main 32767: from all lookup default # routing table management 확인 ip route show table local ... local 192.168.1.64 dev eth0 proto kernel scope host src 192.168.1.64 local 192.168.1.65 dev eth1 proto kernel scope host src 192.168.1.65 ... # 디폴트 네트워크 정보를 eth0 을 통해서 빠져나간다 ip route show table main 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.64 192.168.1.235 dev eni4bae37b3559 scope link 192.168.1.249 dev enifbd243bfedd scope link
2.4 파드 → 외부(인터넷) 통신
파드에서 외부 통신 흐름
- iptable 에 SNAT 을 통하여 노드의 eth0 IP로 변경되어서 외부와 통신됨
https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md
- VPC CNI 의 External source network address translation (SNAT) 설정에 따라, 외부(인터넷) 통신 시 SNAT 하거나 혹은 SNAT 없이 통신을 할 수 있다 - 링크
- 파드가 VPC peering, Transit VPC, or Direct Connect 등으로 연결된 곳과 통신 시 문제 발생 시 VPC CNI v1.8 이상으로 업데이트를 하자 - 링크 링크2
파드에서 외부 통신 테스트 및 확인
- 파드 shell 실행 후 외부로 ping 테스트
- 워커 노드에서 tcpdump 및 iptables 정보 확인
더보기```bash **# 작업용 EC2** kubectl get pod -o=custom-columns=NAME:.metadata.name,IP:.status.podIP kubectl exec -it pod-2 -- zsh ip a route ping -c 2 192.168.2.63 exit # pod-1 Shell 실행 kubectl exec -it pod-1 -- zsh # 아래부터는 pod-1 Shell 에서 실행 : 파드 통신 확인, 외부 통신 확인 ---------------------------- ip a route ping -c 1 <pod-2 IP> # 아래 tcpdump 시 실행 exit ---------------------------- # (옵션) nsenter 를 사용해서 통신 테스트 가능 nsenter -t $MyPID2 -n ping -c 2 8.8.8.8 [root@ip-192-168-1-251 ~]# nsenter -t $MyPID1 -n "ping -c 2 8.8.8.8" 64 bytes from 8.8.8.8: icmp_seq=1 ttl=100 time=32.1 ms 64 bytes from 8.8.8.8: icmp_seq=2 ttl=100 time=32.0 ms **# 워커 노드 EC2** # 각 개별 PID 값으로 lsns -t net 으로 -n ip a 명령어 실행 for PID in $(lsns -o PID,COMMAND -t net | awk 'NR>2 {print $1}'); do nsenter -t $PID -n ip a | grep eth0@ -A2; echo "-----------"; done # TCPDUMP 확인 : eth1 은 패킷 덤프에서 출력되지 않는다 yum -y install tcpdump tcpdump -i any -nn icmp tcpdump -i eth0 -nn icmp tcpdump -i eth1 -nn icmp [워커 노드1] # routing policy database management 확인 ip rule 0: from all lookup local 512: from all to 192.168.1.235 lookup main 512: from all to 192.168.1.249 lookup main 1024: from all fwmark 0x80/0x80 lookup main 32766: from all lookup main 32767: from all lookup default # routing table management 확인 ip route show table local ... local 192.168.1.64 dev eth0 proto kernel scope host src 192.168.1.64 local 192.168.1.65 dev eth1 proto kernel scope host src 192.168.1.65 ... # 디폴트 네트워크 정보를 eth0 을 통해서 빠져나간다 ip route show table main **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.64 192.168.1.235 dev eni4bae37b3559 scope link 192.168.1.249 dev enifbd243bfedd scope link ```
3. 노드에 파드 생성 갯수 제한
Secondary IPv4 addresses : 인스턴스 유형에 최대 ENI 갯수와 할당 가능 IP 수를 조합하여 선정
워커 노드의 인스턴스 타입 별 파드 생성 갯수 제한
- 인스턴스 타입 별 ENI 최대 갯수와 할당 가능한 최대 IP 갯수에 따라서 파드 배치 갯수가 결정됨
- 단, aws-node 와 kube-proxy 파드는 호스트의 IP를 사용함으로 최대 갯수에서 제외함
워커 노드의 인스턴스 정보 확인 : 필자는 현재 t3.medium 사용 중
더보기# t3 타입의 정보(필터) 확인 aws ec2 describe-instance-types --filters Name=instance-type,Values=t3.* \ --query "InstanceTypes[].{Type: InstanceType, MaxENI: NetworkInfo.MaximumNetworkInterfaces, IPv4addr: NetworkInfo.Ipv4AddressesPerInterface}" \ --output table -------------------------------------- | DescribeInstanceTypes | +----------+----------+--------------+ | IPv4addr | MaxENI | Type | +----------+----------+--------------+ | 15 | 4 | t3.2xlarge | | 6 | 3 | t3.medium | | 12 | 3 | t3.large | | 15 | 4 | t3.xlarge | | 2 | 2 | t3.micro | | 2 | 2 | t3.nano | | 4 | 3 | t3.small | +----------+----------+--------------+ # 파드 사용 가능 계산 예시 : aws-node 와 kube-proxy 파드는 host-networking 사용으로 IP 2개 남음 ((MaxENI * (IPv4addr-1)) + 2) t3.medium 경우 : ((3 * (6 - 1) + 2 ) = 17개 >> aws-node 와 kube-proxy 2개 제외하면 15개 # 워커노드 상세 정보 확인 : 노드 상세 정보의 Allocatable 에 pods 에 17개 정보 확인 kubectl describe node ip-192-168-1-64.ap-northeast-2.compute.internal | grep Allocatable: -A7 Allocatable: attachable-volumes-aws-ebs: 25 cpu: 1930m ephemeral-storage: 18242267924 hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 3412904Ki pods:
최대 파드 생성 및 확인
더보기# 워커 노드 EC2 # 모니터링 watch -d "ip link | egrep 'eth|eni'" while true; do ip -br -c addr show && echo "--------------" ; date "+%Y-%m-%d %H:%M:%S" ; sleep 1; done # 작업용 EC2 - 터미널1 watch -d 'kubectl get pods -o wide' # 작업용 EC2 - 터미널2 # 디플로이먼트 생성 cat <<EOF | kubectl create -f - apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:alpine ports: - containerPort: 80 EOF # 파드 증가 테스트 >> 파드 정상 생성 확인, 워커 노드에서 eth, eni 갯수 확인 kubectl scale deployment nginx-deployment --replicas=8 # 파드 증가 테스트 >> 파드 정상 생성 확인, 워커 노드에서 eth, eni 갯수 확인 >> 어떤일이 벌어졌는가? kubectl scale deployment nginx-deployment --replicas=10 # 파드 증가 테스트 >> 파드 정상 생성 확인, 워커 노드에서 eth, eni 갯수 확인 kubectl scale deployment nginx-deployment --replicas=30 # 파드 생성 실패! kubectl get pods | grep Pending nginx-deployment-7fb7fd49b4-d4bk9 0/1 Pending 0 3m37s nginx-deployment-7fb7fd49b4-qpqbm 0/1 Pending 0 3m37s kubectl describe pod <Pending 파드> | grep Events: -A5 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 57s (x4 over 3m5s) default-scheduler 0/3 nodes are available: 3 Too many pods. # 디플로이먼트 삭제 kubectl delete deploy nginx-deployment
- kube-ops-view 웹에서 확인 : 워커 노드 마다 최대 17개(2개는 aws-node, kube-proxy) 파드 생성 이후에 오른쪽 상단에 미 배치된 파드 정보
4. 노드에 파드 생성 갯수 증가
IPv4 Prefix Delegation : IPv4 28bit 서브넷(prefix)를 위임하여 할당 가능 IP 수와 인스턴스 유형에 권장하는 최대 갯수로 선정
AWS VPC CNI prefix assignment mode 에서 최대 파드 생성 갯수
- 간단한 동작 확인을 위해서 기존의 관리형 노드 그룹을 삭제하고, 신규 관리형 노드 그룹(Nitro-base, c5.large, 1대)을 생성하였다
- IPv4 Prefix Delegation 대역의 IP를 파드가 사용 가능하다
- AWS VPC CNI prefix assignment mode 필수 조건
- 인스턴스 유형 : AWS Nitro-based nodes use this capability
- VPC CNI 버전 : Version 1.9.0 or later of the Amazon VPC CNI add-on added to your cluster.
육아로 아직 아래 부분은 남아있는데 일요일 중에 업데이트 할게요~ㅠ
'AWS' 카테고리의 다른 글
[eks 스터디 3주차] - EKS Storage & Node 관리 (0) 2023.05.12 [eks 스터디 1주차] Introduction - EKS 실습 환경 배포 (0) 2023.04.23