Pod는 Running인데 Service로 트래픽이 안 간다면, 먼저 Endpoints를 본다
Pod가 Running이라는 건 “컨테이너가 떠 있다”는 뜻일 뿐, Service가 그 Pod로 트래픽을 보낸다는 보장이 아니다. Service와 Pod를 잇는 고리는 Endpoints(또는 EndpointSlice)이고, 트래픽이 안 가는 사례의 대부분은 이 목록이 비어 있다.
kubectl get endpoints <svc> -n <ns> # ENDPOINTS 가 <none> 이면 여기서 이미 끝난 문제다
Endpoints가 비었다면 — 원인은 둘 중 하나
- selector 불일치 — Service의
selector라벨이 Pod 라벨과 정확히 같아야 한다. 오타 한 글자, 값의 대소문자, 추가 라벨 하나로도 안 잡힌다.kubectl get pod --selector=<key=val>로 실제 잡히는지 확인한다. - readiness 미통과 — Pod가 Running이어도
readinessProbe를 통과하지 못하면 Endpoints에서 제외된다. describe pod의 Conditions에서Ready: False인지 본다. 이게 “Running인데 트래픽 안 감”의 가장 흔한 정체다.
Endpoints는 차 있는데도 안 된다면 — 포트와 바인딩
- targetPort ≠ 컨테이너 포트 — Service의
port는 클러스터 쪽 포트,targetPort는 컨테이너가 실제로 듣는 포트다. targetPort가 앱의 listen 포트와 다르면 연결이 검게 끊긴다. - 127.0.0.1 바인딩 — 앱이
0.0.0.0이 아니라 루프백에만 바인딩하면 Pod 밖에서 못 붙는다. Pod 안에서는 되는데 밖에서 안 되면 이걸 의심한다.
kubectl exec -it <pod> -n <ns> -- sh -c 'wget -qO- localhost:<port> || echo FAIL'
그래도 막히면 — 정책 계층
Endpoints·포트·바인딩이 다 맞는데 막히면 NetworkPolicy가 ingress를 차단하는지 본다. 정책이 하나라도 Pod를 선택하면 “기본 허용”이 “기본 차단”으로 바뀐다. 그 위 계층(Ingress 컨트롤러, 클라우드 LB 헬스체크)도 같은 readiness를 본다는 점을 기억한다.
확인 순서 한 줄 요약
get endpoints → (비었으면) selector·readiness → (차 있으면) targetPort·바인딩 → NetworkPolicy. 이 순서면 “Pod는 멀쩡한데 왜 안 되지”를 대부분 첫 두 단계에서 끝낸다.
빠른 진단 체크리스트
kubectl get endpoints가 비었는지부터 본다- 비었으면 Service selector가 Pod 라벨과 정확히 같은지 확인한다
- Running이어도 readiness 미통과면 Endpoints에서 빠진다
- describe pod의 Conditions에서 Ready: False 여부를 본다
- Endpoints가 찼으면 targetPort가 컨테이너 포트와 같은지 본다
- 앱이 0.0.0.0이 아니라 127.0.0.1에 바인딩했는지 확인한다
- Pod 안 curl은 되는데 밖이 안 되면 바인딩 주소를 의심한다
- 다 맞으면 NetworkPolicy가 ingress를 막는지 본다