# 현상
18개 파드가 존재하는 10.10.0.218 노드가 있다.
그러나 해당 노드엔
2개 eni / eni포함 총 60개의 ip가 붙어있다....
다른 노드들도 사용하는 파드들에 비해 상당히 많은 ip들을 갖고 있었고, 이로 인해 서브넷에 가용 ip가 부족해졌다.
# 분석
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#AvailableIpPerENI
해당 노드의 타입인 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_TARGET과 MINIMUM_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
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
- https://peterica.tistory.com/224
- https://nangman14.tistory.com/100
- https://medium.com/techblog-hayleyshim/aws-eks-networking-698368b77723
'공부 > Kubernetes' 카테고리의 다른 글
[Karpenter] Disruption budget (중단 제어) 사용하기 (v0.34.0~) (feat. karpenter upgrade) (26) | 2024.03.09 |
---|---|
[k8s/EKS] Fargate와 Daemonset (0) | 2024.02.09 |
[ingress-nginx] restart 시 downtime 해결 - minReadySeconds (44) | 2023.11.29 |
[Cluster-Autoscaler] Over Provisioning with Terraform (4) | 2023.11.26 |
[kubernetes/GUI] OpenLens 사용하기 (MAC) (0) | 2023.11.05 |
댓글