볼륨과 영구 볼륨에 이어서 영구 볼륨 클레임(PersistentVolumeClaim, PVC)에 대해서 다룬다. 각각에 대한 짧은 정리는 아래와 같다.
- 볼륨(Volume): 호스트에 미리 준비된 사용 가능한 볼륨을 일컬음. 쿠버네티스에서 볼륨 리소스를 생성/삭제할 수 없다. 매니페스트에 볼륨을 지정하기만 할 수 있음.
- 영구 볼륨(PersistentVolume, PV): 외부의 볼륨 시스템에 연계하여 사용하는 볼륨. 쿠버네티스에서 볼륨 리소스를 생성/삭제한다. 영구 볼륨을 생성하면 클러스터에 등록만 된다.
- 영구 볼륨 클레임(PersistentVolumeClaim, PVC): 이미 생성된 영구 볼륨을 사용 요청하는 리소스. 파드에서 영구 볼륨을 사용하기 위해 이것을 사용한다.
영구 볼륨 클레임은 영구 볼륨을 요청하는 리소스이다. 영구 볼륨 클레임에서는 영구 볼륨에 대해 요구하는 용량, 레이블 등을 지정한다. 파드에서 해당 영구 볼륨 클레임을 사용하면, 스케쥴러는 현재 클러스터에 존재하는 영구 볼륨 중에서 PVC의 조건을 만족하는 가장 적절한 영구 볼륨을 할당해준다.
1. 영구 볼륨 클레임 설정
PVC 에는 아래와 같은 항목들을 설정할 수 있다.
| 항목 | 설명 |
| AccessModes | 읽기/쓰기 권한 - RWO(ReadWriteOnce): 한 노드만 읽고 쓰기 - RWX(ReadWriteMany): 여러 노드가 읽고 쓰기 - ROX(ReadOnlyMany): 여러 노드가 읽기만 |
| Resources | 요청할 스토리지 용량(e.g. 1Gi) |
| StorageClassName | 사용할 스토리지 클래스 |
| Selector(Labels) | 특정 라벨이 붙은 PV 를 찾기 |
이 항목들은 모두 영구 볼륨에도 정의된 값이며, PVC에서 요청하는 값에 부합하는 영구 볼륨이 할당된다. 주의할 점은 용량의 경우 PVC 에서 지정한 값이 최소 용량이 된다는 것이다. 1Gi 를 요청하더라도 1Gi 이상의 가장 작은 PV 가 할당된다.
2. 영구 볼륨 클레임 생성
아래와 같은 매니페스트를 이용하여 PVC를 생성한다.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sample-pvc-nfs
spec:
selector:
matchLabels:
type: nfs
speed: high
matchExpressions:
- key: env
operator: In
values:
- practice
resources:
requests:
storage: 300Mi
accessModes:
- ReadWriteOnce
storageClassName: manual
PVC 를 생성하면 자동으로 적절한 영구 볼륨을 확보한다.
# PV 확인. 현재 STATUS: Available
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
sample-pv-nfs 500Mi RWO Retain Available manual <unset> 4s
# PVC 생성
$ kubectl apply -f sample-pvc-nfs.yaml
persistentvolumeclaim/sample-pvc-nfs created
# PV 확인. STATUS: Bound 로 바뀜. default/sample-pvc-nfs 클레임이 할당됨.
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
sample-pv-nfs 500Mi RWO Retain Bound default/sample-pvc-nfs manual <unset> 19s
# PVC 확인. STATUS: Bound
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
sample-pvc-nfs Bound sample-pv-nfs 500Mi RWO manual <unset> 10s
만약 조건을 만족하는 PV가 없다면 STATUS: Pending 으로 유지되며, PVC 를 describe 해보면 상세 내용을 확인할 수 있다.
3. 영구 볼륨 클레임 삭제
PV가 persistentVolumeReclaimPolicy: Retain 정책을 사용하고 있는 경우 PVC 가 삭제되면 바인딩 되었던 PV 는 Released 상태로 변경된다. Released 상태의 PV 는 다시 자동으로 PVC 에 할당될 수 없다.
# PVC 삭제
$ kubectl delete -f sample-pvc-nfs.yaml
persistentvolumeclaim "sample-pvc-nfs" deleted
# PV 확인. STATUS: Released
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
sample-pv-nfs 500Mi RWO Retain Released default/sample-pvc-nfs manual <unset> 5d15h
4. 파드에서 PVC 를 사용하여 PV 마운트
이제 파드 매니페스트에서 spec.volumes[].persistentVolumeClaim 항목으로 아래와 같이 미리 생성해둔 PVC 를 지정한다.
apiVersion: v1
kind: Pod
metadata:
name: sample-pvc-pod-nfs
spec:
containers:
- name: nginx-container
image: nginx:1.27
ports:
- containerPort: 80
name: "http"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nginx-pvc
volumes:
- name: nginx-pvc
persistentVolumeClaim:
claimName: sample-pvc-nfs
파드가 생성될 때 sample-pvc-nfs 라는 이름의 PVC 를 찾아 바인딩 된 PV 를 컨테이너의 "/usr/share/nginx/html" 경로로 마운트하게 된다.
이 샘플에서 sample-pvc-nfs PVC 가 바인딩한 PV 매니페스트는 아래와 같다. nfs 타입으로 master 노드의 "/srv/nfs/kubedata" 경로를 볼륨으로 사용했다.
apiVersion: v1
kind: PersistentVolume
metadata:
name: sample-pv-nfs
labels: # 파드가 특정 PV를 찾을 수 있게 돕는 이름표
type: nfs
speed: high
env: practice
spec:
capacity:
storage: 500Mi # 사용할 용량
accessModes:
- ReadWriteOnce
storageClassName: manual # 수동으로 만든 PV임을 명시 (중요)
nfs:
server: 192.168.0.36 # 마스터 노드 IP 주소
path: /srv/nfs/kubedata # 마스터 노드에서 만든 경로
이를 기반으로 실제 파드를 구동시켜보고, 파드 내 컨테이너 <-> master 노드 내 스토리지 간에 스토리지가 읽기/쓰기 공유되는지 아래 단계를 따라 확인해보자
# 파드 생성
$ kubectl apply -f sample-pvc-pod-nfs.yaml
pod/sample-pvc-pod-nfs created
# 파드가 Running 중임을 확인
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
sample-pvc-pod-nfs 1/1 Running 0 94s 10.244.1.85 worker01 <none> <none>
# 파드 내 컨테이너에 접속하여 볼륨 마운트 경로에 존재하는 파일이 없음 확인
$ kubectl exec -it sample-pvc-pod-nfs -- /bin/bash
root@sample-pvc-pod-nfs:/# ls /usr/share/nginx/html
# 다른 SSH 터미널 세션을 열고 master 노드의 스토리지 경로 진입
$ cd /srv/nfs/kubedata
# 샘플 파일 생성
$ cat <<EOF > index.html
<h1>Hello, PVC from storage</h1>
EOF
# 컨테이너 내에서 볼륨 마운트 경로 다시 확인
root@sample-pvc-pod-nfs:/# cat /usr/share/nginx/html/index.html
<h1>Hello, PVC from storage</h1>
# 컨테이너 내에서 파일 수정
cat <<EOF > /usr/share/nginx/html/index.html
<h1>Hello, PVC from container</h1>
EOF
# master 노드에서 스토리지 내 파일 다시 확인
$ cat index.html
<h1>Hello, PVC from container</h1>
'Kubernetes' 카테고리의 다른 글
| [Kubernetes] volumeBindingMode 영구 볼륨 할당 타이밍 제어 (0) | 2026.02.18 |
|---|---|
| [Kubernetes] 영구 볼륨 동적 프로비저닝 (0) | 2026.02.16 |
| [Kubernetes] PersistentVolume 이해 (0) | 2026.02.11 |
| [Kubernetes] Volume 이해와 종류 (0) | 2026.01.31 |
| [Kubernetes] ConfigMap 과 Secret 볼륨 마운트시 퍼미션 변경 및 동적 업데이트 (0) | 2026.01.25 |
