Post

Part 8/26: Deployment와 롤링 업데이트

Part 8/26: Deployment와 롤링 업데이트

1. ReplicaSet

1.1 ReplicaSet이란?

원문 (kubernetes.io - ReplicaSet): A ReplicaSet’s purpose is to maintain a stable set of replica Pods running at any given time. As such, it is often used to guarantee the availability of a specified number of identical Pods.

번역: ReplicaSet의 목적은 언제든지 안정적인 복제본 Pod 집합을 유지하는 것이다. 따라서 지정된 수의 동일한 Pod의 가용성을 보장하는 데 자주 사용된다.

flowchart TB
    subgraph rs["ReplicaSet (spec.replicas: 3)"]
        pod1["Pod 1<br/>app=nginx"]
        pod2["Pod 2<br/>app=nginx"]
        pod3["Pod 3<br/>app=nginx"]
    end

    controller["Controller: 항상 3개 유지<br/>- Pod 죽으면 자동 생성<br/>- Pod 초과 시 삭제"]

    rs --> controller

1.2 ReplicaSet 동작

ReplicaSet Controller는 Control Loop를 통해 작동한다:

  1. Label Selector에 매칭되는 Pod 목록 조회
  2. 현재 Pod 수와 desired replicas 비교
  3. 부족하면 Pod 생성, 초과하면 Pod 삭제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx        # selector와 일치해야 함
    spec:
      containers:
      - name: nginx
        image: nginx:1.21

1.3 왜 ReplicaSet을 직접 사용하지 않는가?

ReplicaSet은 직접 사용하기보다 Deployment를 통해 관리하는 것이 권장된다.

ReplicaSet의 한계:

  • 롤링 업데이트 기능 없음
  • 이미지 변경 시 Pod이 자동 교체되지 않음
  • 롤백 기능 없음

Deployment가 제공하는 기능:

  • 롤링 업데이트
  • 롤백
  • 일시 중지/재개
  • 리비전 히스토리

2. Deployment

2.1 Deployment란?

원문 (kubernetes.io - Deployments): A Deployment provides declarative updates for Pods and ReplicaSets. You describe a desired state in a Deployment, and the Deployment Controller changes the actual state to the desired state at a controlled rate.

번역: Deployment는 Pod와 ReplicaSet에 대한 선언적 업데이트를 제공한다. Deployment에서 원하는 상태를 설명하면 Deployment Controller가 제어된 속도로 실제 상태를 원하는 상태로 변경한다.

Deployment는 ReplicaSet을 관리하면서 선언적 업데이트를 제공하는 상위 컨트롤러다.

flowchart TB
    subgraph deploy["Deployment"]
        subgraph rs["ReplicaSet"]
            pod1["Pod"]
            pod2["Pod"]
            pod3["Pod"]
        end
        features["<b>제공 기능</b><br/>- 롤링 업데이트 / 롤백<br/>- 일시 중지 / 재개<br/>- 스케일링<br/>- 리비전 히스토리"]
    end

2.2 Deployment 정의

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 200m
            memory: 256Mi

2.3 Deployment 계층 구조

flowchart TB
    deploy["Deployment<br/>(nginx-deployment)"]
    rs["ReplicaSet<br/>(nginx-deployment-6b9f7c8d5)"]
    pod1["Pod<br/>(nginx-deployment-6b9f7c8d5-abc12)"]
    pod2["Pod<br/>(nginx-deployment-6b9f7c8d5-def34)"]
    pod3["Pod<br/>(nginx-deployment-6b9f7c8d5-ghi56)"]

    deploy --> rs
    rs --> pod1
    rs --> pod2
    rs --> pod3

이미지가 변경되면 새 ReplicaSet이 생성된다:

flowchart TB
    deploy["Deployment<br/>(nginx-deployment)"]
    rsOld["ReplicaSet (구버전)<br/>(nginx-deployment-6b9f7c8d5)<br/>replicas=0"]
    rsNew["ReplicaSet (신버전)<br/>(nginx-deployment-7c9a8d6e4)<br/>replicas=3"]
    pod1["Pod (...)"]
    pod2["Pod (...)"]
    pod3["Pod (...)"]

    deploy --> rsOld
    deploy --> rsNew
    rsNew --> pod1
    rsNew --> pod2
    rsNew --> pod3

3. 롤링 업데이트

3.1 롤링 업데이트란?

원문 (kubernetes.io - Deployment Strategy): The Deployment updates Pods in a rolling update fashion when .spec.strategy.type==RollingUpdate. You can specify maxUnavailable and maxSurge to control the rolling update process. Max Unavailable specifies the maximum number of Pods that can be unavailable during the update. Max Surge specifies the maximum number of Pods that can be created over the desired number of Pods.

