Kubernetes/Kubernetes Advanced

📌 [StatefulSet 심화편 #4] StatefulSet의 롤링 업데이트와 데이터 정합성 유지 전략

ygtoken 2025. 3. 13. 11:04
728x90

 

1️⃣ 개요

 

StatefulSet의 특성상 데이터를 저장하는 애플리케이션(예: MySQL, PostgreSQL, Kafka 등)을 운영할 때 롤링 업데이트가 일반적인 Deployment보다 더 까다롭습니다.

잘못된 업데이트 전략을 적용하면 데이터 손실, 데이터 불일치, 클러스터 다운타임 등의 문제가 발생할 수 있습니다.

 

이번 글에서는 StatefulSet의 롤링 업데이트 방법과, 데이터 정합성을 유지하면서 안전하게 업데이트하는 전략을 설명하겠습니다. 🚀

 


2️⃣ StatefulSet의 롤링 업데이트 원리

 

✅ 1. StatefulSet 롤링 업데이트의 특징

Deployment와 달리 Pod의 종료 및 재배포 순서를 보장함

Pod가 하나씩 순차적으로 종료되고 업데이트됨 (pod-0 → pod-1 → pod-2)

각 Pod는 기존 데이터(Persistent Volume)를 유지하며, 새로운 버전의 애플리케이션을 실행

 

StatefulSet은 각 Pod가 개별적으로 업데이트되므로, 클러스터 전체의 가용성을 유지할 수 있습니다.

 


3️⃣ StatefulSet 롤링 업데이트 수행 방법

 

✅ 1. 기본적인 StatefulSet 롤링 업데이트 진행 방식

 

StatefulSet의 업데이트 전략을 RollingUpdate로 설정하면, Pod가 순차적으로 교체됩니다.

 

📌 StatefulSet 롤링 업데이트 설정 예제

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  updateStrategy:
    type: RollingUpdate  # 순차적 업데이트 수행
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:8  # 새로운 버전으로 업데이트

 

📌 StatefulSet 업데이트 적용

kubectl apply -f mysql-statefulset.yaml

 

📌 업데이트 진행 상태 확인

kubectl rollout status statefulset mysql

이렇게 하면 StatefulSet이 한 번에 하나의 Pod만 종료하고 업데이트합니다.

 


✅ 2. 데이터 정합성을 유지하면서 롤링 업데이트 수행하기

 

Stateful 애플리케이션(예: 데이터베이스)은 모든 노드를 동시에 업데이트하면 데이터 정합성이 깨질 수 있습니다.

이를 방지하려면 다음 사항을 고려해야 합니다.

 

🔹 (1) Pod가 종료되기 전에 데이터 동기화가 완료되었는지 확인

 

📌 PreStop Hook을 활용하여 Pod 종료 전에 데이터 플러싱 수행

lifecycle:
  preStop:
    exec:
      command: [ "mysqladmin", "shutdown" ]

Pod가 종료되기 전에 데이터를 안전하게 저장할 수 있습니다.

 


🔹 (2) 리더-팔로워(마스터-슬레이브) 구조에서 리더를 먼저 변경

 

데이터베이스 클러스터(예: PostgreSQL, MySQL Galera, Kafka 등)는 리더 노드를 먼저 변경한 후, 팔로워 노드를 업데이트해야 합니다.

이를 위해 PodDisruptionBudget(PDB) 를 설정하면 한 번에 하나의 노드만 업데이트하도록 제한할 수 있습니다.

 

📌 PodDisruptionBudget을 설정하여 한 번에 하나의 Pod만 업데이트 허용

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: mysql-pdb
spec:
  minAvailable: 2  # 최소 2개의 Pod가 항상 살아있도록 설정
  selector:
    matchLabels:
      app: mysql

 

📌 PodDisruptionBudget 적용

kubectl apply -f pod-disruption-budget.yaml

PDB를 활용하면 StatefulSet이 한 번에 하나의 Pod만 종료하도록 강제할 수 있습니다.

 


✅ 3. 업데이트 도중 문제가 발생했을 때 롤백하기

 

만약 새로운 버전에서 애플리케이션 장애, 성능 저하, 데이터 손실 등의 문제가 발생하면 즉시 롤백해야 합니다.

 

📌 StatefulSet 롤백 수행

kubectl rollout undo statefulset mysql

 

📌 특정 버전으로 롤백 수행

kubectl rollout undo statefulset mysql --to-revision=2

업데이트 중 문제가 발생하면 즉시 이전 버전으로 복구할 수 있습니다.

 


4️⃣ StatefulSet 롤링 업데이트 전략별 비교

업데이트 전략 설명 사용 사례
RollingUpdate Pod를 순차적으로 업데이트 일반적인 Stateful 애플리케이션 배포
OnDelete 기존 Pod가 삭제될 때만 업데이트 특정 버전 유지가 필요한 경우
Manual Update 수동으로 특정 Pod만 업데이트 데이터베이스 클러스터(마스터-슬레이브)

데이터 정합성이 중요한 애플리케이션에서는 RollingUpdate + PodDisruptionBudget 전략을 사용하는 것이 가장 안정적입니다.

 


5️⃣ StatefulSet 업데이트 시 고려해야 할 점

 

✅ 1. PVC 재사용을 보장해야 함

 

StatefulSet의 Pod는 PVC를 통해 기존 데이터를 유지하며 업데이트되므로, PVC가 삭제되지 않도록 설정해야 합니다.

 

📌 PVC 유지한 채 StatefulSet 삭제하기

kubectl delete statefulset mysql --cascade=orphan

이렇게 하면 StatefulSet만 삭제되고, PVC와 PV는 유지됩니다.

 


✅ 2. 데이터 백업을 수행한 후 업데이트 진행

중요한 데이터가 있는 경우, StatefulSet 업데이트 전에 백업을 수행하는 것이 필수적

예를 들어 MySQL의 경우 다음과 같이 백업 가능

 

📌 MySQL 데이터 백업 수행

kubectl exec -it mysql-0 -- mysqldump -u root -p > backup.sql

데이터 백업 후 업데이트를 수행하면, 장애 발생 시 복구할 수 있습니다.

 


✅ 3. 업데이트 완료 후 애플리케이션 정상 동작 확인

 

업데이트가 정상적으로 완료되었는지 확인하려면 애플리케이션 로그 및 상태를 모니터링해야 합니다.

 

📌 업데이트 후 Pod 상태 확인

kubectl get pods -l app=mysql

 

📌 로그 확인 (에러 발생 여부 체크)

kubectl logs mysql-0

이러한 모니터링 과정을 통해 업데이트가 정상적으로 완료되었는지 확인할 수 있습니다.

 


🔥 6️⃣ 결론

 

StatefulSet의 롤링 업데이트는 Pod를 순차적으로 업데이트하여 데이터 정합성을 유지할 수 있음

업데이트 시 PodDisruptionBudget을 활용하면 한 번에 하나의 Pod만 업데이트하도록 제한 가능

데이터 손실 방지를 위해 PVC를 유지하면서 StatefulSet을 삭제해야 함

업데이트 실패 시 kubectl rollout undo 명령어를 사용하여 롤백 가능

중요한 데이터를 저장하는 애플리케이션이라면, 업데이트 전에 반드시 백업을 수행해야 함

728x90