쿠버네티스 마스터 — Storage·Volume·PV·PVC

2026-05-03확률과 통계 마스터 노트

쿠버네티스 마스터 노트 시리즈 6편. Pod이 일회용인 환경에서 데이터를 영속화하는 4단계 추상화(Volume → PV → PVC → StorageClass), emptyDir·hostPath·PV의 결정적 차이, AccessMode 3종(RWO·ROX·RWX), Dynamic Provisioning이 운영을 바꾼 이유, CSI 드라이버 표준, ReclaimPolicy 함정까지.

이 글은 쿠버네티스 마스터 노트 시리즈의 여섯 번째 편입니다. 5편(Config)까지 설정 주입이었다면, 이번엔 데이터를 어떻게 영속화하나 — Storage 4 계층.

Pod이 사라지면 안 사라져야 하는 데이터 — DB·로그·업로드 파일. K8s Storage 추상화가 그 답. 다만 PV·PVC·StorageClass 3 객체 관계가 처음엔 막연합니다.

처음 Storage가 어렵게 느껴지는 이유

처음 이 단원이 어렵게 느껴지는 이유는 두 가지예요. 첫째, 계층이 4개입니다 — Volume·PV·PVC·StorageClass. 누가 누구를 참조? 둘째, Static vs Dynamic Provisioning 차이가 막연합니다.

해결법은 한 가지예요. "PVC가 PV를 요청하고, StorageClass가 PV를 자동 생성" 한 줄. 사용자(Pod)는 PVC만 작성, 운영자가 PV 만들거나 StorageClass가 자동. 이 그림이 잡히면 흐름이 보입니다.

4 계층 추상화

[Pod]
  ↓ uses
[PVC] (Persistent Volume Claim) — 사용자가 요청
  ↓ binds
[PV] (Persistent Volume) — 클러스터 자원
  ↓ provisioned by (옵션)
[StorageClass] — 자동 PV 생성 정책
  ↓ uses
[CSI Driver] — 실제 스토리지 (AWS EBS·NFS·Ceph 등)

Volume — Pod 안 단순 스토리지

가장 단순. Pod 정의 안에 직접:

spec:
  containers:
    - name: app
      volumeMounts:
        - name: cache
          mountPath: /tmp/cache
  volumes:
    - name: cache
      emptyDir: {}        # 또는 hostPath / configMap / secret 등

emptyDir — 임시

volumes:
  - name: cache
    emptyDir: {}

Pod 생성 시 빈 디렉토리. Pod 삭제 시 함께 사라짐.

용도:

  • 컨테이너 사이 파일 공유 (Sidecar)
  • 임시 캐시
  • 스크래치 공간

여기서 정말 중요한 시험 함정 — emptyDir = Pod 생명주기. Pod 다운 시 데이터 사라짐. 영속 X.

hostPath — 노드 디스크 직접

volumes:
  - name: docker-sock
    hostPath:
      path: /var/run/docker.sock
      type: Socket

노드 호스트 디렉토리 마운트.

여기서 시험 함정이 하나 있어요. hostPath는 보안 위험. 노드 시스템 디렉토리 접근 가능. 운영 환경 거의 X. 모니터링·시스템 데몬에만.

PV — Persistent Volume (영속 자원)

클러스터 단위 영속 스토리지.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-data
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
  hostPath:
    path: /data/pv-data

특성:

  • 클러스터 단위 (namespace X)
  • 관리자가 미리 만들거나 (Static) 동적 생성 (Dynamic)
  • AccessMode·ReclaimPolicy 명시

PVC — Persistent Volume Claim (사용자 요청)

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard
# Pod에서 PVC 사용
spec:
  containers:
    - name: app
      volumeMounts:
        - name: data
          mountPath: /data
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: my-pvc

흐름:

1. PVC 생성 → "5Gi RWO 필요"
2. K8s가 매칭 PV 찾기 → bind
3. Pod에서 PVC 참조 → 자동 마운트

여기서 정말 중요한 시험 함정 — PVC는 namespace 단위, PV는 cluster 단위. PVC 한 namespace 안. 다른 namespace에서 같은 PV 사용 X.

AccessMode — 3종

모드 의미 약자
ReadWriteOnce 한 노드에서만 읽기·쓰기 RWO
ReadOnlyMany 여러 노드에서 읽기만 ROX
ReadWriteMany 여러 노드에서 읽기·쓰기 RWX
ReadWriteOncePod (1.22+) 한 Pod에서만 (RWO 강화) RWOP

스토리지별 지원

스토리지 RWO ROX RWX
AWS EBS O X X
GCP Persistent Disk O O X
NFS O O O
CephFS O O O
GlusterFS O O O
Azure Disk O X X

여기서 정말 중요한 시험 함정 — 블록 스토리지(EBS·Disk)는 RWX 미지원. RWX 필요 = NFS·CephFS·EFS 등 파일 시스템. 여러 Pod에서 같은 데이터 = RWX 필요.

StorageClass — Dynamic Provisioning

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp3
  iopsPerGB: "10"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

PVC가 StorageClass 지정 → 자동으로 PV 생성 (provisioner가 스토리지 생성).

# PVC
spec:
  storageClassName: fast      # ← StorageClass 이름
  accessModes: [ReadWriteOnce]
  resources:
    requests:
      storage: 100Gi

