Networks
A Network groups endpoints into an isolated network. Endpoints are usually pods but may also be hosts outside the cluster. Networks are isolated by default: an endpoint reaches only its own network unless a routing policy opens a path. See Topology for how networks are connected.
spec.type selects one of three kinds:
- l3 — typical CNI single-pod network.
- l2 — suitable for KubeVirt VM workloads.
- external — external underlay addresses.
Every pod in an L2 or L3 network has an associated NetworkEndpoint recording its address and location.
A routed network with an IPv4 and/or IPv6 subnet.
apiVersion: lace-cni.io/v1alpha1kind: Networkmetadata: name: backendspec: type: l3 ipv4Subnet: prefix: 10.40.0.0/16 hostLocalPrefixLength: 24IPAM is host-local:
- The subnet’s prefix is cut into blocks sized by
hostLocalPrefixLength. - The controller allocates a block to each node.
- Each node allocates pod addresses from its own block.
- A node’s block is recorded in its Allocation, a node-scoped resource holding the prefix(es) given to that node for the network.
Forwarding is routed between the nodes’ blocks:
- A destination address resolves to the node that owns the covering block.
- Same-node traffic is delivered over L2.
- Cross-node traffic is the IP packet encapsulated in SRv6 to the destination node.
- The gateway is the first address in the node’s block.
A flat network with a subnet whose endpoints share a single L2 domain.
apiVersion: lace-cni.io/v1alpha1kind: Networkmetadata: name: storagespec: type: l2 ipv4Subnet: prefix: 10.50.0.0/24IPAM is global:
- There are no per-node blocks.
- The controller allocates each pod address directly from the subnet.
Forwarding is by MAC:
- An address is resolved to a MAC (Neighbor), then forwarded to the MAC’s location (FDBEntry).
- ARP and NDP are answered locally with synthetic replies instead of being flooded across the network. See BUM traffic.
- Cross-node traffic is the Ethernet frame encapsulated in SRv6.
- Addresses on the same subnet and their MACs may also be learned, tracked through the same Neighbor and FDBEntry resources. Learned addresses and MACs may be mobile, moving between locations.
- The gateway is the first address in the network’s prefix(es).
External
Section titled “External”Defined by prefixes, with no subnet and no IPAM of its own. Represents addresses outside the cluster.
apiVersion: lace-cni.io/v1alpha1kind: Networkmetadata: name: corpspec: type: external externalPrefixes: - 192.0.2.0/24An underlay address is matched to a network by longest prefix match across all external networks’ prefixes. See External networks.
See Data plane for encapsulation.
Anonymous
Section titled “Anonymous”spec.anonymous suppresses the implicit route that lets endpoints reach their own network. When set, reaching the network (even from its own endpoints) requires an explicit NetworkRoutingPolicy, so the node cannot be used as a transit next hop.
Network fields
Section titled “Network fields”spec.type—l3,l2, orexternal. Immutable.spec.ipv4Subnet,spec.ipv6Subnet— the subnet per address family forl3/l2; at least one is required. Both are immutable.prefix— the subnet CIDR.hostLocalPrefixLength— the size of the block carved out per node for host-local IPAM.l3only.
spec.externalPrefixes— the CIDRs reachable through the network.externalonly, at least one required.spec.anonymous— suppresses the implicit self-route.status.id— the numeric id assigned to the network, used in the data plane.
Binding
Section titled “Binding”A NetworkBindingPolicy decides which network a resource binds to.
- A resource binds to the network of the matching policy.
- Pods are matched once, when they are created.
- Services are matched continuously. A service’s network is the context for routing to its endpoints, so it should match the pods it targets.
NetworkBindingPolicy fields
Section titled “NetworkBindingPolicy fields”spec.priority— orders policies: the lowest value takes precedence, ties broken lexicographically by name. Defaults to0.spec.matchKind— scopes the policy topod,service, and/ornetworkpolicyresources. Omitted matches every kind.spec.rules— an ordered list; at least one rule is required. The highest-priority matching rule decides the binding.network— the static network the rule binds to, or (for a deny rule) shields. An allow rule sets exactly one ofnetworkorcelExpression.celExpression— derives the network name dynamically from the resource instead of naming it statically (see below).policy—allow(default) binds the network;denyshields it from lower-priority policies and selects by name only.selector— selects the resource byname, or bymatchLabels/matchExpressions, with an optional nestednamespaceSelectorthat further scopes the match to namespaces whose labels match.
Dynamic network names with CEL
Section titled “Dynamic network names with CEL”An allow rule may set celExpression instead of a static network. The selectors filter first, then the expression resolves the name from the matched resource. The resource is exposed as object, an unstructured map, and the expression must evaluate to an optional string:
- An absent optional means the rule does not match — evaluation continues with the next rule.
- A present value is the network name; an empty string is allowed and behaves like an unbound network.
This binds a pod to the network named after its namespace with a team- prefix stripped (e.g. namespace team-blue → network blue), falling through to a default otherwise:
apiVersion: lace-cni.io/v1alpha1kind: NetworkBindingPolicymetadata: name: per-teamspec: matchKind: [pod] rules: - celExpression: >- object.metadata.namespace.startsWith('team-') ? optional.of(object.metadata.namespace.substring(5)) : optional.none() - network: defaultWithin a policy, rules are tried in order: the CEL rule yields nothing for namespaces without the prefix, so the walk falls through to the default rule.
Expressions are compiled and validated once. A policy whose expression is invalid is ignored by binding entirely, and its status carries a CELValid condition reporting the error.