MiddleDebuggingCommonNot answered yet
An Ingress returns 503 while the Service's Pods appear up — trace where traffic is lost.
An Ingress returns 503 for an app, but the Pods are running. Trace the request path Ingress → Service → endpoints → Pod, find where it breaks, and give the fix.
$ curl -sI https://app.example.com/ | head -1
HTTP/2 503
$ kubectl get pods -l app=api
NAME READY STATUS RESTARTS AGE
api-abc 0/1 Running 0 2m
api-def 0/1 Running 0 2m
$ kubectl get endpoints api
NAME ENDPOINTS AGE
api <none> 30mDiagnose and fix.
A 503 with kubectl get endpoints api empty means the Service has no ready backends, so kube-proxy cannot route. Two causes: the readiness probe never passes, so Pods stay 0/1 Running and out of the Service, or the Service selector misses the Pod labels.
- ✗Blaming the Ingress controller before checking the Service endpoints
- ✗Forgetting a not-Ready Pod is removed from the Service endpoints
- ✗Overlooking a Service selector that does not match the Pod labels
- →How does a readiness probe differ from a liveness probe in this failure?
- →What command compares a Service's selector against a running Pod's labels?
Contents
Solution
1. Walk the request path
Ingress → Service → Endpoints → Pod
$ kubectl get endpoints api # api <none> ← breaks hereendpoints is empty → the Service has no ready backends, so the Ingress returns 503 (no upstream). The break is between the Service and the Pods.
2. Two causes of empty endpoints
- Readiness never passes: Pods are
0/1 Running(as here) — a not-Ready Pod is excluded from endpoints. Checkdescribe pod→Readiness probe failed, fix the probe/app. - Selector mismatch:
Service.spec.selectordoes not match the Pods'metadata.labels— endpoints is then empty even when Pods are1/1 Ready.
3. Telling them apart, and the fix
$ kubectl get pod api-abc -o jsonpath='{.metadata.labels}' # Pod labels
$ kubectl get svc api -o jsonpath='{.spec.selector}' # selectorMatch but endpoints empty → readiness. Do not match → fix the selector/labels.
Contents