영구 볼륨

영구 볼륨 (Persistent Volumes)

이 문서는 쿠버네티스의 영구 볼륨(persistent volumes) 을 설명해요. 볼륨, StorageClass, VolumeAttributesClasses에 대한 기본 지식을 권장해요.

출처: Kubernetes 공식 문서 — Persistent Volumes

소개 (Introduction)

스토리지를 관리하는 것은 컴퓨팅 인스턴스를 관리하는 것과는 별개의 문제예요. PersistentVolume 하위 시스템은 스토리지가 어떻게 제공되는지와 어떻게 소비되는지의 세부 사항을 추상화하는 API를 사용자와 관리자에게 제공해요. 이를 위해 두 가지 새로운 API 리소스인 PersistentVolume과 PersistentVolumeClaim을 도입해요.

PersistentVolume(PV)은 관리자가 프로비저닝했거나 Storage Class를 사용해 동적으로 프로비저닝된 클러스터 안의 스토리지 조각이에요. 노드가 클러스터 리소스인 것처럼 PV도 클러스터의 리소스예요. PV는 볼륨과 같은 볼륨 플러그인이지만, PV를 사용하는 어떤 개별 Pod와도 독립적인 수명주기를 가져요. 이 API 객체는 스토리지 구현의 세부 사항(NFS, iSCSI, 클라우드 제공자별 스토리지 시스템)을 담아요.

PersistentVolumeClaim(PVC)은 사용자가 하는 스토리지 요청이에요. Pod와 비슷해요. Pod는 노드 리소스를 소비하고 PVC는 PV 리소스를 소비해요. Pod는 특정 수준의 리소스(CPU와 메모리)를 요청할 수 있어요. Claim은 특정 크기와 접근 모드를 요청할 수 있어요(예: ReadWriteOnce, ReadOnlyMany, ReadWriteMany, ReadWriteOncePod로 마운트할 수 있어요. AccessModes 참고).

PersistentVolumeClaim은 사용자가 추상적인 스토리지 리소스를 소비하게 해주지만, 사용자는 문제에 따라 성능 같은 다양한 속성을 가진 PersistentVolume이 필요한 경우가 흔해요. 클러스터 관리자는 크기와 접근 모드 이상으로 달라지는 다양한 PersistentVolume을, 구현 세부 사항을 사용자에게 노출하지 않고 제공할 수 있어야 해요. 이런 요구를 위해 StorageClass 리소스가 있어요.

볼륨과 claim의 수명주기 (Lifecycle of a volume and claim)

PV는 클러스터의 리소스예요. PVC는 그 리소스에 대한 요청이면서 동시에 리소스에 대한 claim 확인 역할을 해요. PV와 PVC의 상호작용은 다음 수명주기를 따라요.

프로비저닝 (Provisioning)

PV는 정적으로나 동적으로 프로비저닝될 수 있는 두 가지 방법이 있어요.

정적 (Static)

클러스터 관리자가 여러 PV를 만들어요. 이 PV들은 클러스터 사용자가 사용할 수 있는 실제 스토리지의 세부 사항을 담아요. 쿠버네티스 API에 존재하며 소비할 수 있게 돼요.

동적 (Dynamic)

관리자가 만든 정적 PV 중 사용자의 PersistentVolumeClaim과 일치하는 것이 없으면, 클러스터가 PVC를 위해 볼륨을 특별히 동적으로 프로비저닝하려고 시도할 수 있어요. 이 프로비저닝은 StorageClass를 기반으로 해요: PVC가 스토리지 클래스를 요청해야 하고, 동적 프로비저닝이 일어나려면 관리자가 그 클래스를 만들고 구성했어야 해요. "" 클래스를 요청하는 claim은 스스로 동적 프로비저닝을 비활성화해요.

스토리지 클래스 기반의 동적 스토리지 프로비저닝을 활성화하려면, 클러스터 관리자가 API 서버에서 DefaultStorageClass 승인 컨트롤러를 활성화해야 해요. 예를 들어 API 서버 컴포넌트의 --enable-admission-plugins 플래그의 쉼표로 구분된 순서 목록에 DefaultStorageClass가 있는지 확인하면 돼요. API 서버 커맨드라인 플래그에 대한 자세한 내용은 kube-apiserver 문서를 확인하세요.

바인딩 (Binding)

사용자는 특정 양의 스토리지를 요청하고 특정 접근 모드를 가진 PersistentVolumeClaim을 만들거나, 동적 프로비저닝의 경우 이미 만들어져 있어요. 컨트롤 플레인의 컨트롤 루프는 새 PVC를 관찰하다가, 가능하면 일치하는 PV를 찾아서 둘을 함께 바인딩해요. 새 PVC를 위해 PV가 동적으로 프로비저닝되었다면 그 루프는 항상 그 PV를 PVC에 바인딩해요. 그 외에는 사용자는 항상 요청한 것 이상은 받지만, 볼륨이 요청한 것보다 클 수 있어요. 일단 바인딩되면 PersistentVolumeClaim 바인딩은 어떻게 바인딩됐든 배타적이에요. PVC에서 PV로의 바인딩은 1:1 매핑이며, PersistentVolume과 PersistentVolumeClaim 사이의 양방향 바인딩인 ClaimRef를 사용해요.

일치하는 볼륨이 존재하지 않으면 claim은 무기한 바인딩되지 않은 상태로 남아요. 일치하는 볼륨이 생기면 claim이 바인딩돼요. 예를 들어 50Gi PV가 많은 클러스터는 100Gi를 요청하는 PVC와 일치하지 않아요. 100Gi PV가 클러스터에 추가되면 PVC가 바인딩될 수 있어요.

사용 (Using)

Pod는 claim을 볼륨으로 사용해요. 클러스터는 claim을 검사해 바인딩된 볼륨을 찾고 그 볼륨을 Pod를 위해 마운트해요. 여러 접근 모드를 지원하는 볼륨의 경우, 사용자는 claim을 Pod의 볼륨으로 사용할 때 원하는 모드를 지정해요.

사용자가 claim을 갖고 그 claim이 바인딩되면, 바인딩된 PV는 사용자가 필요로 하는 동안 사용자에게 속해요. 사용자는 Pod의 volumes 블록에 persistentVolumeClaim 섹션을 포함해 Pod를 스케줄링하고 요청한 PV에 접근해요. 더 자세한 내용은 Claim As Volumes를 참고하세요.

사용 중인 스토리지 객체 보호 (Storage Object in Use Protection)

