학습 내용

쿠버네티스 컨트롤러 종류

ReplicationController, ReplicaSet, Deployment, DaemonSet, StatefulSet, Job, CronJob 총 7가지. 각 컨트롤러는 애플리케이션 특성에 맞춰 선택해서 사용한다.

6-1. ReplicationController

목표: 요구하는 Pod의 개수를 보장하며, Pod 집합의 실행을 항상 안정적으로 유지

  • 부족하면 → template를 이용해 Pod 추가
  • 초과하면 → 최근에 생성된 Pod를 삭제

기본 구성 3요소:

  • selector: 관리할 Pod를 식별하는 라벨 (별명/인식표 개념)
  • replicas: 유지할 Pod 개수
  • template: 새 Pod 생성 시 참조할 스펙

특징:

  • kubectl scale rc rc-nginx --replicas=2 로 즉시 스케일 조정 가능
  • kubectl edit rc rc-nginx 로 replicas 수정하면, 저장 즉시 반영 (controller가 계속 watching)
  • YAML에서 image 값을 바꿔도 실행 중인 Pod에는 영향 없음 → controller는 selector(라벨)만 보고 있으므로
  • replicas가 변경되어 새 Pod 생성 시에는 변경된 image가 적용됨

6-2. ReplicaSet

ReplicationController와 같은 역할이지만, 풍부한 selector를 지원한다.

matchExpressions 연산자:

  • In: key-value가 일치하는 Pod만 연결
  • NotIn: key는 일치하고 value는 일치하지 않는 Pod에 연결
  • Exists: key에 맞는 label의 Pod를 연결
  • DoesNotExist: key와 다른 label의 Pod를 연결

cascade 옵션: --cascade=orphan 으로 삭제하면 RS만 삭제되고 소속 Pod는 남겨짐

6-3. Deployment (RollingUpdate)

목적: ReplicaSet을 컨트롤해서 Pod 수를 조절 — Rolling Update & Rolling Back

롤링업데이트를 사용하지 않으면 ReplicaSet과 동일하게 동작한다.

롤링업데이트란? Pod 인스턴스를 점진적으로 새로운 것으로 업데이트하여, 서비스 중단 없이 배포가 이루어지도록 하는 방식.

strategy 주요 필드:

  • maxSurge: 25% — 롤링업데이트 시 replicas 대비 추가 생성 가능한 비율 (예: replicas=3이면 최대 4대 공존)
  • maxUnavailable: 25% — 업데이트 중 사용 불가능한 Pod 비율
  • revisionHistoryLimit: 10 — 이전 ReplicaSet 보존 개수
  • progressDeadlineSeconds: 600 — 업데이트 완료 제한 시간

annotation 역할: kubernetes.io/change-cause 에 변경 사유를 기록하면 rollout history에 표시됨

주요 명령어:

kubectl rollout history deployment deploy-nginx          # 업데이트 이력 출력
kubectl set image deployment app-deploy web=nginx:1.15 --record  # 이미지 교체 + 이력 기록
kubectl rollout undo deployment app-deploy               # 바로 전 단계로 롤백
kubectl rollout undo deployment --to-revision=3          # 특정 리비전으로 롤백

주의: undo를 반복해도 계속 과거로 가는 것이 아니라, 바로 이전 단계로 전환됨. --to-revision으로 롤백하면 해당 리비전이 history 마지막으로 이동.

6-4. DaemonSet

  • 전체 노드에서 Pod가 한 개씩 실행되도록 보장
  • 노드 당 1개를 보장하므로 replicas 설정이 필요 없음
  • 활용 예시: 로그 수집기, 모니터링 에이전트
  • 롤링업데이트, 롤백 기능 제공

6-5. StatefulSet

  • Pod의 상태를 유지해주는 컨트롤러
  • 일반 Pod: 이름 뒤에 hash값 (랜덤) → StatefulSet: 0, 1, 2 ordinal하게 생성
  • 1번 Pod가 삭제되면, 1번 Pod가 다시 생성됨 (어떤 노드에 배치될지는 랜덤)
  • replicas를 줄이면 큰 번호부터 삭제
  • serviceName 필드가 필수 — Headless Service와 함께 사용하면 Pod별 고정 DNS를 가질 수 있음
  • podManagementPolicy: OrderedReady(순차 생성, 기본값) / Parallel(동시 생성)

6-6. Job Controller

  • Pod의 성공적인 완료를 보장
  • 비정상 종료 → 재실행(restart), 정상 종료 → 완료(end) — 완료되어도 Pod를 삭제하지 않음 (작업완료 상태)
  • Batch 처리에 적합

