이 글은 스터디를 참여하면서 학습한 내용을 중심으로 Kubernetes를 정리하는 연재 글이다.
스터디 진도에 맞춰 4~5개의 글을 작성 할 예정이다.
이 글에서는 AWS 내에서 Kubernetes 의 네트워크와 Pod의 통신 과정과 AWS CNI 특징으로 인한 노드의 Max Pod 제한을 알아본다.
1. 실습환경 배포
마스터 노드 (Master) t3.medium / 워커 노드 (Node1,2) c5d.large EC2 및 kops-ec2 (t3.small)로 구성되어 있다.
첫 번째 글의 실습환경과 동일 구성으로 되어 있고 워커노드의 머신타입만 변경되었다. 실습환경 배포는 첫번째 글 [PKOS] kOps를 사용한 Cluster 설치와 기본 Kubernetes 관리 방법을 참고바란다.
1.1. ExternalDNS, awsLoadBalancerController에 IAM 정책 권한 부여
위 배포는 kops yaml 파일 생성해서 동시 실습에서 사용할 Add-on까지 동시에 설치하도록 했다. Add-on에는 이번 실습에 사용할 ExternalDNS, awsLoadBalancerController이 포함된다. 이 Add-on들은 Controller가 생성되는데 AWS 내에서 접근하여 역할을 수행할 수 있도록 권한을 부여해준다.
# ExternalDNS IAM 정책 생성
curl -s -O https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/AKOS/externaldns/externaldns-aws-r53-policy.json
aws iam create-policy --policy-name AllowExternalDNSUpdates --policy-document file://externaldns-aws-r53-policy.json
# AWSLoadBalancerController IAM 정책 생성
curl -o iam_policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.5/docs/install/iam_policy.json
aws iam create-policy --policy-name AWSLoadBalancerControllerIAMPolicy --policy-document file://iam_policy.json
위에서 생성한 IAM 정책을 attach 해준다. 이 권한으로 ExternalDNS는 도메인을 세팅하게 되고, LoadBalancer Controller는 AWS ELB에 접근 할 수 있다.
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --role-name masters.$KOPS_CLUSTER_NAME
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AWSLoadBalancerControllerIAMPolicy --role-name nodes.$KOPS_CLUSTER_NAME
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AllowExternalDNSUpdates --role-name masters.$KOPS_CLUSTER_NAME
aws iam attach-role-policy --policy-arn arn:aws:iam::$ACCOUNT_ID:policy/AllowExternalDNSUpdates --role-name nodes.$KOPS_CLUSTER_NAME
1.2. LimitRanges 기본 정책 삭제
컨테이너는 기본적으로 0.1CPU(=100m vcpu)를 최소 보장하고 있다. 이 제약조건 때문에 아래 실습해볼 max-pod에서 워커노드 갯수 제한에 걸릴 수 있다. 이 정책을 삭제 해준다.
# kubectl describe limitranges
Name: limits
Namespace: default
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu - - 100m - -
# kubectl delete limitranges limits
limitrange "limits" deleted
# kubectl get limitranges
No resources found in default namespace.
2. K8S CNI와 AWS VPC CNI
2.1 K8S CNI와 AWS VPC CNI
Container Network Interface는 Kubernetes의 네트워크를 구성해준다. AWS에서는 AWS VPC CNI를 사용하고 있다. 즉 AWS에서는 Kubernetes 내에 생성되는 Pod는 AWS VPC에서 IP주소를 할당해준다.
AWS VPC CNI의 가장 큰 장점은 파드의 IP 네트워크 대역과 노드(워커)의 IP 대역이 같아서 직접 통신이 가능하다는 점이다. 아래 그림을 보면 Calico CNI는 파드와 노드의 네트워크 대역이 다르지만 AWS VPC CNIsms 노드와 파드의 네트워크 대역이 같다.
파드간의 통신을 할때를 보면 K8S CNI (아래 그림에서 왼쪽)는 오버레이(VXLAN, IP-IP 등) 통신을 하고, AWS VPC CNI (아래그림 오른쪽)는 동일 대역으로 직접 통신을 한다.
VPC 와 통합하여 VPC Flow logs , VPC 라우팅 정책을 사용할 수 있다. 다만 아쉬운 점은 실습환경에서 사용하는 kops에서는 pod의 보안 그룹(Security group) 사용이 미지원 된다는 점이다.
2.2 네트워크 기본 정보 확인
CNI 정보로 버전을 확인 하고, 노드 IP를 미리 확인 해둔다. 파드는 기본적으로 30개로 찍히는 걸 볼 수 있다.
# CNI 정보 확인: 버전을 확인 한다. v1.12.2이다!
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
amazon-k8s-cni-init:v1.12.2
amazon-k8s-cni:v1.12.2
# 노드 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 |
+---------------------------------------------------+----------------+----------------+-----------+
| nodes-ap-northeast-2c.ygpark.net | 172.30.77.201 | 13.209.40.114 | running |
| nodes-ap-northeast-2a.ygpark.net | 172.30.56.125 | 3.38.181.90 | running |
| control-plane-ap-northeast-2a.masters.ygpark.net | 172.30.49.220 | 54.180.157.55 | running |
| kops-ec2 | 10.0.0.10 | 15.165.15.175 | running |
+---------------------------------------------------+----------------+----------------+-----------+
# 파드 IP 확인
kubectl get pod -n kube-system -o=custom-columns=NAME:.metadata.name,IP:.status.podIP,STATUS:.status.phase
# 파드 이름 확인
kubectl get pod -A -o name
# 파드 갯수 확인
kubectl get pod -A -o name | wc -l
30
각 노드 1, 2에 접속하여 필요한 tool을 설치하고 모니터링 터미널을 생성 해둔다.
# 워커 노드 Public IP 변수 지정
W1PIP=<워커 노드 1 Public IP>
W2PIP=<워커 노드 2 Public IP>
W1PIP=3.38.181.90
W2PIP=13.209.40.114
# 워커 노드 SSH 접속
ssh -i /mnt/c/vswork/_pkos2/secret/ygpark.pem ec2-user@$(aws cloudformation describe-stacks --stack-name mykops --query 'Stacks[*].Outputs[0].OutputValue' --output text)
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP
exit
ssh -i ~/.ssh/id_rsa ubuntu@$W2PIP
exit
# [워커 노드1~2] SSH 접속 : 접속 후 아래 툴 설치 등 정보 각각 확인
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP
ssh -i ~/.ssh/id_rsa ubuntu@$W2PIP
--------------------------------------------------
# 툴 설치
sudo apt install -y tree jq net-tools
# CNI 정보 확인
ls /var/log/aws-routed-eni
cat /var/log/aws-routed-eni/plugin.log | jq
cat /var/log/aws-routed-eni/ipamd.log | jq
# 네트워크 정보 확인
ip -br -c addr
ip -c addr
ip -c route
sudo iptables -t nat -S
sudo iptables -t nat -L -n -v
# 빠져나오기
exit
3. 노드의 기본 네트워크 정보 확인
3.1. 노드의 기본 네트워크
노드 내부의 Network 네임스페이스는 호스트(Root)와 파드 별(Per Pod)로 구분된다.
호스트(Root) 네임스페이스를 보면 특정한 파드(kube-proxy, aws-node)는 호스트(Root)의 IP를 그대로 사용한다. 노드 타입 t3.medium 의 경우 ENI 에 최대 6개의 IP를 가질 수 있다. ENI0, ENI1 으로 2개의 ENI는 자신의 IP 이외에 추가적으로 5개의 보조 프라이빗 IP를 가질수 있다. 이 IP가 파드에 부여된다.
파드 별(Per Pod) 네임스페이스를 보면 coredns 파드는 veth 으로 호스트에는 eniY@ifN 인터페이스와 파드에 eth0 과 연결되어 있다.
3.2. 파드의 보조 IPv4 주소 사용여부 확인 실습
데몬 셋으로 올라가 있는 파드(ebs-csi-node)와 control-plane 노드가 같은 서브넷 대역을 가지는 것을 볼 수 있다.
# ebs-csi-node 파드 IP 정보 확인
kubectl get pod -n kube-system -l app=ebs-csi-node -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ebs-csi-node-6bj7g 3/3 Running 0 75m 172.30.57.0 i-028252b802ad40276 <none> <none>
ebs-csi-node-hjzjj 3/3 Running 0 76m 172.30.61.64 i-026f3209db8a214cb <none> <none>
ebs-csi-node-p5w4r 3/3 Running 0 75m 172.30.93.224 i-0f329621d367cc364 <none> <none>
k get node -owide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
i-026f3209db8a214cb Ready control-plane 79m v1.24.11 172.30.49.220 54.180.157.55 Ubuntu 20.04.5 LTS 5.15.0-1031-aws containerd://1.6.18
i-028252b802ad40276 Ready node 76m v1.24.11 172.30.56.125 3.38.181.90 Ubuntu 20.04.5 LTS 5.15.0-1031-aws containerd://1.6.18
i-0f329621d367cc364 Ready node 76m v1.24.11 172.30.77.201 13.209.40.114 Ubuntu 20.04.5 LTS 5.15.0-1031-aws containerd://1.6.18
EC2 네트워크 정보의 '보조 프라이빗 IPv4 주소'와 비교해보면 구분되어 있지 않고 대역이 같다.
# 노드의 라우팅 정보 확인 >> EC2 네트워크 정보의 '보조 프라이빗 IPv4 주소'와 비교해보자
ssh -i ~/.ssh/id_rsa ubuntu@api.$KOPS_CLUSTER_NAME ip -c route
default via 172.30.32.1 dev ens5 proto dhcp src 172.30.49.220 metric 100
172.30.32.0/19 dev ens5 proto kernel scope link src 172.30.49.220
172.30.32.1 dev ens5 proto dhcp scope link src 172.30.49.220 metric 100
172.30.60.224 dev eni896a8aeaa4c scope link
172.30.61.64 dev enif9c9db3621b scope link
172.30.61.65 dev enia9825b678ae scope link
172.30.61.66 dev eni1937813ded2 scope link
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP ip -c route
default via 172.30.32.1 dev ens5 proto dhcp src 172.30.56.125 metric 100
172.30.32.0/19 dev ens5 proto kernel scope link src 172.30.56.125
172.30.32.1 dev ens5 proto dhcp scope link src 172.30.56.125 metric 100
172.30.57.0 dev eni79b21c5768e scope link
172.30.57.1 dev enib15d7e7a2f4 scope link
172.30.63.80 dev enib241e1cc29a scope link
ssh -i ~/.ssh/id_rsa ubuntu@$W2PIP ip -c route
default via 172.30.64.1 dev ens5 proto dhcp src 172.30.77.201 metric 100
172.30.64.0/19 dev ens5 proto kernel scope link src 172.30.77.201
172.30.64.1 dev ens5 proto dhcp scope link src 172.30.77.201 metric 100
172.30.93.224 dev eni50ae4ba10c8 scope link
172.30.93.225 dev eni2ac1553ca8e scope link
172.30.93.226 dev enied2ffb2c3e6 scope link
172.30.93.227 dev eniabcbe34e2d3 scope link
3.3. 테스트용 파드 생성하고 확인
모니터링을 걸어 놓고 테스트용 파드를 생성하고 확인 해본다.
# [터미널1~2] 워커 노드 1~2 모니터링
ssh -i ~/.ssh/id_rsa ubuntu@$W1PIP
watch -d "ip link | egrep 'ens5|eni' ;echo;echo "[ROUTE TABLE]"; route -n | grep eni"
ssh -i ~/.ssh/id_rsa ubuntu@$W2PIP
watch -d "ip link | egrep 'ens5|eni' ;echo;echo "[ROUTE TABLE]"; route -n | grep eni"
~ 인터페이스 추가 부분
# 테스트용 파드 netshoot-pod 생성
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: netshoot-pod
spec:
replicas: 2
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
# 파드 이름 변수 지정
PODNAME1=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[0].metadata.name})
PODNAME2=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[1].metadata.name})
# 파드 확인
kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
netshoot-pod-7757d5dd99-drnnl 1/1 Running 0 63s 172.30.57.2 i-028252b802ad40276 <none> <none>
netshoot-pod-7757d5dd99-rnkx8 1/1 Running 0 63s 172.30.93.228 i-0f329621d367cc364 <none> <none>
각각의 노드에 파드가 하나씩 생성된 것이 보인다. 모니터링에 보면 파드가 생성될 때, 워커 노드에 eniY@ifN 추가되고 라우팅 테이블에도 정보가 추가된다.
4. 파드의 여러 통신
파드간 통신을 해보고 모니터링으로 걸어둔 tcpdump 내용을 확인해서 통신 과정을 알아본다.
4.1. 노드 간 파드 통신
위에서 설명했듯이 AWS VPC CNI 경우 기존 k8s CNI 처럼 별도의 오버레이(Overlay) 통신하지 않고, VPC Native 하게 파드간 직접 통신이 가능하다. 즉 파드와 노드의 ip 대역이 같아서 NAT없이 서로 통신이 가능하다.
아래에서 ping을 주는 통신을 하고, 노드에서 tcp덤프을 떠서 보면 오버레이 통신이 되지 않고 바로 통신이 되는 걸 볼 수 있다.
# 파드 IP 변수 지정
PODIP1=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[0].status.podIP})
PODIP2=$(kubectl get pod -l app=netshoot-pod -o jsonpath={.items[1].status.podIP})
# 파드1 Shell 에서 파드2로 ping 테스트
kubectl exec -it $PODNAME1 -- ping -c 2 $PODIP2
PING 172.30.93.228 (172.30.93.228) 56(84) bytes of data.
64 bytes from 172.30.93.228: icmp_seq=1 ttl=62 time=0.879 ms
64 bytes from 172.30.93.228: icmp_seq=2 ttl=62 time=0.789 ms
--- 172.30.93.228 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1016ms
rtt min/avg/max/mdev = 0.789/0.834/0.879/0.045 ms
# 파드2 Shell 에서 파드1로 ping 테스트
kubectl exec -it $PODNAME2 -- ping -c 2 $PODIP1
PING 172.30.57.2 (172.30.57.2) 56(84) bytes of data.
64 bytes from 172.30.57.2: icmp_seq=1 ttl=62 time=0.834 ms
64 bytes from 172.30.57.2: icmp_seq=2 ttl=62 time=0.789 ms
--- 172.30.57.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1028ms
rtt min/avg/max/mdev = 0.789/0.811/0.834/0.022 ms
# 워커 노드 EC2 : TCPDUMP 확인 - ens6 에서 패킷 덤프 확인이 되나요?
sudo tcpdump -i any -nn icmp
sudo tcpdump -i ens5 -nn icmp
sudo tcpdump -i ens6 -nn icmp
[1] 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 v1), capture size 262144 bytes
17:22:28.897930 IP 172.30.57.2 > 172.30.93.228: ICMP echo request, id 62807, seq 1, length 64
17:22:28.897971 IP 172.30.57.2 > 172.30.93.228: ICMP echo request, id 62807, seq 1, length 64
17:22:28.898766 IP 172.30.93.228 > 172.30.57.2: ICMP echo reply, id 62807, seq 1, length 64
17:22:28.898809 IP 172.30.93.228 > 172.30.57.2: ICMP echo reply, id 62807, seq 1, length 64
17:22:29.898702 IP 172.30.57.2 > 172.30.93.228: ICMP echo request, id 62807, seq 2, length 64
17:22:29.898735 IP 172.30.57.2 > 172.30.93.228: ICMP echo request, id 62807, seq 2, length 64
17:22:29.899522 IP 172.30.93.228 > 172.30.57.2: ICMP echo reply, id 62807, seq 2, length 64
17:22:29.899534 IP 172.30.93.228 > 172.30.57.2: ICMP echo reply, id 62807, seq 2, length 64
[2] 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 v1), capture size 262144 bytes
17:22:28.898243 IP 172.30.57.2 > 172.30.93.228: ICMP echo request, id 62807, seq 1, length 64
17:22:28.898296 IP 172.30.57.2 > 172.30.93.228: ICMP echo request, id 62807, seq 1, length 64
17:22:28.898318 IP 172.30.93.228 > 172.30.57.2: ICMP echo reply, id 62807, seq 1, length 64
17:22:28.898324 IP 172.30.93.228 > 172.30.57.2: ICMP echo reply, id 62807, seq 1, length 64
17:22:29.899011 IP 172.30.57.2 > 172.30.93.228: ICMP echo request, id 62807, seq 2, length 64
17:22:29.899042 IP 172.30.57.2 > 172.30.93.228: ICMP echo request, id 62807, seq 2, length 64
17:22:29.899070 IP 172.30.93.228 > 172.30.57.2: ICMP echo reply, id 62807, seq 2, length 64
17:22:29.899079 IP 172.30.93.228 > 172.30.57.2: ICMP echo reply, id 62807, seq 2, length 64
k get pod -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
netshoot-pod-7757d5dd99-drnnl 1/1 Running 0 26m 172.30.57.2 i-028252b802ad40276 <none> <none>
netshoot-pod-7757d5dd99-rnkx8 1/1 Running 0 26m 172.30.93.228 i-0f329621d367cc364 <none> <none>ㅠ
[워커 노드1]
# routing policy database management 확인
ip rule
# routing table management 확인
ip route show table local
# 디폴트 네트워크 정보를 ens5 을 통해서 빠져나간다
ip route show table main
default via 172.30.64.1 dev ens5 proto dhcp src 172.30.85.242 metric 100
...
4.2. 파드에서 외부 통신
kops 파드들, 클러스터 대역 끼리는 ip table의 NAT이 걸리지 않는다. 하지만 클러스터 파드 대역이 아니면 외부 인터넷으로 가야되기 때문에 정책이 걸려있다. 파드에서 부터 외부로 나가는 통신 흐름은 iptable 에 SNAT 을 통하여 노드의 eth0 IP로 변경되어서 외부와 통신된다.
# 작업용 EC2 : pod-1 Shell 에서 외부로 ping
kubectl exec -it $PODNAME1 -- ping -c 1 www.google.com
PING www.google.com (142.250.199.100) 56(84) bytes of data.
64 bytes from nrt13s52-in-f4.1e100.net (142.250.199.100): icmp_seq=1 ttl=101 time=32.8 ms
--- www.google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 32.750/32.750/32.750/0.000 ms
kubectl exec -it $PODNAME1 -- ping -i 0.1 www.google.com
PING www.google.com (142.250.199.100) 56(84) bytes of data.
64 bytes from nrt13s52-in-f4.1e100.net (142.250.199.100): icmp_seq=1 ttl=101 time=32.8 ms
64 bytes from nrt13s52-in-f4.1e100.net (142.250.199.100): icmp_seq=2 ttl=101 time=32.7 ms
64 bytes from nrt13s52-in-f4.1e100.net (142.250.199.100): icmp_seq=3 ttl=101 time=32.7 ms
64 bytes from nrt13s52-in-f4.1e100.net (142.250.199.100): icmp_seq=4 ttl=101 time=32.7 ms
64 bytes from nrt13s52-in-f4.1e100.net (142.250.199.100): icmp_seq=5 ttl=101 time=32.8 ms
64 bytes from nrt13s52-in-f4.1e100.net (142.250.199.100): icmp_seq=6 ttl=101 time=32.7 ms
64 bytes from nrt13s52-in-f4.1e100.net (142.250.199.100): icmp_seq=7 ttl=101 time=32.7 ms
...
--- www.google.com ping statistics ---
27 packets transmitted, 26 received, 3.7037% packet loss, time 2605ms
rtt min/avg/max/mdev = 32.731/32.753/32.791/0.016 ms
# 모니터링
17:39:29.547174 IP 172.30.56.125 > 142.250.199.100: ICMP echo request, id 14, seq 26, length 64
17:39:29.579869 IP 142.250.199.100 > 172.30.56.125: ICMP echo reply, id 14, seq 26, length 64
17:39:29.579884 IP 142.250.199.100 > 172.30.57.2: ICMP echo reply, id 26236, seq 26, length 64
17:39:29.647256 IP 172.30.57.2 > 142.250.199.100: ICMP echo request, id 26236, seq 27, length 64
17:39:29.647277 IP 172.30.56.125 > 142.250.199.100: ICMP echo request, id 14, seq 27, length 64
17:39:29.679982 IP 142.250.199.100 > 172.30.56.125: ICMP echo reply, id 14, seq 27, length 64
17:39:29.679996 IP 142.250.199.100 > 172.30.57.2: ICMP echo reply, id 26236, seq 27, length 64
...
워커노드의 외부 ip를 확인, 패킷 덤프를 걸고 나의 파드에서 외부 확인 해보면! 파드도 외부랑 통신이 된다.
외부와 통신할 때 pod1의 ip로 찍힌다. 즉 해당하는 워커노드의 eni 매핑 유동 퍼블릭 ip로 변경되어 뜬다. 외부로 나갈 때는 NAT 된다는 뜻!
# 워커 노드 EC2 : 퍼블릭IP 확인, TCPDUMP 확인
curl -s ipinfo.io/ip ; echo
[pod1] 3.38.181.90
[pod2] 13.209.40.114
# 작업용 EC2 : pod-1 Shell 에서 외부 접속 확인 - 공인IP는 어떤 주소인가?
## The right way to check the weather - 링크
kubectl exec -it $PODNAME1 -- curl -s ipinfo.io/ip ; echo
3.38.181.90
6. 노드의 파드 생성 갯수 제한 해제
6.1. 노드의 파드 생성 갯수 제한의 원인
AWS 워커 노드에 생성 가능한 최대 파드 갯수 제한이 된다. AWS CNI 특징인데, 네트워크 인터페이스 3개, Secondary IPv4 addresses 5개씩 할당 가능하다. Pod IP가 같은 대역에 할당되다보니 최대 IP 할당 수까지 최대로 파드 생성 제한이 생기게 된다.
- Secondary IPv4 addresses : 인스턴스 유형에 최대 ENI 갯수와 할당 가능 IP 수를 조합하여 선정
- 인스턴스 타입 별 ENI 최대 갯수와 할당 가능한 최대 IP 갯수에 따라서 파드 배치 갯수가 결정됨
- 단, aws-node 와 kube-proxy 파드는 호스트의 IP를 사용함으로 최대 갯수에서 제외함
최대 파드 생성 갯수 : (Number of network interfaces for the instance type × (the number of IP addressess per network interface - 1)) + 2
6.2. 노드의 파드 생성 갯수 제한 해제
해결 방안은 Prefix Delegation, WARM & MIN IP/Prefix Targets 옵션을 걸어서 풀어줄 수 있다. kops 클러스터와 인스턴스 그룹에 해당 파라미터 수정한다.
해당 파라미터를 수정하고 많은! 파드 배포를 해본다.
# 파드 갯수 모니터링
watch "kubectl get pod | grep -v NAME | wc -l"
# 노드 인스턴스 타입 확인
kubectl describe nodes | grep "node.kubernetes.io/instance-type"
node.kubernetes.io/instance-type=t3.medium
node.kubernetes.io/instance-type=c5d.large
node.kubernetes.io/instance-type=c5d.large
# 파드 100개 배포
kubectl apply -f ~/pkos/2/nginx-dp.yaml
kubectl scale deployment nginx-deployment --replicas=0
kubectl scale deployment nginx-deployment --replicas=10
kubectl scale deployment nginx-deployment --replicas=30
kubectl scale deployment nginx-deployment --replicas=100
# 파드 배포 확인
kubectl get pod
kubectl get pod | grep -v NAME | wc -l
100
kubectl get replicasets
NAME DESIRED CURRENT READY AGE
nginx-deployment-6fb79bc456 100 100 100 4m54s
NAME READY STATUS RESTARTS AGE
nginx-deployment-6fb79bc456-24k82 1/1 Running 0 46s
nginx-deployment-6fb79bc456-28plm 1/1 Running 0 50s
nginx-deployment-6fb79bc456-2kzzz 1/1 Running 0 47s
nginx-deployment-6fb79bc456-2mc5z 1/1 Running 0 49s
nginx-deployment-6fb79bc456-2r5pg 1/1 Running 0 49s
nginx-deployment-6fb79bc456-2s4jw 1/1 Running 0 50s
nginx-deployment-6fb79bc456-2xssf 1/1 Running 0 47s
...
kubectl scale deployment nginx-deployment --replicas=10000
Every 2.0s:... Fri Mar 17 03:03:04 2023
523
엄청 나게 많은 파드를 배포했다...! 모니터링을 보면 1534개가 올라가 있다. 무서워서 pod 배포 개수를 줄였다 ㅎㅎ
7. 마치며
네트워크 지식과 경험이 부족해서 학습하는데 시간이 꽤 많이 들었다. ip route, ip link 등의 명령어 결과를 해석하는 데에도 한참을 확인 해봐야 했다. 네트워크의 특징으로 max pod의 갯수 제한이 걸린다거나 CNI 특징으로 인해 많은 것이 달라지는걸 알게되어 많이 배울 수 있었다.
참고
- “24단계 실습으로 정복하는 쿠버네티스”: https://ebook-product.kyobobook.co.kr/dig/epd/ebook/E000005050811
- PKOS - CloudNet@ 팀 스터디 내용
- kOps 공식 웹페이지: https://kops.sigs.k8s.io/
- AWS VPC CNI https://github.com/aws/amazon-vpc-cni-k8s/blob/master/docs/cni-proposal.md
'스터디 > Kubernetes' 카테고리의 다른 글
[PKOS] Kubernetes 보안 - kubescape, polaris, RBAC (2/2) (0) | 2023.04.10 |
---|---|
[PKOS] Kubernetes 보안 - kubescape, polaris, RBAC (1/2) (0) | 2023.04.09 |
[PKOS] Kubernetes 모니터링과 로깅 - Prometheus, Grafana, Loki (0) | 2023.04.02 |
[PKOS] Kubernetes GitOps 시스템 - Harbor, GitLab, ArgoCD (0) | 2023.03.26 |
[PKOS] kOps를 사용한 Cluster 설치와 기본 Kubernetes 관리 방법 (0) | 2023.03.12 |