본문 바로가기

[EKS] Amazon VPC CNI 본문

Public Cloud

[EKS] Amazon VPC CNI

겨울바람_ 2024. 7. 26. 00:29

Amazon VPC CNI 소개

Amazon EKS는 Amazon VPC CNI 플러그인을 통해 클러스터 네트워킹 환경을 구성한다.

 

CNI는 Container Network Interface의 약자로 컨테이너 간 네트워킹을 제어하는 표준이라는 의미를 가진다. 참고로 Kubernetes의 경우 kubenet이라는 자체 CNI가 존재하지만 기능적 측면에서 제약이 많아 외부 플러그인을 주로 사용한다.

 

Amazon VPC CNI는 AWS VPC와 자연스럽게 연계되어 네트워킹 환경을 구성할 수 있다. 이로 인해 다양한 VPC 서비스와 통합이 가능하다.

 

Pod와 Node의 IP를 동일한 대역으로 할당할 수 있으며 이로 인해 통신에 대한 오버헤드가 거의 발생하지 않는다.

Assign IP Address on Pod


노드에 Amazon VPC CLI 플러그인을 설치하면 aws-node라는 이름의 DaemonSet이 생성된다. aws-node는 Local IP Address Manager의 약자인 L-IPAM과 CNI 플러그인으로 구성되어 있다.

 

VPC CNI와 L-IPAM은 gRPC를 통해 통신하여 IP주소를 삭제하거나 추가하는 구조이며, L-IPAM은 인스턴스에 대한 메타데이터를 확인하여 사용 가능한 ENI와 Secondary IP 주소를 파악한다.

 

이를 통해 Warm-Pool이라는 사용 가능한 Secondary IP 대역을 구성하는데 Warm-Pool에 구성된 IP 주소를 Pod가 생성될 때마다 하나씩 할당해준다. Warm Pool에 적재 가능한 IP 주소는 인스턴스 유형에 따라 가용 수량이 정해져 있다.

L-IPAM의 Warm-Pool과 인스턴스의 Primary ENI는 밀접한 연관을 지니고 있다.

 

우선 인스턴스에 구성되는 Primary ENI는 다수의 Priavte IP 주소를 포함하고 있을 수 있다. Primary ENI에 구성된 IP 주소는 Slot이라는 영역에 매칭된다.

 

위의 그림을 보면 총 3개의 Slot으로 구성되어 있으며, 이를 통해 해당 ENI에서는 3개의 Private IP 주소를 사용할 수 있다는 것을 알 수 있다.

 

이때 첫 번째 Slot에 매핑되는 IP 주소를 Primary IP 주소라고 하며 그 이외의 주소를 Secondary IP 주소라고 한다. 이 Secondary IP 주소가 Warm-Pool에 할당되는 것이다.

Pod가 생성되면 Warm-Pool 대역의 IP 주소를 제공하는데 이때 ENI에 Secondary IP 주소를 추가하는 개념이다.

 

만약 API Server로부터 Kubelet으로 신규 Pod를 추가하라는 명령이 내려오면 Kubelet은 Amazon VPC CNI로 추가 명령을 전달한다. VPC CNI는 L-IPAM에게 gRPC로 IP 주소 추가 명령을 전달하는 것이다.

 

L-IPAM은 Warm-Pool 대역의 IP 주소를 사용하도록 알리고 ENI의 빈 Slot에 Secondary IP 주소를 매핑한다. 최종적으로는 kubelet이 Pod에 ENI의 Secondary IP를 할당한다. 여기서 Node의 IP 주소는 Primary IP 주소이고 Pod의 IP 주소는 ENI의 Secondary IP 주소로 VPC 내의 동일한 IP 대역으로 유지된다.

 

만약 Primary ENI에 사용 가능한 Slot이 가득 찼을 때 새로운 Pod 생성 요청이 발생하면 어떻게 될까?

 

추가적인 ENI를 구성하여 해당 ENI의 Slot에 IP 주소를 매핑하고 해당 IP 주소를 Pod에게 할당한다. ENI의 경우 인스턴스의 유형에 따라 생성 한계가 정해져 있기 때문에 무한정 IP 주소를 할당할 수는 없다.

VPC CNI Communication

ENI로 연결된 구역은 VPC 연결 구간으로 AWS Networking을 통해 통신이 가능하다. 각각의 Pod는 통신을 위해 veth0로 구성되고 이를 연결하기 위해 가상의 ENI와 1:1 매칭이 된다.

 

