티스토리 뷰

에디.Container

AEWS 2주차. EKS Networking

에디.이이 2023. 5. 3. 21:13

K8s에서는 pod간의 통신을 확장하는 규약을 CNI(Container Network Interface)로 정의합니다.

CNI는 다양한 방식으로 k8s의 네트워크 환경을 구성하며, 

네트워크 관련 제조사나 커뮤니티별로 다양한 플러그인을 제공하고 있기 때문에,

사용자는 K8s의 CNI 관련 페이지에서 각자의 환경에 맞는 네트워크를 선택할 수 있습니다.

 

일반적인 K8s 네트워크에서는 Node의 IP대역과 pod의 IP대역을 서로 다르게 나누어 구성합니다.

Node 내부에서 pod간의 통신이 일어나는 경우, Node 내부의 bridge를 통해서 바로 통신하지만,

Node를 넘어선 pod간의 통신은, Overlay 네트워크를 통해서 최종 목적지 pod를 찾아가는 구조입니다.

 

이 경우 Pod 간의 통신을 위해 VxLAN, IPIP, GRE 등 다양한 Overlay 네트워크의 활용이 필요합니다.

출발지 node에서 패킷에 Overlay 헤더를 덧붙히고, 도착지 Node에서 헤더를 해제하는 두번의 capsulation 과정을 거치며,

이를 위해 Node의 컴퓨팅 리소스를 사용하게 되고, 결과적으로 해당 구간의 네트워크 Latency를 증가시키게 됩니다.

또한, Overlay 구간에서는 패킷의 세부사항을 쉽게 확인할 수 없으며,

Overlay 네트워크와 Underlay 네트워크의 구성이 달라 관리의 복잡성이 증가합니다.

 

 

EKS에서는 이러한 단점들을 극복하기 위해 전용의 AWS VPC CNI를 사용합니다.

AWS VPC CNI는 EKS 배포시 자동으로 선택되며, VPC 네트워크 기능과 통합된 오픈소스 CNI입니다.

기존 VPC 네트워크를 활용하여 Node와 Pod간의 구분없는 네트워크 대역을 사용합니다.

 

즉, AWS VPC CNI를 사용하는 EKS에는 각 Node별로 Pod와 Node의 IP 대역이 같으며,

별도의 Overlay 프로토콜 구성 없이 서로간의 통신이 가능하기 때문에 통신의 구조가 간결해지며, 관리가 수월합니다.

또한, 컴퓨팅 리소스의 사용이 줄고, 네트워크의 지연이 감소하며, 높은 대역폭을 제공할 수 있습니다.

이외에 VPC가 제공하는 VPC Flow log나 라우팅 정책, Security 그룹등에 대한 기능도 함께 활용 가능합니다.

 

AWS VPC CNI 설치시 각 Node마다 AWS-node라고 불리는 데몬셋이 실행되고,

새로운 pod에 할당할 IP 주소를 관리하는 L-IPAM(Local IP Address Management) 데몬이 생성됩니다.

기본적으로 Node로 사용되는 EC2 인스턴스의 ENI에 Primary IP외에 Secondary IP를 구성하고,

L-IPAM에 의해 Secondary IP가 pod의 IP로 순차적으로 할당됩니다.

 

 

만약 인스턴스가 가지고 있는 ENI의 Secondary IP 수량을 넘어서는 pod가 배포될 때,

추가적인 ENI 구성이 가능한 경우에는 신규 ENI가 구성되고, 신규 ENI의 Secondary IP를 pod에 할당됩니다.

만약 더이상의 ENI 배포가 어려운 경우, 선착순으로 배포된 IP를 가진 pod를 제외하고서는

pending 상태에서 추가적인 배포가 진행되지 못합니다.

    1. Primary ENI의 Secondary IP 중에 여유 IP가 있는지 확인 : 존재시 할당

    2. 없다면, Secondary ENI의 Secondary IP 중에 여유 IP가 있는지 확인 : 존재시 할당

    3. 없다면, 신규 ENI를 할당할 수 있는지 확인 : 가능시 해당 ENI 신규 생성 후 Secondary IP 중에서 할당

    4. 없다면 Fail

 

