본문 바로가기
공부/Kubernetes

[EKS/Terraform] Secondary IP 줄이기 with Terraform

by haejang 2024. 2. 6.
728x90
728x90

 

 

# 현상

 

18개 파드가 존재하는 10.10.0.218 노드가 있다.

그러나 해당 노드엔

 

 

2개 eni / eni포함 총 60개의 ip가 붙어있다....

다른 노드들도 사용하는 파드들에 비해 상당히 많은 ip들을 갖고 있었고, 이로 인해 서브넷에 가용 ip가 부족해졌다.

 

# 분석

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI

 

Elastic network interfaces - Amazon Elastic Compute Cloud

For EC2 instances in an IPv6-only subnet, if you attach a secondary network interface to the instance, the private DNS hostname of the second network interface will resolve to the first IPv6 address on the instance's first network interface. For more infor

docs.aws.amazon.com

 

해당 노드의 타입인 m5.4xlarge는 최대 8개 eni / eni별 최대 30개 ip를 가질 수 있다.

이 때, vpc-cni가 배포하는 aws-node란 데몬셋의 환경 변수 설정에 따라 ip를 할당하는 방식이 달라진다.

  • WARM_ENI_TARGET
    • Warm 상태로 유지되는 ENI의 개수
    • 즉 사용하지 않더라도 미리 잡고 있는 ENI를 뜻하며, 기본값은 1이다.
  • WARM_IP_TARGET
    • Warm 상태로 유지되는 IP Address의 개수
    • 즉 사용하지 않더라도 미리 잡고 있는 IP Addres를 뜻하며, 기본값은 설정되어 있지 않다.
  • MINIMUM_IP_TARGET
    • 각 Node가 가져야 할 최소 IP Address의 개수
    • 현재 IP Address 할당이 필요한 Pod 개수와 상관없이 지정된 IP Address를 확보하며, 기본값은 설정되어 있지 않다.

이 때, WARM_IP_TARGETMINIMUM_IP_TARGET 이 설정되어 있지 않은 경우 (Default) ENI를 할당받을 때 마다 최대 갯수의 IP를 미리 할당받는다.

 

즉, m5.4xlarge 노드 한대에 ENI가 한개 붙는 경우 → eni별 최대인 30개 ip 를 미리 할당받는다. (할당될 pod 개수랑 상관없이)

이 때, WARM_ENI_TARGET 이 1이므로 미리 ENI가 한개 더 붙어있음 → 마찬가지로 30개 ip 받아옴

=> 최종적으로 pod를 열몇개밖에 안쓰지만, ENI 2개에 IP 60개를 미리 받아와 쓰고 있는 것.

 

따라서 서브넷 내 IP 개수를 효율적으로 쓰기 위해서, WARM_IP_TARGET & MINIMUM_IP_TARGET 설정이 필요해진다.

(minimum_ip_target보다 pod가 많이 할당되는 경우는 그냥 그만큼 ip를 더 쓰게 되므로 이슈될 것은 없다.)

 

# 정책

본 글에서는

  • WARM_IP_TARGET = 3
  • MINIMUM_IP_TARGET = 25

로 진행한다.

(이미 25개 이상의 pod가 들어있는 노드에 MINIMUM_IP_TARGET = 25 설정이 추가되어도 떠있는 pod들엔 영향을 미치지 않는다.)

 

# CLI로 설정

kubectl set env ds aws-node -n kube-system WARM_IP_TARGET=3
kubectl set env ds aws-node -n kube-system MINIMUM_IP_TARGET=25

 

 

# Terraform으로는?

처음엔 Terraform으로 설정을 할 방법이 없는 것 같아 걱정했다..

아무리 찾아봐도 다들 위처럼 CLI로만 설정하고 terraform으로 한 사람이 없었다.

나만 테라폼으로 하고싶은거야?

 

그러나 역시나 답은 있었다.

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon

 

Terraform Registry

 

registry.terraform.io

 

aws_eks_addon 리소스는 configuration_values 라는 argument를 넣을 수 있다.

함정이 하나 있다면, 독스에서는 describe-addon-configuration이란 api를 통해 나온 값들을 configuration_values 에 넣을 수 있는 것처럼 적어두었는데, 사실 helm chart values값을 참조해야 한다.

관련 이슈 : https://github.com/hashicorp/terraform-provider-aws/issues/29215

aws-vpc-cni helm chart : https://artifacthub.io/packages/helm/aws/aws-vpc-cni/1.0.6

 

따라서 최종적으로는 아래와 같이 작성하면 된다.

resource "aws_eks_addon" "this" {
  ...
  addon_name           = "vpc-cni"
  configuration_values = jsonencode({
    env = {
      WARM_IP_TARGET    = "3"
      MINIMUM_IP_TARGET = "25"
    }
  })
}

 

 

# 확인

아까 ip가 60개 붙어있던 10.10.0.218 노드를 다시 확인해보자

 

eni 2개 + 세컨더리 25개만 남아있다.

처음엔 WARM_IP_TARGET 이 3이므로 25 + 3인 28개가 붙어있어야 하지 않나? 생각했는데,

해당 노드 안에 떠있는 파드가 18개 -> 이미 warm ip가 3개 이상 이므로 3개의 warm ip가 추가될 필요가 없었다.

 

# 추가 - host networking pod

다른 노드도 확인해 보는데,

pod가 39개 있는 노드 -> 세컨더리 38개

pod가 28개 있는 노드 -> 세컨더리 27개 가 각각 붙어있었다.

이게 도대체 무슨 상황이지? 하고 열심히 뒤져보다가 발견한 것은,

 

aws-node, kube-proxy, kubecost-network-costs, prometheus-node-exporter 이 4개 데몬셋의 파드들이 노드의 메인 ip를 갖고 있었다.

이 친구들은 host networking을 하는 친구들로, 노드의 메인 ip를 사용하기 때문에 세컨더리 ip 소비를 하지 않는다.

(aws-node, kube-proxy는 eks를 사용하는 경우 거의 필수이기 때문에 2개 ip를 안쓴다고 생각한다고 하더라)

아무튼 이런 경우는 한 노드에서 총 28개 pod를 사용하지만, 4개파드는 host networking이므로 제외 -> 24개의 파드를 사용함.

이 때 WARM_IP_TARGET이 3 이므로 24 + 3 = 27개의 세컨더리 ip를 소장하게 된다.

 

끝!

 

# Ref

 

 

 

728x90
728x90

댓글