Skip to content

VPCRouter Resource Kind

Kind: VPCRouterapiVersion: pivirt.hu/v1Aliases: router, routers, vpcrouter

A VPCRouter is the gateway of one VPC: a network namespace on a gateway node with a veth into the VPC’s bridge and a veth into the uplink bridge, forwarding between them and masquerading outbound traffic. Public addresses for VMs in the VPC are bound to it with ExternalIP objects.

Routing is centralized on gateway nodes rather than distributed across compute hosts: public addresses only ever need announcing from the gateway, and a VM migration never moves a public IP — only the router’s DNAT target changes. Two routers on one node with the same private CIDR do not collide; each namespace keeps its own routes and its own nftables rule set.


apiVersion: pivirt.hu/v1
kind: VPCRouter
metadata:
name: vpc-10042
spec:
inside:
bridge: br-vpc-10042 # the VPC segment's bridge on this node
address: 10.42.0.1/16 # this router's address — the VPC's gateway
uplink:
bridge: br-ext # the bridge carrying the public network
address: 198.51.100.7/24 # the router's public address
gateway: 198.51.100.1
masquerade: true
mtu: 1450 # optional; 1450 when the inside is a VXLAN

Field Type Required Default Description
netns string No object name Network namespace name
inside.bridge string Yes Host bridge the VPC-facing veth is enslaved to
inside.address string Yes The router’s address on the VPC, in prefix notation; the VPC’s gateway
uplink.bridge string Yes Host bridge the public-facing veth is enslaved to; must differ from inside.bridge
uplink.address string Yes The router’s public address, in prefix notation
uplink.gateway string No Next hop for the default route; must be inside uplink.address’s prefix
masquerade bool No false Rewrite outbound source addresses to the uplink address
mtu int No MTU for both veth ends

Inside the namespace the interfaces are always named inside and uplink, so ExternalIP and operator tooling know where to look.


  • Observe before write. Re-applying an unchanged router, or restoring it at boot, issues no mutating command: the namespace, both veth pairs, the addresses, forwarding, the default route and the masquerade rule are each checked first.
  • Removal deletes the namespace — every interface, route and nftables rule inside it goes with it — and sweeps any stray host-side veth end.
  • Bindings first. A router that still has ExternalIP objects naming its namespace refuses to be deleted; remove the bindings, or let the cascade do it.
  • Adoption. Namespaces on the host that no VPCRouter declares are reported by pivirtctl get routers as adoptable and never touched.

Terminal window
pivirtctl apply -f vpc-router.yaml
pivirtctl get routers
pivirtctl describe router vpc-10042
pivirtctl delete router vpc-10042