Inside VPC CNI: How EKS Nodes Actually Get POD IPs

Sitesh Pattanaik

2026/09/25

Most EKS users treat the pod networking as magic and an abstraction mostly: a pod gets scheduled, it gets a real VPC IP, traffic flow without deeper understand of how things work under the hood. In this blog post, we will de-mystify that by understanding the VPC CNI’s daemon - ipamd and why the pods don’t stall behind an actual EC2 call.

CNI plugin vs ipamd

“vpc cni” is mostly considered a single thing, but actually there are two things.

  1. CNI plugin binary (aws-cni) : invoked directly by the kubelet on each node on pod create/delete (cni add, cni del). it’s job is per-pod network plumbing.
  2. ipamd daemon : runs as a daemonset in every node. it’s job is supply management - talking to ec2 to attach/detach eni, assign/unassign secondary ips, pre-warmed ip pool etc.

The CNI plugin talks to ipamd over a local gRPC socket on the same node.

Note: previous to 1.24, kubelet directly invoked the CNI plugins via it's own. On current EKS clusters, it's the container runtime (containerd) via CRI, that invokes the CNI plugin

Primary ENI and the node boot sequence

Boot sequence

Warm pool knobs

How ipamd actually gets more secondary IPs

When the free pool drops below the target, ipamd doesn’t blindly request WARM_IP_TARGET in one shot. It runs a bounded, iterative algorithm.

It then walks through already-attached ENIs, one at a time and tries to get it to full before allocating new ENI.

So, if all the ENIs are at capacity and the ip-pool isn’t still met, it makes a call to EC2 to create a secondary ENI and get IPs from that.

note: this process goes in the background always.

How ipamd knows current ENI/IP state

ipamd maintains an in-memory cache of the current state as well as the value from EC2 metadata from it’s initial calls

Takeaways

  1. pod IP assigned is fast because expensive EC2 call is decouple and pre-warmed
  2. WARM_IP_TARGET and MIN_IP_TARGET solve different problems. one is a bi-directional elastic buffer vs a one-directional pre-scaled floor.
  3. new ENI creation is a two step trigger: all ENI are at capacity and still shortfall.
  4. subnet selection for ENI creation is three phased
    • default (inherit primary)
    • enhanced discovery (opportunistic pool)
    • custom networking
  5. ipamd state is locally cached and checkpointed.
  6. vpc-cni install/upgrades never touches kubelet or containerd config.