플랫폼, 데브옵스와 클라우드

스토리지와 StatefulSet

meellon 2026. 6. 26. 05:40

학습 목표

PV·PVC·StorageClass로 Pod 영속 볼륨을 요청·바인딩할 수 있다.

emptyDir·PVC·ConfigMap volume 용도 차이를 설명할 수 있다.

StatefulSetstable Pod 이름·순서·PVC 템플릿을 제공하는 이유를 설명할 수 있다.

headless ServicePod DNS로 stateful 워크로드를 연결할 수 있다.

문제 상황

  • Deployment Pod가 재시작하면 로컬 디스크 데이터가 사라진다
    • emptyDir은 Pod와 함께 삭제된다
  • DB를 Deployment 3 replicas로 띄웠더니 데이터가 Pod마다 다르다
    • 공유·순서·고정 ID가 필요하다
  • hostPath로 노드 디렉터리를 마운트했다
    • Pod 재스케줄다른 노드면 데이터 없음, 보안 이슈
  • PVC Pending며칠간 해결되지 않는다
    • StorageClass·프로비저너·용량·accessMode 불일치
  • Kafka·ZooKeeper처럼 pod-0, pod-1 순서가 중요한데 Deployment는 랜덤 이름
    • StatefulSet + headless Service 패턴

앞서 ConfigMap·Secret·Service를 봤다. 이번 편은 데이터가 Pod를 넘어 남아야 할 때의 볼륨StatefulSet이다.

1. Kubernetes 스토리지 개요

Pod는 기본적으로 ephemeral — 컨테이너 파일시스템은 재시작·재스케줄 시 초기화.

리소스 역할
Volume Pod spec — 어떻게 마운트할지
PVC 사용자 요청 (용량·StorageClass·accessMode)
PV 클러스터 실제 볼륨 풀 (또는 동적 생성 결과)
StorageClass 동적 프로비저닝provisioner, parameters
Pod volumeMount → PVC data-db → PV pv-001 → cloud disk / NFS
  • 동적 프로비저닝 — PVC 생성 시 StorageClass가 PV 자동 생성 (일반적)
  • 정적 — 관리자가 PV 미리 만들고 PVC가 바인딩 (legacy·특수)

2. Volume 종류

volume 수명 용도
emptyDir Pod scratch, sidecar 공유, 캐시 (재시작 시 유지, Pod 삭제 시 소멸)
configMap / secret Pod 설정·자격증명 파일 (앞서 8편)
PVC PVC/PV DB·로그·업로드 — Pod 재스케줄 후에도 유지
projected Pod 여러 소스 한 마운트
# emptyDir — ephemeral scratch
volumes:
  - name: cache
    emptyDir:
      sizeLimit: 512Mi
volumeMounts:
  - name: cache
    mountPath: /tmp/cache
# PVC — persistent data
volumes:
  - name: data
    persistentVolumeClaim:
      claimName: data-db
  emptyDir PVC
Pod 삭제 데이터 삭제 데이터 유지
노드 이동 scratch만 같은 PV 재attach (RWO)
비용 노드 디스크 영속 스토리지

3. PVC와 StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: kubernetes.io/aws-ebs   # cloud CSI driver
parameters:
  type: gp3
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-db
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: fast-ssd
  resources:
    requests:
      storage: 20Gi
accessMode 약어 의미
ReadWriteOnce RWO 한 노드 read/write (대부분 block)
ReadOnlyMany ROX 여러 노드 read
ReadWriteMany RWX 여러 노드 read/write (NFS, EFS 등)
StorageClass 옵션 설명
WaitForFirstConsumer Pod 스케줄 볼륨 생성 — AZ 맞춤
Immediate PVC 즉시 프로비저닝
allowVolumeExpansion PVC 용량 확장 (CSI)
kubectl get storageclass
kubectl get pvc,pv
kubectl describe pvc data-db
  • Pending — StorageClass 없음, 프로비저너 미설치, 용량 부족
  • Released PV — persistentVolumeReclaimPolicy: Retain vs Delete

