Provisioning, StorageClass

Jeonghak Choยท2025๋…„ 6์›” 8์ผ

Kubernetes

๋ชฉ๋ก ๋ณด๊ธฐ
15/20

๐Ÿ“— ํ”„๋กœ๋น„์ €๋‹ - Storage - K8S - hostPath

๐Ÿณ๏ธโ€๐ŸŒˆ [๊ถ๊ธˆํ•œ์ ]

  • StorageClass ์‚ฌ์šฉ๋ฐฉ๋ฒ•

๐Ÿ”—[๋ชฉ์ฐจ]

1๏ธโƒฃ ์ค€๋น„

StorageClass[^1] ์ •์˜

  • my-sc-poc.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage1
provisioner: kubernetes.io/no-provisioner
reclaimPolicy: Retain                    
volumeBindingMode: WaitForFirstConsumer  
allowVolumeExpansion: true               
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage2
provisioner: kubernetes.io/no-provisioner
reclaimPolicy: Retain                    
volumeBindingMode: Immediate  
allowVolumeExpansion: true               
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-storage3
provisioner: kubernetes.io/no-provisioner
reclaimPolicy: Delete                    
volumeBindingMode: WaitForFirstConsumer  
allowVolumeExpansion: true               

Persistence Volume[^2] ์ •์˜

  • my-pv-poc.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage1
  hostPath:
    path: /mnt/data1
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv2
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: local-storage2
  hostPath:
    path: /mnt/data2
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv3
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Delete  
  storageClassName: local-storage3
  hostPath:
    path: /mnt/data3

Persistence Volume Claim[^3] ์ •์˜

  • my-pvc-poc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc1
spec:
  storageClassName: local-storage1
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc2
spec:
  storageClassName: local-storage2
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc3
spec:
  storageClassName: local-storage3
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi      
      

2๏ธโƒฃ ์„ค์ •

case1, volumeBindingMode = Immediate

PVC๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ์ฆ‰์‹œ PV ๋ฐ”์ธ๋”ฉ ์‹œ๋„ |

case2, volumeBindingMode = WaitForFirstConsumer

PVC๊ฐ€ ์—ฐ๊ฒฐ๋œ Pod์ด ์Šค์ผ€์ค„๋ง๋  ๋•Œ PV ์ƒ์„ฑ ๋ฐ ๋ฐ”์ธ๋”ฉ ์ˆ˜ํ–‰ โ†’ ๋…ธ๋“œ ์ง€์—ญ ๊ณ ๋ ค ๊ฐ€๋Šฅ

case3, reclaimPolicy Delete

PVC ์‚ญ์ œ ์‹œ PV๋„ ์‚ญ์ œ

case4, reclaimPolicy Retain |

PVC ์‚ญ์ œ ํ›„ PV๋Š” ๋‚จ๊ฒจ๋‘  (๋ฐ์ดํ„ฐ ๋ณด์กด)

3๏ธโƒฃ ์„ค์น˜

SC ์ƒ์„ฑ

k apply -f my-sc-poc.yaml
storageclass.storage.k8s.io/local-storage1 created
storageclass.storage.k8s.io/local-storage2 created
storageclass.storage.k8s.io/local-storage3 created

k get sc
NAME             PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
local-storage1   kubernetes.io/no-provisioner   Retain          WaitForFirstConsumer   true                   8s
local-storage2   kubernetes.io/no-provisioner   Retain          Immediate              true                   8s
local-storage3   kubernetes.io/no-provisioner   Delete          WaitForFirstConsumer   true                   8s

PV ์ƒ์„ฑ

๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ[^4]

ssh slave1

sudo mkdir /mnt/data{1..3}

์ƒ์„ฑ

k apply -f my-pv-poc.yaml
persistentvolume/my-pv1 created
persistentvolume/my-pv2 created
persistentvolume/my-pv3 created

k get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                             STORAGECLASS    REASON   AGE
my-pv1   1Gi        RWO            Retain           Available                                                              11m
my-pv2   1Gi        RWO            Retain           Available                                                              12m
my-pv3   1Gi        RWO            Retain           Available                                                              11m

PVC ์ƒ์„ฑ

k apply -f my-pvc-poc.yaml
persistentvolumeclaim/my-pvc1 created
persistentvolumeclaim/my-pvc2 created
persistentvolumeclaim/my-pvc3 created