이와 같은 절차를 통해 IP 할당에 대한 리소스 사용량을 줄일 수 있습니다.

그러나, 이와 같은 할당 알고리즘으로 인해 기존 EC2의 IP 수량에 대한 제약을 동일하게 pod도 가져갑니다.

 

즉, EC2 인스턴스별로 최대 ENI 수량이 정해져 있으며, ENI별로는 최대 IP 수량이 정해져 있기 때문에,

pod에 할당 가능한 IP의 수도 node용 인스턴스 선정시 이미 확정되어 있습니다.

따라서, pod의 필요 자원이 적어 인스턴스의 사용률이 낮다 하더라도, pod를 추가로 배포할 수 없습니다.

 

예를 들어, m5.large(2 vCore, 8G RAM)의 경우 3개까지의 ENI를 가질 수 있으며, ENI마다 10개의 IP를 가질 수 있습니다.

이 경우 ENI별로 Primary를 제외한 Secondary IP인 9개의 IP가 pod에 사용 가능하고,

총 3개의 ENI를 가지고 있음으로, 총 27개(Secondary IP 수량 9개* ENI 수량 3개)의 사용자 pod를 배포할 수 있습니다.

여기에 추가적으로 AWS CNI(aws-node)와 Kube-proxy가 pod로 배포되고 IP를 사용함으로,

하나의 m5.large 인스턴스에서 총 29개의 pod가 구동 가능하며, 사용자는 최대 27개의 pod를 배포할 수 있습니다.

 

    - MAX 사용자 pod = ENI 최대 수량 x (ENI당 지원하는 IP 수량 - 1개)
    - MAX pod = MAX 사용자 pod + AWS CNI pod(aws-node) 1개 + Kube-proxy 1개

 

만약 EC2 Node가 포함된 subnet의 크기가 작다면, 역시 IP 할당이 원할하지 않을 것이기 때문에,

24bit subnet 보다는 더 많은 IP를 사용할 수 있는 22bit subnet 등으로 올려서 사용하는 것이 좋습니다.

 

계획되지 않은 상황에서 다수의 pod를 배포하고 싶을 경우, 사전에 필요한 IP 수량을 제공하는 인스턴스를 사용하거나,

접두사 위임(prefix delegation)이나 Custom Networking등의 추가적인 기법을 이용해서 추가적인 IP의 사용이 가능합니다.

 

이 중 접두사 위임은 작년 7월 발표된 기능으로 Nitro 인스턴스에서만 확장이 가능한 방법입니다.

이를 통해 인스턴스 타입의 변경없이 동일 사이즈의 인스턴스에서도 Node당 더 많은 IP를 할당할 수 있습니다.

접두사 위임이 적용되면, 각 ENI마다 Secondary IP의 수량만큼 28bit의 전용 서브넷을 할당할 수 있습니다.

만약 동일한 m5.large에 접두사 위임을 적용하면 총 432개의 IP를 할당할 수 있어야 합니다.

 

  - ENI 최대 수량 3개 * ENI별 Secondary IP 수 9개 * 28bit subnet IP수 18개 = 432개

 

그러나 하나의 Node에 과다한 집중을 막기 위해 소프트웨어적인 제약도 존재합니다.

위 계산식을 통해 계산해보면, M5.large가 가질 수 있는 총 IP의 수량은 432개이나,

30vCPU 미만의 인스턴스는 110개 IP로 제한되며, 30vCPU 이상의 인스턴스는 250개의 IP까지 사용할 수 있어

실제 사용한 최대 IP 수량는 110개 입니다.

 

또 하나의 pod IP 확장 방법으로 Custom Network를 활용할 수 있습니다.

이 방법은 일반적인 k8s의 네트워킹 방식과 마찬가지로 Node와 pod의 IP 대역을 분리하는 방법으로,

Node 네트워크과 pod 네트워크를 분리하여 사용합니다.

