[PKOS Study 2주차] Kubernetes Network ( AWS VPC CNI )
- -
CloudNet@ 팀의 가시다님께서 Leading 하시는 PKOS 2기 Study 내용 요약
해당 Kubernetes Study 는 '24단계 실습으로 정복하는 쿠버네티스' 책을 기반으로 진행 중입니다.
이번 포스팅에서는 k8s 의 CNI 중 하나인 AWS VPC CNI 에 대해 알아보겠습니다.
1. AWS VPC CNI 소개
AWS VPC 를 사용하기 위한 Kubernetes Container Network Interface
온프레미스 환경에서 k8s 를 설치하면 기본적으로 쿠버네티스는 Calico CNI 를 사용하고 있습니다.
k8s 의 Calico CNI 는 노드의 IP 대역과 Pod의 IP 대역이 다른 Overlay Network 의 형태를 취하고 있습니다.
하지만 AWS 에서는 쿠버네티스 통신 최적화를 위해 Pod 에 AWS Subnet 의 IP 를 부여하는데,
이를 가능하게 해주는 것이 바로 AWS VPC CNI 입니다.
이미지에서 볼 수 있는 것처럼 Calico CNI 는 가상의 라우터를 한 번 더 거치기 때문에,
AWS 상에서 k8s 를 운영할 때 VPC CNI 보다 네트워크 성능이 다소 떨어질 수 있습니다.
VPC CNI 를 사용할 경우에 장단점은 아래와 같습니다.
장점
- AWS에 최적화된 네트워크
- AWS VPC Flow Logs, 라우팅 정책, 보안 그룹 등의 AWS VPC 서비스 사용 가능
단점
- Pod 1개당 Subnet IP 를 잡아먹기 때문에, IP 부족현상 발생
- Node 의 최대 IP 개수에 따른 Pod 배포 제한 발생
이제 AWS VPC CNI 의 동작 원리와 VPC CNI 의 단점인 Pod 개수 제한을 회피할 수 있는 방법에 대해서 알아보겠습니다.
실습을 위한 EKS 아키텍처 구성이며 비용과 시간 절감을 위해 EKS가 아닌 Kops 로 실습을 진행하였습니다.
2. AWS VPC CNI 실습
AWS VPC CNI 는 aws-node 라는 이름의 pod가 Daemonset 형태로 각 노드마다 배포되어 있습니다.
2.1. AWS VPC CNI 정보 확인
- 먼저 Node 에 대한 정보를 확인합니다.
kubectl get nodes -o wide
- 이후
aws-node
Pod 가 어떻게 배포되어 있는지 확인해봅니다.
kubectl get pods -A -o wide | grep -i -e "aws-node" -e "name"
Node 에 1개씩 배포되어 있는 것을 확인할 수 있습니다.
- 좀 더 자세히 확인하기 위해 daemonset 을 확인해봅시다.
kubectl describe daemonsets.apps aws-node -n kube-system
많은 정보들이 있지만 그 중에도 빨간 상자 안의 부분은 AWS VPC CNI 가 가지고 있는 기능에 대한 부분입니다.
2.2. AWS VPC CNI 의 Pod IP 부여
AWS VPC CNI 는 Pod 에 Subnet IP 를 부여한다고 하였습니다.
실제로 그렇게 작동하는 지 확인해봅시다.
테스트를 위해 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
kubectl get pods -o wide
실제 Subnet 대역에 속한 IP 를 가지는 것을 확인할 수 있습니다.
2.3. Pod 간 통신
- AWS VPC CNI 를 사용했을 때, 서로 다른 노드에 있는 Pod 들은 어떻게 통신이 될까요??
VPC IP 대역을 할당받았으니 Direct 로 통신할 지 , Node 의 IP 를 가지고 통신할 지 한 번 테스트 해봅시다.
- Pod 에서 다른 Pod 로 Ping 테스트를 진행합니다.
kubectl exec -it netshoot-pod-7757d5dd99-57nzf -- ping -c 2 172.30.53.115
Pod 에서 tcpdump 로 확인 결과, Pod IP 간 Direct 통신을 확인할 수 있습니다.
2.4. Pod 의 외부 통신
- 그럼 Pod 에서 외부로 통신할 때는 어떤 IP 를 가지고 통신할까요??
- Pod 에서 외부 사이트로 연결해봅니다.
kubectl exec -it netshoot-pod-7757d5dd99-57nzf -- ping -c 1 www.google.com
Pod 내부 tcpdump
Pod 간 통신과는 다르게 중간 IP 를 거쳐서 통신을 한다.
해당 IP 는 Pod 가 배포된 노드의 IP 인 것을 확인할 수 있습니다.
- Pod가 외부와 통신할 때의 공인 IP 를 확인해봅시다.
kubectl exec -it netshoot-pod-7757d5dd99-57nzf -- curl -s ipinfo.io/ip ; echo
해당 IP 는 노드의 공인 IP 임을 확인할 수 있습니다.
만약 Private Subnet 에 배포된 노드라면 NAT IP 를 사용한다는 것을 알 수 있습니다.
3. VPC CNI 의 Pod 제한
VPC CNI 의 특징에 의해 , EC2 인스턴스 타입별 ENI 최대 개수와 할당 가능한 최대 IP 개수에 의해 파드 개수가 결정됩니다.
인스턴스 타입별 최대 ENI 개수와 IP 개수는 아래 공식 문서에서 확인할 수 있습니다.
탄력적 네트워크 인터페이스 - Amazon Elastic Compute Cloud
이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.
docs.aws.amazon.com
- Max Pod 공식은 다음과 같습니다.
( MaxENI * (IPv4addr-1) + 2 )
ENI 당 할당 가능한 최대 IP 개수를 곱하되, 첫 번째 IP 는 Node 의 IP 이므로, Pod 가 할당되지 않습니다.
또한 , aws-node 와 kube-proxy Pod 는 host-networking 을 사용하므로 별도의 VPC IP 가 필요하지 않아 2개를 더해주게 됩니다.
4. VPC CNI Pod 제한 해결
VPC CNI Pod 제한을 해결할 수 있는 방안으로는 Prefix Delegation, WARM & MIN IP/Prefix Target , Custom Network 등이 있습니다.
4.1. Prefix Delegation
- AWS Docs
Amazon EC2 노드에 사용 가능한 IP 주소의 양 늘리기 - Amazon EKS
관리형 노드 그룹은 maxPods의 값에 최대 수를 적용합니다. vCPU가 30개 미만인 인스턴스의 경우 최대 수는 110이고 다른 모든 인스턴스의 경우 최대 수는 250입니다. 이 최대 수는 접두사 위임의 활성
docs.aws.amazon.com
EC2 인스턴스의 ENI Prefix 할당 모드를 통해 더 많고 탄력적인 IP 를 가질 수 있게 되었습니다.
이 기능은 AWS Nitro 기반의 EC2 인스턴스 유형일 경우에만 사용 가능합니다.
접두사 할당모드를 활성화 시키기 위해서는 앞서 우리가 보았던 AWS Node 의 옵션 중 ENABLE_PREFIX_DELEGATION
옵션을 활성화 시켜야 합니다.
kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true
기존의 IP 할당 방식과 다른 점은 , ENI 에 개별 Secondary IP 가 부여되지 않고 /28 의 범위의 IP 대역이 부여된다는 것입니다.
해당 옵션을 활성화 했다면 실제 Pod 를 여러개 배포해봅시다.
먼저, 쿠버네티스에 limitranges 정책이 걸려있는지 확인합니다.
kubectl describe limitranges
쿠버네티스 상에 올라오는 컨테이너의 성능을 보장하기 위해 컨테이너 당 최소 0.1CPU 를 사용하도록 보장해주는 정책입니다.
실습이니 해당 정책을 삭제합니다.
kubectl delete limitranges limits
이후 Pod 를 배포해봅시다.
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
kubectl scale deployment nginx-deployment --replicas=100
100개를 배포했을 때, 모두 Running 이 되는 것을 확인할 수 있습니다.
이번에는 쿠버네티스 CNI 중 AWS 환경에서 사용하는 AWS VPC CNI 에 대해서 알아보았습니다.
다음에는 AWS LoadBalancer Controller 에 대해서 알아보겠습니다.
'AWS > EKS' 카테고리의 다른 글
[PKOS Study 3주차] GitOps System - Harbor 설치 (0) | 2023.03.26 |
---|---|
[PKOS Study 2주차] Kubernetes Storage ( emptyDir, hostPath, PV/PVC ) (0) | 2023.03.19 |
[PKOS Study 2주차] 쿠버네티스 Service, Ingress (LoadBalancer controller) (0) | 2023.03.19 |
[PKOS Study 1주차] Kubernetes External DNS (0) | 2023.03.14 |
[PKOS Study 1주차] AWS에 kops 로 쿠버네티스 클러스터 생성 (0) | 2023.03.11 |