Kubernetes Service 가이드: 왜 필요하고 언제 써야 할까

Kubernetes Service 가이드: 왜 필요하고 언제 써야 할까


쿠버네티스를 처음 볼 때 Pod는 이해가 가는데 Service에서 한 번 멈추는 경우가 많습니다. Pod가 이미 앱을 실행하고 있는데 왜 또 Service가 필요한지 바로 감이 오지 않기 때문입니다.

하지만 실제 운영에서는 Pod만으로는 안정적인 접속 경로를 만들기 어렵습니다. Pod는 교체될 수 있고, IP도 바뀔 수 있고, 여러 개가 동시에 떠 있을 수도 있습니다. 이때 Service가 트래픽이 들어갈 “고정된 입구” 역할을 해 줍니다.

이 글에서는 아래 내용을 정리합니다.

  • Kubernetes Service가 무엇인지
  • Pod와 어떤 관계를 가지는지
  • ClusterIP, NodePort, LoadBalancer를 언제 쓰는지

핵심은 Service는 Pod 자체를 만드는 리소스가 아니라, Pod 집합에 안정적으로 접근하게 해 주는 네트워크 추상화라는 점입니다.

Kubernetes Service란 무엇인가

Service는 특정 label을 가진 Pod들을 하나의 네트워크 대상처럼 묶어 주는 리소스입니다. Pod가 교체되거나 수가 바뀌어도, 클라이언트는 계속 같은 Service 이름이나 IP로 접근할 수 있습니다.

예를 들어 백엔드 Pod가 3개 떠 있다면, Service는 이 Pod들을 하나의 논리적 엔드포인트처럼 보이게 합니다.

  • Pod는 실제 앱 인스턴스
  • Service는 그 인스턴스들 앞단의 안정적인 접근 지점

이 차이를 이해하면 “왜 Pod IP로 직접 접근하면 안 되는가”도 자연스럽게 보입니다.

왜 Pod만으로는 부족할까

Pod는 영구적인 서버가 아닙니다. Deployment가 새 버전을 배포하면 기존 Pod는 내려가고 새 Pod가 올라옵니다. 노드 장애가 나면 다른 노드로 옮겨질 수도 있습니다.

즉, 아래 문제가 생깁니다.

  • Pod IP가 바뀔 수 있다
  • Pod 개수가 늘거나 줄 수 있다
  • 어떤 Pod가 살아 있는지 매번 직접 찾기 어렵다

Service는 이 변화를 감추고, “지금 살아 있고 준비된 Pod들”로 트래픽을 보냅니다.

Service는 Pod를 어떻게 찾을까

보통은 selector를 사용합니다. Service는 selector와 일치하는 label을 가진 Pod를 endpoint로 잡습니다.

apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  selector:
    app: api
  ports:
    - port: 80
      targetPort: 8080

이 설정은 app: api 라벨을 가진 Pod들에 대해, Service의 80 포트를 Pod의 8080 포트로 연결한다는 뜻입니다.

여기서 중요한 점은 Service가 직접 Pod를 “생성”하지는 않는다는 점입니다. 단지 이미 존재하는 Pod 집합을 찾아서 연결합니다.

가장 자주 쓰는 Service 타입

1. ClusterIP

기본 타입입니다. 클러스터 내부에서만 접근 가능한 가상 IP를 제공합니다.

이런 경우에 자주 씁니다.

  • 프론트엔드 Pod가 백엔드 Pod를 호출할 때
  • 같은 클러스터 안의 다른 서비스와 통신할 때
  • 외부 공개가 필요 없는 내부 API일 때

입문 단계에서는 대부분 ClusterIP부터 이해하면 충분합니다.

2. NodePort

각 노드의 특정 포트를 열고, 그 포트로 들어온 요청을 Service로 전달합니다.

테스트나 간단한 실습에서는 보이지만, 실제 운영에서는 Ingress나 LoadBalancer 뒤에서 더 자주 가려집니다.

3. LoadBalancer

클라우드 환경에서 외부 로드밸런서를 붙여 Service를 외부에 노출할 때 씁니다.

AWS, GCP, Azure 같은 환경에서는 Service를 만들면 클라우드 로드밸런서가 함께 생성되는 패턴이 흔합니다.

port 와 targetPort 는 무엇이 다를까

초보자가 자주 헷갈리는 부분입니다.

  • port: Service가 받는 포트
  • targetPort: 실제 Pod 컨테이너가 듣는 포트

예를 들어 사용자는 Service의 80 포트로 접근하지만, 실제 컨테이너는 8080에서 앱이 떠 있을 수 있습니다.

ports:
  - port: 80
    targetPort: 8080

이 차이를 이해하지 못하면 Service는 정상인데 연결이 안 되는 상황을 자주 만나게 됩니다.

Service 와 Ingress 는 어떻게 다를까

둘 다 네트워크와 관련돼 있어서 자주 혼동됩니다.

  • Service: Pod 집합으로 트래픽을 보내는 내부 연결 단위
  • Ingress: 외부 HTTP 요청을 어떤 Service로 보낼지 라우팅하는 규칙

즉, Ingress는 대개 Service 앞단에 있고, Service는 Pod 앞단에 있습니다. 이 흐름을 한 줄로 보면 보통 이렇게 됩니다.

Client -> Ingress -> Service -> Pod

Ingress 쪽 개념은 Kubernetes Ingress 가이드에서 이어서 보면 좋습니다.

자주 하는 오해

1. Service가 있으면 무조건 외부에서 접근 가능하다

그렇지 않습니다. 기본 ClusterIP는 클러스터 내부 전용입니다.

2. Service가 있으면 Pod가 자동으로 생성된다

Service는 Pod를 만들지 않습니다. Deployment나 다른 workload 리소스가 따로 필요합니다.

3. label만 맞으면 항상 트래픽이 간다

실제로는 readiness 상태도 중요합니다. 준비되지 않은 Pod는 endpoint에 포함되지 않을 수 있습니다.

처음 공부할 때 추천하는 실습

아래 순서로 직접 만들어 보면 감이 빨리 잡힙니다.

  1. Deployment로 nginx Pod 2개 띄우기
  2. ServiceClusterIP로 만들기
  3. label을 일부러 틀려서 endpoint가 없어지는 상황 보기
  4. porttargetPort를 바꿔 보면서 연결 차이 보기

이 실습만 해도 Service가 “추상적인 네트워크 개념”이 아니라, 실제로 Pod 집합을 안정적으로 바라보게 만드는 도구라는 점이 훨씬 선명해집니다.

FAQ

Q. Pod 하나만 있어도 Service를 만들어야 하나요?

대개는 그렇습니다. 나중에 replica가 늘거나 Pod가 교체돼도 같은 접근 경로를 유지하기 쉬워집니다.

Q. Service가 라운드로빈을 하나요?

구현 세부는 환경에 따라 다르지만, 보통 여러 backend Pod로 트래픽을 분산하는 역할을 합니다.

Q. Service가 있는데 endpoint가 0개일 수 있나요?

그럴 수 있습니다. selector mismatch, unready pod, namespace 차이 등이 흔한 원인입니다. 이 경우는 Kubernetes Service Has No Endpoints를 이어서 보면 좋습니다.

먼저 읽어볼 가이드

검색 유입이 많은 핵심 글부터 이어서 보세요.