쿠버네티스 교육

10. Kube 교육 - Kube Storage(PV PVC SC)

Jerry_이정훈 2021. 6. 4. 16:43
728x90

실습

  • PVC 생성 후 Deployment POD Volume 연결
  • Statefulset POD Volume 연결

Why PV PVC?

Kube 환경은 VM과 다르게 default로 data가 pod에 저장되지 않고 pod 재기동(restart가 아니고 terminate되고 신규 pod가 재생성되죠)되면 data가 사라집니다. 단어가 어려워 쉽게 와닿지 않는 ephemeral storage(임시 저장소)라고 합니다. 

[spkr@erdia22 junghoon2.github.io (spkn02:nginx)]$ k exec -it busybox-6d8496d56f-z4mf2 -- sh
/ # touch aaa bbb ccc
/ # ls
aaa   bbb   bin   ccc   dev   etc   home  proc  root  sys   tmp   usr   var

[spkr@erdia22 junghoon2.github.io (spkn02:nginx)]$ k delete pod busybox-6d8496d56f-z4mf2

삭제하고 신규 POD에 접속하면 기존 만들었던 data가 사라집니다. 

[spkr@erdia22 ~ (spkn02:nginx)]$ k exec -it busybox-6d8496d56f-fm68n -- sh
/ # ls
bin   dev   etc   home  proc  root  sys   tmp   usr   var

아마도 VM 에서는 상상도 못하는 data가 사라지는 대참사가 발생 했습니다.

 

Data 저장을 위해서는 POD에 별도의 Volume을 Attach 하는 과정이 필요합니다. 이 Volume을 Kuberentes에서는 영구 볼륨(Persistent Volume, PV)이라고 합니다. MySQL Database, Redis 등 data 저장이 필요한 모든 application 에서 반드시 사용하고 있습니다. 

 

1.  사용 가능한 SC 및 PVC 확인해 보세요

POD에 PV를 연결하기 위해서는 먼저 SC(Storage Class) 및 PVC(Persistent Volume Claim)가 필요합니다. Storage Class 생성하는 방법(openebs 이용) 등은 다른 장에서 알아보겠습니다. 간단히 SC 리스트 확인하겠습니다.
(k3s 환경은 SC로 local-path default로 지원합니다.)

Openebs 설치 시
[spkr@erdia22 11.Service (spkn02:nginx)]$ k get sc
NAME                         PROVISIONER        RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
openebs-device               openebs.io/local   Delete          WaitForFirstConsumer   false                  49d
openebs-hostpath (default)   openebs.io/local   Delete          WaitForFirstConsumer   false                  49d

K3S 환경
[spkr@erdia22 56.MetalLB (k3s:nginx)]$ k get sc
NAME                   PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local-path (default)   rancher.io/local-path   Delete          WaitForFirstConsumer   false                  10d

Storage Class는 비슷한 특징을 가지는 storage의 묶음(class) 정도라 생각하시면 됩니다. 참고로 default로 지정되어 있는 Storage Class가 Storage Class 이름을 지정하지 않는 경우 할당되는 SC입니다.

[spkr@erdia22 ~ (spkn02:nginx)]$ k describe sc openebs-hostpath
Name:            openebs-hostpath
IsDefaultClass:  Yes
Annotations:     cas.openebs.io/config=#hostpath type will create a PV by
# creating a sub-directory under the
# BASEPATH provided below.
- name: StorageType
  value: "hostpath"
#Specify the location (directory) where
# where PV(volume) data will be saved.
# A sub-directory with pv-name will be
# created. When the volume is deleted,
# the PV sub-directory will be deleted.
#Default value is /var/openebs/local
- name: BasePath
  value: "/var/openebs/local/"
,kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"storage.k8s.io/v1","kind":"StorageClass","metadata":{"annotations":{"cas.openebs.io/config":"#hostpath type will create a PV by \n# creating a sub-directory under the\n# BASEPATH provided below.\n- name: StorageType\n  value: \"hostpath\"\n#Specify the location (directory) where\n# where PV(volume) data will be saved. \n# A sub-directory with pv-name will be \n# created. When the volume is deleted, \n# the PV sub-directory will be deleted.\n#Default value is /var/openebs/local\n- name: BasePath\n  value: \"/var/openebs/local/\"\n","openebs.io/cas-type":"local"},"name":"openebs-hostpath"},"provisioner":"openebs.io/local","reclaimPolicy":"Delete","volumeBindingMode":"WaitForFirstConsumer"}
,openebs.io/cas-type=local,storageclass.kubernetes.io/is-default-class=true
Provisioner:           openebs.io/local
Parameters:            <none>
AllowVolumeExpansion:  <unset>
MountOptions:          <none>
ReclaimPolicy:         Delete
VolumeBindingMode:     WaitForFirstConsumer
Events:                <none>

상세한 여러 옵션들이 있으나 Storage 관련 몇가지 특성등이 있구나 정도로 이해하시면 될 것 같습니다. 

 

다음으로 PV, PVC, StorageClass 관계는 대략적으로 아래와 같습니다. (PV가 꼭 노드 안에 있지 않고 외장 스토리지를 사용하는 경우도 물론 많습니다.) PVC를 통하여 PV가 생성되며 PVC는 Storage Class에서 할당할 수 있습니다.

from :  https://blog.mayadata.io/kubernetes-storage-basics-pv-pvc-and-storageclass

그럼, Storage Class를 이용하여 PVC를 만들어 보겠습니다. PVC(Persistent Volume Claim)은 즉 API Server를 통하여 PV를 요청(claim)하는 Object 정도로 지금은 이해 하시면 됩니다.

localpath-pvc.yml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: default-pvc
  namespace: nginx
