Cases4 cases
1 to 4 of 4
IL-0083Intermittent 5xx errors in a multi-tenant Kubernetes cluster came from internal DNS: the node-local dnsmasq hit its 150 concurrent query limit, did not cache cluster.local answers, and ndots search lookups flooded CoreDNSAdevinta2023- Symptoms
On a Friday afternoon a tenant of SCHIP, Adevinta's multi-tenant Kubernetes runtime, reported a spike of HTTP 5xx errors in some of its services. The drops in quality of service came back periodically through the following days, each one short, and were reported mostly around midnight.
- Root cause
- Component
- Contributing factor
- Detection
A tenant reported a spike of HTTP 5xx errors in some of its services; the DNS Latency SLI had already been degraded for some time without being acted on.
- Remediation
- raised the dnsmasq concurrent query limit from 150 to 1500
- added a CoreDNS header block that sets the ra and aa flags and clears rd, so dnsmasq caches cluster.local answers
- configured dnsmasq on each node to answer NXDOMAIN for unresolvable search-domain names instead of forwarding them to CoreDNS
- changed the fluent-bit log router hostname to a fully qualified name
- asked the affected tenants to use fully qualified names for internal calls
- Lessons
The DNS Latency SLI had shown the problem long before anyone looked at it. An SLO only protects you when its SLIs are trusted and a drop is investigated. The investigation took a month partly because several on-call groups worked on it separately, without one place for observations and hypotheses, and sometimes chased hypotheses already discarded. Disprove one hypothesis before starting the next, and collect data the metrics system lacks: DNStop showed the garbage lookups that no dashboard did. With ndots:5, short service names multiply DNS traffic; a node-local cache only helps if it can cache the cluster DNS answers at all.
IL-0517Gitpod workspaces failed to start worldwide and lost data when CoreDNS lookups to 8.8.8.8 timed out in its clustersGitpod2022- Symptoms
At around 5.44pm UTC on 25 January 2022, Gitpod saw a high error rate when pulling images from Google Container Registry (gcr.io), with the error "cannot get manifest". About 10 minutes later users reported that they could not start workspaces.
- Root cause
- Component
- Contributing factor
- Detection
The team noticed a high error rate on image pulls from GCR at around 5.44pm UTC; about 10 minutes later users reported that workspaces would not start, and the on-call team started incident response.
- Remediation
- Created new workspace clusters in the EU and the US with a werft job
- Redirected traffic to the new clusters
- Action items
- Keep workspace data on cloud provider persistent volumes that survive node and cluster failures
- Let users download their files from a workspace that cannot be started
- Improve the workspace backup process
- Use three DNS servers instead of one: a GCP-internal one, 8.8.8.8 and Cloudflare's 1.1.1.1
- Do more DNS resiliency work, tracked in an epic
- Improve support for multi-region clusters and later go multi-cloud
IL-0049Partial DNS outage after CoreDNS scaled down and kube-proxy failed to delete stale conntrack entriesPreply2020- Symptoms
Prometheus detected a high rate of 5xx responses on three services, called A, B and C in the write-up, and paged the on-call engineers through VictorOps at 22:18 EET. The 5xx rate was also visible in Kibana.
- Trigger
Because load in the cluster was low, the CoreDNS autoscaler reduced the number of CoreDNS pods from 3 to 2.
- Root cause
- Component
- Contributing factor
- Detection
Prometheus alerted on a high 5xx rate on services A, B and C and paged on-call through VictorOps.
- Remediation
- reverted the latest release of the affected service
- a regular deploy created new nodes, the CoreDNS autoscaler added CoreDNS pods, and the conntrack table was rewritten
- Action items
- Disable the autoscaler for CoreDNS
- Run a DNS cache server in production
- Monitor conntrack usage
- Lessons
Scaling CoreDNS down is not free: if kube-proxy fails to clear conntrack entries for the removed pod, clients keep sending DNS queries to it. Known DNS weaknesses in a cluster should be prioritised before they cause an outage, and fixes that only treat consequences leave the underlying conntrack problem in place.
IL-0047Pod-to-pod requests delayed by 5, 10 or 15 seconds because of DNS lookups lost to a conntrack raceMindTickle2019- Symptoms
Pod-to-pod calls were intermittently slow and the web application felt slow overall. A request that pod A sent at time x reached pod B at x + 5s, x + 10s or x + 15s, always a multiple of five seconds.
- Trigger
The C library resolver sent the A and AAAA queries for each lookup on the same port; where DNAT or SNAT translation takes place, a race condition in conntrack sometimes left one of the queries unanswered, and the resolver waited 5 seconds before retrying.
- Root cause
- Component
- Contributing factor
- Detection
The team noticed intermittent delays in pod-to-pod calls and slowness in the web application, and that the delays were always multiples of five seconds.
- Remediation
- added the single-request-reopen option to dnsConfig in the deployment specs
- set GRPC_DNS_RESOLVER=native in the Dockerfiles of gRPC applications so they used the libc resolver
- checked with tcpdump port 53 that A and AAAA queries left from different ports
- Lessons
Delays that are exact multiples of five seconds point to DNS lookups being retried after the resolver's 5-second timeout. A resolver option set in the pod spec only helps processes that use the libc resolver; runtimes with their own resolver, such as gRPC with c-ares, ignore it.
These 4 cases involve CoreDNS and conntrack table. kubegap audits a Kubernetes cluster for gaps like these, read-only, from Claude Code or Codex; its checks cite public reports like the ones in this library.
By root cause1
DNS or network fault4 cases
- Component
- Contributing factor
- Organisation
IL-0083Intermittent 5xx errors in a multi-tenant Kubernetes cluster came from internal DNS: the node-local dnsmasq hit its 150 concurrent query limit, did not cache cluster.local answers, and ndots search lookups flooded CoreDNSAdevinta2023IL-0517Gitpod workspaces failed to start worldwide and lost data when CoreDNS lookups to 8.8.8.8 timed out in its clustersGitpod2022IL-0049Partial DNS outage after CoreDNS scaled down and kube-proxy failed to delete stale conntrack entriesPreply2020IL-0047Pod-to-pod requests delayed by 5, 10 or 15 seconds because of DNS lookups lost to a conntrack raceMindTickle2019