{"id":"IL-0007","org":"Adevinta","date":"2024-10-22","docs":["https://aws.amazon.com/blogs/containers/addressing-ipv4-address-exhaustion-in-amazon-eks-clusters-using-private-nat-gateways/"],"title":{"en":"The AWS VPC CNI could not assign IP addresses to pods as an EKS cluster ran out of IPv4 space","ko":"EKS 클러스터에서 VPC-CNI 가 파드마다 VPC IP 를 쓰다가 서브넷 IP 가 바닥나 파드가 IP 를 받지 못했다"},"domain":["kubernetes","aws","networking"],"impact":{"scope":"one small, little-used EKS cluster; a fleet-wide outage was avoided","users":"unknown","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"For a platform team, the VPC CNI is not ready to scale in production without time spent on capacity planning, and every option has its pros and cons. For large clusters started today, IPv6 is the cheaper and more future-proof option. Do not assume that what works in small clusters will keep working when they grow.","ko":"플랫폼 팀이나 클러스터 운영자가 용량 계획에 시간을 들이지 않으면, VPC-CNI 는 큰 규모의 운영 환경에 바로 쓸 수 있는 도구가 아니다. 선택지마다 장단점이 있다. 지금 큰 클러스터를 새로 띄운다면 더 싸고 앞으로도 오래 쓸 수 있는 IPv6 를 쓸 수 있는지 먼저 확인할 만하다. 작은 클러스터에서 되던 것이 규모를 키워도 된다고 가정하면 안 된다.\n\n예측과 용량 계획을 잘하면 이 요구는 감당할 수 있다. 하지만 폭주하는 잡이나, 실패하면서도 회수될 때까지 IP 를 붙잡는 잡을 여럿 띄우는 잘못된 설정 때문에 파드가 갑자기 늘 수 있다."},"related":["IL-0015","IL-0019"],"sources":[{"url":"https://adevinta.com/techblog/how-we-avoided-an-outage-caused-by-running-out-of-ips-in-eks/","kind":"blog","license":"unknown","archived":"http://web.archive.org/web/20260826124239/https://adevinta.com/techblog/how-we-avoided-an-outage-caused-by-running-out-of-ips-in-eks/"}],"summary":{"en":"The AWS VPC CNI, the default network plugin on EKS, gives every pod its own IP address from the VPC, so a cluster of 10,000 pods uses 10,000 IPs. SCHIP is multi-tenant, and its pods reach tenant resources such as RDS databases and ElastiCache in other AWS accounts, first through VPC peering and later through a Transit Gateway. Because overlapping address ranges make those connections harder, the team has to maintain an internal IPAM. Adevinta had been monitoring its IP usage since early in its EKS work.\n\nWhen the first cluster ran out of IPs in June, engineers had already spent several experimentation days, which the team gets every other Friday, testing three options: replacing the CNI with Cilium, VPC CNI custom networking, and IPv6 with the VPC CNI. They chose custom networking with a secondary CIDR because it was the easiest to put in place in time to finish the migration, though not the most elegant choice; Cilium and IPv6 each brought more unknowns.\n\nCustom networking was rolled out in a controlled way to the smaller clusters from late August. In September available IPs were so low that the migration was paused; after the controlled rollout proved successful, custom networking went to the rest of the fleet, available IPs recovered, and the migration finished without the fleet-wide outage the team feared.\n\nMonths later, Karpenter began provisioning smaller instances, and the number of ENIs and IPs a node gets depends on its instance size. Karpenter was not aware of the secondary CIDR and custom networking, so IP shortage alerts returned. Adding the --reserved-enis parameter to the Karpenter deployment let Karpenter compute how many pods fit on a node, taking into account that the first ENI is used for custom networking.","ko":"Adevinta 의 플랫폼 팀은 사내 런타임 플랫폼인 SCHIP 을 운영한다. SCHIP 은 여러 팀이 함께 쓰는 멀티테넌트 클러스터라서, 클러스터의 파드가 다른 AWS 계정에 있는 RDS 나 Elasticache 같은 VPC 자원에 닿아야 할 수 있다. 그래서 사내 IP 주소를 관리하고, 클러스터 VPC 와 사내 고객 VPC 를 이을 방법이 필요했다. 처음에는 VPC 피어링을 쓰다가 연결이 늘자 AWS Transit Gateway, 줄여서 TGW 를 쓰기 시작했다.\n\nEKS 의 기본 VPC-CNI 는 파드마다 IP 하나를 배정하므로 파드가 1만 개면 IP 도 1만 개가 필요하다. 팀은 EKS 를 쓰기 시작한 직후 이 문제를 알고 IP 사용량을 감시해 왔다. 6월, Kube-aws 기반 SCHIP 에서 EKS 기반 클러스터로 대규모 이전을 하던 중 작은 클러스터 하나에서 IP 가 바닥나 파드가 실패했다. 팀은 바로 조치하지 않으면 다음 장애는 심각하고 피할 수 없다고 판단했다.\n\n팀은 격주 금요일 실험 시간에 Cilium 같은 다른 CNI, VPC-CNI 커스텀 네트워킹, VPC-CNI 의 IPv6 를 미리 시험해 두었다. 그중 Secondary CIDR 를 쓰는 커스텀 네트워킹이 이전을 제때 끝내기에 가장 쉬웠다. 8월 말 작은 클러스터부터 조심스럽게 차례로 배포했고, 9월에는 사용 가능한 IP 가 너무 적어 이전을 잠시 멈췄다. 이후 나머지 클러스터 전체에 배포해 IP 여유를 되찾았고, 이전을 끝내 대부분의 고객과 마켓플레이스에 영향을 줄 큰 장애를 피했다.\n\n몇 달 뒤 Karpenter 로 옮기면서 IP 부족 호출이 다시 왔다. Karpenter 는 더 작은 인스턴스를 띄울 수 있는데, 인스턴스가 쓸 수 있는 ENI 와 IP 수는 인스턴스 크기에 따라 정해진다. 또 Karpenter 는 클러스터가 Secondary CIDR 와 커스텀 네트워킹을 쓴다는 것을 고려하지 않았다. 팀은 Karpenter 배포에 --reserved-enis 파라미터를 더해, 첫 번째 ENI 가 커스텀 네트워킹에 쓰인다는 점을 반영해 노드당 파드 수를 계산하게 했다."},"trigger":{"en":"Not stated for the first page. It came in June, during the migration from SCHIP's kube-aws-based clusters to EKS-based clusters; the write-up mentions spikes of pods, such as a job that goes rogue or failing jobs that keep their IPs, as ways a cluster can run out.","ko":"첫 호출의 계기는 원문에 나오지 않는다. 호출은 6월, kube-aws 기반 SCHIP 에서 EKS 기반 클러스터로 옮기던 중에 왔다. 원문은 클러스터의 IP 가 바닥나는 경우로, 잡이 폭주하거나 실패하면서도 회수될 때까지 IP 를 붙잡고 있어 파드가 갑자기 늘어나는 경우를 든다."},"severity":"unknown","symptoms":["no-available-ip","pod-pending"],"timeline":{"detected_after":null,"resolved_after":null},"date_kind":"published","detection":{"en":"A pager alert that some DaemonSets were failing. The on-call engineer checked the pod status and found the aws-cni error about failing to assign an IP address.","ko":"어느 저녁 일부 DaemonSet 이 실패한다는 호출이 왔다. 당직자가 서버에 들어가 파드 상태를 확인하다 aws-cni 의 IP 할당 실패 오류를 보았다. 팀은 그전부터 IP 사용량을 감시하고 있었다."},"components":["vpc-cni","subnet","karpenter"],"root_cause":"capacity","remediation":[{"text":{"en":"Rolled out VPC CNI custom networking with a secondary CIDR to the smaller clusters from late August","ko":"8월 말부터 작은 클러스터에 Secondary CIDR 를 쓰는 VPC-CNI 커스텀 네트워킹을 배포했다."}},{"text":{"en":"Paused the EKS migration in September while available IPs were very low","ko":"9월에 사용 가능한 IP 가 너무 적어지자 EKS 이전을 잠시 멈췄다."}},{"text":{"en":"Rolled out custom networking to the rest of the fleet","ko":"커스텀 네트워킹을 나머지 클러스터 전체에 배포했다."}},{"text":{"en":"Added the --reserved-enis parameter to the Karpenter deployment","ko":"Karpenter 배포에 --reserved-enis 파라미터를 더했다."}}],"action_items":[{"text":{"en":"Use VPC CNI custom networking with a secondary CIDR across the whole fleet","ko":"커스텀 네트워킹을 나머지 클러스터 전체에 배포해 IP 여유를 되찾고 EKS 이전을 끝냈다."}},{"text":{"en":"Make Karpenter account for custom networking with the --reserved-enis parameter","ko":"Karpenter 배포에 --reserved-enis 파라미터를 더해 커스텀 네트워킹이 쓰는 첫 번째 ENI 를 빼고 노드당 파드 수를 계산하게 했다."}}],"contributing":["default-config-unchanged","no-capacity-planning"],"recurrence_of":null,"symptoms_text":{"en":"One evening the platform team that runs SCHIP, Adevinta's internal runtime platform on Kubernetes, was paged because some DaemonSets were failing. Checking the pod status showed this error from the network plugin: name=\"aws-cni\" failed (add): add cmd: failed to assign an IP address to container\n\nThe CNI was saying plainly that no IP address was available for new pods. The affected cluster was small and little used, so the impact was small, but the page came in June, in the middle of a large migration of workloads to EKS-based clusters, and the same shortage could hit the bigger clusters.\n\nIn September the number of available IPs fell so low that the migration had to be paused. Months later, after the move to Karpenter started, pager alerts about a lack of IP addresses came back.","ko":"어느 저녁 일부 DaemonSet 이 실패하고 있다는 호출이 왔다. 당직자가 서버에 들어가 파드 상태를 보니 다음 오류가 찍혀 있었다: name=“aws-cni” failed (add): add cmd: failed to assign an IP address to container\n\n이 오류는 네트워크 드라이버인 CNI 가 쓸 수 있는 IP 주소가 없다는 뜻이었다. 다행히 영향은 작고 거의 쓰지 않는 클러스터 하나에 그쳤다. 이 호출은 6월, EKS 기반 클러스터로 대규모 이전을 하던 중에 왔다.\n\n이후 대시보드에서 사용 가능한 IP 가 계속 줄어드는 추세가 보였고, 9월에는 사용 가능한 IP 가 너무 적어 이전 작업을 멈춰야 했다. 몇 달 뒤 Karpenter 로 옮기면서 IP 부족 호출이 다시 오기 시작했다."},"updated_at":"2026-11-10T00:00:31.560808Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0007","org_slug":"adevinta"}