학습 내용

7-1. 쿠버네티스 Service 개념과 종류

Service란? 동일한 서비스를 제공하는 Pod 그룹의 **단일 진입점(Virtual IP)**을 제공하는 리소스. Pod들의 label을 기준으로 하나로 묶어 Virtual IP를 만든다.

“쿠버야, web-ui 파드들을 하나의 IP로 묶어서 관리해줘!”

Service 4가지 타입:

  1. ClusterIP (default) — Pod 그룹의 단일 진입점(Virtual IP) 생성. 클러스터 내부에서만 접근 가능.
  2. NodePort — ClusterIP가 생성된 후, 모든 Worker Node에 외부에서 접속 가능한 포트를 예약. 외부 트래픽 → 노드의 nodePort → ClusterIP → Pod.
  3. LoadBalancer — 클라우드 환경(AWS, GCP, OpenStack 등)에서 LoadBalancer를 자동 프로비전하는 기능 지원.
  4. ExternalName — 클러스터 안에서 사용할 도메인을 정의. 클러스터 도메인이 실제 외부 도메인으로 치환되어 동작 (DNS CNAME과 유사).

7-3. Headless Service와 Kube Proxy

Headless Service:

  • clusterIP: None으로 설정하는 서비스
  • 단일 진입점이 필요 없을 때 사용
  • Service와 연결된 Pod의 endpoint로 CoreDNS에 A 레코드가 직접 생성됨
  • Pod의 DNS 주소: pod-ip-addr.namespace.pod.cluster.local
  • StatefulSet처럼 Pod 이름이 보존되는 컨트롤러와 함께 사용하면 유용

kube-proxy:

  • 쿠버네티스 서비스의 backend 구현을 담당
  • endpoint 연결을 위한 iptables 구성
  • nodePort로의 접근과 Pod 연결을 구현
  • 모든 노드(컨트롤 플레인 + 워커노드)에서 동작 중인 Pod

kube-proxy 동작 방식:

  • userspace: 초기 버전에서 사용 (현재 미사용)
  • iptables (default): kube-proxy가 Service API 요청 시 iptables rule 생성. 클라이언트 연결은 kube-proxy가 받아서 iptables 룰을 통해 연결
  • IPVS: 리눅스 커널의 L4 로드밸런싱 기술 활용. 별도 ipvs 지원 모듈 설정 후 적용 가능

실습 예제 (GitHub 237summit)

테스트용 Deployment — deploy-nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webui
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14

ClusterIP Service — clusterip-nginx.yaml

apiVersion: v1
kind: Service
metadata:
  name: clusterip-service
spec:
  type: ClusterIP
  clusterIP: 10.100.100.100
  selector:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

NodePort Service — nodeport-nginx.yaml

apiVersion: v1
kind: Service
metadata:
  name: nodeport-service
spec:
  type: NodePort
  clusterIP: 10.100.100.200
  selector:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30200

LoadBalancer Service — loadbalancer-nginx.yaml

apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service
spec:
  type: LoadBalancer
  selector:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

ExternalName Service — external-name.yaml

apiVersion: v1
kind: Service
metadata:
  name: externalname-svc
spec:
  type: ExternalName
  externalName: google.com

Headless Service — headless-nginx.yaml

apiVersion: v1
kind: Service
metadata:
  name: headless-service
spec:
  type: ClusterIP
  clusterIP: None
  selector:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

기본 Service (type 생략=ClusterIP) — service-nginx.yaml

apiVersion: v1
kind: Service
metadata:
  name: webui-svc
spec:
  selector:
    app: webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

핵심 정리

  • Service는 Pod 그룹의 단일 진입점. label selector로 대상 Pod를 결정하고, Virtual IP를 부여한다.
  • ClusterIP → NodePort → LoadBalancer 순으로 확장. NodePort는 ClusterIP를 포함하고, LoadBalancer는 NodePort를 포함한다.
  • Headless Service는 clusterIP: None. Pod의 개별 IP가 DNS에 직접 등록되어, StatefulSet과 궁합이 좋다.
  • kube-proxy는 iptables 룰로 서비스 라우팅을 구현. 모든 노드에서 동작하며, Service API 변경 시 자동으로 룰이 갱신됨.

체크리스트

  • Service 4가지 타입의 차이와 포함 관계를 설명할 수 있는가?
  • Headless Service가 필요한 상황을 설명할 수 있는가?
  • kube-proxy의 iptables 모드 동작 원리를 이해했는가?
  • nodePort 범위(30000-32767)를 알고 있는가?

참고 링크