Kubernetes Service

1. 정의 (Definition)

Kubernetes Service는 동적으로 생성되고 사라지는 파드(Pod) 집합에 고정된 IP 주소(ClusterIP)와 DNS 이름을 제공하여, 안정적인 네트워크 접근을 보장하는 추상화 객체입니다.

2. 등장 배경 (Problem Context)

  • 문제: 파드는 일회성(Ephemeral) 자원입니다. 스케일링이나 장애 복구로 인해 파드가 재생성되면 IP 주소가 바뀝니다. 클라이언트(프론트엔드 등)가 백엔드 파드의 IP를 하드코딩하거나 매번 추적하는 것은 불가능합니다.
  • 해결: 파드 앞단에 **변하지 않는 단일 진입점(VIP)**을 두고, 뒤단에 있는 파드들에게 트래픽을 로드 밸런싱해주는 역할이 필요했습니다.

3. 핵심 메커니즘 (How it Works)

3.1. Selector와 Endpoints

  1. Selector: 서비스는 selector 라벨(예: app: backend)과 일치하는 파드들을 지속적으로 감시합니다.
  2. Endpoints: 감시 결과(살아있는 파드의 IP 목록)를 Endpoints (또는 EndpointSlice) 객체에 실시간으로 업데이트합니다.
    • 조건: 파드가 Running 상태이고 Readiness Probe를 통과해야만 Endpoints에 포함됩니다.

3.2. kube-proxy와 iptables

모든 노드에 있는 kube-proxy가 이 Endpoints 변경을 감지하여 노드의 네트워크 규칙(iptables/IPVS)을 업데이트합니다.

  • 트래픽 흐름: Client Service IP (VIP) iptables (DNAT) Pod IP

4. 불변 조건과 보장 범위 (Invariants & Guarantees)

  • Stable IP: 서비스 객체를 삭제하고 다시 만들지 않는 한, 할당된 ClusterIP는 절대 변하지 않습니다.
  • Load Balancing: 서비스로 들어온 트래픽은 연결된 파드들에게 (기본적으로 랜덤하게) 분산됩니다.

5. 비유 (Analogy)

콜센터 대표 번호와 같습니다.

  • 고객(Client)은 상담원(Pod) 개개인의 직통 번호(Pod IP)를 알 필요가 없습니다.
  • 그냥 대표 번호(Service IP)로 걸면, 교환 시스템(kube-proxy)이 현재 통화 가능한(Ready) 상담원 중 한 명에게 전화를 연결해줍니다. 상담원이 퇴사하고 신입이 와도 대표 번호는 바뀌지 않습니다.

6. 실무적 함의 (Operational Implications)

  • 서비스 디스커버리: K8s 내부 DNS(my-svc.my-ns.svc.cluster.local)를 통해 서로를 찾습니다.
  • 트러블슈팅: “서비스로 연결이 안 돼요” 먼저 kubectl get endpoints <서비스명>을 확인하세요.
    • 결과가 <none>이면? Selector 설정이 잘못되었거나, 파드 라벨이 틀렸습니다.
    • IP는 있는데 연결이 안 되면? 파드 포트 설정이나 Readiness Probe 실패를 의심해야 합니다.

7. 주의사항 / 오해 (Pitfalls & Misconceptions)

  • “서비스는 로드 밸런서 장비다?”: 클라우드의 ELB(L4/L7)와 다릅니다. ClusterIP 서비스는 리눅스 커널의 netfilter(iptables) 규칙일 뿐, 실제 물리 장비나 별도 프로세스가 아닙니다. (핑이 안 갈 수도 있음)
  • “모든 파드에 균등하게 분배된다?”: iptables 모드에서는 확률적(Random) 로드 밸런싱이므로, 요청 수가 적을 때는 불균형할 수 있습니다.

8. References

References