EKS Prefix Mode/Delegation

EKS Prefix Delegation으로 최대 파드 수량 늘리기
이민석's avatar
Aug 23, 2024
EKS Prefix Mode/Delegation

개요

가장 보편적인 형태의 다음의 AWS EKS환경에서는
Managed Node Group*Amazon VPC CNI*를 통해 네트워크 설정이 이루어지며 인스턴스 타입 별로 지정된 숫자의 최대 파드 수량*을 한계로 가지게 됩니다.

Managed Node Group* : 관리형 노드 그룹
Amazon VPC CNI* : Amazon EKS Cluster에 있는 Pod 네트워킹용 Networking Plugin
지정된 숫자의 최대 파드 수량* : 일정한 연산식에 의해서 정해지며 타입 별로 이미 계산된 산정표가 존재합니다.

기본적인 지정 수량은 낮은 파드 밀도*를 가지며,
이런 낮은 밀도로 인하여 저사양 & 다량의 서버로 구성된 Microservices*로 갈수록 비효율적인 비용 구조를 만듭니다.

낮은 파드 밀도* : 단일 인스턴스에 적은 수량의 파드만 할당할 수 있음을 표현하는 관용어입니다.
저사양 & 다량의 서버로 구성된 Microservices* : 블루/그린 배포, 파드 수평 확장 등을 고려하면 파드 총량의 50~60% 미만으로 유지하는 것이 좋습니다.

본 문서는 파드 지정 수량을 넘어 높은 파드 밀도를 가지는 Amazon EKS Prefix Mode (Linux)에 대해서 소개합니다.

# SPEC
EKS Cluster 1.30
Amazon VPC CNI 1.18.x
Managed Node Group

본문에 앞서

최초에는 kubectl*, aws-cli* 등을 사용하여 실습을 진행하였습니다.

kubectl* :
aws-cli* :

하지만 사내에서는 대부분의 인프라를 Terraform으로 관리하고 있기 때문에, Terraform을 통해서 실습을 진행하였습니다.

본 문서는 범용성 높은 가이드를 위해서 kubectl, aws-cli를 기준으로 작성되었음을 안내드립니다.

기본값

본 챕터는 AWS EKS Networking의 최소한의 기본 지식을 포함하고 있습니다.

Managed Node Group 파헤치기

AWS EKS에서 t3.medium 1개 규격의 Managed Node Group을 생성하면, 단일 노드 총 3개의 ENI*가 할당된 것을 볼 수 있습니다. 또한 1개의 ENI는 1개의 PrivateIPAddress*를 가지고 있어 최종적으로 3개의 PrivateIPAddress를 가지게 됩니다.

aws-cli 작성 필요

ENI* : Elastic Network Interfaces
PrivateIPAddress* : 프로덕션 환경에 맞춰서 PrivateEndpoint를 가지는 EKS Cluster 구성을 완료하였다면, ManagedNode는 PrivateIPAddress만을 할당 받습니다.

또한 각각의 PrivateIPAddress에 대해서 지정된 수량 만큼의 SecondaryAddress*를 가지는 것도 확인할 수 있습니다.

aws-cli

이러한 방식을 Secondary IPv4 Address 방식이라고 부릅니다.

Secondary IPv4 Address 작용 방식

앞서 t3.medium은 3개의 ENI와 이에 대응되는 3개의 PrivateIPAddress를 가지고 있습니다. 아래 그림에서 slot1 에 적혀있는 slot1 : 10.0.0.20, 10.0.0.30, 10.0.0.40이 이에 해당합니다. 각각의 ENI에 할당된 slot2,3,4 : 10.0.0.101, ~ 10.0.0.32 가 실제로 파드에 할당되는 IPAddress입니다.

Secondary IPv4 Address과 파드 최대량

Secondary IPv4 Address를 사용하는 경우,
Node에 할당가능한 파드의 최대 수량은 다음과 같습니다.

  • ENI * (IP *- 1) + 2

즉, 앞서 설명한 t3.medium을 기준으로 하면 다음과 같은 수량이 나옵니다.

  • 3 * ( 6 - 1 ) + 2 = 15 + 2 = 17*

