TheKoguryo's 기술 블로그

 Version 2024.04.01
1.2.3.2.2 File Storage 사용하기(CSI Driver 기반) - Dynamic Provisioning

앞선 Static Provisioning 방식으로 File Storage 서비스를 사용하는 경우, Persistent Volume 등록전에, File System과 Mount Target을 매번 만들고, Persistent Volume으로 등록하고, PVC를 요청하는 방식이었습니다. 그리고 Persistent Volume을 만들때 spec.csi.volumeHandle에 <FileSystemOCID>:<MountTargetIP>:<path> 형식으로 매번 지정해야 합니다.

apiVersion: v1
kind: PersistentVolume
...
  csi:
    driver: fss.csi.oraclecloud.com
    volumeHandle: ocid1.filesystem.oc1.ap_chuncheon_1.aaaaa_____wtcaaa:10.0.20.12:/oke-fss-system

Dynamic Provisioning은 사전에 File System을 사전에 만드는 것이 아니라, OKE에서 요청(PVC)가 있을 때, 동적으로 File System을 만드는 방식입니다. 따라서 OKE Cluster가 File System을 동적으로 만들 수 있도록 File Storage 서비스에 대한 관련 권한 설정이 필요합니다.

Policy 설정하기

File Storage 서비스와 OKE 클러스터, Node Pool이 모든 같은 Compartment에 속하는 경우는 다음과 같이 설정하면 됩니다.

