# Cilium Helm values — REFERENCE COPY of the parity set (docs/02 Cilium-ownership contract). # # The AUTHORITATIVE values that Flux reconciles are inlined in helmrelease.yaml. This file is a # readable, un-nested mirror of that value set so WS-NET can diff it against the live cluster and # the Ansible bootstrap render at a glance. Keep the two in sync. # # SOURCE OF TRUTH (all [parity] fields MUST equal these): # infra/ansible/roles/cilium/templates/cilium-values.yaml.j2 # infra/ansible/roles/cilium/defaults/main.yml (cilium_version: 1.20.1) # infra/ansible/inventory/group_vars/all.yml (k3s_apiserver_endpoint = the kube-vip VIP, # k3s_api_port) — NOT k3s_api_host, which is the # founder's own address and bootstrap-only # # chart version (helmrelease.yaml chart.spec.version): 1.20.1 # [parity] = cilium_version # [parity] k3s kube-proxy disabled → Cilium replaces it (ADR-0001/0002) kubeProxyReplacement: true # [parity] = the k3s API endpoint + port. THE CONTROL-PLANE VIP (kube-vip), not the primary node — # changed 2026-09-06; the Ansible half is k3s_apiserver_endpoint, NOT k3s_api_host. # Mirrors the HelmRelease's ${K3S_API_HOST} cluster-vars token (R-ENV-02). This file is NOT a # kustomize resource, so nothing substitutes it — the token is shown with its dev value beside it. k8sServiceHost: "${K3S_API_HOST}" # the CONTROL-PLANE VIP — dev: 192.168.1.49 | prod: 192.168.2.9 k8sServicePort: 6443 # [parity] ingress via Gateway API, no Traefik (docs/09) gatewayAPI: enabled: true # [parity] egress-class steering (ADR-0002; VPN model ADR-0013) egressGateway: enabled: true # [parity] Egress Gateway REQUIRES masquerade; ipv4 + eBPF is the Phase-1 crash fix — keep BOTH enableIPv4Masquerade: true bpf: masquerade: true # [parity] flow observability / isolation audit # [parity] roll the agents when cilium-config changes. The chart default (false) rewrites the # ConfigMap but leaves the pod template alone, and cilium-agent only reads it at STARTUP — so a # merged config change is SILENTLY INERT. Measured 2026-10-04..05: the Hubble exporter keys were # live in cilium-config and the HelmRelease said UpgradeSucceeded, while all three agents were # still pre-merge pods exporting nothing for over a day. Cost: config edits now roll the agents # (one node at a time via maxUnavailable: 1), which can briefly blip the VIPs on the lease-holding # node. Full rationale in helmrelease.yaml. rollOutCiliumPods: true hubble: enabled: true relay: enabled: true ui: enabled: true # [parity] static flow export -> cilium-agent stdout -> Alloy -> Loki. Records the PRE-SNAT # client address for Plex's raw tcp/32400, which Plex's own log cannot show (every LB Service here # is externalTrafficPolicy: Cluster, so the VIP lease holder SNATs the client). Scoped BY PORT, # not namespace: the flow carrying the real client IP does not match a namespace filter. Full # rationale, measurements and the rejected alternatives are in helmrelease.yaml. export: static: enabled: true filePath: stdout allowList: - '{"destination_port":["32400"]}' - '{"source_port":["32400"]}' # [parity] ingress VIP announcement on the flat LAN (docs/09, OQ-1) l2announcements: enabled: true # [parity] the host's cgroup2 root is /sys/fs/cgroup (systemd mounts it); do not auto-mount. # NOT /run/cilium/cgroupv2: nothing mounts cgroup2 there, so socket-LB attached to the agent's own # cgroup and host processes lost Service/LB translation (2026-10-03 — see helmrelease.yaml). cgroup: autoMount: enabled: false hostRoot: /sys/fs/cgroup # [parity] roll the agent DaemonSet ONE node at a time. Overrides the cilium 1.20.1 chart # default of 2, which on 3 nodes lets a single bad render break 2/3 agents at once — as the # 2026-09-01 incident did (k8sServiceHost: "" → the `config` init container fell back to the # ClusterIP 10.43.0.1:443, translatable only by the very agent being replaced). A CNI upgrade # has no healthy-peer fallback, least of all on a cold prod bootstrap; maxUnavailable: 1 stops # the rollout at the first unready pod. Cost: serialised, slower upgrades (fine at 3 nodes). updateStrategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 # NON-parity (Flux/prod may differ; dev sets 1 to save RAM) — omitted from the HelmRelease: # operator.replicas # # TODO (Phase 2, WS-NET): ipam / ipv4NativeRoutingCIDR pinned to cluster CIDRs; east-west # encryption (wireguard/ipsec) decision (WS-SEC/WS-NET).