[AEWS] 2주차 - EKS Networking
[EKS] AMazon VPC CNI에서의 최대 파드 개수

실제로는 매번 연산을 하기 보다는 Kubelet/ENI Max Pods 등을 참고하여 진행하게 됩니다.

MaxPods 확인하기

실제로 Secondary IPv4 Address 방식을 사용할때,
EKS ManagedNodeGroup의 MaxPods를 확인할 수 있습니다. [Ref]

kubectl get nodes -o=custom-columns=NAME:.metadata.name,CAPACITY:.status.capacity.pods
NAME                                          CAPACITY
ip-0-0-0-0.ap-northeast-2.compute.internal    17
ip-0-0-0-0.ap-northeast-2.compute.internal    17
ip-0-0-0-0.ap-northeast-2.compute.internal    17

악분의 블로그 | 쿠버네티스 노드당 pod 갯수 제한 확인

개선안

Secondary IPv4 Address 방식은 파드 밀도가 낮다는 단점이 있습니다. 이 문제를 해결하기 위한 것이 Prefix Mode(Linux)입니다.

Prefix Mode 간단 소개

EKS Prefix Mode는 NodeGroup의 Prefix Delegation*을 통해서 ENI에 IPv4/IPv6 CIDR 범위를 할당할 수 있습니다.

Prefix Delegation* : 이 기능을 사용하여 접두사(Prefix)가 할당하면 인스턴스에서 여러 IP 주소가 필요한 컨테이너 및 네트워킹 어플리케이션을 포함한 애플리케이션의 관리를 확장하고 간소화 할 수 있습니다.

Prefix Mode 활성화 확인

다음과 같은 명령어를 통해서 Prefix Mode 활성화 여부를 확인할 수 있습니다.

kubectl describe daemonset aws-node -n kube-system | grep -i delegation

p.s. EKS Node 조회

kubectl get pods --selector=k8s-app=aws-node -n kube-system

Prefix Mode 활성화 요구사항

Prefix Mode를 사용하기 위해서는 Amazon VPC CNI가 1.9 버전보다 높아야 합니다. 아래 명령어를 통해서 Amazon VPC CNI 버전을 확인할 수 있습니다.

  • Windows PowerShell

    kubectl describe daemonset aws-node --namespace kube-system | Select-String "Image" | %{ $_.ToString().Split('/')[1] }
  • Linux/MacOS Terminal

    kubectl describe daemonset aws-node --namespace kube-system | grep "Image" | awk -F'/' '{print $2}'

Prefix Mode/Delegation 활성화

다음으로 Prefix Delegation을 활성화 할 수 있습니다.

kubectl set env daemonset aws-node -n kube-system ENABLE_PREFIX_DELEGATION=true

또한 WARM_PREFIX_TARGET*을 활성화합시다.

kubectl set env ds aws-node -n kube-system WARM_PREFIX_TARGET=1


 

Prefix Mode/Delegation 확인

다음으로 Prefix Deleagtion을 확인할 수 있습ㄴ다.

aws ec2 describe-instances \
   --query 'Reservations[*].Instances[].{InstanceId: InstanceId, Prefixes: NetworkInterfaces[].Ipv4Prefixes[]}'

또한 WARM_PREFIX_TARGET 적용 내역도 볼 수 있습니다.

kubectl describe daemonset aws-node -n kube-system | grep -i WARM

AWS Console에서도 Prefix Delegation이 활성화된 Node(EC2)의 첫 번째 ENI에 IPv4 Prefix가 할당된 것을 볼 수 있습니다.

수정 사항이 적용되었다면, t3.medium을 기준으로 아래와 같이 MaxPods가 변경됨이 기대됩니다.

  • AS-IS : 17

  • TO-BE : 110

하지만 다음의 구문으로 테스트를 진행하면 Running Pods의 수량이 17에서 더이상 증가하지 않는 것을 알 수 있습니다.

echo "apiVersion: apps/v1
kind: Deployment
metadata:
  name: pause-pods-prefix
  namespace: prefix-delegation
spec:
  replicas: 150
  selector:
    matchLabels:
      run: pause-pods-prefix
  template:
    metadata:
      labels:
        run: pause-pods-prefix
    spec:
      containers:
      - name: reserve-resources
        image: registry.k8s.io/pause
