[kubernetes] Storage (Volume, CSI, PV, PVC, Storage Class)

Xabi·2025년 9월 16일

kubernetes

목록 보기
18/20

📦 Kubernetes Storage 완전 정리

쿠버네티스에서 스토리지를 다룰 때 꼭 알아야 할 개념들을 정리했습니다.
Volume, PV, PVC, StorageClass, CSI, mount까지 하나의 글로 연결해 설명합니다.


1. 왜 Volume이 필요한가?

  • 컨테이너는 이미지 위에 쓰기 가능한 레이어(Write Layer)를 올려 실행됨
  • 컨테이너 내부에 저장한 데이터는 컨테이너 종료 시 함께 삭제
  • Pod도 재시작하면 새로운 컨테이너가 만들어져 데이터 손실 발생

👉 따라서 데이터 영속성(Persistence)이 필요하고, 이를 위해 Volume 개념이 등장함


2. Volume 기본 개념

  • Pod 내부 컨테이너가 사용할 수 있는 디스크 공간
  • 컨테이너가 종료되어도 데이터를 보존 가능 (종류에 따라 다름)
  • 예시:
    • emptyDir: Pod가 살아있는 동안만 유지, Pod가 죽으면 데이터도 삭제
    • hostPath: 노드 파일시스템의 특정 경로를 Pod에 마운트

👉 하지만 여전히 노드에 종속되어, 다른 노드로 이동 시 데이터 접근 불가


3. PersistentVolume (PV)

  • 클러스터 차원에서 관리되는 스토리지 리소스
  • 실제 물리/클라우드 스토리지에 대한 추상화
  • Pod와 독립적으로 존재
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /srv/nfs
    server: 10.0.0.1

4. PersistentVolumeClaim (PVC)

  • 사용자가 작성하는 스토리지 요청서
  • PV와 조건이 맞으면 자동으로 바인딩됨
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-demo
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

5. Pod에서 PVC 사용

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가 연결된 스토리지에 접근 가능


6. StorageClass

  • 스토리지를 동적으로 생성하기 위한 설정
  • 어떤 CSI 드라이버를 사용할지, 어떤 종류의 스토리지를 만들지 정의
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가 프로비저닝됨

StorageClass 상세 설명

예시 출력

$ 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

컬럼별 의미

  • NAME: StorageClass 이름. (default) 라벨이 있으면 PVC에서 지정하지 않아도 기본 사용됨
  • PROVISIONER: 어떤 CSI/인트리 드라이버가 실제 스토리지를 생성할지
  • RECLAIMPOLICY: PVC 삭제 시 스토리지 처리 방식 (Delete, Retain)
  • VOLUMEBINDINGMODE: PV 바인딩 시점 (Immediate, WaitForFirstConsumer)
  • ALLOWVOLUMEEXPANSION: PVC 크기 확장 가능 여부
  • AGE: 생성된 지 얼마나 되었는지
컬럼의미예시
NAMEStorageClass 이름 (PVC에서 지정)gp2 (default)
PROVISIONER실제 스토리지를 생성하는 드라이버kubernetes.io/aws-ebs, nfs.csi.k8s.io
RECLAIMPOLICYPVC 삭제 시 스토리지 처리 방식Delete, Retain
VOLUMEBINDINGMODEPV 바인딩 시점Immediate, WaitForFirstConsumer
ALLOWVOLUMEEXPANSIONPVC 크기 확장 가능 여부true, false
AGE생성된 시간120d

스토리지 클래스는 WaitForFirstConsumer로 설정된 VolumeBindingMode를 사용. 이것은 PersistentVolumeClaim을 사용하는 파드가 생성될 때까지 PersistentVolume의 바인딩과 프로비저닝을 지연시킴.


7. CSI (Container Storage Interface)

  • 쿠버네티스가 다양한 스토리지 벤더(AWS, GCP, Ceph 등)를 표준 방식으로 연결할 수 있도록 만든 인터페이스
  • CSI 드라이버가 실제 스토리지를 붙여줌
  • Kubernetes는 CSI 덕분에 클라우드/온프레미스/외부 스토리지 모두 통합적으로 다룰 수 있음

8. Mount 개념

Mount란?

운영체제에서 저장소(디스크, 네트워크 스토리지)를 특정 디렉토리와 연결하는 과정

리눅스 예시:

mount /dev/sdb1 /mnt/usb
# 이제 /mnt/usb 디렉토리 안에서 USB 내용을 확인 가능

Kubernetes에서의 Mount

  • CSI 드라이버가 외부 스토리지를 노드에 마운트
  • 그 경로를 다시 Pod의 /data 같은 디렉토리에 연결
Pod ─▶ PVC ─▶ PV ─▶ Storage Backend (EBS, NFS, Ceph 등)
       │
       └─▶ MountPath (/data)

👉 Pod 입장에서는 로컬 디렉토리처럼 보이지만, 실제로는 외부 스토리지에 저장됨


9. 프로비저닝 (Provisioning)

(1) 정적 프로비저닝 (Static Provisioning)

  • 관리자가 미리 PV를 생성
  • PVC는 해당 PV와 바인딩만 수행
  • 유연성이 낮음

(2) 동적 프로비저닝 (Dynamic Provisioning)

  • PVC가 생성되면 Kubernetes가 StorageClass를 참고하여
    PV와 실제 스토리지를 자동 생성
  • 실무에서 가장 많이 쓰임
[ Static Provisioning ]
관리자: PV 생성 ─────▶ PVC와 바인딩

[ Dynamic Provisioning ]
개발자: PVC 생성 ──▶ StorageClass 확인 ──▶ CSI 드라이버가 스토리지 백엔드에 볼륨 생성 ──▶ PV 자동 생성 & PVC 바인딩

10. 전체 구조 도식화

[Pod]                          [Kubernetes Node]                   [외부 스토리지]
┌─────────────┐                 ┌───────────────────────┐          ┌──────────────┐
│   Container │ <--/data-->     │   Kubelet + CSI Driver │ <--->   │   EBS / NFS  │
└─────────────┘                 └───────────────────────┘          └──────────────┘
       │                                  │
       │ PVC 요청 (1Gi)                   │ PV 매핑
       ▼                                  ▼
  PersistentVolumeClaim  ───>  PersistentVolume  ───>  실제 Storage

✅ 요약

  • Volume: Pod 내 컨테이너에서 사용하는 저장소
  • PV: 클러스터 단위에서 정의된 스토리지 리소스 (추상화)
  • PVC: 사용자가 요청하는 스토리지 (요청서)
  • StorageClass: 스토리지를 동적으로 생성/관리하는 방법 정의
  • CSI: 실제 스토리지 시스템과 Kubernetes를 연결하는 표준
  • Mount: 디렉토리와 스토리지를 연결하는 과정

👉 Pod는 단순히 /data처럼 보이지만, 실제로는 외부 스토리지에 연결되어 영속 데이터를 저장할 수 있음


최종 흐름 정리

개발자: PVC 생성
  └─▶ StorageClass 확인
        └─▶ CSI 드라이버 호출
              └─▶ 실제 스토리지 생성 (EBS, NFS, Ceph 등)
                    └─▶ PV 생성 & PVC 바인딩
                          └─▶ Pod에서 mountPath로 사용 (/data)
profile
롱런하는 개발자!

0개의 댓글