# oke-ffs-dynamic-provisioning-policy
ALLOW any-user to manage file-family in compartment <compartment-name> where request.principal.type = 'cluster'
ALLOW any-user to use virtual-network-family in compartment <compartment-name> where request.principal.type = 'cluster'
File Storage 서비스를 이용하여 Persistent Volume을 Dynamic Provision 하기
  1. Storage Class를 만듭니다.

    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: <storage-class-name>
    provisioner: fss.csi.oraclecloud.com
    parameters:
      availabilityDomain: <ad-name>
      mountTargetOcid: <mt-ocid> | mountTargetSubnetOcid: <mt-subnet-ocid>
      compartmentOcid: <compartment-ocid>
      kmsKeyOcid: <key-ocid>
      exportPath: <path>
      exportOptions: [{<options-in-json-format>}]
      encryptInTransit: "true"|"false"
    
  2. 여기서는 최소 설정을 사용하겠습니다.

    • availabilityDomain: File Storage 서비스의 File System을 만들 AD를 지정

    • mountTargetSubnetOcid: 마운트 타겟도 자동으로 만들어지게 마운트 타겟이 만들어질 Subnet을 지정합니다.

      • 예시에서는 Node가 속한 oke-nodesubnet-…-regional 서브넷의 OCID 사용
    • reclaimPolicy: OKE 문서상의 위 예시에는 없지만, Kubernetes Storage Class 유형에서 설정할 수 있는 항목으로, 여기에 설정하면, 이 Storage Class를 사용하는 PV는 이 설정값을 따라갑니다. 설정하지 않는 경우, 기본값은 Delete 이면, 이때는 PVC 삭제시 PV와 함께 자동생성된 Mount Target, File System도 지워집니다. Delete 또는 Retain 선택 가능

    • 나머지는 기본값을 사용합니다. 이후 PV 생성 요청이 오면, OKE 노드가 속한 동일 Compartment에 File System, Mount Target이 만들어지게 됩니다.

    # fss-dyn-storage-class.yaml
    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: fss-dyn-storage
    provisioner: fss.csi.oraclecloud.com
    parameters:
      availabilityDomain: AP-CHUNCHEON-1-AD-1
      mountTargetSubnetOcid: ocid1.subnet.oc1.ap-chuncheon-1.aaaaa_____wwwa
    reclaimPolicy: Delete
    
    • 실행예시
    $ kubectl apply -f fss-dyn-storage-class.yaml
    storageclass.storage.k8s.io/fss-dyn-storage created
    $ kubectl get sc
    NAME               PROVISIONER                       RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
    fss-dyn-storage    fss.csi.oraclecloud.com           Delete          Immediate              false                  13s
    oci                oracle.com/oci                    Delete          Immediate              false                  18h
    oci-bv (default)   blockvolume.csi.oraclecloud.com   Delete          WaitForFirstConsumer   true                   18h
    
  3. Security List 설정

    OKE Worker Nodes -> Mount Target, Mount Target -> OKE Worker Nodes간의 통신을 위해 Security List에 등록할 필요가 있습니다. 둘다 같은 서브넷에 있는 경우 아래와 같이 설정합니다. 서로 다른 경우는 관련 문서를 참조하여 설정합니다.

    • 10.0.10.0/24는 Quick Create 모드로 생성된 OKE Cluster의 Node용 서브넷 CIDR

    • Ingress

      image-20230206173352019

    • Egress

      image-20230206173451632

  4. Persistent Volume Claim(PVC) 만들기

    • storageClassName: 앞서 만든 Storage Class 이름
    • accessModes: ReadWriteMany
    • storage: 50Gi
      • PersistentVolumeClaim 유형에 필수 요구항목이기 때문에 입력하지만, File Storage는 용량은 자동관리되며 확장되기 때문에, 입력값과 상관없이 새 File System은 기본사이즈로 생성됩니다.
    # fss-dyn-pvc.yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: fss-dyn-pvc
    spec:
      accessModes:
        - ReadWriteMany
      storageClassName: "fss-dyn-storage"
      resources:
        requests:
          storage: 50Gi
    
  5. PVC를 만들면 자동으로 PV가 만들어지는 것을 볼 수 있습니다. File System이 자동으로 생성될때까지 잠시 기다립니다. 그래도 Pending 상태인 경우 Policy를 설정했는지 확인합니다.

    $ kubectl apply -f fss-dyn-pvc.yaml
    $ kubectl get pvc
    NAME          STATUS   VOLUME                                         CAPACITY   ACCESS MODES   STORAGECLASS      AGE
    fss-dyn-pvc   Bound    csi-fss-d62f6ef1-33a1-477d-8f73-ec8eeb1db4ab   50Gi       RWX            fss-dyn-storage   68s
    $ kubectl get pv
    NAME                                           CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS      REASON   AGE
    csi-fss-d62f6ef1-33a1-477d-8f73-ec8eeb1db4ab   50Gi       RWX            Delete           Bound    default/fss-dyn-pvc   fss-dyn-storage            50s
    
  6. File Storage 서비스를 콘솔에서 확인해 보면, PV와 같은 이름으로 마운트 타겟과 File System이 자동으로 만들어 진 것을 볼 수 있습니다.

    image-20230517111501447

    image-20230517111538035

  7. PVC를 사용하는 POD 배포하기

    생성한 PVC(spec.template.spec.volumes.persistentVolumeClaim.claimName)를 볼륨으로 등록하여 마운트합니다.

    ReadWriteMany 접근모드를 사용하므로 앞선 Block Volume을 PV 사용하는 예제와 달리 replica를 복수개로 지정할 수 있습니다.

    # nginx-deployment-fss-dyn-pvc.yaml 
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: nginx-fss-dyn-pvc
      name: nginx-fss-dyn-pvc
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: nginx-fss-dyn-pvc
      template:
        metadata:
          labels:
            app: nginx-fss-dyn-pvc
        spec:
          containers:
          - name: nginx
            image: nginx:latest
            volumeMounts:
            - name: data
              mountPath: /usr/share/nginx/html
          volumes:
          - name: data
            persistentVolumeClaim:
              claimName: fss-dyn-pvc
    
  8. 실행 및 결과 예시

    3개 POD가 각각 서로 다른 3개의 Worker Node에 위치하지만 정상 기동된 것을 볼 수 있습니다.

    $ kubectl apply -f nginx-deployment-fss-dyn-pvc.yaml
    deployment.apps/nginx-fss-dyn-pvc created
    $ kubectl get pod -o wide
    NAME                                 READY   STATUS    RESTARTS   AGE   IP             NODE          NOMINATED NODE   READINESS GATES
    nginx-fss-dyn-pvc-7ccc9b45bb-fphnc   1/1     Running   0          9s    10.244.1.6     10.0.10.39    <none>           <none>
    nginx-fss-dyn-pvc-7ccc9b45bb-lc86c   1/1     Running   0          9s    10.244.0.8     10.0.10.107   <none>           <none>
    nginx-fss-dyn-pvc-7ccc9b45bb-vmv9t   1/1     Running   0          9s    10.244.0.136   10.0.10.143   <none>           <none>
    
  9. 파일 쓰기 테스트

    • 아래와 같이 첫번째 POD에서 PV로 파일쓰기를 했지만, 모든 POD에서 동일내용을 확인할 수 있습니다.

      $ kubectl exec -it nginx-fss-dyn-pvc-7ccc9b45bb-fphnc -- bash -c 'echo "Hello FSS - 1" >> /usr/share/nginx/html/hello_world.txt'
      $ kubectl exec -it nginx-fss-dyn-pvc-7ccc9b45bb-fphnc -- cat /usr/share/nginx/html/hello_world.txt
      Hello FSS - 1
      $ kubectl exec -it nginx-fss-dyn-pvc-7ccc9b45bb-lc86c -- cat /usr/share/nginx/html/hello_world.txt
      Hello FSS - 1
      $ kubectl exec -it nginx-fss-dyn-pvc-7ccc9b45bb-lc86c -- bash -c 'echo "Hello FSS - 2" >> /usr/share/nginx/html/hello_world.txt'
      $ kubectl exec -it nginx-fss-dyn-pvc-7ccc9b45bb-vmv9t -- cat /usr/share/nginx/html/hello_world.txt
      Hello FSS - 1
      Hello FSS - 2
      
  10. 자동으로 생성된 Persitent Volume은 StorageClass의 RECLAIM POLICY을 상속받으며, 기본값이 Delete입니다. Delete인 경우 PVC를 삭제하는 경우, PV가 삭제되면, 실제 만들어진 File Storage 의 마운트 타겟과 File System은 자동으로 삭제됩니다.

    $ kubectl get pv
    NAME                                           CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS      REASON   AGE
    csi-fss-d4e59f1d-fa2a-4e92-857f-22a32869141b   50Gi       RWX            Delete           Bound    default/fss-dyn-pvc   fss-dyn-storage            13m
    
  11. RECLAIM POLICY를 Retain으로 변경 적용하면, PVC 삭제시, PV는 Release 되며 삭제되지 않습니다. PV를 삭제하더라도, 실제 마운트 타겟과 File System은 자동으로 삭제되지 않습니다.

참고 문서


이 글은 개인으로서, 개인의 시간을 할애하여 작성된 글입니다. 글의 내용에 오류가 있을 수 있으며, 글 속의 의견은 개인적인 의견입니다.

Last updated on 6 Feb 2023