spec:
  accessModes:
  - ReadWriteOnce  ## block accessmode 지정 
  resources:
    requests:
      storage: 10Gi
  storageClassName: "local-path"  ## SC 이름 지정

accessModes list 는 아래의 종류가 있습니다. 흔히 아시는 NAS, SAN 차이 정도라 생각하시면 됩니다.


ReadWriteOnce -- 하나의 노드에서 볼륨을 읽기-쓰기로 마운트할 수 있다

ReadOnlyMany -- 여러 노드에서 볼륨을 읽기 전용으로 마운트할 수 있다

ReadWriteMany -- 여러 노드에서 볼륨을 읽기-쓰기로 마운트할 수 있다

 

각각의 accessMode는 지원 가능한 스토리지가 별도로 있습니다.

(SC마다 사용 가능한 accessModes가 따로 있습니다.)

 

storageClassName 으로 현재 사용 가능한 SC를 지정하시면 됩니다. 

 

2. POD Volume 할당해 보세요

그럼, POD에 볼륨을 할당하겠습니다.

date-pvc-deploy.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: date-pod
  namespace: nginx
  labels:
    app: date
spec:
  replicas: 1
  selector:
    matchLabels:
      app: date
  template:    
    metadata:
      labels:
        app: date
    spec:
      containers:
      - name: date-pod
        image: busybox
        command:
        - "/bin/sh"
        - "-c"
        - "while true; do date >> /data/pod-out.txt; cd /data; sync; sync; sleep 30; done"
        volumeMounts:  
        - name: date-vol  # Volume 이름
          mountPath: /data  # Mount 이름 
      volumes:  # 어떤 Volume을 사용할 것인지
      - name: date-vol
        persistentVolumeClaim:
          claimName: default-pvc   

pod에 볼륨을 할당하기 위해서는 위와 같이 volumeMounts, volumes가 필요합니다.  그리고 volumeMounts.name 과 volumes.name 이름을 동일하게 지정합니다. 

 

다음으로 persistenctVolumeClaim.claimName 으로 위에서 생성한 pvc 이름을 지정합니다. 적용(k apply -f)하시고 볼륨을 확인하겠습니다. 

[spkr@erdia22 05.Volume (k3s:nginx)]$ ka date-pvc-deploy.yml 
deployment.apps/date-pod created

[spkr@erdia22 05.Volume (k3s:default)]$ ka localpath-pvc.yml 
persistentvolumeclaim/default-pvc created

[spkr@erdia22 05.Volume (k3s:nginx)]$ k get pod,pvc
NAME                                   READY   STATUS    RESTARTS   AGE
pod/date-pod-874f7cf88-sbwfv           1/1     Running   0          36s

NAME                                STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/default-pvc   Bound    pvc-83bef3c3-74fc-4451-a8c6-2c50d819c19c   10Gi       RWO            local-path     2m16s

POD로 접속하여 정상적으로 Volume이 생성되었는지 확인해 보겠습니다.

[spkr@erdia22 05.Volume (spkn02:nginx)]$ k exec -it date-pod-874f7cf88-k2n8l -- sh
/ # 
/ # df -h
Filesystem                Size      Used Available Use% Mounted on
overlay                 490.9G     15.0G    475.9G   3% /
tmpfs                    64.0M         0     64.0M   0% /dev
tmpfs                     7.8G         0      7.8G   0% /sys/fs/cgroup
/dev/mapper/centos-root
                        490.9G     15.0G    475.9G   3% /data
(생략) 

/data 디렉토리에 정상적으로 데이터가 생성되는 걸 확인 가능합니다. 

/ # touch /data/aaa /data/bbb
/ # ls /data
aaa          bbb          pod-out.txt

/ # touch /data/aaa /data/bbb
/ # ls /data
aaa          bbb          pod-out.txt

 

POD 삭제 후 생성되는 신규 POD에서 기존 데이터를 확인해 보겠습니다.

[spkr@erdia22 05.Volume (spkn02:nginx)]$ k delete pod date-pod-874f7cf88-k2n8l 
pod "date-pod-874f7cf88-k2n8l" deleted

[spkr@erdia22 junghoon2.github.io (spkn02:nginx)]$ k exec -it date-pod-874f7cf88-4qb88 -- sh
/ # cat /data/
aaa          bbb          pod-out.txt
/ # cat /data/pod-out.txt
Fri May 21 05:47:08 UTC 2021
Fri May 21 05:47:38 UTC 2021
Fri May 21 05:48:08 UTC 2021
Fri May 21 05:48:38 UTC 2021
(생략)

[spkr@erdia22 05.Volume (spkn02:nginx)]$ k delete pod date-pod-874f7cf88-k2n8l 

pod "date-pod-874f7cf88-k2n8l" deleted

 

[spkr@erdia22 junghoon2.github.io (spkn02:nginx)]$ k exec -it date-pod-874f7cf88-4qb88 -- sh

/ # cat /data/

aaa          bbb          pod-out.txt

/ # cat /data/pod-out.txt

Fri May 21 05:47:08 UTC 2021

Fri May 21 05:47:38 UTC 2021

Fri May 21 05:48:08 UTC 2021

Fri May 21 05:48:38 UTC 2021

(생략)

 

30s 단위로 date 출력 결과를 /data/pod.out 파일로 저장하도록 하였는데, 이전 데이터까지 잘 보이는 것을 확인 가능합니다. 

 

이상 간단하게 Kube PV, PVC, SC에 대하여 알아 보았습니다. 너무 간단한데요 ^^ 다른 포스트에서 OpenEBS 이용하여 Kube에서 사용 가능한 Storage 만드는 방법을 알아 보겠습니다. 



반응형