번역: Deployment는 .spec.strategy.type==RollingUpdate일 때 롤링 업데이트 방식으로 Pod을 업데이트한다. maxUnavailablemaxSurge를 지정하여 롤링 업데이트 프로세스를 제어할 수 있다. Max Unavailable은 업데이트 중 사용 불가능할 수 있는 최대 Pod 수를 지정한다. Max Surge는 원하는 Pod 수를 초과하여 생성할 수 있는 최대 Pod 수를 지정한다.

롤링 업데이트는 기존 Pod을 순차적으로 새 Pod으로 교체하는 배포 방식이다. 서비스 중단 없이 배포할 수 있다.

flowchart TB
    step1["Step 1: v1 v1 v1<br/>(3개 모두 v1)"]
    step2["Step 2: v1 v1 v2<br/>(v2 생성, v1 삭제)"]
    step3["Step 3: v1 v2 v2"]
    step4["Step 4: v2 v2 v2<br/>(v2 완료)"]

    step1 --> step2 --> step3 --> step4

3.2 업데이트 전략 설정

1
2
3
4
5
6
spec:
  strategy:
    type: RollingUpdate       # 기본값
    rollingUpdate:
      maxSurge: 1             # 추가로 생성할 수 있는 Pod 수
      maxUnavailable: 1       # 동시에 사용 불가능한 Pod 수

maxSurge:

  • 원하는 replicas 수를 초과하여 생성할 수 있는 Pod 수
  • 숫자 또는 백분율 (예: 25%)
  • 값이 클수록 빠른 배포, 더 많은 리소스 사용

maxUnavailable:

  • 업데이트 중 사용 불가능할 수 있는 Pod 수
  • 숫자 또는 백분율
  • 값이 클수록 빠른 배포, 가용성 감소

예시 시나리오 (replicas=10):

설정동작
maxSurge=2, maxUnavailable=0최대 12개까지 생성 가능, 항상 10개 Ready
maxSurge=0, maxUnavailable=2항상 10개 유지, 8개만 Ready 보장
maxSurge=25%, maxUnavailable=25%최대 13개, 최소 8개 Ready

3.3 Recreate 전략

모든 기존 Pod을 삭제한 후 새 Pod을 생성한다. 다운타임이 발생한다.

1
2
3
spec:
  strategy:
    type: Recreate

사용 사례:

  • 여러 버전 공존이 불가능한 경우
  • 스토리지 마이그레이션이 필요한 경우
  • 개발/테스트 환경

4. 롤아웃 관리

4.1 롤아웃 상태 확인

1
2
3
4
5
6
7
8
# 롤아웃 상태 실시간 확인
kubectl rollout status deployment/nginx-deployment

# 롤아웃 히스토리
kubectl rollout history deployment/nginx-deployment

# 특정 리비전 상세 정보
kubectl rollout history deployment/nginx-deployment --revision=2

4.2 이미지 업데이트

1
2
3
4
5
6
7
8
9
10
11
# 방법 1: kubectl set image
kubectl set image deployment/nginx-deployment nginx=nginx:1.22

# 방법 2: kubectl edit
kubectl edit deployment nginx-deployment

# 방법 3: kubectl patch
kubectl patch deployment nginx-deployment -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx:1.22"}]}}}}'

# 방법 4: YAML 수정 후 apply (권장)
kubectl apply -f deployment.yaml

4.3 롤백

원문 (kubernetes.io - Rolling Back a Deployment): Sometimes, you may want to rollback a Deployment; for example, when the Deployment is not stable, such as crash looping. By default, all of the Deployment’s rollout history is kept in the system so that you can rollback anytime you want.

번역: 때때로 Deployment를 롤백하고 싶을 수 있다. 예를 들어 Deployment가 크래시 루프와 같이 안정적이지 않을 때다. 기본적으로 Deployment의 모든 롤아웃 히스토리가 시스템에 보관되므로 원하는 시점으로 언제든지 롤백할 수 있다.

1
2
3
4
5
# 바로 이전 버전으로 롤백
kubectl rollout undo deployment/nginx-deployment

# 특정 리비전으로 롤백
kubectl rollout undo deployment/nginx-deployment --to-revision=2

4.4 롤아웃 일시 중지/재개

대규모 변경 시 롤아웃을 일시 중지하고 여러 변경을 적용한 후 재개할 수 있다:

1
2
3
4
5
6
7
8
9
# 일시 중지
kubectl rollout pause deployment/nginx-deployment

# 여러 변경 적용 (각 변경이 개별 롤아웃을 트리거하지 않음)
kubectl set image deployment/nginx-deployment nginx=nginx:1.22
kubectl set resources deployment/nginx-deployment -c nginx --limits=cpu=200m,memory=256Mi

# 재개 (한 번의 롤아웃으로 모든 변경 적용)
kubectl rollout resume deployment/nginx-deployment

4.5 변경 원인 기록

롤아웃 히스토리에 변경 원인을 기록하려면:

1
2
3
4
5
# 방법 1: --record 플래그 (deprecated)
kubectl set image deployment/nginx-deployment nginx=nginx:1.22 --record

# 방법 2: annotation 직접 설정 (권장)
kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="Update to nginx 1.22"

