Skip to content

Fixed address for a pod or VM

You want a workload to keep one address for as long as it exists - because a peer is configured with that address, a licence is bound to it, or a firewall outside the platform allows it by address. On AWS the closest thing is a fixed private IPv4 address on an EC2 network interface.

Here the object is an IPAMClaim. It lives in the project of a subnet, it reserves one address from that subnet's range, and a workload that names the claim receives that address every time it starts. A virtual machine gets a claim without asking. A pod gets one when you create the claim and name it on the pod template.

Prerequisites

  • A subnet, public or private. The claim reserves an address from a subnet's range, so this applies to workloads in a subnet's project
  • The admin or edit role on that project

The step-by-step guide covers the operations. The rest of this page explains how it fits together. There is no console form for a claim, so there is no console walkthrough.

Why a pod's address changes

A pod takes a free address from the subnet's range when it is scheduled and gives it back when it is deleted. A Deployment replaces its pod on every rollout, every node drain and every crash, so the address you read today belongs to a different pod, or to none, after the next one.

Inside one project a Service hides that: callers use the Service name and never see the pod address. That stops at the edge of the subnet. A Service is only reachable from inside its own subnet, so a caller in another subnet has nothing stable to point at.

The DNS name of a pod in a subnet resolves to an address the subnet cannot reach

A pod in a subnet has two interfaces. ovn-udn1 carries the subnet address. eth0 carries a cluster-internal address that is not part of the subnet and is not routed to it. Cluster DNS answers with the eth0 address - for a headless Service and for a StatefulSet pod name alike - so a name does not replace a fixed address here.

What the claim changes

flowchart LR
    CLAIM["IPAMClaim"] -->|reserves| ADDR["one address from the subnet range"]
    POD1["pod, first start"] -->|names the claim| CLAIM
    POD2["replacement pod"] -->|names the claim| CLAIM
    ADDR --> POD1
    ADDR --> POD2
Without a claim With a claim
Address is assigned when the pod is scheduled the first time a pod names the claim
Address is released when the pod is deleted when the claim is deleted
After the pod is replaced a different address the same address

The claim, not the pod, owns the address. Deleting a pod leaves the claim and its address in place, and the replacement pod picks both up. This behaves the same in a private and in a public subnet; in a public subnet the reserved address is one of the subnet's public addresses.

Virtual machines already have a claim

Every VM in a subnet's project gets a claim created for it, named <vm>.<network> after the VM and the network name in its spec. The VM keeps its address across a restart and a live migration, and the claim is removed when the VM is deleted. There is nothing to configure - this is why the address in VM with a direct public IP stays put.

The rest of this guide is about pods.

Limits

  • You cannot choose the address. A claim has no field to request one. The platform picks a free address the first time a pod names the claim.
  • One pod per claim. A second pod naming a claim that is in use does not start. It stays in ContainerCreating with an ErrorAllocatingPod event. Run the workload with one replica and the Recreate strategy, so a rollout stops the old pod before it starts the new one.
  • Deleting the claim gives the address up. A claim created afterwards under the same name receives whichever address is free, which is not necessarily the old one.
  • The claim counts against the subnet's size. A reserved address is unavailable to other workloads whether or not a pod is running on it. In a small public subnet that is one of very few: see the address table.