" > prefix-delegation.yaml

kubectl create ns prefix-delegation
kubectl apply -f prefix-delegation.yaml

watch -n 1 "kubectl get pods | grep -E 'Running' | wc -l"

Prefix Mode is not working

Prefix Mode가 적용되지 않는 이유는 allocatable 설정값이 여전히 17이기 때문입니다. [Ref]

EKS NodeGroup allocatable 확인

그 이유는 EKS NodeGroup의 각 Node에 allocatable 설정값이 여전히 17이기 때문입니다.

[EKS Study 2주차] EKS Networking - Prefix Delegation

아래 명령어를 통해서 allocatable 값을 확인할 수 있습니다.

kubectl get node -o yaml | grep allocatable -A7
    allocatable:
      cpu: 1930m
      ephemeral-storage: "18181869946"
      hugepages-1Gi: "0"
      hugepages-2Mi: "0"
      memory: 3364612Ki
      pods: "17"
    capacity:

EKS NodeGroup allocatable 변경

EKS Node의 allocatable 변경하기 위해서 레퍼런스에서는 SSH로 접속해서 bootstrap.sh 파일의 인자에 maxPods를 110으로 전달할 것으로 소개되어 있었습니다. 하지만 이 방식으 아래와 같은 이유로 자사와 적합하지 않았습니다.

  1. 운영망 전체에서 EKS NodeGroup에는 EC2 KeyPair를 사용하지 않고 있음

  2. 신규로 배포되는 서버가 생길 때마다 수동으로 SSH로 접속해서 값을 변경해야함

  3. 구조적으로 안정성이 높다고 보기 어려움

이 중에 1, 2번의 문제점으로 인해서 다른 해결방법이 필요했습니다.

EKS Managed NodeGroup UserData

Node(EC2)가 처음 켜질때 MaxPods 값을 반영하도록 접근법을 바꿨습니다. 이에 따라 Launch Template에 사용자 데이터를 확인해보았습니다.

Managed NodeGroup의 경우 아래와 같은 NodeConfig이 있는 것을 확인할 수 있습니다.

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="//"

--//
Content-Type: application/node.eks.aws

---
apiVersion: node.eks.aws/v1alpha1
kind: NodeConfig
spec:
  cluster:
    apiServerEndpoint: {{ EKS HTTPS ENDPOINT }}
    certificateAuthority: {{ EKS CertificateAuthority }}
    cidr: {{ EKS CIDR Block }}
    name: {{ EKS Cluster Name }}
  kubelet:
    config:
      maxPods: {{ NodeGroup MaxPods }}
      clusterDNS:
      - {{ CLUSTER DNS }}
    flags:
    - {{ … }}
--//--

Nitro Instance에서 vCPU30개 미만인 인스턴스의 최대 파드 숫자는 110개로 제한이 됩니다. 따라서 t3.medium의 maxPods도 110으로 설정하면 됩니다.

      maxPods: 110

이후 Managed Node Group에서 LaunchTemplate의 개정을 1에서 2(신규 개정)으로 변경해야 합니다.

최종적으로 Managed Node Group의 최소 수량을 늘리고 기존의 Node에서 신규 Node로 파드를 옮기면 작업이 완료됩니다.

Secondary IPv4 Address vs Prefix Mode : MaxPods

t3.medium을 기준으로 두 방식을 비교해봅시다.
전체적으로 Prefix Mode(Linux) 방식이 더 높은 파드 밀도를 가지는 것을 알 수 있습니다.

구분

Secondary
IPv4 Address

Prefix
Mode(Delegation)

ENI

3개

1개

Secondary
IPv4 Address

9개

0개

Prefix Delegation

0개

3개

MaxPods

17개

110개

Secondary IPv4 Address vs Prefix Mode : Network Hop

당연히 방식의 네트워크 기술이 사용되었기 때문에 Network Hop*도 다르게 나올 것이라고 생각했습니다. 결론부터 말하면 Prefix Mode가 더 적은 경로의 Network Router를 지난다는 점을 알게 되었습니다.

Share article

Unchaptered