5. 스케일링

5.1 수동 스케일링

1
2
3
4
5
# replicas 변경
kubectl scale deployment/nginx-deployment --replicas=5

# 조건부 스케일링 (현재 replicas가 3일 때만)
kubectl scale deployment/nginx-deployment --replicas=5 --current-replicas=3

5.2 YAML로 스케일링

1
2
spec:
  replicas: 5    # 값 변경
1
kubectl apply -f deployment.yaml

6. Deployment 상태

6.1 Deployment Conditions

1
kubectl get deployment nginx-deployment -o yaml
1
2
3
4
5
6
7
8
status:
  conditions:
  - type: Available
    status: "True"
    reason: MinimumReplicasAvailable
  - type: Progressing
    status: "True"
    reason: NewReplicaSetAvailable
Condition의미
Available최소 가용 Pod 수 충족
Progressing롤아웃 진행 중 또는 완료

6.2 진행 데드라인

롤아웃이 지정된 시간 내에 완료되지 않으면 실패로 간주:

1
2
spec:
  progressDeadlineSeconds: 600  # 기본값: 600초 (10분)

7. 면접 빈출 질문

Q1. Deployment와 ReplicaSet의 차이는?

ReplicaSet:

  • Pod 복제본 수 유지
  • 단순히 replicas 수만 관리
  • 이미지 변경해도 기존 Pod이 자동 교체되지 않음

Deployment:

  • ReplicaSet을 관리하는 상위 컨트롤러
  • 롤링 업데이트, 롤백 제공
  • 이미지 변경 시 새 ReplicaSet 생성하여 롤링 업데이트
  • 리비전 히스토리 관리

실무에서는 거의 항상 Deployment를 사용한다.

Q2. maxSurge와 maxUnavailable을 설명해라

maxSurge:

  • 롤링 업데이트 중 desired replicas를 초과하여 생성할 수 있는 Pod 수
  • 값이 크면: 빠른 배포, 더 많은 리소스 사용

maxUnavailable:

  • 롤링 업데이트 중 사용 불가능할 수 있는 Pod 수
  • 값이 크면: 빠른 배포, 가용성 감소

둘 다 0일 수는 없다 (무한 대기 상태).

Q3. 롤백은 어떻게 동작하는가?

  1. Deployment는 이전 ReplicaSet들을 보관 (revisionHistoryLimit까지)
  2. kubectl rollout undo 실행
  3. 이전 ReplicaSet의 replicas를 증가
  4. 현재 ReplicaSet의 replicas를 감소
  5. 롤링 업데이트와 동일한 방식으로 교체
1
2
spec:
  revisionHistoryLimit: 10  # 보관할 이전 ReplicaSet 수 (기본값: 10)

Q4. Pod Template이 변경되지 않으면 롤아웃이 트리거되는가?

아니다. Deployment는 spec.template이 변경될 때만 롤아웃을 트리거한다.

다음 변경은 롤아웃을 트리거하지 않는다:

  • spec.replicas 변경 (스케일링만)
  • metadata.labels 변경
  • metadata.annotations 변경

8. CKA 실습

8.1 Deployment 생성

1
2
3
4
5
# 명령형
kubectl create deployment nginx --image=nginx:1.21 --replicas=3

# YAML 생성 (dry-run)
kubectl create deployment nginx --image=nginx:1.21 --replicas=3 --dry-run=client -o yaml > deployment.yaml

8.2 롤링 업데이트 실습

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Deployment 생성
kubectl create deployment nginx --image=nginx:1.21 --replicas=3

# 롤아웃 상태 확인 (다른 터미널)
kubectl rollout status deployment/nginx -w

# 이미지 업데이트
kubectl set image deployment/nginx nginx=nginx:1.22

# 변경 원인 기록
kubectl annotate deployment/nginx kubernetes.io/change-cause="Update to nginx 1.22"

# 히스토리 확인
kubectl rollout history deployment/nginx

8.3 롤백 실습

1
2
3
4
5
6
7
8
9
10
11
# 잘못된 이미지로 업데이트
kubectl set image deployment/nginx nginx=nginx:invalid-tag

# 롤아웃 상태 확인 (실패)
kubectl rollout status deployment/nginx

# 롤백
kubectl rollout undo deployment/nginx

# 또는 특정 리비전으로
kubectl rollout undo deployment/nginx --to-revision=1

8.4 전략 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# rolling-update.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.21

정리

주요 개념 체크리스트

  • ReplicaSet의 역할과 한계
  • Deployment가 ReplicaSet을 관리하는 방식
  • 롤링 업데이트와 Recreate 전략
  • maxSurge와 maxUnavailable의 의미
  • 롤아웃 관리 (상태 확인, 일시 중지, 롤백)
  • 변경 원인 기록

다음 포스트

Part 9: StatefulSet과 DaemonSet에서는 상태가 있는 애플리케이션과 노드별 배포를 다룬다.


참고 자료

This post is licensed under CC BY 4.0 by the author.