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-2 → redis-1 → redis-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을 점진적으로 업데이트 가능