콘텐츠로 이동
Study NoteCKA

StatefulSet과 Pod별 저장소

결론부터
StatefulSet의 volumeClaimTemplates는 Pod의 고정된 이름마다 PVC를 만들어 데이터를 연결한다.

앞에서는 PVC 하나를 연결했다. 이제 Pod이 여러 개이거나 교체될 때 누가 어떤 PVC를 쓰는가를 본다. 이 장은 Pod별 저장소가 필요한 경우와, Deployment가 하나의 RWO 볼륨을 공유할 때의 충돌을 설명한다.

Deployment의 Pod들은 서로 구별되지 않으므로 PVC 하나를 모두가 나눠 갖는다 — DB 복제본처럼 각자 자기 데이터를 가져야 하는 워크로드에는 맞지 않는다. PVC를 replica 수만큼 손으로 만들어도, 어느 Pod이 어느 PVC를 잡을지 고정할 방법이 없다. volumeClaimTemplates는 Pod의 고정된 신원(ordinal)에 PVC를 1:1로 붙여 이 문제를 푼다.

spec:
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: fast
resources:
requests:
storage: 10Gi

Pod마다 PVC가 하나씩 생긴다. 이름이 고정이라 Pod이 죽었다 살아나도 같은 볼륨으로 돌아온다.

StatefulSet의 volumeClaimTemplates가 Pod마다 PVC와 PV를 만들고 삭제 뒤에도 PVC가 남는 구조
  • Pod마다 PVC가 하나씩 생긴다: data-db-0, data-db-1, …
  • Pod이 죽었다 살아나도 같은 PVC를 다시 붙인다 (이름이 고정이므로)
  • StatefulSet을 지워도 PVC는 남는다. 데이터 보호가 기본 동작이다
터미널 창
kubectl get pvc -l app=db
kubectl delete pvc data-db-0 # 정말 지우려면 명시적으로

Deployment + RWO PVC + RollingUpdate에서 새 Pod이 다른 노드에 배치되면 옛 Pod과 볼륨을 동시에 쓰려다 막힐 수 있다. 왜 교착이 되는지는 시간순으로 보면 명확하다.

RollingUpdate에서 RWO PV를 두고 옛 Pod과 새 Pod이 서로를 기다리는 교착
  1. 새 Pod이 다른 노드에 스케줄된다
  2. 옛 Pod이 아직 볼륨을 잡고 있다
  3. 새 Pod: Multi-Attach error → ContainerCreating에서 멈춘다
  4. 옛 Pod은 새 Pod이 Ready가 될 때까지 안 죽는다 → 교착

해결 — 넷 중 하나

strategy: Recreate

옛 Pod을 먼저 죽이고 새 Pod을 만든다. 가장 간단하다. 짧은 다운타임을 받아들이는 셈.

maxSurge: 0

replicas: 1을 유지하고 새 Pod을 덧붙이지 않게 한다.

StatefulSet

Pod마다 PVC가 따로 생기므로 애초에 충돌하지 않는다.

RWX 스토리지

NFS·CephFS·EFS로 바꾸면 여러 노드에서 동시 마운트가 된다.

  • volumeClaimTemplates는 Pod의 ordinal마다 별도 PVC를 만든다.
  • 기본 보존 정책에서는 StatefulSet을 지워도 PVC가 남는다.
  • 공유 RWO 볼륨의 Multi-Attach는 옛 Pod과 새 Pod의 노드·교체 순서를 확인한다.