Computing

Pod 스토리지 (2): PV & PVC, Dynamic Provisioning 본문

Cloud/Kubernetes

Pod 스토리지 (2): PV & PVC, Dynamic Provisioning

jhson989 2023. 5. 9. 21:57

이전글

- Pod 스토리지 (1): Volume, PersistentVolume, PersistentVolumeClaim 개념

 

 

PV (PersistentVolume) & PVC (PersistentVolumeClaim)

이전 글에서 정리하였지만, Volume 컴포넌트는 Pod에 외부 저장소(스토리지)를 제공하기 위한 Pod의 컴포넌트이다(emptyDir 타입 Volume은 제외). 따라서 Pod가 제거된다면 Volume 컴포넌트 또한 함께 제거된다. 다만 주의할 점은 외부 저장소 자체가 제거되는 것은 아니라 데이터는 보존 가능하다.

 

그에 비해 PersistentVolume(PV, 지속되는 볼륨)은 이름 그대로 Volume과는 다르게 지속된다. 즉 Pod와 제거되더라도 유지된다. PersistentVolume은 Volume 컴포넌트와는 다르게 Pod와 마찬가지로 최상위 레벨 리소스이다. 즉 개발자가 PV만을 위한 yaml 파일을 작성하여 PV만을 독립적으로 배포할 수 있다. 따라서 개발자가 PV를 의도적으로 지우지 않는 한 계속 지속되는 Volume이다.

 

개발자가 PV를 사용하기 위해서(즉 Pod에 마운트 시키기 위해서)는 PersistentVolumeClaim(PVC, PV 신청)을 생성하여야 한다. PVC도 Pod와 마찬가지인 최상위 레벨 리소스로, 개발자가 yaml 파일을 작성하여 독립적으로 배포한다. PVC에는 어떠한 접근 모드(ReadWriteOnce, ReadOnlyMany, ReadWriteMany), 얼마만큼의 용량을 가진 볼륨이 필요한지가 명시된다. 경우에 따라 어떤 유형의 PV를 사용할지를 명시하기도 한다(StorageClass라는 항목을 통해 명시, 명시하지 않는다면 기본 StorageClass를 사용함).

 

구체적으로 PV를 Pod에 사용하는 Mount하는 과정은 다음 Fig 1.과 같다.

 

Fig 1. PV&PVC를 이용한 외부 저장소 마운트

 

Fig 1.에서 보듯, PV&PVC를 사용하면 쿠버네티스 인프라 담당자와 Pod 개발자(애플리케이션 개발자)의 역할이 구분됨을 확인할 수 있다. 인프라 담당자는 NFS, Ceph, gcePersistentDisk, awsElastic-BlockStore 등 다양한 네트워크 스토리지 상에서 저장공간을 미리 Provisioning(프로비저닝, 자원 할당)하고 이를 PV로 쿠버네티스 시스템에 등록해둔다. Pod 개발자는 원하는 조건을 담은 PVC를 생성한다. 이때 쿠버네티스 시스템이 자동으로 PVC에 맞는 PV를 찾아 Binding(바인딩, 할당)한다. 마지막으로 Pod가 내부 Volume 컴포넌트를 통해 PVC를 참조하면, 최종으로 Pod에 외부 스토리지가 마운트된다.

 

이전 글에서도 정리하였지만, 이러한 방식을 정적 프로비저닝(Static Provisioning)이라고 한다. 인프라 담당자가 미리 PV를 만들어놓아야 하고, 사용자가 요청=PVC가 생성되면 미리 만들어진 PV 중 선택하여 PVC에 바인딩한다. 문제는 PV가 미리 만들어져 있어야 하기에, 미리 많은 PV를 만들어두어야 한다. 만약 사용자의 요청=PVC가 생성될 때, 자동으로 PVC에 맞는 PV가 생성되면 좋지 않을까? 쿠버네티스는 이를 위해 동적 프로비저닝(Dynamic Provisioning)을 지원한다. 동적 프로비저닝은 인프라 담당자의 개입없이도 자동으로 PVC에 맞는 PV를 생성할 수 있게 한다.

 

 

 

Dynamic Provisioning

동적 프로비저닝[1]은 PV 생성(=볼륨 프로비저닝) 과정을 온전히 쿠버네티스 시스템에게 맡기는 것이다. 동적 볼륨 프로비저닝은 개발자의 스토리지 요청될 때(=PVC가 생성될 때)에 On-demand 방식으로 스토리지 볼륨을 생성한다. 이를 통해 인프라 관리자는 수동으로 PV를 생성할 필요가 없어진다.

 

동적 볼륨 프로비저닝이 활성화되기 위해서는 어떤 쿠버네티스 오브젝트가 인프라 관리자의 역할(=볼륨 프로비저닝)을 대신 수행하여야 할 것이다.  쿠버네티스는 StorageClass(스토리지 클래스) API 오브젝트와 볼륨 플러그인(혹은 프로비저너)를 통해 볼륨 프로비저닝을 자동으로 수행한다. 볼륨 플러그인은 PVC가 생성되었을 때 실제로 PV를 만드는 기능을 수행한다. 스토리지 클래스는 PV 생성 시 필요한 parameter들의 집합이다.

인프라 담당자가 스토리지 클래스와 볼륨 플러그인만을 미리 쿠버네티스 상에 배포해두면, 앞으로 해당 스토리지 클래스를 사용하는 PVC는 동적 프로비저닝된다.

 

예를 들어 nfs-subdir-external-provisioner[2]라는 NFS용 동적 프로비저닝 지원 프로젝트가 있다. 이 프로젝트에는 NFS의 동적 프로비저닝을 지원하기 위한 볼륨 플러그인 yaml과 스토리지 클래스 yaml이 포함되어 있다. 해당 프로젝트의 설치법에 따라 설치하면 NFS 동적 프로비저닝을 위한 볼륨 플러그인 역할을 수행하는 Pod 하나와 스토리지 클래스 리소스(ex, nfs-client라고 하자)가 하나 배포된다. 

 

앞으로 다음과 같이 PVC yaml을 작성하여 배포하면, 자동으로 NFS 동적 프로비저닝이 수행된다.

 

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
spec:
  storageClassName: nfs-client
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi

 

주목할 점은 PVC yaml에 storageClassName에 [nfs-client]라고 적혀 있다는 점이다. 쿠버네티스 시스템은 PVC의 storageClassName에 명시된 스토리지 클래스 이름을 보고 어떤 볼륨 플러그인을 사용할 지 판단한다. 해당 스토리지 클래스에는 어떤 파라미터로 어떤 볼륨 플러그인을 사용하면 PV가 생성될 지 정보가 적혀있다. nfs-client 볼륨 플러그인에는 앞서 배포된 Pod를 사용하라고 명시되어 있다. 이를 통해 해당 플로그인을 실행시켜 PV를 만들 수 있다.

 

다만 이 경우 Pod 개발자가 쿠버네티스 시스템 상에 어떤 스토리지 클래스가 있는 지 알고 있어야 한다는 단점이 있다. 다만 이름만 알고 있으면 되고, Pod 개발자에게 스토리지 시스템을 선택할 수 있게 한다는 장점이 될 수도 있다. 이것이 단점이라고 생각한다면 storageClassName을 생략할 경우 default 스토리지 클래스가 자동 선택되도록 설정할 수 있다[3].

 

위 과정을 다음 Fig 2.로 정리할 수 있다.

 

 

 

 

Reference

[1] https://kubernetes.io/ko/docs/concepts/storage/dynamic-provisioning/

[2] https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

[3] https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/#defaulting-behavior