흐름:

1. PVC 생성 (StorageClass: fast)
2. provisioner가 AWS EBS 100Gi 자동 생성
3. PV 자동 생성·PVC와 자동 bind
4. Pod 사용

Static vs Dynamic

측면 Static Dynamic
PV 생성 관리자 수동 StorageClass 자동
환경 온프레미스·고정 자원 클라우드
권장 작은 클러스터 운영 표준

여기서 시험 함정이 하나 있어요. 클라우드 환경 = Dynamic이 표준. EKS·GKE는 기본 StorageClass 자동 설치 (gp2·standard 등).

ReclaimPolicy — PV 회수 정책

spec:
  persistentVolumeReclaimPolicy: Retain   # 또는 Delete / Recycle
정책 의미
Retain PVC 삭제 시 PV·데이터 보존 (수동 정리)
Delete PVC 삭제 시 PV·실제 스토리지 삭제
Recycle (deprecated)

여기서 정말 중요한 시험 함정 — Dynamic Provisioning 기본 = Delete. PVC 실수 삭제 시 데이터 영영 사라짐. DB·중요 데이터 = Retain 권장.

# 안전한 패턴
storageClassName: critical
reclaimPolicy: Retain

VolumeBindingMode

volumeBindingMode: Immediate            # 또는 WaitForFirstConsumer
  • Immediate — PVC 생성 즉시 PV bind
  • WaitForFirstConsumer — Pod이 PVC 사용할 때까지 대기

여기서 시험 함정이 하나 있어요. WaitForFirstConsumer 권장 (Multi-AZ 환경). PV의 AZ가 Pod 스케줄링되는 노드 AZ와 일치하도록 대기. Immediate 시 잘못된 AZ에 PV 생성 가능.

CSI — Container Storage Interface

K8s 1.13+ 표준 스토리지 플러그인 인터페이스.

[K8s] → CSI Driver → [실제 스토리지]
                     - AWS EBS CSI Driver
                     - GCP PD CSI Driver
                     - Azure Disk CSI Driver
                     - Longhorn (분산 블록)
                     - Rook/Ceph
                     - OpenEBS
                     - NFS CSI Driver

이전엔 in-tree 플러그인 (K8s 코드에 직접). 지금은 모두 CSI로 분리. 외부 도구·확장 자유.

VolumeSnapshot — 백업

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: db-snapshot
spec:
  volumeSnapshotClassName: csi-snapshot
  source:
    persistentVolumeClaimName: db-pvc

CSI 지원 시 PVC를 스냅샷으로. 복구 = 새 PVC를 스냅샷에서 생성.

운영 권장 패턴

DB·중요 데이터

storageClassName: standard
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true

일회용·캐시

emptyDir: {}
# 또는
storageClassName: fast
reclaimPolicy: Delete

StatefulSet과 결합

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

각 StatefulSet Pod마다 자동 PVC 생성 (data-pg-0, data-pg-1).

디버깅

# PV·PVC 상태
kubectl get pv
kubectl get pvc
kubectl describe pvc <name>

# StorageClass
kubectl get sc

# Pod의 PVC 사용 확인
kubectl describe pod <name>

상태:

  • Pending — 매칭 PV 없음 (Static) / Provisioner 동작 중 (Dynamic)
  • Bound — 정상
  • Lost — PV 사라짐

시험 직전 한 번 더 — 자주 헷갈리는 함정 모음

여기까지가 6편의 핵심입니다. 시험 직전 또는 실무에서 헷갈릴 때 다시 펼쳐 볼 수 있게 압축 노트로 마무리할게요.

  • 4 계층 — Volume / PV / PVC / StorageClass
  • Volume = Pod 안 단순 (emptyDir·hostPath·configMap·secret 등)
  • emptyDir = Pod 생명주기
  • hostPath = 보안 위험·운영 X (시스템 데몬만)
  • PV = 클러스터 단위 영속 자원
  • PVC = namespace 단위 사용자 요청
  • PVC가 PV bind, Pod이 PVC 참조
  • AccessMode 3종 — RWO·ROX·RWX
  • 블록 스토리지(EBS·Disk) = RWX 미지원
  • RWX 필요 = NFS·CephFS·EFS
  • StorageClass = Dynamic Provisioning 자동
  • 클라우드 환경 표준
  • 클라우드 = 기본 StorageClass 자동 설치
  • ReclaimPolicy — Retain (보존) / Delete (삭제)
  • Dynamic 기본 = Delete (위험) → DB는 Retain
  • VolumeBindingMode — Immediate / WaitForFirstConsumer (Multi-AZ 권장)
  • CSI = 표준 스토리지 플러그인 인터페이스
  • in-tree → CSI로 분리 (1.13+)
  • VolumeSnapshot = PVC 백업 (CSI 지원 시)
  • allowVolumeExpansion = 크기 확장 가능
  • StatefulSet volumeClaimTemplates = Pod별 자동 PVC

시리즈 다른 편

공식 문서: Kubernetes Storage / CSI Drivers 에서 더 깊이.

다음 글(7편)에서는 Scaling & Scheduling — HPA·VPA·Probes·Affinity·Taint/Toleration까지 풀어 갑니다.

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!