Cases3 cases
1 to 3 of 3
IL-0062Intermittent 502 errors behind a GKE Ingress because pods shut down before the load balancer stopped sending them trafficRavelin2019- Symptoms
After Ravelin moved its API layer from VMs into its GKE cluster behind a Kubernetes Ingress, the integration tests occasionally received 502 errors.
- Trigger
Pods behind the Ingress being removed by their controller, as happens during rolling deploys and scaling.
- Root cause
- Component
- Contributing factor
- Detection
Integration tests occasionally received 502 errors.
- Lessons
Removing a pod's endpoint and signalling the pod happen at the same time, and an ingress can take a long time to catch up. A pod behind an ingress should keep serving after SIGTERM until its grace period ends, and the grace period should be longer than the load balancer's reprogramming time.
IL-0011HAProxy ingress piled requests onto the same pods because a Go template visited the backend map in sorted pod IP orderSkyscanner2019- Symptoms
On a Sunday, a team using one of Skyscanner's Kubernetes clusters manually paged the out-of-hours Kubernetes support because their service showed elevated latency, worst at the p90 and maximum levels.
- Trigger
Upgrading the HAProxy ingress controller to v0.6 and going back from Service virtual IPs to individual pod IPs as backends, on the understanding that the sort-backends flag introduced in v0.5, false by default, meant backends were randomly shuffled.
- Root cause
- Component
- Contributing factor
- Detection
A cluster user manually paged the out-of-hours Kubernetes support about elevated latency; Prometheus queries then showed the uneven request distribution across pods.
- Remediation
- switched the affected service from pod IPs back to the Service virtual IP through a config change in the internal deployment tool Slingshot
- patched the controller to keep each backend's servers in an insertion-ordered slice and changed the template to iterate over that slice
- tested the patch in sandbox clusters and rolled it out to the production clusters
- Action items
- Run the internal controller patch in production and return to pod IPs as the default backends
- Raise the problem upstream with a GitHub issue and pull request
- Test changes to cluster components against the specific behaviour and conditions that matter
- Lessons
The team already knew that sorted backends cause hot-podding and still did not test the new flag well enough to see that it did not work; changes to cluster components need tests aimed at the exact behaviour that matters, under conditions like production. A keyword can behave differently in different parts of a language: range over a map is unordered in Go code but sorted in text/template. A small cluster component can do outsized harm to every user of the cluster and, in the end, to customers.
IL-0050Pods on Kubernetes failed to resolve an external Redis hostname because of ndots:5, the musl resolver in Alpine images, and Netty's DNS resolverToyota Connected2018- Symptoms
Services that used the team's Redis-dependent library crashed on start-up, and their teams reported it to the ops members. The Spring Boot logs showed the applications failing to resolve the Redis hostname during bean initialisation.
- Root cause
- Component
- Contributing factor
- Detection
Service teams reported start-up crashes to the ops members of the team; later the resolution failures were seen in Kibana.
- Remediation
- set ndots to 4 with a dnsConfig block in the Kubernetes deployment manifests
- corrected the maximum connection pool size in the Redis library, cutting Redis connections by about 70%
- Action items
- Test Debian glibc-based base images added to the image library to see whether they resolve the DNS problems
- Update dependencies to newer Netty versions
- Lessons
With ndots:5, a name outside the cluster that has fewer than five dots is first tried with every cluster search domain. Adding a trailing dot avoids that, but only if every library in the path accepts it, and the Netty version in use did not. The ndots change is a workaround that will not hold forever. The author would like better alerting for this kind of failure but notes that alerts on one-off DNS failures are not wanted.
These 3 cases involve Ingress controller and Configuration templating. 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
Software defect3 cases
- Component
- Contributing factor
- Organisation
IL-0062Intermittent 502 errors behind a GKE Ingress because pods shut down before the load balancer stopped sending them trafficRavelin2019IL-0011HAProxy ingress piled requests onto the same pods because a Go template visited the backend map in sorted pod IP orderSkyscanner2019IL-0050Pods on Kubernetes failed to resolve an external Redis hostname because of ndots:5, the musl resolver in Alpine images, and Netty's DNS resolverToyota Connected2018