fix(k3s): restore traefik template parity, then bypass ServiceLB for real client IPs #941
No reviewers
Labels
No labels
burndown-2026-06
burndown-2026-08
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/advocate
role/director
role/exec
role/frontend
role/gamedev
role/human
role/platform
role/qa
role/science
role/sysadmin
state
ambient
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/infrastructure!941
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/traefik-hostnetwork-source-ip"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Refs #909. Sequencing agreed with Kai: ServiceLB bypass first, then the 499-triggered self-healing script, because every actuator for that script is currently bent around the masked source IP.
Two commits, deliberately separate.
1.
fix(k3s): restore template parity with live — an armed landmine, no live changeThe ansible template that converges
HelmChartConfig/traefikstill carried the deadservice.loadBalancerIPkey that #910 was closed for. #910 was fixed on the live object only. The authoring layer was never updated, so the fix was one ansible run away from being undone.Running the
k3s-configrole today would rewrite/var/lib/rancher/k3s/server/manifests/traefik-config.yamlwith the old spelling. k3s auto-applies that directory, which triggers a helm upgrade, which re-renders the Service withoutloadBalancerIPand drops the public IP binding for every public hostname on the cluster. That is the exact #910 outage, reachable from an ordinary ansible run rather than a deliberate edit.The template was also missing
externalTrafficPolicyand the entirelogs.accessblock. Those access logs carryUser-AgentandReferer, are the only reason the 2026-08-26 crawler could be attributed at all, and are the source for the 499 signal in #909.This commit only makes the template match what is already live, so applying it is a no-op against the running cluster.
Same class as the
1500Mivs3Gidrift found earlier tonight: fixed live, never landed in the source.2.
feat(k3s): hostNetwork bypass — this one has an outageService becomes
ClusterIP(no ServiceLB, no svclb DaemonSet) and Traefik binds the node's :80/:443 viahostNetwork. Three traps carried:NET_BIND_SERVICEadded, since the chart runs as UID 65532 with all caps dropped and otherwise cannot bind privileged ports.loadBalancerIPandexternalTrafficPolicydropped, because both are rejected on a ClusterIP Service. An earlier draft leaked them and would have failed the apply.Verification
Per #910's instruction, verified by rendering rather than applying. Chart pulled from the k3s static path,
helm templaterun with the k3sHelmChartvaluesContent as base and these values on top:A server-side dry-run of the rendered Service is accepted by the API server.
Worth recording: my first render layered the previous HelmChartConfig underneath and leaked
loadBalancerIPandexternalTrafficPolicyonto the ClusterIP Service. k3s replaces the HelmChartConfig rather than merging with the old one, so that render was wrong. The trap is now indocs/k3s-deploy-notes-manifests.md.Blast radius and rollback
DNS cannot move: all published ingresses pin
external-dns.alpha.kubernetes.io/targetand external-dns runs--policy=upsert-only, so records never derive from Service status and are never deleted.Traefik is the only LoadBalancer Service in the cluster, so nothing else loses svclb. cert-manager uses DNS-01, so certificate issuance does not depend on port 80.
Applying commit 2 restarts Traefik and briefly drops every public hostname while svclb tears down and the hostNetwork pod binds the ports. Expect tens of seconds, longer if the pod hits CrashLoopBackOff backoff while svclb is still holding the ports. The k3s API is on the tailnet independently of Traefik, so rollback stays available even with ingress down.
Not done
The
k3s_traefik_load_balancer_ip_availablegate and its SSM lookup are now vestigial, since the config no longer consumes the public IP. Left in place because it fails safe by preserving the existing file, and because a role refactor does not belong in a change this risky. Tracked separately.