파드는 Running인데 Service 주소로 호출하면 connection refused나 타임아웃이 납니다. 이때 범인은 거의 항상 트래픽이 흐르는 경로 어딘가에서 라벨이나 포트가 어긋난 것입니다. Service → Endpoints → 파드, 또는 Ingress → Service 순서로 한 칸씩 확인하면 끊긴 지점이 드러납니다.
1단계 — Service가 파드를 실제로 잡고 있나
Kubernetes
kubectl get endpoints <service>
여기서 ENDPOINTS가 <none>이면 Service의 selector가 어떤 파드도 못 잡은 것입니다. 이게 가장 흔한 원인입니다.
Kubernetes
kubectl get svc <service> -o yaml | grep -A3 selector
kubectl get pods --show-labels
selector의 라벨과 파드의 라벨이 글자 하나까지 같은지 비교합니다. app: web vs app: web-server처럼 미묘하게 다른 경우가 많습니다.
2단계 — 포트가 맞물려 있나
Kubernetes
kubectl get svc <service> -o yaml
확인할 세 포트의 관계:
- Service의
port— 클라이언트가 호출하는 포트 - Service의
targetPort— 파드 컨테이너가 실제로 듣는 포트 - 컨테이너의
containerPort— 앱이 bind한 포트
targetPort가 앱이 실제로 듣는 포트와 다르면 endpoints는 있어도 연결이 거부됩니다. 클러스터 안에서 직접 때려 봅니다.
Kubernetes
kubectl run tmp --rm -it --image=busybox -- sh
wget -qO- http://<service>.<namespace>:<port>/
3단계 — 원인별 정리
| 증상 | 원인 | 해결 |
|---|---|---|
endpoints <none> | selector·라벨 불일치 | 라벨 양쪽 일치시키기 |
| endpoints 있는데 거부 | targetPort≠앱 포트 | targetPort 수정 |
| 클러스터 안은 되는데 밖에서 안 됨 | Service type이 ClusterIP | NodePort/LoadBalancer 또는 Ingress |
| Ingress 404/503 | Ingress의 service.name·port 오타 | backend 매핑 확인 |
4단계 — Ingress 경로 확인
Kubernetes
kubectl describe ingress <ingress>
describe의 Default backend나 rules에서 backend Service 이름·포트가 1·2단계에서 확인한 Service와 정확히 일치하는지 봅니다. 503이면 보통 Ingress가 가리키는 Service의 endpoints가 비어 있는 것이니 1단계로 되돌아갑니다.
체크리스트
Kubernetes
kubectl get endpoints <service> # 비어 있으면 selector 문제
kubectl get svc <service> -o yaml # port/targetPort 확인
kubectl run tmp --rm -it --image=busybox -- wget -qO- http://<service>:<port>
kubectl describe ingress <ingress> # backend 매핑
endpoints → 포트 → Ingress 순서만 지키면 끊긴 칸이 바로 보입니다.
Service와 Ingress를 직접 연결해 보며 끊기는 지점을 손으로 고쳐 보는 실습은 쿠버네티스 트랙에서 회원가입 없이 무료로 할 수 있습니다.