사용 중인 스토리지 객체 보호 기능의 목적은 Pod가 활발히 사용 중인 PersistentVolumeClaim(PVC)과 PVC에 바인딩된 PersistentVolume(PV)이 시스템에서 제거되지 않도록 보장하는 거예요. 이는 데이터 손실로 이어질 수 있기 때문이에요.

참고:

PVC를 사용하는 Pod 객체가 존재하면 그 PVC는 Pod가 활발히 사용 중인 상태예요.

Pod가 활발히 사용 중인 PVC를 사용자가 삭제하면 PVC는 즉시 제거되지 않아요. PVC 제거는 어떤 Pod도 더 이상 그 PVC를 활발히 사용하지 않을 때까지 연기돼요. 또한 관리자가 PVC에 바인딩된 PV를 삭제해도 PV는 즉시 제거되지 않아요. PV 제거는 더 이상 PVC에 바인딩되지 않을 때까지 연기돼요.

PVC의 상태가 Terminating이고 Finalizers 목록에 kubernetes.io/pvc-protection이 포함되어 있으면 해당 PVC가 보호되고 있음을 알 수 있어요:

kubectl describe pvc hostpath
Name:          hostpath
Namespace:     default
StorageClass:  example-hostpath
Status:        Terminating
Volume:
Labels:        <none>
Annotations:   volume.beta.kubernetes.io/storage-class=example-hostpath
               volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers:    [kubernetes.io/pvc-protection]
...

PV의 상태가 Terminating이고 Finalizers 목록에 kubernetes.io/pv-protection도 포함되어 있으면 해당 PV가 보호되고 있음을 알 수 있어요:

kubectl describe pv task-pv-volume
Name:            task-pv-volume
Labels:          type=local
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    standard
Status:          Terminating
Claim:
Reclaim Policy:  Delete
Access Modes:    RWO
Capacity:        1Gi
Message:
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /tmp/data
    HostPathType:
Events:            <none>

반환 (Reclaiming)

사용자가 볼륨을 다 쓰면 API에서 PVC 객체를 삭제해 리소스 반환을 허용할 수 있어요. PersistentVolume의 반환 정책(reclaim policy)은 claim에서 해제된 후 클러스터가 볼륨을 어떻게 할지 알려줘요. 현재 볼륨은 Retained, Recycled, Deleted 중 하나가 될 수 있어요.

유지 (Retain)

Retain 반환 정책은 리소스의 수동 반환을 허용해요. PersistentVolumeClaim이 삭제되면 PersistentVolume은 여전히 존재하고 볼륨은 "해제(released)"된 것으로 간주돼요. 하지만 이전 요청자의 데이터가 볼륨에 남아 있으므로 아직 다른 claim에 사용할 수 없어요. 관리자는 다음 단계로 볼륨을 수동으로 반환할 수 있어요.

  1. PersistentVolume을 삭제해요. PV가 삭제된 후에도 외부 인프라의 관련 스토리지 자산은 여전히 존재해요.
  2. 관련 스토리지 자산의 데이터를 그에 맞게 수동으로 정리해요.
  3. 관련 스토리지 자산을 수동으로 삭제해요.

같은 스토리지 자산을 재사용하려면 같은 스토리지 자산 정의를 가진 새 PersistentVolume을 만들어요.

삭제 (Delete)

Delete 반환 정책을 지원하는 볼륨 플러그인의 경우, 삭제는 PersistentVolume 객체를 쿠버네티스에서 제거할 뿐 아니라 외부 인프라의 관련 스토리지 자산도 제거해요. 동적으로 프로비저닝된 볼륨은 기본적으로 Delete인 StorageClass의 반환 정책을 상속해요. 관리자는 사용자 기대에 맞게 StorageClass를 구성해야 해요. 그렇지 않으면 PV가 생성된 후 편집하거나 패치해야 해요. PersistentVolume의 반환 정책 변경하기를 참고하세요.

재활용 (Recycle)

경고:

Recycle 반환 정책은 폐기(deprecated)됐어요. 대신 동적 프로비저닝을 사용하는 방법이 권장돼요.

