CNI architecture and protocols¶
Network topology¶
Plugin¶
/opt/cni/bin/pyroute2-cni-plugin
a static binary that only forwards info to the server container
The plugin workflow:
executed by kubelet
get CNI JSON from stdin
get environment variables
parse the variables and open CNI_NETNS -> obtain an open FD
obtain a new request id from the server
send the FD to the server over socket_path_fd
send the CNI and env data to the server over socket_path_api
await the response
print the response to stdout
Server¶
Container: pyroute2-frr¶
image: ghcr.io/svinota/pyroute2-cni:{version}
runs FRR: zebra, staticd, bgpd
runs EVPN-VXLAN controlplane
exposes and monitors a UNIX socket to reload configuratuion
Container: pyroute2-cni¶
image: ghcr.io/svinota/pyroute2-cni:{version}
uses the host network namespace
exposes two UNIX sockets for the API and an HTTP readiness endpoint
The server workflow:
watch namespaces and VRF domain objects
reconcile periodic address-pool and firewall jobs
await request init
allocate and respond with a request id
collect netns FD, CNI data and env variables from all the communication sockets
set up the container network
send the CNI response to the plugin
Controller flow¶
The server keeps node state synchronised with background controllers:
NamespaceController watches namespaces and triggers namespace lifecycle hooks.
VRFController watches VRFDomain objects, creates or removes VRFs and VXLAN-backed bridges, and reconciles firewall rules.
Also it has managers:
AddressPool handles allocation, reconciliation, and garbage collection of pod address blocks.
FirewallManager owns the nftables setup and per-VRF NAT and marking rules.