Kubernetes/Kubernetes Advanced

📌 [StatefulSet 심화편 #22] StatefulSet에서 Rolling Update와 Canary Deployment 적용하기

ygtoken 2025. 3. 15. 11:18
728x90

 

1️⃣ 개요

 

StatefulSet을 운영할 때, 애플리케이션을 무중단으로 업데이트하는 것은 중요한 도전 과제입니다.

특히, 데이터베이스, 메시지 브로커와 같은 Stateful 애플리케이션은 업데이트 시 데이터 정합성을 유지하면서 안전하게 배포해야 합니다.

 

이번 글에서는 StatefulSet에서 Rolling Update를 활용하여 점진적으로 업데이트하는 방법과, Canary Deployment를 통해 새로운 버전을 점진적으로 도입하는 전략을 설명하겠습니다. 🚀

 


2️⃣ StatefulSet에서 Rolling Update가 필요한 이유

 

📌 Rolling Update가 필요한 주요 이유

상황 설명
무중단 배포 필요 Stateful 애플리케이션을 중단 없이 점진적으로 업데이트해야 함
데이터 정합성 유지 Pod가 하나씩 업데이트되면서 데이터가 손실되지 않도록 해야 함
실패 시 빠른 롤백 가능 특정 버전에서 문제가 발생하면, 이전 버전으로 빠르게 복구할 수 있어야 함

Rolling Update를 사용하면 StatefulSet의 모든 Pod를 한 번에 업데이트하지 않고, 하나씩 점진적으로 업데이트할 수 있습니다.

 


3️⃣ StatefulSet에서 Rolling Update 적용 방법

 

✅ 1. Rolling Update 기본 설정

 

📌 StatefulSet에서 Rolling Update를 활성화하는 기본 설정

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  serviceName: redis
  replicas: 3
  updateStrategy:
    type: RollingUpdate  # 점진적 업데이트 활성화
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: redis
          image: redis:6.2
          volumeMounts:
            - name: redis-data
              mountPath: /data
  volumeClaimTemplates:
    - metadata:
        name: redis-data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 10Gi

 

📌 Rolling Update 진행 확인

kubectl rollout status statefulset redis

Rolling Update가 진행되면서 Pod가 하나씩 업데이트되는 것을 확인할 수 있습니다.

 


✅ 2. Rolling Update 진행 방식

Rolling Update 방식에서는 가장 높은 숫자를 가진 Pod부터 업데이트됨

예를 들어, redis-2redis-1redis-0 순서로 업데이트 진행

각 Pod가 정상적으로 준비된 후(next Ready 상태) 다음 Pod가 업데이트됨

 

📌 Rolling Update 진행 로그 예시

statefulset-controller: Pod redis-2 successfully updated.
statefulset-controller: Pod redis-1 successfully updated.
statefulset-controller: Pod redis-0 successfully updated.

Pod가 하나씩 교체되므로, 무중단 배포가 가능합니다.

 


4️⃣ StatefulSet Rolling Update 시 고려해야 할 사항

 

✅ 1. 데이터 정합성 유지

 

Stateful 애플리케이션(예: MySQL, PostgreSQL, Kafka)은 데이터 정합성이 중요한 경우, 무중단 배포 전에 리더 노드를 보호하는 전략이 필요합니다.

 

📌 리더 노드를 보호하는 방법 (MySQL 예제)

readinessProbe:
  exec:
    command: ["mysqladmin", "ping"]
  initialDelaySeconds: 10
  periodSeconds: 5

리더 노드가 안전하게 유지되도록 설정해야 합니다.

 


✅ 2. StatefulSet Rolling Update 중단 및 롤백 방법

 

업데이트 도중 문제가 발생하면 즉시 롤백해야 합니다.

 

📌 업데이트 도중 중단

kubectl rollout pause statefulset redis

 

📌 롤백 실행 (이전 버전으로 되돌리기)

kubectl rollout undo statefulset redis

문제가 발생하면 빠르게 롤백하여 장애를 방지할 수 있습니다.

 


5️⃣ StatefulSet에서 Canary Deployment 적용 방법

 

✅ 1. Canary Deployment 개념

 

Canary Deployment는 새로운 버전을 일부 Pod에만 배포하여 테스트한 후, 문제가 없으면 전체 업데이트를 진행하는 배포 전략입니다.

 

📌 Canary Deployment의 장점

장점 설명
안정적인 배포 일부 사용자만 새로운 버전을 사용하도록 제한 가능
빠른 문제 감지 전체 배포 전에 버그나 장애를 사전에 감지 가능
점진적 확대 가능 Canary 버전이 안정적이면 점진적으로 확장 가능

Canary Deployment는 StatefulSet을 운영할 때, 안정성을 유지하는 데 중요한 전략입니다.

 


✅ 2. StatefulSet에서 Canary Deployment 적용하기

 

📌 Canary Deployment를 위한 새로운 StatefulSet 추가 (부분적으로 새 버전 배포)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-canary
spec:
  serviceName: redis
  replicas: 1  # 기존 StatefulSet보다 적은 수의 Pod만 배포
  selector:
    matchLabels:
      app: redis
      version: canary
  template:
    metadata:
      labels:
        app: redis
        version: canary  # Canary 버전 구분을 위한 라벨 추가
    spec:
      containers:
        - name: redis
          image: redis:7.0  # 새로운 버전
          volumeMounts:
            - name: redis-data
              mountPath: /data
  volumeClaimTemplates:
    - metadata:
        name: redis-data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 10Gi

 

📌 Canary 버전과 기존 버전을 구분하는 서비스 추가

apiVersion: v1
kind: Service
metadata:
  name: redis-canary
spec:
  selector:
    app: redis
    version: canary  # Canary 버전의 StatefulSet과 연결
  ports:
    - protocol: TCP
      port: 6379
      targetPort: 6379

 

📌 Canary 버전 트래픽 테스트

kubectl port-forward svc/redis-canary 6379:6379

Canary Deployment를 활용하면 새로운 버전이 일부 사용자에게만 제공되도록 조정할 수 있습니다.

 


6️⃣ Canary Deployment 이후 전체 업데이트 진행

 

Canary 버전이 안정적으로 운영되면, 전체 StatefulSet을 새로운 버전으로 업데이트할 수 있습니다.

 

📌 StatefulSet 전체 Rolling Update 진행

kubectl set image statefulset redis redis=redis:7.0

 

📌 Canary StatefulSet 삭제 (기존 StatefulSet으로 완전 전환)

kubectl delete statefulset redis-canary

이제 모든 StatefulSet Pod가 새로운 버전으로 업데이트됩니다.

 


🔥 7️⃣ 결론

 

Rolling Update를 활용하면 StatefulSet을 무중단으로 업데이트할 수 있음

데이터 정합성을 유지하기 위해 리더 노드를 보호하는 설정이 필요함

업데이트 도중 문제가 발생하면 kubectl rollout undo 명령어로 빠르게 롤백 가능

Canary Deployment를 적용하면 일부 Pod에서 새로운 버전을 먼저 테스트할 수 있음

Canary 버전이 안정적이면 전체 StatefulSet을 점진적으로 업데이트 가능

 

728x90