4. StatefulSet이 필요한 이유

Deployment — Pod 교체 가능, 이름·IP 랜덤, 순서 없음.

StatefulSetstable 네트워크 ID, 순서 있는 rollout, per-Pod PVC.

  Deployment StatefulSet
Pod 이름 api-7d4f8-xyz web-0, web-1, web-2
PVC 공유 또는 없음 volumeClaimTemplate → Pod마다 PVC
생성 순서 병렬 0 → 1 → 2 순차
삭제 순서 병렬 2 → 1 → 0 역순
DNS 일반 Service headless — Pod별 A 레코드
  • Kafka, etcd, MySQL primary-replica — peer discovery에 고정 hostname 필요
  • 단순 stateless API — Deployment가 기본

5. StatefulSet과 headless Service

apiVersion: v1
kind: Service
metadata:
  name: db
spec:
  clusterIP: None          # headless
  selector:
    app: db
  ports:
    - port: 5432
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: db
spec:
  serviceName: db          # headless Service 이름 (필수)
  replicas: 3
  selector:
    matchLabels:
      app: db
  template:
    metadata:
      labels:
        app: db
    spec:
      containers:
        - name: postgres
          image: postgres:16
          ports:
            - containerPort: 5432
          volumeMounts:
            - name: data
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        storageClassName: fast-ssd
        resources:
          requests:
            storage: 20Gi
Pod DNS (cluster) PVC
db-0 db-0.db.default.svc.cluster.local data-db-0
db-1 db-1.db.default.svc.cluster.local data-db-1
db-2 db-2.db.default.svc.cluster.local data-db-2
  • serviceName — StatefulSet과 headless Service 연결
  • volumeClaimTemplates — Pod 생성 시 PVC 자동 (data-db-0 …)
  • Pod 삭제해도 PVC 유지 (데이터 보존) — reclaim 정책 확인
kubectl apply -f code/statefulset-storage.yaml
kubectl get sts,po,pvc,svc
kubectl exec db-0 -- hostname -f

6. StatefulSet 운영

항목 동작
scale up web-2 생성 web-1 Ready
scale down 높은 ordinal부터 삭제
rolling update partition — N 이상만 새 버전
Pod 삭제 같은 ordinal재생성, 같은 PVC
spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 2    # web-0, web-1 old · web-2+ new image
  • OnDelete — 수동 삭제 시에만 업데이트 (레거시)
  • ReadWriteOnce — 한 PV는 한 Pod만 — StatefulSet Pod는 보통 노드 분산 필요

7. 실무 선택

워크로드 권장
Stateless API Deployment + emptyDir cache
단일 DB StatefulSet 1 replica 또는 관리형 RDS (17편)
Kafka·ZooKeeper StatefulSet + headless + per-Pod PVC
공유 파일 RWX StorageClass (NFS, EFS)
로그·임시 emptyDir 또는 stdout (Observability)
체크  
PVC Pending StorageClass, CSI driver, quota
Pod Pending RWO + 다른 노드에 PV 묶임
백업 PV snapshot (CSI), 앱 일관성
DR snapshot·restore, 관리형 복제

8. 정리

  • emptyDir — Pod 수명 임시 · PVC영속 데이터
  • PVC → PV → StorageClass — 동적 프로비저닝이 기본
  • StatefulSetstable name, 순서, volumeClaimTemplate
  • headless Servicepod-N.service DNS
  • stateless는 Deployment, 데이터·순서 필요 시 StatefulSet

다음에 다룰 것

  • 스케줄링과 리소스
  • requests/limits, QoS, node affinity, HPA

해당 내용은 Kubernetes Documentation (kubernetes.io) 의 내용을 기반으로 합니다.

'플랫폼, 데브옵스와 클라우드' 카테고리의 다른 글

CI/CD 개요  (0) 2026.06.28
스케줄링과 리소스  (0) 2026.06.27
ConfigMap과 Secret  (0) 2026.06.25
Service와 Ingress  (0) 2026.06.24
Pod와 Deployment  (0) 2026.06.23