Kubernetes

[k8s] pv/pvc ㅡ 이해하기

최선을 다하자! 2026. 6. 9. 10:35

PV와 PVC

Pod가 재시작되어도 데이터를 유지하는 방법


- 컨테이너는 기본적으로 상태를 저장하지 않는다.
- Pod 안에서 파일을 만들어도 Pod가 재시작되면 전부 사라진다.
- DB나 로그처럼 데이터를 보존해야 하는 경우, 외부 스토리지를 연결해야 한다.
- 쿠버네티스는 이 문제를 PersistentVolumePersistentVolumeClaim으로 해결한다.


PV와 PVC의 관계

두 오브젝트의 역할을 먼저 구분해야 한다.

오브젝트 역할 비유
PV (PersistentVolume) 실제 저장공간 하드디스크
PVC (PersistentVolumeClaim) 저장공간 요청서 "나 1GB 필요해"

Pod는 PV에 직접 연결하지 않는다. PVC를 통해서 연결한다. PVC가 조건에 맞는 PV를 찾아서 연결(Bound)시켜주는 방식이다.

Pod  →  PVC  →  PV  →  실제 저장소

PV 만들기

PV는 kubectl create 명령어가 없어서 yaml 파일로만 생성할 수 있다.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /data/nginx
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - k8s-worker-jwc

주요 항목 설명:

항목 설명
storage: 1Gi 저장공간 크기
ReadWriteOnce 노드 1개만 읽기/쓰기 가능
Retain PVC 삭제해도 데이터 보존
hostPath 노드의 실제 경로와 연결
kubectl apply -f nginx-pv.yaml
kubectl get pv

[ 캡처 - PV STATUS: Available ]


PVC 만들기

PVC는 "조건에 맞는 PV를 연결해줘" 하는 요청서다. 용량과 accessMode가 PV와 맞아야 연결된다.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
  namespace: default
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  volumeName: nginx-pv
kubectl apply -f nginx-pvc.yaml
kubectl get pvc

STATUS가 Bound로 바뀌면 PV와 연결된 것이다.

[ 캡처 - PVC STATUS: Bound ]


Deployment에 PVC 연결하기

Deployment yaml에 두 가지를 추가해야 한다. 컨테이너 안에 마운트 경로, 컨테이너 밖에 볼륨 선언.

spec:
  containers:
  - name: nginx
    image: nginx:1.27
    volumeMounts:
    - mountPath: /data       # Pod 안에서 보이는 경로
      name: nginx-storage
  volumes:
  - name: nginx-storage
    persistentVolumeClaim:
      claimName: nginx-pvc   # 연결할 PVC 이름

경로 매핑 구조:

Pod 안의 /data  ←→  노드의 /data/nginx

Pod에서 /data/test.txt에 파일을 쓰면 노드의 /data/nginx/test.txt에 저장된다.


데이터 영속성 확인

Pod 안에 파일을 쓰고 재시작해서 파일이 남아있는지 확인한다.

# Pod 안에 파일 쓰기
kubectl exec deploy/nginx-configmap -- sh -c "echo 'hello nginx' > /data/test.txt"

# 파일 확인
kubectl exec deploy/nginx-configmap -- cat /data/test.txt

# Pod 재시작
kubectl rollout restart deployment nginx-configmap

# 재시작 후 파일 다시 확인
kubectl exec deploy/nginx-configmap -- cat /data/test.txt

재시작 후에도 hello nginx가 그대로 출력된다. 파일은 Pod가 아닌 노드에 저장되어 있기 때문이다.

[ 캡처 - 재시작 후 파일 확인 결과 ]


다음 파트는 Namespace — 같은 클러스터 안에서 리소스를 논리적으로 분리하는 방법을 다룬다.