본문 바로가기

NCP

[NCP] NKS 에서 블록스토리지 CSI 기능 사용하기

반응형

NKS 환경에서 구동 중인 컨테이너에 파일을 새로 추가할 경우, 해당 파일들을 프로세스

가 종료되거나 Kubernetes Liveness Probe의 상태 체크에 실패하여 컨테이너가 재시작될 때 모두 삭제됩니다. 이 때 블록 스토리지를 사용하여 새로 추가된 파일들이 프로세스 종료 또는 컨테이너 재시작 후에도 유지되도록 설정할 수 있습니다.

 

Kubernetes 블록 스토리지는 컨테이너를 배포할 때 PersistentVolumeClaim(PVC)를 생성하여 추가할 수 있습니다.

NCP의 NKS에서는 볼륨 드라이버로 Container Storage Interface(CSI)를 제공합니다. 이 드라이버는 Kubernetes와 연동되어 블록 스토리지 생성, 삭제, 리사이징 등의 작업을 지원합니다.

 

CSI 드라이버 상세 사항

Storage Class

Storage Class는 각 스토리지 정책과 타입을 설정한 오브젝트입니다. NCP에서는 블록 스토리지를 사용하는 기본 Storage Class를 제공합니다.

블록 스토리지의 Storage Class 오브젝트를 확인하려면 네임스페이스 kube-system 내의 StorageClass 중 nks-block-storage 이름을 가진 오브젝트를 확인해 주시면 됩니다.

 

