[Retry, k8s] 24. 컨피그 & 스토리지 API - 영구 볼륨 클레임(PVC)
카테고리: KUBERNETES
태그: kubernetes
🔔 영구 볼륨 클레임
시작하기 전 선행 작업 및 확인해야할 내용
- https://revenge1005.github.io/kubernetes/ch03-6-1/
- https://revenge1005.github.io/kubernetes/ch03-6-2/
- https://revenge1005.github.io/kubernetes/ch03-6-3/
PVC는 영구 볼륨(PV)을 요청하는 리소스로, PVC에서 지정한 조건(용량, 레이블)을 기반으로 PV에 대한 요청이 들어오면 스케줄러는 현재 가지고 있는 영구 볼륨에서 적당한 볼륨을 할당한다.
(1) PVC 설정
-
레이블 셀렉터
-
용량
-
접근 모드
-
스토리지클래스
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sample-pvc
spec:
selector:
matchLabels:
type: ceph-pv
matchExpressions:
- key: environment
operator: In
values:
- stg
resources:
requests:
storage: 1Gi
accessModes:
- ReadWriteMany
storageClassName: csi-fs-sc
(2) PVC 생성
# PVC 정보 확인
$ kubectl get pvc sample-pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
sample-pvc Bound sample-pv 1Gi RWX csi-fs-sc 49s
# PV 정보 확인
$ kubectl get pv sample-pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
sample-pv 1Gi RWX Retain Bound default/sample-pvc csi-fs-sc 49m
(2) PVC 삭제
-
Retain 정책을 사용하고 있는 경우 PVC를 삭제할 때 PV의 STATUS가 Bound에서 Released로 변경된다.
-
Released 상태의 PV은 다시 PVC에서 할당하여 사용할 수 없다.
$ kubectl delete pvc sample-pvc
persistentvolumeclaim "sample-pvc" deleted
$ kubectl get pv sample-pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
sample-pv 1Gi RWX Retain Released default/sample-pvc csi-fs-sc 55m
(3) 동적 프로비저닝
-
지금까지 PVC에서는 PV을 미리 생성해 두고 PVC 요청에 따라 볼륨을 할당하는 순서로 진행되었다.
-
그래서 사전에 PV을 생성해야 하는 번거로움과 PVC이 요청하는 용량 이상으로 영구 볼륨이 할당되어 낭비가 발생하는 문제가 있었다.
-
이런 문제를 해결하는 것이 동적 프로비저닝이다.
-
동적 프로비저닝을 사용한 PVC의 경우 PVC이 생성되는 타이밍에 동적으로 PV를 생성하고 할당한다.
-
클라우드 서비스 환경에서는 따로 설정할 것은 없으나, 온프레미스에서는 따로 작업을 해줘야 한다.
-
ceph 서버 구성: https://revenge1005.github.io/kubernetes/ch03-6-2/
-
k8s cephfs csi 설정: https://revenge1005.github.io/kubernetes/ch03-6-3/
-

【스토리지클래스 생성】
- 동적 프로비저닝을 사용하려면 사전에 어떤 PV를 생성할지 정의한 스토리지 클래스를 생성해야 한다.
cat csi-fs-sc.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-fs-sc
allowVolumeExpansion: true
provisioner: cephfs.csi.ceph.com
parameters:
clusterID: myceph
fsName: kubernetes
csi.storage.k8s.io/controller-expand-secret-name: csi-fs-secret
csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi-cephfs
csi.storage.k8s.io/provisioner-secret-name: csi-fs-secret
csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi-cephfs
csi.storage.k8s.io/node-stage-secret-name: csi-fs-secret
csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi-cephfs
reclaimPolicy: Delete
mountOptions:
- debug
【PVC 생성】
-
동적 프로비저닝용 스토리지클래스를 지정하여 PVC를 생성한다.
-
이 PVC을 생성하면 pvc-로 시작하는 이름이 붙은 PV가 자동으로 생성되고 할당된다.
$ cat /root/fs-pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: csi-fs-sc
# PVC 확인
$ kubectl get pvc csi-cephfs-pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
csi-cephfs-pvc Bound pvc-7f521f85-af28-437f-be7b-0da7efe38628 1Gi RWX csi-fs-sc 3h19m
# 생생한 PV 확인
$ kubectl get pv pvc-7f521f85-af28-437f-be7b-0da7efe38628
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-7f521f85-af28-437f-be7b-0da7efe38628 1Gi RWX Delete Bound default/csi-cephfs-pvc csi-fs-sc 3h18m
【파드 생성】
$ cat <<EOF > sample-pvc-dynamic-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: sample-pvc-pod
spec:
containers:
- name: nginx-container
image: nginx:1.16
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-pvc
volumes:
- name: nginx-pvc
persistentVolumeClaim:
claimName: csi-cephfs-pvc
EOF
(4) PVC 조정을 사용한 볼륨 확장
-
PVC 크기를 조정하려면 사전에 스토리지클래스에 “allowVolumeExpansion: true”를 설정하고 그 스토리지클래스로 PVC를 생성해야 한다.
-
위 스토리지클래스 예제에 이미 설정되어 있다.