YAML 주요 필드:

  • restartPolicy: OnFailure — 실패 시 컨테이너를 재실행
  • restartPolicy: Never — 실패 시 새 Pod를 생성하여 재실행
  • backoffLimit — 재실행 시도 횟수
  • completions — 총 성공해야 하는 횟수
  • parallelism — 동시 실행 개수
  • activeDeadlineSeconds — 지정 시간 내 완료되지 않으면 종료

쿠버네티스는 기본적으로 Pod를 running 상태로 유지하려 하므로, 1회성 배치 처리가 필요할 때 Job을 사용한다.

6-7. CronJob

  • 사용자가 원하는 시간에 Job 실행 예약
  • Linux cronjob 스케줄링 + Job Controller
  • 활용 예시: 데이터 백업, 이메일 전송, 작업 내역 삭제

schedule 형식: 분 시 일 월 요일 (예: 0 9 1 * * = 매월 1일 아침 9시)

주요 필드:

  • startingDeadlineSeconds: 500 — 500초 안에 실행하지 못하면 취소
  • concurrencyPolicy: Allow — 동시에 여러 Job 실행 허용
  • concurrencyPolicy: Forbid — 동시 실행 금지

실습 예제 (GitHub 237summit)

ReplicationController — rc-nginx.yaml

apiVersion: v1
kind: ReplicationController
metadata:
  name: rc-nginx
spec:
  replicas: 3
  selector:
    app: webui
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14

ReplicationController 실습 — rc-lab1.yaml

apiVersion: v1
kind: ReplicationController
metadata:
  name: rc-main
spec:
  replicas: 2
  selector:
    app: main
    name: apache
    rel: stable
  template:
    metadata:
      labels:
        app: main
        name: apache
        rel: stable
    spec:
      containers:
      - name: webui
        image: httpd:2.2
        ports:
        - containerPort: 80

ReplicaSet 기본 — rs-nginx.yaml

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

ReplicaSet matchExpressions — rs-exam1.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: rs-exam1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webui
    matchExpressions:
    - {key: ver, operator: Exists}
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
        ver: "1.15"
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14

Deployment 기본 — deploy-nginx.yaml

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

Deployment 롤링업데이트 — deployment-exam2.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
  annotations:
    kubernetes.io/change-cause: version 1.15
spec:
  progressDeadlineSeconds: 600
  revisionHistoryLimit: 10
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  replicas: 3
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      labels:
        app: webui
    spec:
      containers:
      - name: web
        image: nginx:1.15
        ports:
        - containerPort: 80

DaemonSet — daemonset-exam.yaml

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

StatefulSet — statefulset-exam.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sf-nginx
spec:
  replicas: 3
  serviceName: sf-service
  podManagementPolicy: Parallel
  selector:
    matchLabels:
      app: webui
  template:
    metadata:
      name: nginx-pod
      labels:
        app: webui
    spec:
      containers:
      - name: nginx-container
        image: nginx:1.14

Job — job-exam.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: centos-job
spec:
#  completions: 5
#  parallelism: 2
  activeDeadlineSeconds: 5
  template:
    spec:
      containers:
      - name: centos-container
        image: centos:7
        command: ["bash"]
        args:
        - "-c"
        - "echo 'Hello World'; sleep 25; echo 'Bye'"
      restartPolicy: Never
#      restartPolicy: OnFailure
#  backoffLimit: 3

CronJob — cronjob-exam.yaml

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: cronjob-exam
spec:
  schedule: "* * * * *"
  startingDeadlineSeconds: 500
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - echo Hello; sleep 10; echo Bye
          restartPolicy: Never

핵심 정리

  • Controller = Pod 개수 보장자. selector로 라벨을 보고, replicas 수를 유지한다.
  • ReplicaSet > ReplicationController. matchExpressions로 더 유연한 셀렉터를 지원.
  • Deployment = ReplicaSet + 롤링업데이트/롤백. annotation의 change-cause가 history에 기록됨.
  • DaemonSet = 노드당 1개. 모니터링/로그 수집에 적합.
  • StatefulSet = ordinal 이름 보장 + 볼륨 유지. Headless Service와 같이 사용.
  • Job = 1회성 배치. restartPolicy(OnFailure vs Never)에 따라 재시작 방식이 다름.
  • CronJob = Job + 스케줄. concurrencyPolicy로 동시 실행 제어.

체크리스트

  • RC → RS → Deployment 계층 관계를 설명할 수 있는가?
  • 롤링업데이트 시 maxSurge / maxUnavailable 동작을 이해했는가?
  • StatefulSet의 ordinal 이름 보장과 삭제 순서를 이해했는가?
  • Job의 restartPolicy OnFailure vs Never 차이를 설명할 수 있는가?
  • CronJob schedule 문법(분 시 일 월 요일)을 외웠는가?

참고 링크