:bulb: K8s 업데이트 전략은 두 추상화 층위로 분리해서 보아야 정확히 이해된다 — K8s API의 update strategy(RollingUpdate/Recreate/OnDelete)와 배포 패턴(Rolling/Blue-Green/Canary). NVIDIA Driver Operator 같은 host kernel 결합 워크로드 케이스까지 포함하여 정리한다.


[01] Rolling Update 개요

K8s의 기본 무중단 배포 전략. Deployment의 Pod를 점진적으로 교체하여 두 버전이 일시적으로 공존하다가 최종적으로 새 버전으로 완전히 전환된다.

1-1. 동작 방식

새 ReplicaSet을 생성하고, 기존 ReplicaSet의 Pod를 줄이면서 새 Pod를 늘려가는 방식이다.

graph LR
    OLD["ReplicaSet v1
(10 Pods)"] -->|점진 감소| MID["v1: 8 / v2: 4
(공존)"] MID -->|점진 교체| NEW["ReplicaSet v2
(10 Pods)"] style OLD fill:#ffcccc,stroke:#c62828 style MID fill:#fff3e0,stroke:#e65100 style NEW fill:#e8f5e9,stroke:#2e7d32

1-2. 핵심 파라미터

spec.strategy.rollingUpdate 하위:

파라미터 의미 기본값
maxUnavailable 동시에 사용 불가능할 수 있는 최대 Pod 수 25%
maxSurge desired replica를 초과해 추가로 띄울 수 있는 최대 Pod 수 25%

예: replicas=10, maxUnavailable=2, maxSurge=2 → 항상 최소 8개 살아 있고, 최대 12개까지 띄우며 교체.

1-3. 주요 명령어

1
2
3
4
kubectl set image deployment/myapp container=myapp:v2  # 트리거
kubectl rollout status deployment/myapp                # 진행 상황
kubectl rollout history deployment/myapp               # 이력
kubectl rollout undo deployment/myapp                  # 롤백

1-4. 전제 조건

  • Pod에 적절한 readinessProbe — 새 Pod의 트래픽 수신 준비 여부 판단
  • Stateful 워크로드는 StatefulSet 순차 업데이트 또는 Recreate 전략이 더 적합한 경우 있음

[02] 배포 패턴 비교 — Rolling / Blue-Green / Canary

2-1. Blue/Green Deployment

두 개의 동일한 환경(Blue=현재, Green=신규)을 완전히 분리해서 운영하다가 트래픽을 한 번에 스위치한다.

1
2
3
4
5
6
7
[Service] ──► Blue (v1)  ✅ 현재 트래픽
              Green (v2) 🟢 대기 (검증 중)

       ↓ 스위치

[Service] ──► Blue (v1)  ⚪ 대기 (롤백용)
              Green (v2) ✅ 현재 트래픽
항목 내용
장점 즉시 롤백, 두 버전이 트래픽에 동시 노출 안 됨
단점 리소스 2배, DB 스키마 호환성 이슈

2-2. Canary Deployment

신규 버전에 소수 트래픽을 먼저 흘려보내 검증한 뒤 비율을 점진적으로 증가시킨다.

1
2
3
4
5
6
v1 (95%) ──┐
v2 (5%)  ──┴──► 메트릭 관찰 (에러율, 레이턴시)
                ↓ 정상이면 비율 ↑
                v1 (50%) / v2 (50%)
                ↓
                v1 (0%)  / v2 (100%)
항목 내용
장점 실 트래픽 검증, 영향 범위 최소화
단점 구현 복잡, 관측(observability) 인프라 필수

2-3. 비교표

항목 Rolling Update Blue/Green Canary
리소스 부담 낮음 (maxSurge만큼) 높음 (2배) 중간
롤백 속도 느림 (재배포) 즉시 (스위치) 즉시 (라우팅 변경)
트래픽 분리 불가 (혼재) 완전 분리 비율 제어
구현 난이도 매우 낮음 (K8s 기본) 중간 높음
검증 방식 readinessProbe 위주 사전 스모크 테스트 실 트래픽 메트릭
적합 케이스 대부분 stateless 워크로드 DB/캐시 호환성 검증 필요 리스크 큰 변경, A/B 테스트

[03] K8s API 차원의 Update Strategy

K8s API spec이 직접 정의한 update enum 값.

Workload 사용 가능한 strategy
Deployment RollingUpdate, Recreate
StatefulSet RollingUpdate, OnDelete
DaemonSet RollingUpdate, OnDelete

3-1. 각 전략의 동작

전략 동작 K8s 컨트롤러가 자동 처리?
RollingUpdate 점진 교체, maxUnavailable/maxSurge 준수 O
Recreate 모든 구버전 Pod 종료 후 신버전 생성 (다운타임 발생) O
OnDelete Pod가 명시적으로 삭제될 때만 새 버전으로 교체 X — 사람 또는 Operator가 직접

3-2. DaemonSet에는 Recreate가 없다

DaemonSet은 노드당 1개 Pod 모델이라 Recreate가 의미상 부적합하다. 대신 OnDelete가 그 역할을 일부 대체하며, 보통 Operator가 노드별 교체 로직을 추가로 구현한다.


[04] 두 추상화 층위의 구분 (핵심 개념)

4-1. 흔한 오해

“K8s resource의 update는 Rolling Update / Blue-Green / Canary 3개로 분류된다”

부정확하다. 두 다른 추상화 층위가 섞여 있다.

4-2. 두 층위의 정의

층위 정체 항목
A: K8s 리소스 update 방법 = K8s API strategy K8s가 내 리소스 spec을 어떻게 손볼 건가 RollingUpdate, Recreate, OnDelete
B: 배포 패턴 내 애플리케이션의 새 버전을 사용자에게 어떻게 노출할 건가 Rolling Update, Blue/Green, Canary

:warning: “K8s API의 update strategy”와 “K8s resource의 업데이트 방법”은 같은 것(둘 다 A층위)이다. 표현만 다를 뿐 동일한 대상을 가리킨다. 진짜 구분은 A층위 vs B층위 사이에 있다.

4-3. 두 층위의 관계

graph TD
    subgraph B["B층위: 배포 패턴 (애플리케이션 버전 전환 방식)"]
        B1["Rolling Update"]
        B2["Blue/Green"]
        B3["Canary"]
    end

    subgraph A["A층위: K8s 리소스 update 방법 (= API strategy)"]
        A1["RollingUpdate"]
        A2["Recreate"]
        A3["OnDelete"]
    end

    B1 -.->|uses| A1
    B2 -.->|uses| A1
    B3 -.->|uses| A1

    style B fill:#e3f2fd,stroke:#1565c0
    style A fill:#fff3e0,stroke:#e65100
  • A는 K8s가 직접 제공하는 primitive
  • B는 그 primitive를 빌딩블록 삼아 조합해서 만드는 상위 패턴

4-4. 왜 헷갈리는가 — 이름 충돌

  • “Rolling Update”는 A층위에도 있고 B층위에도 있다 — 이름이 같지만 다른 추상화 층위
  • “Recreate”도 A층위(Deployment strategy)와 B층위(개념적 패턴)에 모두 등장

그래서 “K8s 업데이트 분류 = Rolling/Recreate/Blue-Green/Canary”처럼 한 줄로 묶이는 듯 보이지만, 실제로는 두 다른 층위가 섞여 있는 것이다.

4-5. 왜 B는 A 한 줄로 표현할 수 없는가

A층위(K8s native strategy)는 단일 워크로드 리소스의 update 동작을 정의한다. 반면 Blue/Green과 Canary는 여러 리소스의 조합 패턴이라 strategy 한 줄로 표현 불가.

패턴 K8s 표현 A층위 단독 표현?
Rolling Update Deployment 하나의 .spec.strategy 필드 O
Blue/Green Deployment(blue) + Deployment(green) + Service(selector swap) X
Canary Deployment 둘 + Ingress/VirtualService(weight) + 메트릭 로직 X

4-6. Blue/Green의 K8s 구현 예시

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
# blue-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-blue
spec:
  strategy:
    type: RollingUpdate    # ← A층위: 이 Deployment의 update strategy
  selector:
    matchLabels:
      app: myapp
      color: blue
  template:
    metadata:
      labels:
        app: myapp
        color: blue
---
# green-deployment.yaml (동일 구조, color: green)
---
# service.yaml — selector를 blue ↔ green으로 스위치
apiVersion: v1
kind: Service
spec:
  selector:
    app: myapp
    color: blue            # ← B층위: 이 selector swap이 Blue/Green 패턴 자체

위 예시에서:

  • 각 Deployment가 내부적으로 update될 때의 방식(A) = RollingUpdate
  • 전체적으로 사용자에게 v1 → v2를 노출하는 패턴(B) = Blue/Green

Blue/Green 패턴을 만들기 위해 사용하는 K8s strategy는 여전히 RollingUpdate이다. B는 A를 빌딩블록으로 사용해서 만든 상위 개념.

4-7. 패턴 → K8s 구현 매핑

배포 패턴 (B층위) K8s에서의 구현 A층위 strategy
Rolling Update Deployment 단독, strategy=RollingUpdate RollingUpdate
Recreate Deployment 단독, strategy=Recreate Recreate
Blue/Green 두 Deployment + Service selector swap, 또는 Rollout CRD 각 Deployment는 RollingUpdate
Canary 두 Deployment + Ingress weight / 서비스 메시, 또는 Rollout CRD 각 Deployment는 RollingUpdate

[05] 외부 솔루션

도구 Blue/Green Canary 특징
Argo Rollouts O O Rollout CRD가 Deployment 대체. AnalysisRun으로 메트릭 기반 자동 promote/rollback
Flagger O O 기존 Deployment 유지. Prometheus 메트릭 기반 progressive delivery 자동화
Istio / Linkerd O O 트래픽 분산 primitive 제공. Argo/Flagger와 조합이 일반적
ingress-nginx 제한적 O nginx.ingress.kubernetes.io/canary 어노테이션. 메트릭 분석은 별도
수동 (vanilla K8s) 가능 사실상 불가 두 Deployment + Service patch로 Blue/Green은 그럭저럭 가능, Canary는 트래픽 가중치 제어 불가

[06] NVIDIA Driver Operator 케이스 분석

6-1. 왜 노드 안에서 Rolling Update가 불가능한가

NVIDIA driver는 본질이 host kernel module 적재(nvidia.ko, nvidia-uvm.ko, nvidia-modeset.ko)이며, 이로 인한 제약이 있다.

# 제약 설명
1 커널 모듈 싱글톤 동일 모듈의 두 버전을 host kernel에 동시 로드 불가. 같은 노드에서 v1·v2 driver pod 공존이 OS 레벨에서 거부됨
2 모듈 unload의 ref count 조건 rmmod은 reference count가 0이어야 성공. GPU 사용 중인 컨테이너, nvidia-persistenced, X server 등이 붙어 있으면 EBUSY → 재부팅 필요
3 container-toolkit 의존성 사슬 nvidia-container-toolkit, libnvidia-container, device plugin이 모두 현재 driver 참조. driver만 갈아끼우면 사슬 붕괴
4 재부팅 강제 케이스 secure boot + signed module 변경, persistent mode, driver-firmware coupling

이 모든 제약이 “두 버전 일시 공존”을 전제하는 Rolling Update와 정면 충돌한다.

6-2. 그래도 클러스터 단위 무중단 롤아웃은 가능

1
2
3
4
5
6
7
8
9
for each node (보통 maxUnavailable=1):
  cordon                           # 새 GPU pod 스케줄 차단
  drain GPU workloads              # PDB 준수
  wait module ref_count == 0
  unload old module                # 실패 → reboot 분기
  delete old driver pod (OnDelete)
  reconcile new driver pod
  wait Ready + module loaded + smoke test
  uncordon

6-3. 핵심 분리 — K8s vs Operator

요소 누가 정의 / 구현
OnDelete enum 값 K8s API
DaemonSet 매니페스트의 updateStrategy.type: OnDelete K8s API spec 위에 사용자가 선언
노드별 cordon/drain/unload/replace 상태머신 Operator
클러스터 전체 노드 순차 롤아웃 정책 (maxUnavailable, drainTimeout, rebootStrategy) Operator
검증 게이트 (nvidia-smi, device plugin health) Operator

OnDelete는 K8s가 준 “빈 칠판”이고, Operator가 그 위에 그린 그림이 “노드별로 어떻게 안전하게 driver를 교체할 것인가”의 로직이다.

6-4. 행위적 분류

관점 실제 모습
K8s API 레벨 (A층위) OnDelete 전략
노드 안에서의 동작 “Recreate처럼 보임” — 두 버전 공존 불가
클러스터 전체에서의 동작 “Rolling Update처럼 보임” — 노드별 순차 처리

6-5. 설계 의사결정 순서

  1. A층위 결정 — DaemonSet의 updateStrategy.typeRollingUpdate로 둘 거냐 OnDelete로 둘 거냐 (driver는 OnDelete)
  2. B층위 결정 — 그 위에서 어떤 배포 패턴을 흉내낼 거냐 (driver는 host kernel 결합 때문에 Blue/Green·Canary 사실상 불가, 노드별 Recreate를 순차 진행이 사실상 유일 옵션)

[07] 핵심 요약

# 요약
1 두 추상화 층위가 따로 존재한다 — A층위(K8s API strategy)와 B층위(배포 패턴)
2 A층위 항목: RollingUpdate, Recreate, OnDelete (워크로드 종류별로 사용 가능 값 상이)
3 B층위 항목: Rolling Update, Blue/Green, Canary (+ Recreate, A/B, Shadow 등)
4 K8s native로 직접 제공되는 패턴은 Rolling Update와 Recreate뿐. Blue/Green·Canary는 외부 CRD(Argo Rollouts, Flagger) 또는 multi-resource 조합으로 구현
5 OnDelete는 A층위의 enum 값이고, 그것이 활성화됐을 때의 오케스트레이션 로직은 Operator가 직접 구현해야 함
6 NVIDIA driver처럼 host kernel과 결합된 워크로드는 Rolling Update가 노드 안에서 물리적으로 불가능. “노드 안은 Recreate, 노드 간은 통제된 Rolling” 패턴이 사실상 유일한 정답

:bulb: “K8s API의 update strategy”와 “K8s resource의 업데이트 방법”은 같은 것을 다르게 부른 것이다. 진짜 구분은 그 사이가 아니라 A층위 vs B층위(배포 패턴) 사이에 있다.