Kubernetes에서 애플리케이션을 배포할 때, 대부분의 경우 Deployment를 사용하여 Pod를 관리합니다.
하지만 데이터를 저장해야 하거나, 특정 순서로 Pod가 배포되어야 하는 경우에는 StatefulSet이 필요합니다.
이번 글에서는 StatefulSet의 개념, Deployment와의 차이, 동작 방식, 그리고 실전 활용법을 정리해 보겠습니다.
🔹 StatefulSet이란?
StatefulSet은 상태(State)를 유지해야 하는 애플리케이션을 배포하는 데 사용하는 Kubernetes 리소스입니다.
기본적으로 Pod를 관리하지만, 각 Pod에 고유한 네트워크 ID와 스토리지를 보장하는 점이 특징입니다.
📌 StatefulSet의 주요 특징
✔️ 각 Pod에 고유한 이름 부여 (my-app-0, my-app-1, my-app-2 형태)
✔️ Pod가 순차적으로 생성되고 종료됨
✔️ 각 Pod는 고유한 영구 스토리지를 가짐
✔️ Pod가 재시작되거나 이동해도 동일한 볼륨 유지
사용 예시:
- 데이터베이스(MySQL, PostgreSQL, MongoDB, etcd)
- 메시지 브로커(Kafka, RabbitMQ)
- 분산 파일 시스템(Ceph, GlusterFS)
🔹 StatefulSet vs Deployment 차이점
기능 StatefulSet Deployment
Pod 개수 유지 | ✅ 가능 | ✅ 가능 |
Pod 이름 고유성 보장 | ✅ 가능 (pod-0, pod-1) | ❌ 불가능 |
순차적 배포 및 종료 | ✅ 가능 (0 → 1 → 2) | ❌ 순서 없음 |
고유한 네트워크 ID | ✅ 가능 (pod-0.svc) | ❌ 불가능 |
영구적인 볼륨 유지 | ✅ 가능 | ❌ 기본적으로 지원 안 함 |
💡 Deployment는 Pod가 상태를 유지하지 않아도 되는 일반 애플리케이션 배포에 적합하고, StatefulSet은 데이터 저장이 필요한 애플리케이션에 적합합니다.
🔹 StatefulSet YAML 예제
아래 예제는 3개의 Pod로 구성된 StatefulSet을 생성합니다.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-statefulset
spec:
serviceName: "my-service" # Headless Service와 연동됨
replicas: 3 # Pod 개수
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-container
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: storage
mountPath: /usr/share/nginx/html
volumeClaimTemplates: # 영구 볼륨 정의
- metadata:
name: storage
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
📌 StatefulSet의 주요 필드 설명
필드 설명
serviceName | Pod 간 통신을 위해 Headless Service와 연동 |
replicas | 생성할 Pod 개수 |
selector.matchLabels | 어떤 Pod를 관리할지 결정 |
volumeClaimTemplates | 각 Pod에 영구 볼륨을 제공 |
💡 StatefulSet은 volumeClaimTemplates을 사용하여 각 Pod에 독립적인 스토리지를 제공합니다.
🔹 StatefulSet 배포 및 확인
kubectl apply -f statefulset.yaml
kubectl get pods
출력 결과:
NAME READY STATUS RESTARTS AGE
my-statefulset-0 1/1 Running 0 10s
my-statefulset-1 1/1 Running 0 15s
my-statefulset-2 1/1 Running 0 20s
Pod 이름이 my-statefulset-0, my-statefulset-1, my-statefulset-2처럼 일련번호가 붙어 생성된 것을 확인할 수 있습니다.
🔹 StatefulSet의 네트워킹
StatefulSet의 Pod는 고유한 네트워크 ID를 갖습니다.
이를 위해 Headless Service를 사용합니다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
clusterIP: None # Headless Service 설정
selector:
app: my-app
ports:
- port: 80
💡 Pod 간 통신할 때 도메인 사용 가능
ping my-statefulset-0.my-service
ping my-statefulset-1.my-service
🔹 StatefulSet의 Pod 순서 보장
StatefulSet은 순차적으로 Pod를 생성 및 삭제합니다.
📌 StatefulSet Pod 삭제 실험
kubectl delete pod my-statefulset-1
kubectl get pods
출력 결과: my-statefulset-1이 다시 생성됨.
StatefulSet은 삭제된 Pod를 동일한 이름으로 복구합니다.
📌 StatefulSet 전체 삭제
kubectl delete statefulset my-statefulset
kubectl get pods
Pod는 삭제되지만 PersistentVolumeClaim(PVC)은 유지됩니다.
🔹 StatefulSet에서 볼륨 유지 확인
kubectl get pvc
출력 결과:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS
storage-my-statefulset-0 Bound pvc-xxx 1Gi RWO
storage-my-statefulset-1 Bound pvc-yyy 1Gi RWO
storage-my-statefulset-2 Bound pvc-zzz 1Gi RWO
💡 StatefulSet을 삭제해도 PVC는 유지되므로, Pod가 다시 생성되면 데이터를 복구할 수 있습니다.
🚀 StatefulSet을 사용할 때 고려해야 할 사항
- StatefulSet은 스케일링이 Deployment보다 느리다
- 새로운 Pod를 생성할 때 기존 Pod가 준비될 때까지 기다림
- 빠른 확장이 필요하면 Deployment를 고려
- 데이터 손실을 방지하려면 PersistentVolume을 올바르게 설정해야 한다
- volumeClaimTemplates을 사용하여 Pod별로 볼륨을 보장
- 스토리지 클래스를 명확히 설정해야 함
- StatefulSet Pod는 특정 노드에 고정되지 않는다
- 노드 장애 발생 시 다른 노드에서 재배치 가능
- 특정 노드에 고정하려면 nodeSelector 또는 affinity 설정 필요
🚀 마무리
StatefulSet은 데이터를 저장하고, Pod 간 네트워크 ID를 유지해야 하는 애플리케이션에 필수적인 리소스입니다.
데이터베이스, 분산 시스템, 메시지 큐와 같은 애플리케이션을 Kubernetes에서 안정적으로 운영하려면 StatefulSet을 올바르게 이해하고 활용해야 합니다.
다음 글에서는 DaemonSet을 다뤄보겠습니다! 🚀
'Kubernetes > Kubernetes Advanced' 카테고리의 다른 글
Kubernetes 리소스 시리즈 #5: Job & CronJob (워크로드 리소스) (0) | 2025.03.05 |
---|---|
Kubernetes 리소스 시리즈 #4: DaemonSet (워크로드 리소스) (0) | 2025.03.05 |
Kubernetes 리소스 시리즈 #2: ReplicaSet & Deployment (워크로드 리소스) (0) | 2025.03.04 |
Kubernetes 리소스 시리즈 #1: Pod (워크로드 리소스) (0) | 2025.03.04 |
Kubernetes 리소스 정리: 개념과 종류 (0) | 2025.03.04 |