본문 바로가기

CKA

[k8s] Service : selector / endpoints / (port, targetPort)

728x90
Kubernetes Service는 "Pod는 IP가 자주 바뀌니까, 고정된 접속 지점(가상 IP/DNS)을 만들고 뒤에 Pod들을 붙여주는" 리소스다.

용어정리

selector

  • Service가 "어떤 Pod들을 내 뒤에 붙일지" 고르는 라벨 조건
  • spec.selector에 들어감

endpoints / endpointslice

  • selector로 선택된 Pod들이 실제로 연결된 결과 목록 (Pod IP:Port)
  • 즉, "Service 뒤에 누가 붙어 있는지"를 보여주는 실체
  • kubectl get endpoints 또는 kubectl get endpointslice로 확인

port / targetPort

  • port: 클러스터 내부에서 Service가 받는 포트
  • targetPort: Pod(컨테이너)로 실제 전달되는 포트
  • 예: 서비스는 80으로 받고 > Pod는 8080으로 받게 라우팅 가능

구조 예시(가장 흔한 패턴)

apiVersion: v1
kind: Service
metadata:
  name: web-svc
spec:
  selector:
    app: web
  ports:
  - name: http
    port: 80
    targetPort: 8080

디버깅 루틴 핵심 결론

Service 장애는 대부분 아래 줄 중 하나로 갈린다:

  • Case A: endpoints가 비어있다 → selector/label 불일치
  • Case B: endpoints는 있는데 접속이 안된다 → targetPort(또는 앱 리슨 포트) 불일치

Case A) selector 라벨이 안 맞아서 endpoints가 비는 케이스

증상

  • Service는 존재함
  • 근데 kubectl get endpoints web-svc가 <none> 또는 비어있음
  • Service DNS로 curl 치면 timout / 연결 실패

확인 순서

kubectl describe svc web-svc	# selector 확인
kubectl get pod --show-labels	# Pod 라벨 확인
kubectl get pod -l app=web		# selector로 Pod가 실제 잡히는지
kubectl get endpoints web-svc -o wide	# endpoints가 비어있는지
kubectl get endpointslice -l kubernetes.io/service-name=web-svc

 

대표 원인

  • Service selector: app=web
  • Pod label app=wep(오타), app=web-v2 (불일치), label 자체 없음

해결

  • Pod 라벨을 Service selector에 맞추거나
  • Service selector를 실제 Pod 라벨에 맞춘다
kubectl label pod <pod-name> app=web --overwrite

Case B) endpoints는 있는데 targetPort가 틀린 케이스

증상

  • kubectl get endpoints web-svc에서 Pod IP가 찍힘 (selector OK)
  • 근데 접속하면 connectin refused가 많이 뜸

확인 순서

1) Service 포트 매핑 확인

kubectl describe svc web-svc
# Port: 80/TCP
# TargetPort: 80/TCP	<- 여기랑 실제 앱 포트가 맞는지 확인

 

2) Pod가 실제로 어떤 포트로 리슨 중인지 확인

  • 가장 확실: Pod 안에서 확인
kubectl exec -it <pod-name> -- sh
ss -lntp || netstat -lntp

 

3) Service로 직접 테스트 (클러스터 내부에서)

kubectl run tmp --rm -it --image=curlimages/curl:8.5.0 -- sh
curl -v http://web-svc:80

 

대표 원인 1) 앱은 8080인데 targetPort가 80

해결: targetPort를 8080으로

ports:
- port: 80
  targetPort: 8080

 

대표 원인 2) targetPort를 "이름"으로 썼는데 Pod 쪽 이름이 다름

예: Service가 targetPort: http 인데 Pod containerPort 이름이 web라면 매칭 실패 가능

해결: 이름을 통일

# Pod/Deployment
ports:
- name: http
  containerPort: 8080

# Service
targetPort: http

3) 디버깅 요약 체크리스트

Service가 선택한 Pod가 있는가?

kubectl describe svc <svc>
kubectl get pod -l <selector>

 

endpoints가 비어있는가?

kubectl get endpoints <svc>
kubectl get endpointslice -l kubernetes.io/service-name=<svc>

 

클러스터 내부에서 서비스 DNS로 직접 찍어봤는가?

kubectl run tmp --rm -it --image=curlimages/curl:8.5.0 -- sh
curl -v http://<svc>:<port>

 

728x90