Kubernetes

쿠버네티스 스테이트풀셋 (StatefulSet)

1. StatefulSet 개요

StatefulSet은 상태를 가지는(스테이트풀) 애플리케이션을 관리하기 위한 쿠버네티스 리소스입니다.
기본적으로 Deployment는 스테이트리스(stateless) 애플리케이션을 위한 것이지만, 데이터베이스, 메시지 큐, 분산 스토리지와 같은 상태를 유지해야 하는 애플리케이션은 StatefulSet을 사용해야 합니다.

🔹 StatefulSet의 주요 특징

✅ 각 Pod에 고유한 정적인 네트워크 ID를 부여 (예: myapp-0, myapp-1, …)
✅ 각 Pod에 고유한 영구 볼륨(Persistent Volume, PV)을 할당 (재시작 후에도 데이터 유지)
✅ Pod 종료 및 시작 순서를 보장 (순차적 배포 및 종료)
✅ 데이터 정합성이 중요한 애플리케이션을 위한 배포 방식


2. StatefulSet이 필요한 경우

📌 어떤 경우 StatefulSet을 사용할까?

  • 데이터 정합성이 중요한 데이터베이스(MySQL, PostgreSQL, MongoDB)
  • 분산 시스템(Zookeeper, Kafka, Elasticsearch, etcd)
  • 마스터-슬레이브 구조의 애플리케이션
  • 특정 Pod의 네트워크 ID가 고정적으로 유지되어야 할 때

📌 StatefulSet이 불필요한 경우

  • 웹 서버, API 서버, 캐시 서버 등 상태가 필요 없는 서비스
  • 로드 밸런싱이 중요한 서비스 (이 경우 Deployment + Service 조합이 적절)

3. StatefulSet의 주요 기능

1) 각 Pod에 고유한 이름 부여

StatefulSet의 Pod들은 고유한 이름과 네트워크 정체성을 유지합니다.
예를 들어, web이라는 StatefulSet을 만들면 각 Pod는 숫자가 붙은 고유한 이름을 가집니다.

web-0
web-1
web-2

➡️ Deployment에서 생성된 Pod들은 랜덤한 이름을 갖지만, StatefulSet의 Pod는 순서와 네이밍을 유지합니다.


2) Pod 순차적 배포 및 종료

StatefulSet은 Pod를 하나씩 순차적으로 배포합니다.

1️⃣ web-0이 먼저 생성되고 정상 작동하면
2️⃣ web-1이 생성됨
3️⃣ web-1이 정상 작동하면 web-2 생성

Pod가 삭제될 때도 반대로 순서대로 종료됩니다.


3) 각 Pod가 고유한 영구 볼륨(Persistent Volume) 유지

  • Deployment와 다르게, StatefulSet은 각 Pod가 독립적인 스토리지를 유지합니다.
  • 즉, Pod가 삭제되더라도 해당 Pod에 할당된 볼륨(PersistentVolumeClaim, PVC)은 유지됨.
  • 이를 통해 데이터베이스 등의 데이터 유실을 방지할 수 있음.

📌 예제: Pod별 고유한 PVC 생성

myapp-0 → pvc-myapp-0
myapp-1 → pvc-myapp-1
myapp-2 → pvc-myapp-2
Pod가 삭제되어도 pvc-myapp-0에 저장된 데이터는 유지됩니다.

4) Stable Network Identity (고유한 네트워크 ID 유지)

StatefulSet의 Pod들은 클러스터 내에서 고유한 DNS 이름을 갖습니다.

web-0.web.default.svc.cluster.local
web-1.web.default.svc.cluster.local
web-2.web.default.svc.cluster.local

이러한 네트워크 ID 덕분에 각 Pod는 서로의 주소를 고정적으로 참조 가능하며, 분산 데이터베이스와 같은 환경에서 유용합니다.


4. StatefulSet 예제 (MySQL 클러스터)

아래는 MySQL Master-Slave 구조를 StatefulSet을 사용하여 배포하는 예제입니다.

yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "mysql"
  replicas: 2  # 두 개의 Pod 생성 (master-slave 구조)
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "mypassword"
        volumeMounts:
        - name: mysql-storage
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: mysql-storage
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 1Gi

5. StatefulSet과 Service 연동

StatefulSet Pod들은 Headless Service 를 사용하여 각 Pod에 고유한 DNS를 부여할 수 있습니다.

Headless Service 예제

yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  clusterIP: None  # Headless Service 설정
  selector:
    app: mysql
  ports:
  - protocol: TCP
    port: 3306

이렇게 하면 mysql-0, mysql-1에 개별적으로 접근 가능하게 됩니다.


6. StatefulSet vs Deployment 비교

비교 항목 StatefulSet Deployment
Pod 이름 고유한 이름 유지 (pod-0, pod-1) 랜덤한 이름
배포 순서 순차적 (pod-0pod-1) 동시 배포 가능
스토리지 각 Pod에 고유한 Persistent Volume 모든 Pod가 공유 가능
네트워크 ID 고유한 DNS 유지 (pod-0.svc) 공유 DNS 사용
용도 데이터베이스, 분산 시스템 웹 서버, 마이크로서비스

➡ 배포가 빠르고 동적인 웹 애플리케이션이라면 Deployment 사용
➡ 데이터 정합성이 중요한 DB나 분산 시스템이라면 StatefulSet 사용


7. StatefulSet 스케일링

📌 StatefulSet 확장(Scale Up)

bash
kubectl scale statefulset mysql --replicas=3

이렇게 하면 mysql-2가 추가됩니다.

📌 StatefulSet 축소(Scale Down) 주의점

bash
kubectl scale statefulset mysql --replicas=1
  • StatefulSet을 축소하면 마지막 Pod(mysql-1)부터 삭제되지만,
  • PVC(스토리지)는 삭제되지 않음!
    (필요 시 kubectl delete pvc pvc-mysql-1로 수동 삭제)

8. StatefulSet 삭제 시 주의점

StatefulSet을 삭제해도 Persistent Volume은 남아 있음

bash
kubectl delete statefulset mysql

📌 데이터까지 삭제하려면?

bash
</div>
kubectl delete pvc -l app=mysql

9. 결론

✅ StatefulSet은 데이터 정합성이 중요한 애플리케이션에 적합
✅ Pod의 순차적 배포/삭제를 보장하며, 각 Pod에 고유한 네트워크 ID 제공
✅ 각 Pod는 독립적인 영구 볼륨을 가지며, 삭제 후에도 데이터 유지
✅ Deployment보다 StatefulSet이 필요한 경우: DB, Kafka, Zookeeper, Elasticsearch 등

❓ StatefulSet을 사용할지 고민된다면? 📌 애플리케이션이 상태를 유지해야 하는지 고려하라!
📌 데이터베이스, 분산 시스템이라면 StatefulSet을 선택
📌 단순 웹 서버라면 Deployment가 더 적합

🚀 StatefulSet을 잘 활용하면, 안정적인 분산 시스템을 구축할 수 있습니다!

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

error: Content is protected !!