Calico/Cilium IP Pool & Block Size Calculator
Size the CNI-level IP pool underneath your pod CIDR — the layer self-hosted and kubeadm clusters have to plan by hand.
Calico/Cilium IP Pool & Block Size Calculator
Breakdown
⚠️ Max pods per node exceeds the IPs a single block holds — nodes may need more than one block, which can starve pod scheduling on a single node even while the pool overall has space.
Copy-paste config
apiVersion: projectcalico.org/v3 kind: IPPool metadata: name: default-ipv4-ippool spec: cidr: 10.244.0.0/16 blockSize: 26 ipipMode: Never vxlanMode: Never natOutgoing: true nodeSelector: all()
Tracking IP pools across multiple clusters?
💾 Join the SubnetVault waitlistAlso see: Kubernetes pod & service CIDR calculator · EKS max pods per node calculator
What a "block" actually is
The Kubernetes pod CIDR you configure at cluster creation only says how big the overall pod address space is. It doesn't say how that space gets divided among nodes — that's a separate job handled by the CNI's own IPAM, one layer below. Calico's default IPAM carves its IP pool into fixed-size chunks called blocks (a /26, 64 addresses, by default) and hands out whole blocks to nodes on demand. A node claims a block the first time it needs a pod IP, then allocates addresses out of that block locally — without contacting the pool again — until the block runs dry.
This is deliberately different from a flat pool where every pod IP request hits shared state: block ownership lets each node allocate pod IPs independently and fast, at the cost of some IPs sitting idle inside a block that isn't full. The trade-off is set by block size — the CNI IP pool calculator above works out exactly how many blocks your pool CIDR holds at a given block size, and therefore how many nodes it can support before you run out.
Why Calico allocates per-block-per-node instead of a flat pool
A flat pool — where every node's kubelet asks a central allocator for each pod IP individually — turns IP assignment into a bottleneck that scales with cluster-wide pod churn, not per-node pod churn. Block ownership avoids that: once a node holds a block, creating or deleting a pod is a purely local IPAM operation on that node, and the only time the cluster-wide pool gets touched is when a node claims or releases an entire block. That's a deliberate scalability choice, not an accident of implementation — it's the same reason cloud IPAM (ENI-based prefix delegation, GKE alias IP ranges) also allocates in chunks rather than one IP at a time.
The cost is the same one any chunked-allocation scheme pays: a block is claimed by exactly one node at a time, so a pool with spare capacity overall can still be unable to serve a specific node if every block is already owned by some other node. Sizing the pool with real headroom — not just enough raw IPs for the pod count, but enough whole blocks for the node count — is what avoids that.
The failure mode: block exhaustion on one node, space everywhere else
- Per-node, not cluster-wide. A pool at 40% overall utilization can still starve one node if that node's pods have grown past what a single block holds and no free block is left in the pool for a second one.
- Pods per node vs. IPs per block. If your node's max-pods setting exceeds the IP count in one block, that node will need more than one block just to run at full density — plan the block size around pod density, not just node count.
- Symptom looks like scheduling trouble, not networking. Pods stuck in ContainerCreating or Pending on one specific node, with plenty of cluster capacity elsewhere, is the signature of block exhaustion — check
calicoctl ipam show --show-blocksbefore assuming it's a scheduler or resource issue. - Fix is pool-level, not node-level. Since blocks come from the shared pool, the real fix is a bigger pool CIDR or a smaller block size — not adjusting anything on the affected node itself.
CNI IP Pool FAQ
What happens when a node's block is full?
Calico requests another block from the pool for that node once its current block runs out of free IPs. If the pool has spare blocks, the request succeeds transparently. If the pool is exhausted — every block already claimed by some node — new pods on that node stay Pending with a failed IPAM allocation, even though other nodes in the same cluster still have plenty of headroom in their own blocks. That's the specific failure mode block-based IPAM introduces: exhaustion is per-node before it's cluster-wide.
What's the difference between Calico and Cilium IPAM at a high level?
Calico's default IPAM hands out fixed-size blocks (a /26 by default) per node from the pool, and a node keeps a block until its IPs are released. Cilium's cluster-pool IPAM also carves the pool into per-node CIDRs (sized by cluster-pool-ipv4-mask-size), but Cilium can additionally run in modes that skip block ownership entirely — ENI-mode on AWS or Azure IPAM, for example — where pod IPs come directly from the cloud provider's network instead of an internal pool. This calculator models the block/mask-size sizing math both share in cluster-pool mode; it doesn't model Cilium's other IPAM modes.
Why not just make the block size as large as possible?
A larger block (a shorter prefix like /24) holds more IPs per node, but the pool divides into fewer total blocks — so fewer nodes fit. A smaller block (a longer prefix like /28) supports more nodes but caps how many pods a single node can run before it needs a second block. The right size depends on which constraint binds first: node count or pods-per-node. This calculator flags it directly — if your max-pods-per-node figure exceeds what one block holds, the block size is too small for that node's pod density.
Does resizing the block size require recreating the cluster?
For Calico, no — blockSize is set per IPPool, and you can create a new IPPool with a different block size and phase nodes over by disabling the old pool for new allocations. It's an operational migration, not a rebuild, but it does mean planning the block size upfront saves that migration work later. The IP pool CIDR itself is much harder to change once nodes hold live blocks from it, so get the pool size right before block size.
More Network Tools
Free tools for network engineers — no signup, no rate-limit walls.