Networking¶
kMetal's networking model is built on Kube-OVN and gives every tenant a private virtual network on shared bare metal. The two top-level abstractions are VPCs and Subnets — both Kube-OVN custom resources, and both cluster-scoped.
Tenants never write either of them. They write claims, and the platform writes the objects.
VPC — the tenant network boundary¶
A VPC is the tenant's isolated routing domain. Under the hood it is an OVN Logical Router with its own routing table, its own ACL set, and no static path to any other tenant's VPC. The under cluster's OVN deployment maintains one VPC per tenant.
What a VPC enforces:
- Cross-tenant traffic is dropped by default. Two tenants on the same physical hosts cannot reach each other's pods, services, or worker IPs — the routing tables don't list each other.
- Hard multi-tenancy against the platform. A default OVN Logical Router Policy on every tenant VPC also blocks traffic destined for the kMetal external CIDR (the under cluster's API server, platform services, other tenants' load-balancer VIPs). A tenant cannot pivot from a compromised workload into the platform.
- Independent IP space. Each tenant chooses their own pod and service CIDRs. Overlapping CIDRs between tenants are fine — they are isolated by the routing domain, not by global allocation.
Subnet — IP space inside a VPC¶
A Subnet is a Kube-OVN Subnet resource bound to a VPC. It defines the IP CIDR and the gateway IP. A subnet is what a CAPI Cluster attaches to — one tenant cluster lives in one subnet inside one VPC.
A tenant can have multiple subnets per VPC. The kMetal ClusterClass exposes a network.subnet variable so multiple Cluster objects in the same VPC can each pick a different subnet for their worker VMs. This lets a single tenant build out separate dev/stage/prod clusters with separate IP planes inside one isolated network boundary.
Claims — the tenant-facing API¶
Kube-OVN's Vpc, Subnet and EIP objects are cluster-scoped, which makes them the wrong thing to hand a tenant: nothing cluster-scoped can be owned by a namespace, bounded by a quota, or scoped by RBAC to one tenant.
So kMetal puts a namespaced claim in front of each one, in the tenant's Environment:
| Claim | Reconciles into | Notes |
|---|---|---|
VpcClaim |
the Environment's Vpc |
Exactly one per Environment. The tenant states whether they want external access; the routing that makes it safe is not theirs to write. |
SubnetClaim |
a Subnet in that VPC, plus the NetworkAttachmentDefinition worker VMs attach through |
Several per Environment — one per cluster, typically. The VPC binding is derived, never declared. |
EipClaim |
an external address on the provider network | One per address a tenant wants to publish a workload on. |
Three things follow from that shape.
A tenant writes intent, not configuration.
A VpcClaim says external access: yes.
The static route, and the policy routes that keep this VPC off the provider segment and away from its neighbours, are injected by the controller — a tenant can neither get them wrong nor leave them out.
The same applies to a SubnetClaim: it carries a CIDR and a gateway, while the VPC it belongs to and the namespaces it serves are derived from the Environment.
Claims can be counted. Address space and routable IPv4 are shared, finite, and exhaustible by a tenant acting entirely within their rights. Because a claim is an ordinary namespaced object, a Tenant can be capped on how many they hold — and told so when they claim, rather than when something quietly fails to get an address. See Tenant Layer.
Status is the tenant's view of the platform. A claim reports the cluster-scoped object it bound, and its capacity — how many addresses the subnet has left, for instance — so a tenant can see what they are using without any read access to Kube-OVN itself.
Claim specs are immutable. A CIDR or an external-access decision is settled when the claim is created, because changing either underneath a running cluster is not something a controller can do safely.
Tenant traffic is always overlay¶
Tenant traffic is encapsulated in Geneve tunnels between under-cluster nodes. There is one networking mode, and this is it — there is no per-tenant VLAN mode to choose between.
What that buys:
- The data-center switch sees only generic Geneve traffic — no per-tenant VLANs, no per-tenant switch port configuration.
- Adding a tenant is purely a software operation, with no network team involvement.
- Tenants can overlap each other's CIDRs freely, because isolation is the routing domain rather than the wire.
What it asks for: the overlay is carried on one interface per node — typically a kernel VLAN sub-interface — and wants jumbo frames (MTU 9100) on that transport for good performance.
Per-tenant isolation on the wire is available where it is needed, but at the egress edge rather than inside the overlay: a tenant can be given a provider network of its own, so its egress leaves on a dedicated segment. See the provider network below.
Provider network — egress and external IPs¶
Separate from tenant VPCs, the under cluster has a provider network: a dedicated VLAN that carries tenant SNAT/egress traffic and hosts the IPs that external clients connect to.
- A distributed gateway runs an external OVN Logical Router Port on every node, so any node can do SNAT for any tenant. There is no single egress chokepoint.
- Tenant
LoadBalancerservices get External IPs from this provider network. A tenant claims one with anEipClaimin their Environment and points a Service at it by annotation; traffic arriving for that address is translated straight to the workload, with the under cluster never in the data path. - The under cluster announces those IPs into the data-center routing fabric (via a static route at the edge router, or 1:1 NAT).
- The edge router is decoupled from kMetal — it doesn't run any Kube-OVN logic. kMetal just publishes the right IPs and the edge router handles the public-facing piece.
Where to go next¶
- Networking Configuration — operator-side setup: address pools, the overlay transport interface, MTU.
- Load Balancer — tenant-facing service exposure: the OVN gateway and edge router integration.
- Hard Multi-Tenancy — how VPC isolation fits with KVM compute isolation and a control plane per tenant to form kMetal's tenant boundary.
- Create First Environment — the claims, written out, with the manifests a tenant actually applies.