쿠버네티스에서 스토리지를 다룰 때 꼭 알아야 할 개념들을 정리했습니다.
Volume, PV, PVC, StorageClass, CSI, mount까지 하나의 글로 연결해 설명합니다.
👉 따라서 데이터 영속성(Persistence)이 필요하고, 이를 위해 Volume 개념이 등장함
emptyDir: Pod가 살아있는 동안만 유지, Pod가 죽으면 데이터도 삭제hostPath: 노드 파일시스템의 특정 경로를 Pod에 마운트👉 하지만 여전히 노드에 종속되어, 다른 노드로 이동 시 데이터 접근 불가
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
path: /srv/nfs
server: 10.0.0.1
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-demo
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "echo hello > /data/hello.txt; sleep 3600"]
volumeMounts:
- mountPath: /data
name: storage
volumes:
- name: storage
persistentVolumeClaim:
claimName: pvc-demo
👉 Pod는 /data를 통해 실제 PV가 연결된 스토리지에 접근 가능
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: sc-gcp
provisioner: pd.csi.storage.gke.io
parameters:
type: pd-standard
PVC에서 storageClassName: sc-gcp를 지정하면, 자동으로 PV가 프로비저닝됨
$ kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer true 120d
standard kubernetes.io/gce-pd Delete Immediate true 150d
nfs-storage nfs.csi.k8s.io Retain Immediate false 30d
(default) 라벨이 있으면 PVC에서 지정하지 않아도 기본 사용됨Delete, Retain)Immediate, WaitForFirstConsumer)| 컬럼 | 의미 | 예시 |
|---|---|---|
| NAME | StorageClass 이름 (PVC에서 지정) | gp2 (default) |
| PROVISIONER | 실제 스토리지를 생성하는 드라이버 | kubernetes.io/aws-ebs, nfs.csi.k8s.io |
| RECLAIMPOLICY | PVC 삭제 시 스토리지 처리 방식 | Delete, Retain |
| VOLUMEBINDINGMODE | PV 바인딩 시점 | Immediate, WaitForFirstConsumer |
| ALLOWVOLUMEEXPANSION | PVC 크기 확장 가능 여부 | true, false |
| AGE | 생성된 시간 | 120d |
스토리지 클래스는 WaitForFirstConsumer로 설정된 VolumeBindingMode를 사용. 이것은 PersistentVolumeClaim을 사용하는 파드가 생성될 때까지 PersistentVolume의 바인딩과 프로비저닝을 지연시킴.

운영체제에서 저장소(디스크, 네트워크 스토리지)를 특정 디렉토리와 연결하는 과정
리눅스 예시:
mount /dev/sdb1 /mnt/usb
# 이제 /mnt/usb 디렉토리 안에서 USB 내용을 확인 가능
/data 같은 디렉토리에 연결Pod ─▶ PVC ─▶ PV ─▶ Storage Backend (EBS, NFS, Ceph 등)
│
└─▶ MountPath (/data)
👉 Pod 입장에서는 로컬 디렉토리처럼 보이지만, 실제로는 외부 스토리지에 저장됨
[ Static Provisioning ]
관리자: PV 생성 ─────▶ PVC와 바인딩
[ Dynamic Provisioning ]
개발자: PVC 생성 ──▶ StorageClass 확인 ──▶ CSI 드라이버가 스토리지 백엔드에 볼륨 생성 ──▶ PV 자동 생성 & PVC 바인딩
[Pod] [Kubernetes Node] [외부 스토리지]
┌─────────────┐ ┌───────────────────────┐ ┌──────────────┐
│ Container │ <--/data--> │ Kubelet + CSI Driver │ <---> │ EBS / NFS │
└─────────────┘ └───────────────────────┘ └──────────────┘
│ │
│ PVC 요청 (1Gi) │ PV 매핑
▼ ▼
PersistentVolumeClaim ───> PersistentVolume ───> 실제 Storage
👉 Pod는 단순히 /data처럼 보이지만, 실제로는 외부 스토리지에 연결되어 영속 데이터를 저장할 수 있음
개발자: PVC 생성
└─▶ StorageClass 확인
└─▶ CSI 드라이버 호출
└─▶ 실제 스토리지 생성 (EBS, NFS, Ceph 등)
└─▶ PV 생성 & PVC 바인딩
└─▶ Pod에서 mountPath로 사용 (/data)