Skip to content

Pod attachment

The container runtime invoking the CNI binary is the hand-off between Kubernetes and Lace: it is how the cluster tells the node plugin a pod needs networking. This page follows what happens from there for every added pod — the work the node plugin does, and the per-pod NetworkEndpoint resource that backs it. Where the binary comes from is covered in the architecture overview.

When the container runtime sets up a pod’s sandbox, it invokes the CNI binary, which makes a single call over a local socket to the node plugin and blocks waiting for the result.

The node plugin registers the request against the pod and wakes its endpoint reconciler; the call stays blocked until that work finishes. Asynchronously, the reconciler:

  • evaluates the NetworkBindingPolicy for the pod to decide which Network it joins,
  • reserves the pod’s addresses from that network’s allocation,
  • creates the NetworkEndpoint for the pod, recording the binding,
  • builds the pod’s interface — the veth pair, addresses and routes in the pod namespace, attachment to the network’s bridge or VRF, and the eBPF program and map entries that make it reachable,
  • assigns the endpoint its policy segment and marks it ready.

Once the endpoint is ready the blocked call returns, and the binary reports the assigned interfaces and addresses back to the runtime.

Every pod on the node has exactly one NetworkEndpoint, owned by its Pod so it is garbage-collected with it. It is the node’s record of the pod’s networking, and the object the reconcile loop acts on:

  • spec — the binding, fixed once set: the network, its type (L3 or L2), and the assigned addresses and gateways.
  • status — the realised and live state: the host-side interface name, the pod’s MAC, the current sandbox’s container ID, the container ports, the assigned Segment (its id, the policy generation the assignment is valid for, and the named-port variation), and a Ready condition.

The binding fields are immutable once written, so a pod keeps the same network and addresses for its whole life.

Attachment is not one-shot. After the endpoint is ready its reconciler keeps running for the life of the pod, because the endpoint’s policy identity can change while its interface does not:

  • a change to the pod’s or namespace’s labels, or to the policy set, can move the endpoint into a different Segment; the reconciler recomputes the relevant labels, re-stamps the segment id, generation and variation, and updates the data plane in place,
  • a generation rollout only re-points the endpoint at a new segment once every node is ready for it.

When the pod is deleted the runtime calls a CNI delete, the node plugin deletes the NetworkEndpoint, and a finalizer drives the data plane teardown — interface, device, addresses — before the object is removed.