k get pvc
NAME      STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS     AGE
my-pvc1   Pending                                      local-storage1   17s
my-pvc2   Bound     my-pv2   1Gi        RWO            local-storage2   17s
my-pvc3   Pending                                      local-storage3   17s

4๏ธโƒฃ ๊ฒ€์ฆ

case1, volumeBindingMode = Immediate

pv๊ฐ€ Immediate์ธ ๊ฒฝ์šฐ POD ์ƒ์„ฑ ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ์•„๋ž˜ ์ฒ˜๋Ÿผ ์กฐ๊ฑด์— ๋งž๋Š” pvc์™€ Bound ๋œ๋‹ค.

k get pvc
NAME      STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS     AGE
my-pvc1   Pending                                      local-storage1   17s
my-pvc2   Bound     my-pv2   1Gi        RWO            local-storage2   17s
my-pvc3   Pending  

case2, volumeBindingMode = WaitForFirstConsumer

  • pod์ •์˜, my-pod-poc.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod1
spec:
  containers:
    - name: app
      image: busybox
      command: ["/bin/sh", "-c", "sleep 3600"]
      volumeMounts:
        - name: my-storage
          mountPath: /data
  volumes:
    - name: my-storage
      persistentVolumeClaim:
        claimName: my-pvc1
---
apiVersion: v1
kind: Pod
metadata:
  name: my-pod3
spec:
  containers:
    - name: app
      image: busybox
      command: ["/bin/sh", "-c", "sleep 3600"]
      volumeMounts:
        - name: my-storage
          mountPath: /data
  volumes:
    - name: my-storage
      persistentVolumeClaim:
        claimName: my-pvc3        
  • pod ์ƒ์„ฑ
k apply -f my-pod-poc.yaml

pod/my-pod1 created
  • PVC ํ™•์ธ
    POD์ƒ์„ฑ๊ณผ ํ•จ๊ป˜ WaitForFirstConsumer ์ธ my-pvc1,my-pvc3์ด Bound๋˜์—ˆ๋‹ค.
k get pvc
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS     AGE
my-pvc1   Bound    my-pv1   1Gi        RWO            local-storage1   14m
my-pvc2   Bound    my-pv2   1Gi        RWO            local-storage2   14m
my-pvc3   Bound    my-pv3   1Gi        RWO            local-storage3   14m

case3, reclaimPolicy Delete

  • pv ํ™•์ธ
k get pv

NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                             STORAGECLASS     REASON   AGE
my-pv1   1Gi        RWO            Retain           Bound       default/my-pvc1                   local-storage1            8s
my-pv2   1Gi        RWO            Retain           Bound       default/my-pvc2                   local-storage2            8s
my-pv3   1Gi        RWO            Delete           Bound       default/my-pvc3                   local-storage3            8s

StorageClass์˜ reclaimPolicy: Delete๋Š” ๋™์  ํ”„๋กœ๋น„์ €๋‹(PVC โ†’ PV ์ž๋™ ์ƒ์„ฑ) ์„ ์‚ฌ์šฉํ•  ๋•Œ์—๋งŒ ์˜๋ฏธ๊ฐ€ ์žˆ๋‹ค.
์ฆ‰, PVC๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” PV์˜ ๊ธฐ๋ณธ reclaimPolicy๋ฅผ ์„ค์ •ํ•˜๋Š” ์šฉ๋„์ด๋‹ค. ์ˆ˜์ž‘์—…์œผ๋กœ PV๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” PV์— persistentVolumeReclaimPolicy: Delete ์ฒ˜๋Ÿผ ๋ช…๊ธฐ๋˜์–ด์•ผ ํ•œ๋‹ค.

my-pv3์˜ RECLAIM POLICY ๊ฐ€ Delete ์ธ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

pod,pvc๋ฅผ ์‚ญ์ œํ•œ๋‹ค.

k delete -f my-pod-poc.yaml
k delete pvc my-pvc1
k delete pvc my-pvc3

k get pvc
NAME      STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS     AGE
my-pvc2   Bound    my-pv2   1Gi        RWO            local-storage2   5m46s

k get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                             STORAGECLASS     REASON   AGE
my-pv1   1Gi        RWO            Retain           Released    default/my-pvc1                   local-storage1            5m53s
my-pv2   1Gi        RWO            Retain           Bound       default/my-pvc2                   local-storage2            5m53s
my-pv3   1Gi        RWO            Delete           Failed      default/my-pvc3                   local-storage3            5m53s

