Chapter 13

파드를 사용하는 다른 오브젝트들

  • 13.1 잡(Job)
  • 13.2 데몬셋(DaemonSet)
  • 13.3 스테이트풀셋(StatefulSet)

모든 워크로드가 "항상 떠 있는 웹 서버" 형태는 아니잖아. 한 번 실행하고 끝나는 작업, 모든 노드에 하나씩 배포해야 하는 에이전트, 순서와 상태가 중요한 데이터베이스 — 각 상황에 맞는 오브젝트가 따로 있어.

**잡(Job)**은 한 번 실행하고 완료되면 끝나는 작업을 위한 오브젝트야. 디플로이먼트는 파드가 죽으면 다시 만들지만, 잡은 파드가 성공적으로 완료되면 더 이상 재시작하지 않아.

apiVersion: batch/v1
kind: Job
metadata:
  name: data-migration
spec:
  template:
    spec:
      containers:
        - name: migrate
          image: my-migration:1.0
          command: ["python", "migrate.py"]
      restartPolicy: Never
  backoffLimit: 3
  • restartPolicy: Never 또는 OnFailure야. Always는 Job에서 사용할 수 없어.
  • backoffLimit: 실패 시 재시도 횟수인데, 기본값은 6이야.
  • 파드가 성공적으로 완료되면(exit code 0) 잡은 Complete 상태가 돼.

병렬 잡도 가능해:

spec:
  completions: 5    # 총 5번 성공해야 완료
  parallelism: 2    # 동시에 2개씩 실행

데이터 처리, 배치 작업, DB 마이그레이션 같은 일회성 작업에 쓰지.

**크론잡(CronJob)**은 잡을 스케줄에 따라 반복 실행하는 오브젝트야:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: daily-backup
spec:
  schedule: "0 2 * * *"    # 매일 새벽 2시
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: backup
              image: my-backup:1.0
              command: ["sh", "-c", "backup.sh"]
          restartPolicy: OnFailure
  successfulJobsHistoryLimit: 3
  failedJobsHistoryLimit: 1

schedule은 리눅스 crontab과 같은 형식이야. successfulJobsHistoryLimit으로 완료된 잡 히스토리를 몇 개까지 보관할지 설정할 수 있지.

**데몬셋(DaemonSet)**은 모든 노드(또는 특정 노드)에 파드를 하나씩 배포하는 오브젝트야. 노드가 추가되면 자동으로 해당 노드에 파드가 생성되고, 노드가 제거되면 파드도 삭제돼.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: log-collector
spec:
  selector:
    matchLabels:
      app: log-collector
  template:
    metadata:
      labels:
        app: log-collector
    spec:
      containers:
        - name: fluentd
          image: fluentd:latest
          volumeMounts:
            - name: varlog
              mountPath: /var/log
      volumes:
        - name: varlog
          hostPath:
            path: /var/log

데몬셋의 대표적인 사용 사례를 보면:

  • 로그 수집: Fluentd, Filebeat 같은 로그 수집기. 모든 노드에서 로그를 수집해야 하니까.
  • 모니터링 에이전트: node-exporter, Datadog Agent. 노드 메트릭을 수집하지.
  • 네트워크 플러그인: kube-proxy, Calico, Flannel. CNI 플러그인은 모든 노드에 있어야 해.
  • 스토리지 데몬: Ceph, GlusterFS. 분산 스토리지 시스템이야.

특정 노드에만 배포하려면 nodeSelectornodeAffinity를 사용하면 돼:

spec:
  template:
    spec:
      nodeSelector:
        role: worker

데몬셋은 스케줄러를 거치지 않고 직접 파드를 배치하기 때문에, 노드의 Taint도 기본적으로 무시해 (tolerations가 자동 추가돼). 하지만 명시적으로 특정 Taint를 tolerate하도록 설정할 수도 있지.

**스테이트풀셋(StatefulSet)**은 상태가 있는(stateful) 애플리케이션을 위한 오브젝트야. 디플로이먼트와 비슷하지만, 파드에 고유한 정체성(identity)을 부여해.

디플로이먼트 vs 스테이트풀셋을 비교하면:

특성 디플로이먼트 스테이트풀셋
파드 이름 랜덤 (app-7d8f9c6b-x2k4j) 순번 (db-0, db-1, db-2)
스토리지 공유 또는 없음 각 파드에 고유한 PVC
시작/종료 순서 동시, 무순서 순차적 (0 → 1 → 2)
네트워크 ID 없음 (서비스로 접근) 고유 DNS (db-0.db-svc)
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: db
spec:
  serviceName: db-svc
  replicas: 3
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
        - name: postgres
          image: postgres:15
          volumeMounts:
            - name: data
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 10Gi

핵심 특징을 보면, 안정적인 네트워크 ID가 있어. serviceNameHeadless Service를 지정하면 각 파드에 고유한 DNS가 부여돼. db-0.db-svc.default.svc.cluster.local 형태지. 클러스터 구성에서 마스터/슬레이브를 구분할 때 이 DNS를 사용해.

apiVersion: v1
kind: Service
metadata:
  name: db-svc
spec:
  clusterIP: None    # Headless Service
  selector:
    app: db
  ports:
    - port: 5432

고유한 스토리지도 있어. volumeClaimTemplates로 각 파드에 별도의 PVC가 생성되거든. db-0data-db-0, db-1data-db-1 PVC를 가지지. 파드가 재시작되더라도 같은 PVC에 바인딩되니까 데이터가 보존돼.

순차적 관리도 중요해. 파드가 0, 1, 2 순서로 생성되고, 삭제는 2, 1, 0 역순이야. 스케일 업/다운도 순차적이지. 데이터베이스 클러스터에서 마스터가 먼저 뜨고 슬레이브가 그 다음에 뜨는 순서를 보장할 때 중요해.

스테이트풀셋이 필요한 대표적인 워크로드는 PostgreSQL/MySQL 클러스터, Elasticsearch, Kafka, ZooKeeper, Redis Cluster 같은 거야. 상태 없는 웹 서버나 API 서버라면 디플로이먼트를 쓰면 돼.


정리

13장 읽고 기억할 거 세 가지:

  1. 잡은 일회성 작업, 크론잡은 반복 작업이다. 완료되면 끝나는 배치 처리에 사용. restartPolicy가 Always가 아니어야 함.
  2. 데몬셋은 모든 노드에 하나씩 배포한다. 로그 수집, 모니터링 에이전트, 네트워크 플러그인 같은 노드 레벨 서비스에 사용.
  3. 스테이트풀셋은 파드에 고유한 정체성을 부여한다. 안정적인 네트워크 ID, 고유한 스토리지, 순차적 관리가 핵심. 데이터베이스 같은 stateful 워크로드에 사용.