root@ptty-nks-mgmt:~# k get storageclass -n kube-system
NAME                          PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local-storage                 kubernetes.io/no-provisioner   Delete          WaitForFirstConsumer   false                  16d
nks-block-storage (default)   blk.csi.ncloud.com             Delete          WaitForFirstConsumer   true                   27d
nks-nas-csi                   nas.csi.ncloud.com             Delete          WaitForFirstConsumer   true                   27d
root@ptty-nks-mgmt:~# k describe storageclass nks-block-storage -n kube-system
Name:            nks-block-storage
IsDefaultClass:  Yes
Annotations:     kubectl.kubernetes.io/last-applied-configuration={"allowVolumeExpansion":true,"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{"annotations":{"storageclass.kubernetes.io/is-default-class":"true"},"name":"nks-block-storage"},"parameters":{"type":"SSD"},"provisioner":"blk.csi.ncloud.com","reclaimPolicy":"Delete","volumeBindingMode":"WaitForFirstConsumer"}
,storageclass.kubernetes.io/is-default-class=true
Provisioner:           blk.csi.ncloud.com
Parameters:            type=SSD
AllowVolumeExpansion:  True
MountOptions:          <none>
ReclaimPolicy:         Delete
VolumeBindingMode:     WaitForFirstConsumer
Events:                <none>
  • Annotations: storageclass.kubernetes.io/is-default-class: 기본 Storage Class일 경우 true 값을 가집니다. true가 아닌 다른 값을 입력하거나 어노테이션이 없는 경우 false 값을 가집니다.
  • volumeBindingMode: 볼륨 바인딩과 동적 프로비저닝이 동작하는 시점을 설정할 수 있습니다. 기본값은 Immediate입니다.
    • immediate : PVC가 생성되는 시점에 동작
    • WaitForFirstConsumer : Pod가 생성되는 시점에 동작
  • reclaimPolicy: 사용이 끝난 PVC가 삭제될 때 사용 중이던 PersistentVolume을 재확보 또는 삭제하도록 정책을 설정할 수 있습니다. 기본값은 Delete입니다.
    • Retain : PVC가 삭제될 때 사용 중인 PV는 재사용이 가능한 상태로 변경되며, 블록 스토리지 내부 데이터를유지
    • Delete : PVC가 삭제될 때 사용 중인 PV를 함께 삭제하며, 블록 스토리지를 반납
  • allowVolumeExpansion: 값을 true로 설정하여 PersistentVolumeClaim을 확장할 수 있습니다.
  • parameters.type:: 블록 스토리지의 타입을 SSD와 HDD 중에서 선택할 수 있습니다. 기본값은 SSD입니다.

생성된 StorageClass 오브젝트의 기본 Storage Class 내용을 변경하려면 https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/#changing-the-default-storageclass 를 참조합니다.

 

CSI Controller

CSI Controller는 볼륨의 생성, 삭제, 할당, 할당 해제, 스냅샷 등 각종 제어와 관리를 담당하는 인터페이스입니다.

CSI Controller를 확인해봅시다.

root@ptty-nks-mgmt:~# kubectl get deploy -n kube-system --kubeconfig=$HOME/.kube/config
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
cilium-operator          2/2     2            2           27d
coredns                  2/2     2            2           27d
csi-nks-controller       1/1     1            1           27d
dns-autoscaler           1/1     1            1           27d
nks-nas-csi-controller   1/1     1            1           27d

 

그럼 이제 CSI 드라이버 사용을 해봅니다.

 

CSI 드라이버 사용

블록 스토리지 추가

CSI 드라이버를 통해 블록 스토리지를 추가하려면 아래 yaml 코드를 통해 PersistentVolumeClaim(PVC)을 요청해 주십시오. CSI 드라이버가 해당 PVC를 확인하여 필요한 PersistentVolume(PV)를 자동으로 생성합니다.

 

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-pod-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: nks-block-storage
  • AccessMode: 네이버 클라우드 플랫폼에서는 ReadWriteOnce 모드만 지원됩니다. 단일 노드가 볼륨에 대해 읽기/쓰기 작업을 수행할 수 있도록 마운트합니다.
  • Resources: 생성할 스토리지의 크기입니다. 기본값은 20 GB이며, 최소 10 GB부터 최대 2,000 GB 사이에서 10 GB 단위로 Gi를 사용해 입력할 수 있습니다.

Pod에 단일 신규 볼륨 할당

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-pod-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: nks-block-storage
---
kind: Pod
apiVersion: v1
metadata:
  name: my-csi-app
spec:
  containers:
    - name: my-frontend
      image: busybox
      volumeMounts:
      - mountPath: "/data"
        name: my-volume
      command: [ "sleep", "1000000" ]
  volumes:
    - name: my-volume
      persistentVolumeClaim:
        claimName: csi-pod-pvc
  • Pod
    • spec.container: volumeMounts에 마운트할 스토리지 이름을 입력한 후 mountPath에 마운트 경로를 입력하십시오.
    • spec.volumes: 컨테이너에 마운트될 스토리지를 정의하기 위해 생성된 PersistentVolumeClaim의 이름을 persistentVolumeClaim.claimName에 입력하십시오.

 

이미 생성된 블록 스토리지를 Pod에 마운트

이미 생성된 블록 스토리지가 있을 경우, 해당 스토리지를 사용하여 PersistentVolume을 생성한 후 마운트할 수 있습니다.

이미 생성된 블록 스토리지를 사용하여 PersistentVolume을 생성한 후 Pod에 마운트하려면 아래 yaml 코드를 사용하면 됩니다.

kind: PersistentVolume
apiVersion: v1
metadata:
  name: volume-existing-01
  annotations:
    pv.kubernetes.io/provisioned-by: blk.csi.ncloud.com # 블록 스토리지와 연동될 provisoner 이름
spec:
  storageClassName: nks-block-storage # 블록 스토리지의 스토리지 클래스 이름
  persistentVolumeReclaimPolicy: Retain
  capacity:
    storage: 10Gi # 블록 스토리지 크기
  accessModes:
    - ReadWriteOnce
  csi:
    driver: blk.csi.ncloud.com
    fsType: ext4
    volumeHandle: "952814"  # Block Storage Instance ID
    volumeAttributes:
      blk.csi.ncloud.com/noformat: "true"  # 블록스토리지를 포맷하지 않음
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-pod-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: nks-block-storage
  volumeName: "volume-existing-01"
---
kind: Pod
apiVersion: v1
metadata:
  name: my-csi-app
spec:
  containers:
    - name: my-frontend
      image: busybox
      volumeMounts:
      - mountPath: "/data"
        name: my-volume
      command: [ "sleep", "1000000" ]
  volumes:
    - name: my-volume
      persistentVolumeClaim:
        claimName: csi-pod-pvc
  • kind: PersistentVolume
    이미 존재하는 블랙 스토리지를 Kubernetes 클러스터에서 사용할 수 있도록 정보를 입력합니다.
    • storageClassname: 네이버 클라우드 플랫폼의 스토리지 클래스인 nks-block-storage를 입력하십시오.
    • capacity.storage: 이미 존재하는 블록 스토리지의 크기를 입력하십시오.
    • accessModes: ReadWriteOnce를 입력하십시오.
    • csi.driver: 스토리지 클래스 드라이버 이름인 blk.csi.ncloud.com을 입력하십시오.
    • csi.volumeHandle: 생성되어 있는 블록 스토리지의 인스턴스 ID를 입력하십시오.
    • csi.volumeAttributes: 포맷을 진행하지 않고 기존에 저장된 내용을 유지한 상태로 마운트하도록 blk.csi.ncloud.com/noformat: "true"를 입력하십시오.
  • kind: PersistentVolumeClaim
    생성된 PersistentVolume과 바인딩되는 PersistentVolumeClaim을 생성합니다.
    • resources.storage: 이미 존재하는 블록 스토리지의 크기를 입력하십시오.
    • storageClassname: 블록 스토리지 클래스 이름인 nks-block-storage를 입력하십시오.
    • volumeName: 생성한 PersistentVolume의 이름을 입력하십시오.
  • kind: Pod
    볼륨 요청인 PersistentVolumeClaim을 지정하여 사용할 볼륨을 마운트합니다.
    • volumes.persistentVolumeClaim.claimName: 지정할 PersistentVolumeClaim의 이름을 입력합니다.

 

볼륨 리사이징 (XEN)

NCP의 XEN 블록 스토리지는 이미 생성되어 있는 볼륨에 대한 오프라인 리사이징 기능을 제공합니다.

*주의 : 볼륨 리사이징을 수행할 때, 운영 중인 Pod의 Conroller에서 Replica의 수를 0으로 조정하는 과정에서 애플리케이션의 운영이 일시적으로 중단될 수 있습니다. 이러한 중단을 피하려면 처음 볼륨을 생성할 때 충분한 크기로 설정하여 리사이징이 필요하지 않도록 하는 것을 권장합니다.

 

아래의 yaml 코드를 사용하여 10GB 크기의 신규 블록 스토리지 볼륨 생성을 요청합니다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-deployment-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: nks-block-storage
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-csi-app
spec:
  selector:
    matchLabels:
      app: my-csi-app
  replicas: 1
  template:
    metadata:
      labels:
        app: my-csi-app
    spec:
      containers:
        - name: my-frontend
          image: busybox
          volumeMounts:
          - mountPath: "/data"
            name: my-volume
          command: [ "sleep", "1000000" ]
      volumes:
        - name: my-volume
          persistentVolumeClaim:
            claimName: csi-deployment-pvc

 

 

Replica의 수를 0으로 조정한다.

root@ptty-nks-mgmt:~# k scale --replicas=0 deployment/my-csi-app
deployment.apps/my-csi-app scaled

 

 

PersistentVolumeClaim의 Volume Request 크기를 10GB에서 20GB로 조정합니다.

root@ptty-nks-mgmt:~# k patch pvc csi-deployment-pvc -p '{"spec" :{"resources" :{"requests" :{"storage" :"20Gi" }}}}'
persistentvolumeclaim/csi-deployment-pvc patched

 

 

 

 

PVC 의 condition이 FireSystemResizePending 상태인지 확인합니다.

root@ptty-nks-mgmt:~# k get pvc csi-deployment-pvc -o yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"PersistentVolumeClaim","metadata":{"annotations":{},"name":"csi-deployment-pvc","namespace":"default"},"spec":{"accessModes":["ReadWriteOnce"],"resources":{"requests":{"storage":"10Gi"}},"storageClassName":"nks-block-storage"}}
    pv.kubernetes.io/bind-completed: "yes"
    pv.kubernetes.io/bound-by-controller: "yes"
    volume.beta.kubernetes.io/storage-provisioner: blk.csi.ncloud.com
    volume.kubernetes.io/selected-node: ptty-node-w-4emo
    volume.kubernetes.io/storage-provisioner: blk.csi.ncloud.com
  creationTimestamp: "2024-03-28T04:20:07Z"
  finalizers:
  - kubernetes.io/pvc-protection
  name: csi-deployment-pvc
  namespace: default
  resourceVersion: "9663734"
  uid: 4ed9a9cc-937d-4707-a5b7-9eb1cdb4ea65
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
  storageClassName: nks-block-storage
  volumeMode: Filesystem
  volumeName: pvc-4ed9a9cc937d4707a5b79eb1cd
status:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Gi
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2024-03-28T04:24:28Z"
    message: Waiting for user to (re-)start a pod to finish file system resize of
      volume on node.
    status: "True"
    type: FileSystemResizePending
  phase: Bound

 

type: FileSystemResizePending 상태를 확인 할 수 있다.

 

 

이제 Replica의 수를 1개로 원복해줍니다.

root@ptty-nks-mgmt:~# k scale --replicas=1 deployment/my-csi-app
deployment.apps/my-csi-app scaled

 

하단의 명령어를 실행하여 Pod Status가 Running으로 정상 변경 되었는지 확인합니다.

root@ptty-nks-mgmt:~# k get pod
NAME                          READY   STATUS    RESTARTS   AGE
my-csi-app                    1/1     Running   0          23h
my-csi-app-7d7bc6dfc4-6kfzx   1/1     Running   0          39s

 

 

스냅샷 생성 및 볼륨 복구

볼륨 스냅샷 생성

PersistentVolume의 스냅샷을 생성합니다.

apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
  name: csi-nks-test-snapshot
spec:
  source:
    persistentVolumeClaimName: csi-pod-pvc
  • metadata.name: 생성할 스냅샷의 이름을 입력하십시오.
  • spec.source.persistentVolumeClaimName: 스냅샷을 생성할 PersistentVolume과 바인딩되어 있는 PersistentVolumeClaim의 이름을 입력하십시오.

 

root@ptty-nks-mgmt:~# k apply -f csi-nks-test-snapshot.yaml 
volumesnapshot.snapshot.storage.k8s.io/csi-nks-test-snapshot created

 

생성된 볼륨 스냅샷 확인

root@ptty-nks-mgmt:~# k get volumesnapshot
NAME                    READYTOUSE   SOURCEPVC     SOURCESNAPSHOTCONTENT   RESTORESIZE   SNAPSHOTCLASS       SNAPSHOTCONTENT                                    CREATIONTIME   AGE
csi-nks-test-snapshot   true         csi-pod-pvc                           10Gi          nks-block-storage   snapcontent-be8e8ab5-900c-4d8b-b2ce-891e2f8e975c   54s            54s

 

 

 

생성된 볼륨 스냅샷 삭제

root@ptty-nks-mgmt:~# k get volumesnapshot
NAME                    READYTOUSE   SOURCEPVC     SOURCESNAPSHOTCONTENT   RESTORESIZE   SNAPSHOTCLASS       SNAPSHOTCONTENT                                    CREATIONTIME   AGE
csi-nks-test-snapshot   true         csi-pod-pvc                           10Gi          nks-block-storage   snapcontent-be8e8ab5-900c-4d8b-b2ce-891e2f8e975c   2m29s          2m29s
root@ptty-nks-mgmt:~# k delete volumesnapshot csi-nks-test-snapshot
volumesnapshot.snapshot.storage.k8s.io "csi-nks-test-snapshot" deleted

 

console 상에도 삭제됨을 확인합니다.

 

 

 

생성된 볼륨 스냅샷으로부터 볼륨 복구

볼륨 스냅샷을 이용하여 볼륨 생성을 요청하는 방식으로 볼륨을 복구할 수 있습니다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: csi-nks-test-pvc-restore
spec:
  dataSource:
    name: csi-nks-test-snapshot
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: nks-block-storage
---
kind: Pod
apiVersion: v1
metadata:
  name: csi-restore-app
spec:
  containers:
    - name: my-frontend
      image: busybox
      volumeMounts:
        - mountPath: "/data"
          name: my-volume
      command: [ "sleep", "1000000" ]
  volumes:
    - name: my-volume
      persistentVolumeClaim:
        claimName: csi-nks-test-pvc-restore
  • PersistentVolumeClaim
    • spec.datasource.name: 복구할 볼륨 스냅샷의 이름을 입력하십시오.
    • spec.datasource.kind: 복구할 볼륨 스냅샷의 리소스 이름인 VolumeSnapshot을 입력하십시오.
    • spec.datasource.apiGroup: 스냅샷의 apiGroup인 snapshot.storage.k8s.io를 입력합니다.
    • resources.request.storage: 볼륨 스냅샷의 크기와 동일한 값을 입력하십시오.
  • Pod
    • claimName: 요청한 볼륨 정보인 PersistentVolumeClaim의 이름을 입력하십시오.

 

 

 

 

NKS 환경에서 CSI 드라이버를 사용하여 블록 스토리지를 추가하고 관리하는 과정을 살펴봤습니다.

이러한 과정을 통해 NKS 환경에서 CSI 드라이버를 사용하여 블록 스토리지를 효과적으로 관리하고 데이터를 안전하게 저장했습니다.

이어서 NKS 환경에서 일어나는 다양한 문제를 해결하는 실습을 가져오겠습니다.