🔌 Cilium CNI support (Secure Containers)
FluxVM does not ship a Cilium fork or write Cilium-private BPF maps.
On Cilium nodes, Secure Containers keep Cilium as the Pod CNI and hand the
Pod's primary L2 endpoint (eth0 IP/MAC/routes) into the guest VM.
Network Fabric sandbox.dataplane.mode = "cilium" is a separate coexistence
path for VM-edge TC policy — see ebpf-cilium.md. This
document covers the containerd shim CNI L2 path.
✅ What works
| Piece | Behavior |
|---|---|
| Provider | FLUXVM_CONTAINER_CNI_PROVIDER=auto|cilium|generic (default auto) |
| Detection | auto checks cilium.sock, /opt/cni/bin/cilium-cni, /etc/cni/net.d/*cilium*, and pod-side cilium* ifaces |
| Primary iface | Prefers configured iface (default eth0); falls back to first routable non-Multus iface |
| Multus | netN secondaries are prepared as extra host bridges and attached as guest NICs (network.extra at create, or POST /v1/vms/{id}/hotplug/nic after a warm-pool claim) |
| Dual-stack | IPv4 + IPv6 addresses/routes on the primary iface (Set 6) |
| Host TC | Cilium programs stay on the host lxc* peer; FluxVM bridges the pod-side endpoint |
⚠️ What does not work (honesty bounds)
- Non-
netNextra interfaces still fail closed whenFLUXVM_CONTAINER_CNI_STRICT_MULTI_INTERFACE=1. - Writing Cilium identity / ipcache / endpoints maps.
- Replacing Cilium NetworkPolicy with FluxVM as the Pod CNI.
- Claiming Hubble attribution for every guest packet without CEP enrich (hubble-lite.md).
🛠️ Operator setup
- Install Secure Containers (
scripts/install-secure-containers.sh) and mergedeploy/containerd/fluxvm-runtime.toml. - On Cilium nodes, export shim env (or use
configs/cilium-cni.tomlas the Network Fabric coexistence fragment + the env comments as SoT):
export FLUXVM_CONTAINER_CNI=1
export FLUXVM_CONTAINER_CNI_PROVIDER=auto # or force cilium
export FLUXVM_CONTAINER_CNI_INTERFACE=eth0
- Optional VM-edge Fabric coexistence:
sudo ./scripts/enable-network-fabric-ga.sh --cilium --restart
-
Deploy RuntimeClass / DaemonSet mounts from deploy/k8s/cilium/.
-
Evidence:
./scripts/evidence-cilium-cni.sh
# live (optional): FLUXVM_CILIUM_CNI_LIVE=1 ./scripts/evidence-cilium-cni.sh
📡 Packet path (primary)
lxc* ⇄ Pod netns eth0 (CNI-assigned IP; the guest takes over IP/MAC/routes)
→ in-Pod bridge → second veth pair → host bridge → guest TAP → guest virtio-net
Host lxc* peer keeps Cilium TC/eBPF; FluxVM never writes Cilium maps.
That bridge chain is the fallback. By default (FLUXVM_CONTAINER_CNI_DATAPATH=auto, a veth Pod, no
Multus secondaries, kernel ≥ 5.10, an ebpf/cilium daemon dataplane) a TC redirect replaces it;
FLUXVM_CONTAINER_CNI_DATAPATH=bridge forces the chain — see direct-datapath.md.
📚 Related
- secure-containers-set6.md — dual-stack + Multus guard
- direct-datapath.md — bridge-less veth ⇄ guest redirect (opt-in)
- ebpf-cilium.md —
mode=ciliumFabric coexistence - network-policy.md — FluxVM policy vs Cilium CNP