local ๋ณผ๋ฅจ์€ ๋ณดํ†ต reclaimPolicy: Retain์œผ๋กœ ์จ์•ผ ํ•œ๋‹ค. local ๋ณผ๋ฅจ์€ ์ˆ˜๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ๋กœ์ปฌ ๋””์Šคํฌ ๊ฒฝ๋กœ ๊ธฐ๋ฐ˜์ด๋‹ค (/mnt/data ๋“ฑ). ์ด๋กœ ์ธํ•ด ๋ณด์•ˆ/์•ˆ์ •์„ฑ ๋ฌธ์ œ๋กœ Kubernetes๋Š” ๋…ธ๋“œ์˜ ๋กœ์ปฌ ํŒŒ์ผ์‹œ์Šคํ…œ์„ ์ž๋™์œผ๋กœ ์‚ญ์ œํ•  ์ˆ˜ ์—†๋‹ค.

๊ผญ ์ž๋™ ์‚ญ์ œ๋ฅผ ํ™•์ธํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋…ธ๋“œ ๋งˆ์šดํŠธ ๊ฒฝ๋กœ๋ฅผ /mnt/data ๋Œ€์‹ ์— /tmp/data ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ์ด ์ƒํƒœ์—์„œ ๊ฐ™์€ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•˜๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ pvc ์‚ญ์ œ์™€ ๋™์‹œ์— pv๊ฐ€ ์‚ญ์ œ๋œ๋‹ค.

k get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                             STORAGECLASS     REASON   AGE
my-pv1   1Gi        RWO            Retain           Released    default/my-pvc1                   local-storage1            66s
my-pv2   1Gi        RWO            Retain           Bound       default/my-pvc2                   local-storage2            66s

case4, reclaimPolicy Retain

์œ„ ๊ณผ์ •์—์„œ Delete ์ƒํƒœ์˜ PV๊ฐ€ PVC์‚ญ์ œ์™€ ๋™์‹œ์— ์—†์–ด์กŒ์ง€๋งŒ, Retain์ƒํƒœ์ธ my-pv1์€ ๋‚จ์•„ ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฐธ๊ณ 

[^1]: StorageClass๋Š” Kubernetes์—์„œ ๋™์  ํ”„๋กœ๋น„์ €๋‹์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฆฌ์†Œ์Šค์ด๋‹ค.์‚ฌ์šฉ์ž๊ฐ€ PVC(PersistentVolumeClaim)๋ฅผ ๋งŒ๋“ค๋ฉด, PVC๊ฐ€ ์ฐธ์กฐํ•˜๋Š” StorageClass์— ๋”ฐ๋ผ ์•Œ๋งž์€ PV๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค ๊ฐœ์š”
[^2]: Kubernetes์—์„œ PersistentVolume (PV) ๋Š” ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•˜๋Š” ์ž์›์ด๋‹ค. ์ผ๋ฐ˜์ ์ธ Kubernetes Pod๋Š” ์ƒ์„ฑ๊ณผ ์‚ญ์ œ๊ฐ€ ๋ฐ˜๋ณต๋˜๋ฏ€๋กœ, Pod์™€๋Š” ์ˆ˜๋ช…์ด ๋‹ค๋ฅด๊ณ  ๋…๋ฆฝ์ ์ธ ์ €์žฅ์†Œ๊ฐ€ ํ•„์š”ํ•  ๋•Œ PV๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.PV ๊ฐœ์š”
[^3]: Kubernetes์—์„œ PVC (PersistentVolumeClaim) ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์Šคํ† ๋ฆฌ์ง€ ์ž์›์„ ์š”์ฒญํ•˜๋Š” ๊ฐ์ฒด๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•ด, ์‚ฌ์šฉ์ž๊ฐ€ "๋‚˜ 5Gi ํฌ๊ธฐ์˜ ๋ณผ๋ฅจ์ด ํ•„์š”ํ•ด!"๋ผ๊ณ  Kubernetes์— ์š”์ฒญํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.PVC ๊ฐœ์š”
[^4]: ๋ชจ๋“  ๋…ธ๋“œ์— ํด๋” ์ƒ์„ฑ์ด ํ•„์š”ํ•˜๋‹ค. ์ˆ˜๊ณ ๋ฅผ ๋œ๊ธฐ ์œ„ํ•ด ๋ฐ๋ชฌ์„ ์ด์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค. ํ”„๋กœ๋น„์ €๋‹ ๋ฐ๋ชฌ์…‹

0๊ฐœ์˜ ๋Œ“๊ธ€