# 크기 조정이 가능한 스토리지 클래스를 지정한 PVC 예제
$ cat <<EOF > sample-pvc-resize.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sample-pvc-resize
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
storageClassName: csi-fs-sc
EOF
# PVC를 사용하여 2Gi PV 생성
$ kubectl apply -f sample-pvc-resize.yaml
persistentvolumeclaim/sample-pvc-resize created
$ kubectl get pvc sample-pvc-resize
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
sample-pvc-resize Bound pvc-10b5ff6e-c5fa-4ef5-84d5-94f73ae693bf 2Gi RWX csi-fs-sc 12s
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-10b5ff6e-c5fa-4ef5-84d5-94f73ae693bf 2Gi RWX Delete Bound default/sample-pvc-resize csi-fs-sc 25s
파드 매니패스트 작성
$ cat <<EOF > sample-pvc-resize-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: sample-pvc-resize-pod
spec:
containers:
- name: nginx-container
image: nginx:1.16
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-pvc
volumes:
- name: nginx-pvc
persistentVolumeClaim:
claimName: sample-pvc-resize
EOF
$ kubectl exec -it sample-pvc-resize-pod -- df -h | grep /usr/share/nginx/html
192.168.219.51:6789:/volumes/csi/csi-vol-cf3a02d2-f785-43f5-af56-8c9f6aa8b194/4c930cb3-d90d-42e6-9df9-e167aca8cd38 2.0G 0 2.0G 0% /usr/share/nginx/html
# PVC에서 요청하는 용량 변경
$ kubectl patch pvc sample-pvc-resize --patch '{"spec": {"resources": {"requests": {"storage": "4Gi"}}}}'
persistentvolumeclaim/sample-pvc-resize patched
# PV이 확장된 것을 확인
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-10b5ff6e-c5fa-4ef5-84d5-94f73ae693bf 4Gi RWX Delete Bound default/sample-pvc-resize csi-fs-sc 10m
PVC 조정은 디스크 크기를 확장할 수 있지만 축소할 수는 없다는 점에 주의해야 한다.
$ kubectl patch pvc sample-pvc-resize --patch '{"spec": {"resources": {"requests": {"storage": "1Gi"}}}}'
The PersistentVolumeClaim "sample-pvc-resize" is invalid: spec.resources.requests.storage: Forbidden: field can not be less than previous value
(5) 스테이트풀셋에서 PVC - volumeClaimTemplate
-
스테이트풀셋의 워크로드에서는 영구 데이터 영역을 사용하는 경우가 많다.
-
spec.volumeClaimTemplate을 사용하면 PVC을 별도로 정의하지 않아도 자동으로 PVC를 생성할 수 있다.
-
또 컨테이너 내부의 volumeMounts에 volumeClaimTemplate 이름을 지정하는 것만으로 완료되고, 스테이트풀셋 매니페스트만으로 설정이 끝난다.

cat <<EOF > sample-statefulset-with-pvc.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sample-statefulset-with-pvc
spec:
serviceName: stateful-with-pvc
replicas: 2
selector:
matchLabels:
app: sample-pvc
template:
metadata:
labels:
app: sample-pvc
spec:
containers:
- name: sample-pvc
image: nginx:1.16
volumeMounts:
- name: pvc-template-volume
mountPath: /tmp
volumeClaimTemplates:
- metadata:
name: pvc-template-volume
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: csi-fs-sc
EOF
# 스테이프풀셋을 생성하면 PVC 두 개가 생성되고 각각 영구 볼륨이 생성된 것을 확인할 수 있다.
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-template-volume-sample-statefulset-with-pvc-0 Bound pvc-bc55a161-7305-4fbd-bafb-1a518571ed3a 1Gi RWX csi-fs-sc 99s
pvc-template-volume-sample-statefulset-with-pvc-1 Bound pvc-821ec652-c920-4053-977d-1aa5d062b822 1Gi RWX csi-fs-sc 85s
댓글 남기기