밑바탕이 되는 볼륨 플러그인이 지원한다면, Recycle 반환 정책은 볼륨에 기본 정리(rm -rf /thevolume/*)를 수행하고 새 claim에 다시 사용할 수 있게 해요.

하지만 관리자는 참조 문서에 설명된 쿠버네티스 컨트롤러 매니저 커맨드라인 인자를 사용해 커스텀 재활용 Pod 템플릿을 구성할 수 있어요. 커스텀 재활용 Pod 템플릿은 아래 예시처럼 volumes 사양을 포함해야 해요:

apiVersion: v1
kind: Pod
metadata:
  name: pv-recycler
  namespace: default
spec:
  restartPolicy: Never
  volumes:
  - name: vol
    hostPath:
      path: /any/path/it/will/be/replaced
  containers:
  - name: pv-recycler
    image: "registry.k8s.io/busybox"
    command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/*  && test -z \"$(ls -A /scrub)\" || exit 1"]
    volumeMounts:
    - name: vol
      mountPath: /scrub

다만 커스텀 재활용 Pod 템플릿의 volumes 부분에 지정된 특정 경로는 재활용 중인 볼륨의 특정 경로로 바뀌어요.

PersistentVolume 삭제 보호 finalizer

기능 상태: Kubernetes v1.33 [stable](기본 활성화)

finalizer를 PersistentVolume에 추가해서 Delete 반환 정책을 가진 PersistentVolume이 백킹 스토리지가 삭제된 후에만 삭제되도록 보장할 수 있어요.

external-provisioner.volume.kubernetes.io/finalizer finalizer(v1.31에서 도입)는 동적 프로비저닝된 CSI 볼륨과 정적 프로비저닝된 CSI 볼륨 모두에 추가돼요.

kubernetes.io/pv-controller finalizer(v1.31에서 도입)는 동적으로 프로비저닝된 in-tree 플러그인 볼륨에 추가되고, 정적으로 프로비저닝된 in-tree 플러그인 볼륨에는 건너뛰어요.

다음은 동적으로 프로비저닝된 in-tree 플러그인 볼륨의 예시예요:

kubectl describe pv pvc-74a498d6-3929-47e8-8c02-078c1ece4d78
Name:            pvc-74a498d6-3929-47e8-8c02-078c1ece4d78
Labels:          <none>
Annotations:     kubernetes.io/createdby: vsphere-volume-dynamic-provisioner
                 pv.kubernetes.io/bound-by-controller: yes
                 pv.kubernetes.io/provisioned-by: kubernetes.io/vsphere-volume
Finalizers:      [kubernetes.io/pv-protection kubernetes.io/pv-controller]
StorageClass:    vcp-sc
Status:          Bound
Claim:           default/vcp-pvc-1
Reclaim Policy:  Delete
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        1Gi
Node Affinity:   <none>
Message:
Source:
    Type:               vSphereVolume (a Persistent Disk resource in vSphere)
    VolumePath:         [vsanDatastore] d49c4a62-166f-ce12-c464-020077ba5d46/kubernetes-dynamic-pvc-74a498d6-3929-47e8-8c02-078c1ece4d78.vmdk
    FSType:             ext4
    StoragePolicyName:  vSAN Default Storage Policy
Events:                 <none>

external-provisioner.volume.kubernetes.io/finalizer finalizer는 CSI 볼륨에 추가돼요. 다음은 예시예요:

Name:            pvc-2f0bab97-85a8-4552-8044-eb8be45cf48d
Labels:          <none>
Annotations:     pv.kubernetes.io/provisioned-by: csi.vsphere.vmware.com
Finalizers:      [kubernetes.io/pv-protection external-provisioner.volume.kubernetes.io/finalizer]
StorageClass:    fast
Status:          Bound
Claim:           demo-app/nginx-logs
Reclaim Policy:  Delete
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        200Mi
Node Affinity:   <none>
Message:
Source:
    Type:              CSI (a Container Storage Interface (CSI) volume source)
    Driver:            csi.vsphere.vmware.com
    FSType:            ext4
    VolumeHandle:      44830fa8-79b4-406b-8b58-621ba25353fd
    ReadOnly:          false
    VolumeAttributes:      storage.kubernetes.io/csiProvisionerIdentity=1648442357185-8081-csi.vsphere.vmware.com
                           type=vSphere CNS Block Volume
Events:                <none>

특정 in-tree 볼륨 플러그인에 대해 CSIMigration{provider} 기능 플래그가 활성화되면, kubernetes.io/pv-controller finalizer는 external-provisioner.volume.kubernetes.io/finalizer finalizer로 바뀌어요.

이 finalizer들은 PV의 반환 정책이 Delete일 때 볼륨이 스토리지 백엔드에서 삭제된 후에만 PV 객체가 제거되도록 보장해요. 또한 PV와 PVC의 삭제 순서와 관계없이 볼륨이 스토리지 백엔드에서 삭제되도록 보장해요.

PersistentVolume 예약 (Reserving a PersistentVolume)

컨트롤 플레인은 PersistentVolumeClaim을 일치하는 클러스터의 PersistentVolume에 바인딩할 수 있어요. 하지만 PVC를 특정 PV에 바인딩하고 싶다면 미리 바인딩(pre-bind)해야 해요.

PersistentVolumeClaim에 PersistentVolume을 지정하면, 그 특정 PV와 PVC 사이의 바인딩을 선언하는 거예요. PersistentVolume이 존재하고 claimRef 필드를 통해 PersistentVolumeClaim을 예약하지 않았다면, PersistentVolume과 PersistentVolumeClaim이 바인딩돼요.

바인딩은 노드 친화성 같은 일부 볼륨 일치 기준과 무관하게 일어나요. 컨트롤 플레인은 여전히 스토리지 클래스, 접근 모드, 요청된 스토리지 크기가 유효한지는 확인해요.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: foo-pvc
  namespace: foo
spec:
  storageClassName: "" # 빈 문자열은 명시적으로 설정해야 해요. 그렇지 않으면 기본 StorageClass가 설정돼요.
  volumeName: foo-pv
  ...

이 방법은 PersistentVolume에 어떤 바인딩 특권도 보장하지 않아요. 지정한 PV를 다른 PersistentVolumeClaim이 사용할 수 있다면, 먼저 그 스토리지 볼륨을 예약해야 해요. 다른 PVC가 바인딩할 수 없도록 PV의 claimRef 필드에 관련 PersistentVolumeClaim을 지정하세요.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: foo-pv
spec:
  storageClassName: ""
  claimRef:
    name: foo-pvc
    namespace: foo
  ...

이 방법은 persistentVolumeReclaimPolicyRetain으로 설정된 PersistentVolume을 소비하고 싶을 때, 기존 PV를 재사용하는 경우를 포함해 유용해요.

PersistentVolumeClaim 확장 (Expanding Persistent Volumes Claims)

기능 상태: Kubernetes v1.24 [stable]

PersistentVolumeClaim(PVC) 확장 지원은 기본 활성화돼 있어요. 다음 유형의 볼륨을 확장할 수 있어요.

  • csi(일부 CSI 마이그레이션 볼륨 유형 포함)
  • flexVolume(폐기됨)
  • portworxVolume(폐기됨)

PVC의 스토리지 클래스 allowVolumeExpansion 필드가 true로 설정된 경우에만 PVC를 확장할 수 있어요.

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: example-vol-default
provisioner: vendor-name.example/magicstorage
parameters:
  resturl: "http://192.168.10.100:8080"
  restuser: ""
  secretNamespace: ""
  secretName: ""
allowVolumeExpansion: true

PVC에 더 큰 볼륨을 요청하려면 PVC 객체를 편집하고 더 큰 크기를 지정해요. 이렇게 하면 밑바탕이 되는 PersistentVolume을 백킹하는 볼륨의 확장이 촉발돼요. claim을 충족하기 위해 새 PersistentVolume이 만들어지지는 않아요. 대신 기존 볼륨의 크기가 조정돼요.

경고:

PersistentVolume의 크기를 직접 편집하면 그 볼륨의 자동 크기 조정을 막을 수 있어요. PersistentVolume의 용량을 편집한 다음 일치하는 PersistentVolumeClaim의 .spec을 편집해 PVC 크기를 PV와 맞추면, 스토리지 크기 조정은 일어나지 않아요. 쿠버네티스 컨트롤 플레인은 두 리소스의 원하는 상태가 일치함을 보고, 백킹 볼륨 크기가 수동으로 늘어났고 크기 조정이 필요 없다고 결론 내려요.

CSI 볼륨 확장

기능 상태: Kubernetes v1.24 [stable]

CSI 볼륨 확장 지원은 기본 활성화돼 있지만, 특정 CSI 드라이버가 볼륨 확장을 지원해야 해요. 자세한 내용은 특정 CSI 드라이버 문서를 참고하세요.

파일시스템을 포함한 볼륨 크기 조정

파일시스템을 포함한 볼륨은 파일시스템이 XFS, Ext3, Ext4인 경우에만 크기를 조정할 수 있어요.

볼륨이 파일시스템을 포함하면, 새 Pod가 ReadWrite 모드로 PersistentVolumeClaim을 사용할 때만 파일시스템 크기가 조정돼요. 파일시스템 확장은 Pod가 시작할 때나, Pod가 실행 중이고 밑바탕이 되는 파일시스템이 온라인 확장을 지원할 때 수행돼요.

FlexVolumes(쿠버네티스 v1.23부터 폐기)는 드라이버가 RequiresFSResize capability를 true로 구성된 경우 크기 조정을 허용해요. FlexVolume은 Pod 재시작 시 크기를 조정할 수 있어요.

사용 중인 PersistentVolumeClaim 크기 조정

기능 상태: Kubernetes v1.24 [stable]

이 경우 기존 PVC를 사용하는 Pod나 배포를 삭제하고 다시 만들 필요가 없어요. 사용 중인 PVC는 파일시스템이 확장되는 즉시 해당 Pod에서 자동으로 사용 가능하게 돼요. 이 기능은 Pod나 배포가 사용하지 않는 PVC에는 효과가 없어요. 확장이 완료되기 전에 PVC를 사용하는 Pod를 만들어야 해요.

다른 볼륨 유형과 비슷하게 FlexVolume 볼륨도 Pod가 사용 중일 때 확장할 수 있어요.

참고:

FlexVolume 크기 조정은 밑바탕이 되는 드라이버가 크기 조정을 지원할 때만 가능해요.

볼륨 확장 실패에서 복구하기

사용자가 밑바탕이 되는 스토리지 시스템이 충족할 수 없을 만큼 큰 새 크기를 지정하면, PVC 확장은 사용자나 클러스터 관리자가 어떤 조치를 취할 때까지 계속 재시도돼요. 이는 바람직하지 않을 수 있어서, 쿠버네티스는 이런 실패에서 복구하는 다음 방법을 제공해요.

밑바탕이 되는 스토리지 확장이 실패하면, 클러스터 관리자가 PersistentVolumeClaim(PVC) 상태를 수동으로 복구하고 크기 조정 요청을 취소할 수 있어요. 그렇지 않으면 크기 조정 요청은 관리자 개입 없이 컨트롤러가 계속 재시도해요.

  1. PersistentVolumeClaim(PVC)에 바인딩된 PersistentVolume(PV)을 Retain 반환 정책으로 표시해요.
  2. PVC를 삭제해요. PV가 Retain 반환 정책이므로 PVC를 다시 만들어도 데이터는 잃지 않아요.
  3. 새 PVC가 바인딩할 수 있도록 PV 스펙에서 claimRef 항목을 삭제해요. 그러면 PV가 Available이 돼요.
  4. PV보다 작은 크기로 PVC를 다시 만들고 PVC의 volumeName 필드를 PV의 이름으로 설정해요. 이러면 새 PVC가 기존 PV에 바인딩돼요.
  5. PV의 반환 정책을 복원하는 것을 잊지 마세요.

PVC 확장이 실패했다면 이전에 요청한 값보다 작은 크기로 확장을 재시도할 수 있어요. 더 작은 크기로 새 확장 시도를 요청하려면 그 PVC의 .spec.resources를 편집하고 이전에 시도한 값보다 작은 값을 선택해요. 용량 제약 때문에 더 큰 값으로의 확장이 성공하지 못했을 때 유용해요. 그런 일이 발생했거나 발생할 수도 있다고 의심된다면, 밑바탕이 되는 스토리지 제공자의 용량 한도 내에 있는 크기를 지정해 확장을 재시도할 수 있어요. 크기 조정 작업 상태는 .status.allocatedResourceStatuses와 PVC의 이벤트를 관찰해 모니터링할 수 있어요.

이전에 요청한 것보다 적은 스토리지 양을 지정할 수는 있지만, 새 값은 여전히 .status.capacity보다는 커야 한다는 점에 주의하세요. 쿠버네티스는 PVC를 현재 크기보다 작게 줄이는 것을 지원하지 않아요.

Persistent Volume의 유형 (Types of Persistent Volumes)

PersistentVolume 유형은 플러그인으로 구현돼요. 쿠버네티스는 현재 다음 플러그인을 지원해요.

  • csi - Container Storage Interface (CSI)
  • fc - Fibre Channel (FC) 스토리지
  • hostPath - HostPath 볼륨(단일 노드 테스트 전용. 멀티 노드 클러스터에서는 작동하지 않아요. local 볼륨 사용을 고려하세요)
  • iscsi - iSCSI (SCSI over IP) 스토리지
  • local - 노드에 마운트된 로컬 스토리지 장치
  • nfs - Network File System (NFS) 스토리지

다음 PersistentVolume 유형은 폐기됐지만 여전히 사용할 수 있어요. flexVolume, cephfs, rbd를 제외한 이 볼륨 유형을 사용한다면 해당 CSI 드라이버를 설치하세요.

  • awsElasticBlockStore - AWS Elastic Block Store (EBS)(v1.23부터 마이그레이션 기본 활성화)
  • azureDisk - Azure Disk(v1.23부터 마이그레이션 기본 활성화)
  • azureFile - Azure File(v1.24부터 마이그레이션 기본 활성화)
  • cinder - Cinder(OpenStack 블록 스토리지)(v1.21부터 마이그레이션 기본 활성화)
  • flexVolume - FlexVolume(v1.23부터 폐기, 마이그레이션 계획도 지원 제거 계획도 없음)
  • gcePersistentDisk - GCE Persistent Disk(v1.23부터 마이그레이션 기본 활성화)
  • portworxVolume - Portworx 볼륨(v1.31부터 마이그레이션 기본 활성화)
  • vsphereVolume - vSphere VMDK 볼륨(v1.25부터 마이그레이션 기본 활성화)

이전 쿠버네티스 버전은 다음 in-tree PersistentVolume 유형도 지원했어요.

  • cephfs(v1.31부터 사용 불가)
  • flocker - Flocker 스토리지(v1.25부터 사용 불가)
  • glusterfs - GlusterFS 스토리지(v1.26부터 사용 불가)
  • photonPersistentDisk - Photon 컨트롤러 영구 디스크(v1.15부터 사용 불가)
  • quobyte - Quobyte 볼륨(v1.25부터 사용 불가)
  • rbd - Rados Block Device (RBD) 볼륨(v1.31부터 사용 불가)
  • scaleIO - ScaleIO 볼륨(v1.21부터 사용 불가)
  • storageos - StorageOS 볼륨(v1.25부터 사용 불가)

Persistent Volumes

각 PV에는 볼륨의 스펙과 상태인 spec과 status가 포함돼요. PersistentVolume 객체의 이름은 유효한 DNS 하위 도메인 이름이어야 해요.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  mountOptions:
    - hard
    - nfsvers=4.1
  nfs:
    path: /tmp
    server: 172.17.0.2

참고:

클러스터 안에서 PersistentVolume을 소비하려면 볼륨 유형과 관련된 도우미 프로그램이 필요할 수 있어요. 이 예시에서 PersistentVolume은 NFS 유형이고, NFS 파일시스템의 마운트를 지원하려면 도우미 프로그램 /sbin/mount.nfs가 필요해요.

용량 (Capacity)

일반적으로 PV는 특정 스토리지 용량을 가져요. PV의 capacity 속성으로 설정하는데, 이 속성은 Quantity 값이에요.

현재 스토리지 크기만 설정하거나 요청할 수 있는 리소스예요. 미래에는 IOPS, 처리량 같은 속성이 추가될 수 있어요.

볼륨 모드 (Volume Mode)

기능 상태: Kubernetes v1.18 [stable]

쿠버네티스는 PersistentVolume의 두 가지 volumeModeFilesystemBlock을 지원해요.

volumeMode는 선택적 API 파라미터예요. volumeMode 파라미터를 생략하면 Filesystem이 기본 모드예요.

volumeMode: Filesystem인 볼륨은 Pod에 디렉터리로 마운트돼요. 볼륨이 블록 장치에 의해 백킹되고 장치가 비어 있다면, 쿠버네티스는 처음 마운트하기 전에 장치에 파일시스템을 만들어요.

volumeMode 값을 Block으로 설정하면 볼륨을 원시 블록 장치로 사용할 수 있어요. 그런 볼륨은 파일시스템 없이 블록 장치로 Pod에 제공돼요. 이 모드는 Pod와 볼륨 사이에 파일시스템 계층 없이, Pod가 볼륨에 접근할 수 있는 가장 빠른 방법을 제공할 때 유용해요. 반면 Pod에서 실행 중인 애플리케이션은 원시 블록 장치를 다루는 법을 알아야 해요. Pod에서 volumeMode: Block 볼륨을 사용하는 예시는 Raw Block Volume Support를 참고하세요.

접근 모드 (Access Modes)

PersistentVolume은 리소스 제공자가 지원하는 어떤 방식으로든 호스트에 마운트될 수 있어요. 아래 표처럼 제공자는 각자 다른 능력을 갖고 있고, 각 PV의 접근 모드는 그 특정 볼륨이 지원하는 특정 모드로 설정돼요. 예를 들어 NFS는 여러 읽기/쓰기 클라이언트를 지원할 수 있지만, 특정 NFS PV는 서버에서 읽기 전용으로 내보내질 수 있어요. 각 PV는 그 특정 PV의 능력을 설명하는 자체 접근 모드 집합을 가져요.

접근 모드는 다음과 같아요.

  • ReadWriteOnce 볼륨은 단일 노드가 읽기-쓰기로 마운트할 수 있어요. ReadWriteOnce 접근 모드는 Pod들이 같은 노드에서 실행 중일 때 여전히 여러 Pod가 그 볼륨에 접근(읽거나 쓰거나)할 수 있게 해줘요. 단일 Pod 접근은 ReadWriteOncePod를 참고하세요.
  • ReadOnlyMany 볼륨은 여러 노드가 읽기 전용으로 마운트할 수 있어요.
  • ReadWriteMany 볼륨은 여러 노드가 읽기-쓰기로 마운트할 수 있어요.
  • ReadWriteOncePod 기능 상태: Kubernetes v1.29 [stable] — 볼륨은 단일 Pod가 읽기-쓰기로 마운트할 수 있어요. 클러스터 전체에서 오직 하나의 Pod만 그 PVC를 읽거나 쓸 수 있게 보장하고 싶다면 ReadWriteOncePod 접근 모드를 사용하세요.

CLI에서 접근 모드는 다음과 같이 축약돼요.

  • RWO - ReadWriteOnce
  • ROX - ReadOnlyMany
  • RWX - ReadWriteMany
  • RWOP - ReadWriteOncePod

참고:

쿠버네티스는 볼륨 접근 모드를 사용해 PersistentVolumeClaim과 PersistentVolume을 일치시켜요. 어떤 경우에는 볼륨 접근 모드가 PersistentVolume을 어디에 마운트할 수 있는지도 제한해요. 볼륨 접근 모드는 스토리지가 마운트된 후에는 쓰기 보호를 강제하지 않아요. ReadWriteOnce, ReadOnlyMany, ReadWriteMany로 지정돼도 볼륨에 제약을 설정하지 않아요. 예를 들어 PersistentVolume이 ReadOnlyMany로 만들어져도 읽기 전용이라는 보장은 없어요. 접근 모드가 ReadWriteOncePod로 지정되면 볼륨은 제약되어 단일 Pod에만 마운트될 수 있어요.

중요! 볼륨은 여러 접근 모드를 지원하더라도 한 번에 하나의 접근 모드로만 마운트할 수 있어요.

볼륨 플러그인 ReadWriteOnce ReadOnlyMany ReadWriteMany ReadWriteOncePod
AzureFile -
CephFS -
CSI 드라이버에 따라 다름 드라이버에 따라 다름 드라이버에 따라 다름 드라이버에 따라 다름
FC - -
FlexVolume 드라이버에 따라 다름 -
HostPath - - -
iSCSI - -
NFS -
RBD - -
VsphereVolume - -(Pod가 같은 위치에 있을 때 작동) -
PortworxVolume - -

클래스 (Class)

PV는 storageClassName 속성을 StorageClass의 이름으로 설정해 클래스를 가질 수 있어요. 특정 클래스의 PV는 그 클래스를 요청하는 PVC에만 바인딩될 수 있어요. storageClassName이 없는 PV는 클래스가 없고, 특정 클래스를 요청하지 않는 PVC에만 바인딩될 수 있어요.

과거에는 storageClassName 속성 대신 volume.beta.kubernetes.io/storage-class 애노테이션을 사용했어요. 이 애노테이션은 여전히 작동하지만, 향후 쿠버네티스 릴리스에서 완전히 폐기될 거예요.

반환 정책 (Reclaim Policy)

현재 반환 정책은 다음과 같아요.

  • Retain — 수동 반환
  • Recycle — 기본 정리(rm -rf /thevolume/*)
  • Delete — 볼륨 삭제

쿠버네티스 1.36에서는 nfshostPath 볼륨 유형만 재활용을 지원해요.

마운트 옵션 (Mount Options)

쿠버네티스 관리자는 Persistent Volume이 노드에 마운트될 때 추가 마운트 옵션을 지정할 수 있어요.

참고:

모든 Persistent Volume 유형이 마운트 옵션을 지원하는 것은 아니에요.

다음 볼륨 유형이 마운트 옵션을 지원해요.

  • csi(CSI 마이그레이션 볼륨 유형 포함)
  • iscsi
  • nfs

마운트 옵션은 검증되지 않아요. 마운트 옵션이 유효하지 않으면 마운트가 실패해요.

과거에는 mountOptions 속성 대신 volume.beta.kubernetes.io/mount-options 애노테이션을 사용했어요. 이 애노테이션은 여전히 작동하지만, 향후 쿠버네티스 릴리스에서 완전히 폐기될 거예요.

노드 친화성 (Node Affinity)

참고:

대부분의 볼륨 유형에서는 이 필드를 설정할 필요가 없어요. local 볼륨에는 명시적으로 설정해야 해요.

PV는 이 볼륨이 접근될 수 있는 노드를 제한하는 제약을 정의하는 노드 친화성을 지정할 수 있어요. PV를 사용하는 Pod는 노드 친화성이 선택한 노드에만 스케줄링돼요. 노드 친화성을 지정하려면 PV의 .specnodeAffinity를 설정해요. PersistentVolume API 참조에 이 필드에 대한 더 많은 세부 사항이 있어요.

노드 친화성 업데이트

기능 상태: Kubernetes v1.35 [alpha](기본 비활성화)

클러스터에서 MutablePVNodeAffinity 기능 게이트가 활성화되면, PersistentVolume의 .spec.nodeAffinity 필드는 변경 가능해요. 이렇게 하면 클러스터 관리자나 외부 스토리지 컨트롤러가 실행 중인 Pod를 중단하지 않고 데이터가 마이그레이션될 때 PersistentVolume의 노드 친화성을 업데이트할 수 있어요.

노드 친화성을 업데이트할 때, 새 노드 친화성이 볼륨이 현재 사용 중인 노드와 여전히 일치하는지 확인해야 해요. 새 친화성을 위반하는 Pod는 이미 실행 중이라면 계속 실행될 수 있어요. 하지만 쿠버네티스는 이 구성을 지원하지 않아요. 위반하는 Pod는 곧 종료해야 해요. 인메모리 캐싱 때문에, 업데이트 후 생성된 Pod가 잠시 동안 이전 노드 친화성에 따라 스케줄링될 수도 있어요.

이 기능을 사용하려면 다음 컴포넌트에서 MutablePVNodeAffinity 기능 게이트를 활성화해야 해요.

  • kube-apiserver
  • kubelet

단계 (Phase)

PersistentVolume은 다음 단계 중 하나에 있게 돼요.

  • Available 아직 claim에 바인딩되지 않은 사용 가능한 리소스
  • Bound 볼륨이 claim에 바인딩됨
  • Released claim이 삭제됐지만 관련 스토리지 리소스가 아직 클러스터에 반환되지 않음
  • Failed 볼륨이 (자동) 반환에 실패함

kubectl describe persistentvolume <name>을 사용해 PV에 바인딩된 PVC의 이름을 볼 수 있어요.

기능 상태: Kubernetes v1.31 [stable](기본 활성화)

PersistentVolume의 .status 필드는 알파 상태의 lastPhaseTransitionTime 필드를 포함할 수 있어요. 이 필드는 볼륨이 마지막으로 단계를 전환한 시점의 타임스탬프를 기록해요. 새로 생성된 볼륨의 경우 단계는 Pending으로 설정되고 lastPhaseTransitionTime은 현재 시간으로 설정돼요.

PersistentVolumeClaims

각 PVC에는 claim의 스펙과 상태인 spec과 status가 포함돼요. PersistentVolumeClaim 객체의 이름은 유효한 DNS 하위 도메인 이름이어야 해요.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

접근 모드 (Access Modes)

Claim은 특정 접근 모드로 스토리지를 요청할 때 볼륨과 같은 규칙을 사용해요.

볼륨 모드 (Volume Modes)

Claim은 볼륨을 파일시스템이나 블록 장치로 소비함을 나타낼 때 볼륨과 같은 규칙을 사용해요.

볼륨 이름 (Volume Name)

Claim은 volumeName 필드를 사용해 특정 PersistentVolume에 명시적으로 바인딩할 수 있어요. volumeName을 설정하지 않으면 쿠버네티스가 claim과 일치하는 새 PersistentVolume을 설정하길 원한다는 의미예요. 지정한 PV가 이미 다른 PVC에 바인딩되어 있으면 바인딩이 pending 상태에 갇히게 돼요.

리소스 (Resources)

Claim은 Pod처럼 특정 양의 리소스를 요청할 수 있어요. 이 경우 요청은 스토리지에 대한 거예요. 리소스 모델이 볼륨과 claim 모두에 적용돼요.

참고:

Filesystem 볼륨의 경우 스토리지 요청은 "바깥쪽" 볼륨 크기(스토리지 백엔드에서 할당된 크기)를 의미해요. 즉 블록 장치 위에 파일시스템을 만드는 제공자의 경우 파일시스템 오버헤드 때문에 쓰기 가능한 크기가 약간 더 작을 수 있어요. 특히 XFS에서는 많은 메타데이터 기능이 기본 활성화되어 있어서 더 눈에 띄어요.

셀렉터 (Selector)

Claim은 라벨 셀렉터를 지정해 볼륨 집합을 더 필터링할 수 있어요. 셀렉터와 일치하는 라벨을 가진 볼륨만 claim에 바인딩될 수 있어요. 셀렉터는 두 필드로 구성될 수 있어요.

  • matchLabels - 볼륨이 이 값의 라벨을 가져야 해요.
  • matchExpressions - 키, 값 목록, 키와 값을 연결하는 연산자를 지정해 만든 요구사항 목록이에요. 유효한 연산자는 In, NotIn, Exists, DoesNotExist예요.

matchLabelsmatchExpressions의 모든 요구사항은 AND로 결합돼요 — 모두 충족해야 일치해요.

클래스 (Class)

Claim은 storageClassName 속성을 사용해 StorageClass의 이름을 지정해 특정 클래스를 요청할 수 있어요. 요청한 클래스의 PV, 즉 PVC와 같은 storageClassName을 가진 PV만 PVC에 바인딩될 수 있어요.

PVC가 꼭 클래스를 요청할 필요는 없어요. storageClassName""로 설정된 PVC는 항상 클래스가 없는 PV를 요청하는 것으로 해석되므로, 클래스가 없는 PV(애노테이션이 없거나 ""로 설정된 것)에만 바인딩될 수 있어요. storageClassName이 없는 PVC는 완전히 같지는 않아서, DefaultStorageClass 승인 플러그인이 켜져 있는지에 따라 클러스터가 다르게 처리해요.

  • 승인 플러그인이 켜져 있으면 관리자가 기본 StorageClass를 지정할 수 있어요. storageClassName이 없는 모든 PVC는 그 기본 클래스의 PV에만 바인딩될 수 있어요. 기본 StorageClass를 지정하는 것은 StorageClass 객체에 storageclass.kubernetes.io/is-default-class 애노테이션을 true로 설정해요. 관리자가 기본을 지정하지 않으면, 클러스터는 승인 플러그인이 꺼진 것처럼 PVC 생성을 처리해요. 기본 StorageClass가 두 개 이상 지정되면, PVC가 동적으로 프로비저닝될 때 가장 최신 기본이 사용돼요.
  • 승인 플러그인이 꺼져 있으면 기본 StorageClass라는 개념이 없어요. storageClassName""로 설정된 모든 PVC는 storageClassName""로 설정된 PV에만 바인딩될 수 있어요. 하지만 storageClassName이 없는 PVC는 나중에 기본 StorageClass가 생기면 업데이트될 수 있어요. PVC가 업데이트되면 그 이후로는 storageClassName""로 설정된 PV에 바인딩되지 않아요.

자세한 내용은 소급 기본 StorageClass 할당을 참고하세요.

설치 방법에 따라 기본 StorageClass는 설치 중 애드온 매니저가 쿠버네티스 클러스터에 배포할 수 있어요.

PVC가 StorageClass를 요청하는 것에 더해 selector를 지정하면, 요구사항이 AND로 결합돼요: 요청한 클래스이면서 요청한 라벨을 가진 PV만 PVC에 바인딩될 수 있어요.

참고:

현재 비어 있지 않은 selector를 가진 PVC는 PV가 동적으로 프로비저닝될 수 없어요.

과거에는 storageClassName 속성 대신 volume.beta.kubernetes.io/storage-class 애노테이션을 사용했어요. 이 애노테이션은 여전히 작동하지만, 향후 쿠버네티스 릴리스에서 지원되지 않을 거예요.

소급 기본 StorageClass 할당 (Retroactive default StorageClass assignment)

기능 상태: Kubernetes v1.28 [stable]

새 PVC에 storageClassName을 지정하지 않고 PersistentVolumeClaim을 만들 수 있어요. 클러스터에 기본 StorageClass가 없을 때도 가능해요. 이 경우 새 PVC는 정의한 대로 생성되고, 기본이 생길 때까지 그 PVC의 storageClassName은 설정되지 않은 상태로 남아요.

기본 StorageClass가 생기면, 컨트롤 플레인은 storageClassName이 없는 기존 PVC를 식별해요. storageClassName이 빈 값이거나 이 키가 없는 PVC에 대해 컨트롤 플레인은 그 PVC의 storageClassName을 새 기본 StorageClass와 일치하도록 업데이트해요. 기존 PVC에서 storageClassName""이고 기본 StorageClass를 구성했다면, 이 PVC는 업데이트되지 않아요.

(기본 StorageClass가 있는 동안) storageClassName""로 설정된 PV에 계속 바인딩하려면, 관련 PVC의 storageClassName""로 설정해야 해요.

이 동작은 관리자가 먼저 기존 기본을 제거한 다음 다른 것을 만들거나 설정해서 기본 StorageClass를 바꾸는 데 도움이 돼요. 기본이 없는 이 짧은 창 동안 생성된 storageClassName 없는 PVC는 기본이 없게 되지만, 소급 기본 StorageClass 할당 덕분에 이렇게 기본을 바꾸는 방식은 안전해요.

사용하지 않는 PVC 추적 (Unused PVC tracking)

기능 상태: Kubernetes v1.36 [alpha](기본 비활성화)

활성화되면 PVC 보호 컨트롤러가 각 PersistentVolumeClaim에 Unused 조건을 추가해서, 현재 어떤 비종료(non-terminal) Pod가 참조하고 있는지 여부를 나타내요.

이 조건에는 두 가지 상태가 있어요.

  • status"True"Unused(reason NoPodsUsingPVC) 어떤 비종료 Pod도 이 PVC를 참조하지 않아요. lastTransitionTime은 PVC가 사용되지 않게 된 시점을 기록해요.
  • status"False"Unused(reason PodUsingPVC) 현재 하나 이상의 비종료 Pod가 이 PVC를 참조해요. lastTransitionTime은 PVC 사용이 시작된 시점을 기록해요.

Pod의 phase가 SucceededFailed가 아니면 비종료로 간주돼요. 즉 Pending Pod(아직 스케줄링되지 않은 것 포함)도 PVC를 사용하는 것으로 간주돼요.

Unused 조건의 lastTransitionTime은 클러스터 관리자, 모니터링 도구, 외부 컨트롤러가 오랫동안 사용되지 않은 PVC를 식별하는 데 사용할 수 있어요. 예를 들어 30일 이상 사용되지 않은 모든 PVC를 찾으려면 Unused 조건의 status: "True"이고 lastTransitionTime이 30일보다 오래된 PVC를 조회하면 돼요.

참고:

이 조건이 나타내는 미사용 기간은 컨트롤러의 처리 지연이나 PVC가 이미 사용되지 않은 후에 기능이 활성화됐기 때문에 실제 미사용 시간보다 짧을 수 있어요. 이 조건은 PVC에 deletionTimestamp가 설정되면(즉 삭제 중인 PVC) 업데이트되지 않아요.

Claim을 볼륨으로 사용 (Claims As Volumes)

Pod는 claim을 볼륨으로 사용해 스토리지에 접근해요. claim은 claim을 사용하는 Pod와 같은 네임스페이스에 존재해야 해요. 클러스터는 Pod의 네임스페이스에서 claim을 찾아 claim을 백킹하는 PersistentVolume을 얻는 데 사용해요. 그런 다음 볼륨이 호스트와 Pod에 마운트돼요.

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: myfrontend
      image: nginx
      volumeMounts:
      - mountPath: "/var/www/html"
        name: mypd
  volumes:
    - name: mypd
      persistentVolumeClaim:
        claimName: myclaim

네임스페이스에 대한 참고 (A Note on Namespaces)

PersistentVolume 바인딩은 배타적이고, PersistentVolumeClaim은 네임스페이스가 있는 객체이므로, "Many" 모드(ROX, RWX)로 claim을 마운트하는 것은 하나의 네임스페이스 안에서만 가능해요.

hostPath 유형의 PersistentVolume

hostPath PersistentVolume은 노드의 파일이나 디렉터리를 사용해 네트워크 연결 스토리지를 흉내 내요. hostPath 유형 볼륨의 예시를 참고하세요.

원시 블록 볼륨 지원 (Raw Block Volume Support)

기능 상태: Kubernetes v1.18 [stable]

다음 볼륨 플러그인은 해당되는 경우 동적 프로비저닝을 포함해 원시 블록 볼륨을 지원해요.

  • CSI(일부 CSI 마이그레이션 볼륨 유형 포함)
  • FC(Fibre Channel)
  • iSCSI
  • Local 볼륨

원시 블록 볼륨을 사용하는 PersistentVolume

apiVersion: v1
kind: PersistentVolume
metadata:
  name: block-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  volumeMode: Block
  persistentVolumeReclaimPolicy: Retain
  fc:
    targetWWNs: ["50060e801049cfd1"]
    lun: 0
    readOnly: false

원시 블록 볼륨을 요청하는 PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: block-pvc
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Block
  resources:
    requests:
      storage: 10Gi

컨테이너에 원시 블록 장치 경로를 추가하는 Pod 스펙

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-block-volume
spec:
  containers:
    - name: fc-container
      image: fedora:26
      command: ["/bin/sh", "-c"]
      args: [ "tail -f /dev/null" ]
      volumeDevices:
        - name: data
          devicePath: /dev/xvda
  volumes:
    - name: data
      persistentVolumeClaim:
        claimName: block-pvc

참고:

Pod에 원시 블록 장치를 추가할 때는 마운트 경로 대신 컨테이너에 장치 경로를 지정해요.

블록 볼륨 바인딩 (Binding Block Volumes)

사용자가 PersistentVolumeClaim 스펙의 volumeMode 필드로 원시 블록 볼륨을 요청하면, 바인딩 규칙은 이 모드를 스펙의 일부로 고려하지 않던 이전 릴리스와 약간 달라져요. 사용자와 관리자가 원시 블록 장치를 요청할 때 지정할 수 있는 가능한 조합의 표는 다음과 같아요. 이 표는 조합에 따라 볼륨이 바인딩되는지 여부를 나타내요. 정적으로 프로비저닝된 볼륨에 대한 볼륨 바인딩 행렬:

PV volumeMode PVC volumeMode 결과
지정 안 함 지정 안 함 BIND
지정 안 함 Block NO BIND
지정 안 함 Filesystem BIND
Block 지정 안 함 NO BIND
Block Block BIND
Block Filesystem NO BIND
Filesystem Filesystem BIND
Filesystem Block NO BIND
Filesystem 지정 안 함 BIND

참고:

알파 릴리스에서는 정적으로 프로비저닝된 볼륨만 지원돼요. 관리자는 원시 블록 장치를 작업할 때 이 값들을 고려해야 해요.

볼륨 스냅샷과 스냅샷에서 볼륨 복원 지원 (Volume Snapshot and Restore Volume from Snapshot Support)

기능 상태: Kubernetes v1.20 [stable]

볼륨 스냅샷은 out-of-tree CSI 볼륨 플러그인만 지원해요. 자세한 내용은 볼륨 스냅샷을 참고하세요. In-tree 볼륨 플러그인은 폐기됐어요. 폐기된 볼륨 플러그인에 대해 볼륨 플러그인 FAQ에서 읽을 수 있어요.

볼륨 스냅샷에서 PersistentVolumeClaim 만들기

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: restore-pvc
spec:
  storageClassName: csi-hostpath-sc
  dataSource:
    name: new-snapshot-test
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

볼륨 클로닝 (Volume Cloning)

볼륨 클로닝은 CSI 볼륨 플러그인에서만 사용할 수 있어요.

기존 PVC에서 PersistentVolumeClaim 만들기

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: cloned-pvc
spec:
  storageClassName: my-csi-plugin
  dataSource:
    name: existing-src-pvc-name
    kind: PersistentVolumeClaim
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

볼륨 선별자(populator)와 데이터 소스 (Volume populators and data sources)

볼륨 클로닝과 스냅샷 복원은 새 볼륨을 내장 데이터 소스에서 미리 채워요. 볼륨 선별자는 이 메커니즘을 확장해서 PersistentVolumeClaim이 dataSourceRef 필드를 통해 참조되는 다른 종류의 소스(커스텀 리소스)에서 미리 채워질 수 있게 해줘요:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: populated-pvc
spec:
  dataSourceRef:
    name: example-name
    kind: ExampleDataSource
    apiGroup: example.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

네임스페이스 간 데이터 소스를 포함한 자세한 내용은 볼륨 선별자와 데이터 소스를 참고하세요.

이식 가능한 구성 작성 (Writing Portable Configuration)

광범위한 클러스터에서 실행되고 영구 스토리지가 필요한 구성 템플릿이나 예시를 작성한다면 다음 패턴을 사용하는 것이 권장돼요.

  • PersistentVolumeClaim 객체를 (Deployment, ConfigMap 등과 함께) 구성 번들에 포함해요.
  • PersistentVolume 객체는 구성에 포함하지 마세요. 구성을 생성하는 사용자가 PersistentVolume을 만들 권한이 없을 수 있기 때문이에요.
  • 템플릿을 생성할 때 사용자에게 스토리지 클래스 이름을 제공할 옵션을 주세요.
    • 사용자가 스토리지 클래스 이름을 제공하면 그 값을 persistentVolumeClaim.storageClassName 필드에 넣어요. 그러면 클러스터에 관리자가 활성화한 StorageClass가 있다면 PVC가 올바른 스토리지 클래스와 일치해요.
    • 사용자가 스토리지 클래스 이름을 제공하지 않으면 persistentVolumeClaim.storageClassName 필드를 nil로 남겨두세요. 그러면 클러스터의 기본 StorageClass로 사용자를 위해 PV가 자동 프로비저닝돼요. 많은 클러스터 환경에 기본 StorageClass가 설치되어 있거나, 관리자가 직접 기본 StorageClass를 만들 수 있어요.
  • 도구에서 얼마 후에도 바인딩되지 않는 PVC를 관찰하고 이를 사용자에게 알려주세요. 이는 클러스터에 동적 스토리지 지원이 없거나(이 경우 사용자가 일치하는 PV를 만들어야 함) 클러스터에 스토리지 시스템이 없어서(PVC가 필요한 구성을 배포할 수 없음)일 수 있어요.

다음으로 볼 것 (What's next)

API 참조 (API references)

이 페이지에 설명된 API에 대해 읽어보세요.