DNSConfigForming nameserver-limit warnings are the bulk of standing event noise on kai-server #864
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#864
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Found during a fleet health sweep on 2026-08-18. Low severity, filed so it stops being rediscovered.
Observed
Several pods on kai-server emit
DNSConfigFormingwarnings continuously:Counts at time of sweep:
kube-system/coredns-94b8d5df-tr5fs- 23,855observability/node-exporter-prometheus-node-exporter-qt58z- 21,167fleet-reachability/gatus-786db97fc-t26qr- 21,126Reading
The node's resolv.conf carries more than the three nameservers Kubernetes will propagate, so kubelet truncates and warns every time it forms a pod DNS config. The three that survive are the LAN gateway, its IPv6 counterpart, and the Tailscale MagicDNS resolver, which is the set actually wanted.
So the warning is almost certainly cosmetic, and name resolution works. The cost is volume: these three sources alone are roughly 66,000 events, which is most of the standing warning noise on the cluster and makes event streams hard to read during a real incident.
Not established: whether any resolver that matters is among the omitted ones. Worth one look at the node's resolv.conf to confirm the truncation is dropping only redundant entries.
Suggested
Trim the host resolv.conf to three or fewer nameservers through the owning Ansible role, or set an explicit
resolvConffor kubelet pointing at a trimmed file. Either removes the warning at the source rather than muting it.Diagnosed to root cause. The fix already exists in this repo and has never been converged onto kai-server. Not applying it: it needs an attended sudo password and a k3s restart.
Root cause
/etc/resolv.confon kai-server is the systemd-resolved stub with a single nameserver, which is not what kubelet reads. With systemd-resolved active, k3s selects/run/systemd/resolve/resolv.conf, and that file carries four nameservers:Kubernetes caps a pod's resolv.conf at three. Kubelet drops one and emits
DNSConfigFormingevery time, which is why the count is what it is: 31,146 on coredns, 28,437 on node-exporter, 2,632 on gatus.Worth noting the cluster runs
disable-ipv6: true, so two of those four slots are spent on resolvers pods cannot use anyway.The fix is already written
ansible/roles/k3s-confighandles this and the design is good.k3s_pod_resolver_nameserversdefaults to a single entry,192.168.0.194, which is kai-server's own LAN address. The role setsDNSStubListenerExtra=192.168.0.194so systemd-resolved listens there, then points pods at that one nameserver. Resolved keeps doing the split-DNS routing upstream, so pods get full resolution from a single entry and the three-nameserver limit stops being reachable at all.There is even an assert that
k3s_pod_resolver_nameserversholds between one and three entries.Why it is not in effect
None of it has been applied:
The live
config.yamldoes carry the currentkubelet-argblock, so it is not wholly stale. Theresolv-confhalf specifically never landed.This is the same shape as the restic failure-alert work in #921: kai-server's privileged Ansible roles fail unattended with
Missing sudo password, so authored fixes sit unapplied. That pattern is worth its own issue if it keeps recurring.Applying it is safe, but attended
The handler order is correct, and I checked it rather than assuming. Ansible runs handlers in definition order:
Reload k3s unitRestart systemd-resolvedVerify the pod DNS listener-wait_forport 53 on each configured nameserver, 10s timeoutRestart k3sSo resolved comes up and is verified listening before k3s is touched. If the listener does not appear, the run aborts before the k3s restart rather than leaving pods pointed at a dead resolver. That is the guard this needs.
There is also a
k3s-config-stagetag that skips the k3s restart, so the resolved half can land and be verified independently first.The second command restarts k3s, which briefly bounces the control plane. That plus the sudo prompt is why this is Kai's to run rather than mine.
Duplicate of #811, which survives.
Read both before choosing. Same root cause, same
DNSConfigFormingtruncation, but #811 is a strict superset:Both issues independently reached the same honest conclusion, that the truncation is probably benign but unproven because neither could read the node's
resolv.conf.Confirmed still true today:
/etc/resolv.confremains outside the node-stats MCP readable-root allowlist on both nodes, so the open question in both issues, which nameserver is being dropped, is still unanswerable without a shell on the host.Part of the 2026-08-28 burn-down, rationale in #981. Tagged
burndown-2026-08for recovery.