← Back to Projects

Crash-Loops with Three DNS Root Causes

Three workloads stuck in startup-probe crash-loops, each from a different private DNS gap, all proven from inside the pod

Platform: AKS (stateful cluster)
Workloads: Containerised functions
Type: Read-only diagnosis
Role: Investigator

Overview

Three newly deployed services had never become Ready, and each had racked up around a thousand restarts. Their logs all said the same thing: health check failed. Testing from inside each pod, one network layer at a time, found three separate DNS problems, and a redeploy wouldn't have fixed any of them.

Why It Was Hard

Architecture

PodCoreDNSVNet custom DNScorporate resolverPrivatelink zones+ on-prem DNS
A record only helps a pod if its zone is reachable through this chain

Method: Test Every Layer from Inside

run from a debug pod in the same namespace
getent hosts <fqdn>                                   # DNS  - what does the pod resolve?
nc -zv <ip> 443                                       # TCP  - is the port reachable?
openssl s_client -connect <fqdn>:443 </dev/null       # TLS  - is it the right endpoint?
wget -qO- https://<fqdn>/health                       # HTTP - does the app answer?
ServiceWhat failedRoot cause
Auth-dependent workerThe identity provider's hostname was NXDOMAIN inside the cluster onlyThe company domain lived on on-prem DNS, and the cluster VNet's resolver didn't serve that zone
Notifications workerBlob hostname NXDOMAIN, yet TCP 443 to the private IP was openThe record existed, but its zone was linked to a different VNet. A missing link, not a firewall
Event-stream consumerName resolved and TCP connected, but the TLS handshake failedSeveral duplicate privatelink.servicebus zones held conflicting records, and the cluster got a stale IP

Recommendations

  1. Serve or forward the company domain through the cluster's DNS path.
  2. Register private endpoint records in the single zone the corporate resolver treats as authoritative, instead of adding ad-hoc VNet links.
  3. Reduce duplicate privatelink zones to one per service type, and audit them regularly.
  4. Make the pod-level connectivity checks above a standard runbook for every new private endpoint.
Azure Resource Graph
// Find duplicate privatelink zones across subscriptions
resources
| where type =~ 'microsoft.network/privatednszones'
| where name startswith 'privatelink.'
| summarize copies = count(), groups = make_set(resourceGroup) by name
| where copies > 1

Key Outcomes

Lessons Learned

Conclusion

One symptom hid three causes. Methodical, layer-by-layer testing separated them quickly and turned three tickets into one platform fix.

Technologies Used

AKSCoreDNSStartup ProbesAzure Functions on KubernetesAzure Private DNSPrivate EndpointsEvent HubsBlob StorageAzure Resource Graph

About this case study: this write-up is drawn from my hands-on platform engineering experience. Organisation names, system names, figures and timelines have been changed or generalised, and all code, configuration and queries are illustrative examples written for this page.

← Designing for Node Failure on AKSInside-Out Ingress Troubleshooting →
← Back to Projects Get in Touch