사용자가 설정한 pod용 네트워크 사용을 위해 Node에서는 신규 ENI를 해당 subnet과 연결하며,

기존 ENI는 Node의 관리를 위한 대역으로, 새로운 ENI는 pod 전용으로 사용하게 됩니다.

 

 

만약 pod가 외부 인터넷과의 통신이 필요할 경우,

Node의 Node IP(eth0)를 활용하여 SNAT를 통해 Node의 인터넷과 동일한 경로와 보안으로 통신합니다.

필요시 SNAT는 제거할 수 있으며, node 내 IPtables내 위치한 AWS-SANT-CHAIN을 활용합니다.

이 IPtable에 의하면, 기본적으로 EKS에 할당된 네트워크의 경우 그냥 통신하지만,

목적지가 EKS에 할당되지 않은 네트워크라면 node의 Private IP로 SNAT되어 통신합니다.

 

그럼 반대로 외부에서 pod에 접근이 필요할 경우에는

Ingress 또는 Service를 이용하여 실행중인 pod를 외부와 연결할 수 있습니다.

 

그러나 기본적인 K8s의 경우 Service 생성시 모두 IPtables를 통해 처리되어야 합니다.

    1) Cluster IP

        - K8s 클러스터 내부에서 접근시(IP와 DNS 가능)

        - 클러스터 IP(가상IP)를 생성하고, 해당 Cluster IP로 접근시 IPtables에 생성된 분산 규칙에 따라 처리

    2) Node port

        - K8s 클러스터 외부에서 접근시 외부에 노출

        - Nodeport로 접근시 내부의 클러스터 IP를 위해 생성된 IPtables로 전달되고, 해당 분산 규칙에 따라 자동 분산

    3) LoadBalancer

        - K8s 클러스터 외부에서 접근시 외부에 노출

        - 외부 로드밸런서를 통해 패킷이 들어오고 로드밸런서는 Nodeport로 패킷을 전달

        - Nodeport로 들어온 패킷은 다시 IPtables를 확인하여 처리

 

 

 

AWS VPC CNI의 경우 Service 생성시 L4 로드밸런싱을 위한 NLB를 자동으로 생성합니다.

해당 NLB에 pod들을 등록하고 들어오는 요청에 대해 즉시 패킷을 해당 pod로 직접 부하분산하여 전달합니다.

즉, 별도의 Nodeport나 IPtables의 처리절차를 거지치 않기 때문에 훨씬 빠른 서비스를 제공할 수 있습니다.

Node와 pod가 동일 네트워크를 사용하고 있고, pod의 정보를 공유하기 때문에 생기는 장점입니다.

또한, EKS 클러스터 내부의 변화에 대해 AWS load balancer controller가 자동으로

pod의 IP등 관련 정보를 지속적으로 NLB에 전달하여 Scaling에 즉시 대응합니다.

 

만약 EKS 내부에서 사용자가 ingress를 생성하는 경우,

AWS load balancer controller는 L7 로드밸런싱을 위한 ALB를 자동으로 생성하며, NLB와 동일하게 동작합니다.

 

여기에 덧붙혀 External DNS pod까지 구성하게 되면, 

자동으로 domain에 대한 정보가 AWS를 비롯한 글로벌 CSP(AWS, Azure, GCP)의

DNS 서비스(AWS Route53, Azure DNS, GCP Cloud DNS)에 A레코드로 등록되어,

별도의 외부 설정 없이 DNS 구성까지 자동화합니다.

 

관련 실습

-----------------------------------------------------------------------------------------------

이 내용은 AEWS(AWS EKS Workshop Study) 1기의 과제로써 작성되었습니다.

AEWS는 '가시다'님이 속한 CloudNet@에서 진행하는 AWS EKS workshop에 대한 스터디입니다.

매주 일요일마다 소중한 정보를 퍼주시는 '가시다'님께 무한 감사 드립니다.

https://gasidaseo.notion.site/23-AWS-EKS-Workshop-07165aec800042b9ac9357aee18fdf17

댓글
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함
최근에 올라온 글
Total
Today
Yesterday
링크