Load Balancer¶
kMetal runs two load-balancer implementations, and which one serves a LoadBalancer Service depends on which cluster the Service was created in.
| Service created in | Served by | Address comes from |
|---|---|---|
| The under cluster — platform Services, and the Service in front of each tenant control plane | MetalLB, layer 2 | The pools in spec.networking.loadBalancer |
| A tenant cluster — the tenant's own workloads | Kube-OVN | An EipClaim on the provider segment |
They never overlap. Nothing a tenant creates in their own cluster can draw from a MetalLB pool, and nothing on the under cluster is served from the provider segment's EIP space.
For the MetalLB side, see Address pools for the surface and Networking Tasks for handing out control-plane addresses. The rest of this page is the tenant-workload path.
How a tenant Service is served¶
A tenant's LoadBalancer Service is fulfilled by Kube-OVN, not by anything running in the tenant cluster.
cloud-provider-ovn watches LoadBalancer Services in every tenant cluster from the under cluster, and reconciles the ones carrying spec.loadBalancerClass: kmetal into two OVN objects:
- an
OvnEip— the external address, allocated from the provider subnet the tenant's VPC egresses through, - an OVN load balancer — DNAT from that address to the Service's backends, with multiple backends supported.
Any other LoadBalancer implementation the tenant installs in their own cluster is left alone, because it will not carry that class.
The under cluster is not in the data path. Once the load balancer is programmed, traffic arriving for the address enters the provider segment, hits OVN, and is DNATed straight to a worker VM's pod IP. No proxy hop, no per-Service controller inside the tenant cluster, and no under-cluster component to fall over in the middle of a tenant's traffic.
The address itself is granted, not self-served: an EipClaim in the tenant's Environment is what a Service binds to, and a tenant with no free claim cannot publish a Service at all.
See EipClaim in Networking Tasks for the grant and the binding rules.
Edge router integration¶
The provider segment's addresses have to be reachable from outside the data centre, and that part is the router's, not kMetal's. Two patterns work:
| Pattern | How | Trade-off |
|---|---|---|
| Direct routing | The edge router holds a static route for the provider CIDR pointing at the under cluster's gateway nodes. | Zero per-tenant coupling: once the route is in place, EIPs come and go without touching the router. This is the one to ask for. |
| Edge NAT | The edge router 1:1 NATs a public address onto each tenant EIP. | A fallback where the provider CIDR cannot be routed directly. Every address needs router configuration, so onboarding a tenant now involves the network team. |
Either way the edge router runs no Kube-OVN logic and holds no per-tenant state beyond, in the NAT case, the mappings themselves.
Pool models¶
Which subnet a tenant's EIPs come from follows their VPC:
- One shared provider subnet — every tenant's EIPs are allocated from
defaultProviderSubnet. Simple, and the only shape validated for v1. - A provider network per tenant — the tenant's
VpcClaimnames its own provider network, and their EIPs come from that segment alone. Stronger isolation on the wire, and how per-tenant egress isolation is done: see Give a tenant its own provider network.
Per-tenant EIP pools are not validated yet
Combining a dedicated provider subnet per tenant with the multi-DGP topology kMetal uses hits an upstream bug (kube-ovn#3329, ovn-org/ovn#222). Per-tenant egress on a dedicated segment works; treat per-tenant EIP allocation as unvalidated until those are resolved.
Where to go next¶
- Networking Configuration — the provider networks and MetalLB pools these draw from.
- Networking Tasks — granting
EipClaims, control-plane addresses, and diagnosing a Service with no address. - Control Plane External Access — publishing tenant api-server endpoints, which is a separate path from either of these.