그리고 이들을 서로 연결하여 통신이 가능하게 하는 Virtual Router가 각각의 가상의 ENI와 연결되는 Linux Networking 공간에 구성된다. 아래의 그림에서 Pod와 Node의 대역대가 동일한 것을 확인할 수 있는데 이는 VPC IP 대역을 활용하기 위해서다.

 

위의 그림은 Pod A에서 Pod C로 통신하는 상황을 예시로 그려둔 것이다.

 

Pod A에서 발생한 Packet은 Linux Networking을 통해 Node A의 ENI까지 전달되고 VPC 구간의 AWS Networking을 통해 Node B로 전달된다. Node B에 들어온 Packet이 Pod C로 전달될 때는 동일한 IP 대역이기 때문에 별도의 작업 없이 전달된다.

 

이러한 측면에서 오버헤드의 발생이 적어 빠른 통신이 가능하다.

EKS VPC CNI vs Kubernetes Calico

Kubernetes 환경에서 보편적으로 많이 사용하고 있는 CNI 플러그인 중 하나인 Calico와 VPC CNI를 비교해보자. 참고로 필자의 홈 서버에 구축된 쿠버네티스의 CNI 또한 Calico를 사용하고 있다.

우선 가장 다른 점은 Node와 Pod가 서로 다른 대역대로 IP 주소가 할당된다는 것이다.

 

VPC CNI의 예제와 동일하게 Pod A와 Pod C가 통신한다고 가정해보자. Pod A에서 목적지 주소를 Pod C의 IP 주소인 10.0.2.1로 할당한 Packet을 Linux Networking을 통해 Node A의 ENI까지 전달할 것이다.

 

하지만 Node 간 연결되는 네트워크 구간은 10.0.2.1의 IP 대역을 알지 못한다. 즉, 통신이 불가능하다는 것이다. 이러한 문제점을 해결하기 위해 VXLAN이나 IPIP같은 오버레이 네트워크를 구성하여 동작한다.

오버레이 네트워크는 Packet의 IP 헤더에 추가적인 IP 헤더를 덧붙여 전달하는 방법이다. Pod A가 전달하는 Packet을 VXLAN이나 IPIP로 ENI끼리 통신할 수 있는 IP 헤더를 캡슐화하여 전달한다.

 

그렇게 되면 ENI 구간은 추가된 IP 헤더를 사용하여 Node B까지 통신이 가능해진다. Packet을 Pod C로 전달할 때는 앞에서 덧붙였던 IP 헤더를 역캡슐화하여 원본 Packet을 Pod C에 전달한다.

 

오버레이 네트워크를 통해 Packet을 캡슐화 혹은 역캡슐화 하는 과정에서 VPC CNI에서는 발생하지 않았던 오버헤드가 발생하기 때문에 VPC CNI 보다는 비효율적인 통신이라고 생각할 수 있다.

Amazon VPC CNI Maximum Pod Quantity

Amazon VPC CNI를 통해 Pod를 생성할 경우 인스턴스 유형에 따라 최대 Pod 생성 수량에 제한이 존재한다.

 

위에서 살펴본 Secondary IPv4 Address 방식의 경우 최대 Pod 생성 개수는 ENI 수 x (ENI 당 지원하는 IPv4 수 - 1) + 2 라는 수식을 통해 계산할 수 있다.

 

ENI 별로 첫 번째 IP 주소는 Primary IP이기 때문에 제외하고 Node 별로 구성되는 aws-node와 kube-proxy Pod 2대를 포함하여 산정한다. 해당 Pod들은 Node의 Primary IP를 사용하기 때문에 카운팅되지 않는다.

 

이러한 최대 Pod 생성 수량에 대한 제약을 늘리기 위해 2021년 8월에 IP Prefix Delegation 방식이 추가되었다.

 

해당 방식의 원리는 ENI의 Slot에 하나의 IP가 아닌 /28의 IP Prefix 대역으로 구성하는 것이다. /28의 IP Prefix는 2의 4승으로 총 16개의 IP를 사용할 수 있는 대역이다. 그로 인해 계산식이 다음과 같이 변경되었다.

 

ENI 수 x (ENI 당 지원하는 IPv4 수 - 1) x 16

 

하지만 IP Prefix Delegation 방식은 Nitro System 계열의 인스턴스 유형에서만 사용이 가능하다. 또한 vCPU 30 코어 미만은 110개로 제한, 그 외에는 250개로 최대치가 정해져있다. 해당 방식을 사용하기 위해서는 kubectl 명령을 통해 활성화해야 한다.

Comments