개요
AWS EKS의 VPC CNI에 대해 학습
VPC CNI
VPC CNI는 k8s CNI와 비슷하게 Pod의 IP 주소를 할당해주는 역할도 수행해주는데, 특징으로는 Pod의 네트워크 대역과 워커 노드의 네트워크 대역을 같게하여 Pod와 워커 노드 간 직접 통신이 가능하다는 점이 있음
또한 VPC Flow Logs, 라우팅 정책, 보안 그룹들과의 통합이 용이하며, VPC ENI (Elastic Network Interface)에 미리 할당된 IP 주소 (L-IPAM)들을 Pod에 할당하여 Pod의 빠른 시작을 지원
EC2가 생성되면 기본 서브넷과 관련된 ENI 생성하고 연결하는데, 호스트 네트워크 모드로 동작하는 Pod는 기본 ENI에 할당된 IP 주소를 사용하고 호스트 네트워크 네임 스페이스를 공유하게 됨
구성 요소
VPC CNI는 CNI Binary와 ipamd로 나뉨
•
CNI Binary는 Pod 간 통신이 가능하도록 루트 파일 시스템에서 동작하여 네트워크를 구성해주는데, 새로운 Pod가 추가 되거나 삭제되는 경우 Kubelet에 의해 실행
•
ipamd는 노드 상에서 동작하는 IPAM 데몬으로, 노드의 ENI를 관리하고, L-IPAM에 가용할 수 있는 IP 주소들을 유지시키는 역할을 담당
VPC CNI는 노드의 ENI를 관리한다고 했었는데, 노드가 프로비저닝 되면 CNI 플러그인이 자동으로 노드의 서브넷으로부터 ENI에 Slot Pool을 할당 (Slot Pool은 Warm Pool이라고도 부르고, CNI 세팅에 따라 Slot은 IP 주소일 수도 있고 Prefix 형태일 수 있음)
ENI 에 Slot Pool이 할당되면 CNI는 추가적인 ENI를 노드에 추가할 수 있는데, 이렇게 추가된 ENI는 보조 ENI라고 지칭 (각 ENI는 정해진 수의 Slot들만 지원할 수 있고, 총 Slot 수는 노드의 인스턴스 타입에 따라 결정)
CNI는 필요한 Slot 수에 따라 노드에 ENI를 붙이게 되는데, 이 때 필요한 Slot 수는 일반적으로 Pod 수에 해당 (노드가 추가 ENI를 받을 수 없을 때까지 ENI를 붙이는 과정이 반복)
노드에 붙일 수 있는 ENI 수와 이에 따른 총 Slot 수는 노드의 인스턴스 타입에 따라 결정되고, 이는 곧 생성할 수 있는 Pod 수도 노드의 인스턴스 타입에 따라 결정되는 것이므로, max-pod-calculator.sh 같은 스크립트를 이용하여 호스트 네트워크에서 생성할 수 있는 Pod 수를 미리 예측 가능
인스턴스 타입에 따라 최대 ENI 수와 할당 가능 IP 주소를 조합하여 최대 Pod 수를 결정하는 것을 Secondary IPv4 Address 방식이라 하고, IPv4 28비트 서브넷 위임을 통해 할당 가능 IP 주소 수를 이용하여 최대 Pod 수를 결정 짓는 것을 IPv4 Prefix Delegation이라 함
Calico CNI와 차이
VPC CNI는 네트워크 통신의 성능과 지연에서의 최적화를 위해 노드와 Pod의 네트워크 대역을 동일하게 설정
반면에 Calico CNI는 다른 일반적인 k8s CNI와 마찬가지로 오버레이 네트워크를 거치기 때문에 VPC CNI가 지원하는 것처럼 직접적으로 통신을 할 수는 없음
네트워크 구조
통신 과정에서 흐름을 알 수 있도록 클러스터를 구성하고 있는 각 노드 내부에서의 구조를 확인 (각 노드들은 모두 동일한 구조를 갖고 있음)
네트워크 네임스페이스는 호스트 네트워크 네임스페이스와 Per Pod 네트워크 네임스페이스로 구분되는데, kube-proxy 혹은 aws-node 같은 특정 Pod들은 호스트의 IP를 그대로 사용
t3.medium의 경우 ENI마다 최대 6개의 IP 주소를 가질 수 있으며, ENI0 ENI1은 각각의 자신 IP 주소를 제외하고 추가적으로 5개의 보조 프라이빗 IP 주소를 가질 수 있음
AWS LB Controller
Service 종류는 ClusterIP, NodePort, LoadBalancer가 있었는데, 이 중에서 LoadBalancer 타입의 Service를 이용하게 되면 AWS VPC CNI에 의해 AWS LB Controller와 NLB IP 모드로 동작하게 됨
externalTrafficPolicy
externalTrafficPolicy가 Cluster라면 2번의 부하 분산 과정과 함께 sNAT로 클라이언트 IP 주소 확인이 불가능하고, Local이라면 워커 노드의 iptables를 이용함으로써 1번의 부하 분산 과정만 이뤄지고 클라이언트 IP 주소를 그대로 유지하여 이용
AWS VPC CNI에서 LoadBalancer의 기본 externalTrafficPolicy는 Cluster
Proxy Protocol v2
Proxy Protocol v2 비활성화 시 NLB에서 Pod로 즉각 인입되고, 클라이언트 IP 주소는 NLB로 sNAT되어 확인 불가능
Proxy Protocol v2 활성화 시 NLB에서 Pod로 즉각 인입되는 것은 동일한데, PPv2를 애플리케이션이 인지할 수 있도록 설정이 필요하고 이를 통해 클라이언트 IP 주소 확인 가능
Ingress
Ingress는 ClusterIP, NodePort, LoadBalancer를 외부로 노출하는 Proxy였는데, AWS VPC CNI에서의 Ingress는 AWS LB Controller를 통해 ALB IP 모드로 동작
1.
Service Controller로 Service 노출
2.
External LB 목적의 Ingress 적용
3.
Internal Reverse Proxy 목적의 Ingress 적용
4.
k8s Gateway API
AWS에는 Route 53 서비스가 있고 (비슷한 서비스론 Azure의 DNS, GCP의 Cloud DNS) 도메인을 설정하게 되면, k8s에서 Service 및 Ingress를 생성 및 삭제했을 때 A 레코드 및 TXT 레코드를 자동으로 생성하고 삭제해주는 기능을 제공
ExternalDNS 기능을 이용하기 위해선 Node IAM Role, Static Credentials, IRSA 중 하나라도 권한을 주어야 제어 가능하고, 퍼블릭 도메인을 소유 필요
Network Policy
eBPF로 패킷 필터링이 동작하기 위해선 아래와 같은 조건이 필요
•
EKS 1.25 버전 이상
•
AWS VPC CNI 1.14 이상
•
OS 커널 5.10 이상
EKS 1.25 버전 이상일 시 Network Policy Controller 자동 설치되며, 통제 정책 모니터링으로 eBPF 프로그램을 생성하고 업데이트 할 수 있도록 Node Agent에 지시
Node Agent는 aws-node라는 DaemonSet으로 AWS VPC CNI의 번들이며 ipamd 플러그인과 함께 설치되어 eBPF 프로그램을 관리
AWS VPC CNI에서는 노드에서 eBPF 프로그램과 상호작용할 수 있는 SDK를 포함하고 있는데, 이를 eBPF SDK라고 하며 eBPF 실행의 런타임 검사와 추적 그리고 분석을 지원
Hybrid Mode: AWS VPC CNI + Cilium CNI
•
AWS VPC CNI - IPAM, Routing
•
Cilium CNI - LB, Network Policy, Encryption, Visibility
하이브리드 모드에서 AWS VPC CNI의 역할은 ENI를 통해 IPAM을 지원하고 가상 네트워크를 셋업하는데 있음
초기 네트워크가 AWS VPC CNI로 구성되면 AWS VPC CNI는 Network Policy 적용, 부하 분산 수행, 암호화 적용을 위해 Cilium CNI를 적용하는 과정을 거침
Cilium CNI를 적용하는 과정은 eBPF 프로그램을 AWS VPC CNI가 구성한 네트워크 장치에 붙도록 설정을 진행
AWS VPC CNI와 Cilium CNI의 강점 조합을 원하는 것이 아니라 Cilium의 모든 기능을 원한다면 Cilium CNI만 적용하여 사용하는 것을 권장