콘텐츠로 이동
Study NoteCKA

PV 회수 정책과 재사용

결론부터
PVC를 삭제한 뒤 PV와 데이터가 어떻게 남는지는 회수 정책과 저장소 구현에 달려 있다.

PV/PVC 바인딩은 연결의 시작이다. 이 장은 연결을 해제한 뒤 PV 상태와 실제 데이터에 무슨 일이 생기는지, 다시 쓰려면 무엇을 확인해야 하는지 다룬다.

PV의 생애 — 상태가 어떻게 움직이는가

섹션 제목: “PV의 생애 — 상태가 어떻게 움직이는가”
PersistentVolume의 Available·Bound·Released·Failed 상태 전이
상태의미
Available비어 있고 바인딩 가능
BoundPVC에 묶여 있다
ReleasedPVC가 삭제됐지만 아직 회수되지 않았다
Failed자동 회수에 실패했다

reclaimPolicy — PVC를 지우면 데이터는?

섹션 제목: “reclaimPolicy — PVC를 지우면 데이터는?”
정책PVC 삭제 시
RetainPV는 남고 상태가 Released 가 된다. 데이터 보존. 재사용하려면 수동 조치
Delete지원하는 프로비저너·플러그인이 PV와 실제 스토리지까지 삭제한다. 동적 프로비저닝의 기본값
Recycledeprecated — 쓰지 말 것. 대신 동적 프로비저닝을 쓴다
터미널 창
kubectl patch pv pv-data -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'

Delete는 원하는 회수 동작이지 삭제 성공의 증거가 아니다. 직접 만든 NFS·local PV처럼 수명 주기를 대신 관리할 외부 프로비저너가 없거나 플러그인이 삭제를 지원하지 않으면 실제 백엔드는 남거나 PV가 Failed가 될 수 있다. PVC를 지운 뒤 kubectl get pv와 백엔드를 함께 확인한다.

터미널 창
kubectl get pv
kubectl get pvc
kubectl describe pvc data # ★ Events에 왜 Pending인지 나온다

같은 데이터로 PV를 다시 연결하기

섹션 제목: “같은 데이터로 PV를 다시 연결하기”

워크로드와 PVC가 지워졌는데 Retain 덕분에 PV가 남았다면, 그 데이터를 그대로 다시 쓸 수 있다. 위 함정과 달리 복구가 목적이면 데이터는 건드리지 않고 연결 정보만 푼다.

Released PV의 spec.claimRef에는 옛 PVC의 이름과 UID가 남아 있다. 같은 이름으로 PVC를 다시 만들어도 UID가 달라서 자동으로 묶이지 않는다. 그래서 순서는 다음과 같다.

  1. PV의 조건을 읽는다. 용량·접근 모드·storageClassName을 PVC에 그대로 맞춰야 한다.

    터미널 창
    kubectl get pv
  2. claimRef를 지워 Available로 돌린다.

    터미널 창
    kubectl patch pv pv-data -p '{"spec":{"claimRef":null}}'
  3. PVC를 만든다. volumeName으로 대상 PV를 고정하면 다른 PV나 동적 프로비저닝으로 새지 않는다.

    spec:
    accessModes: ["ReadWriteOnce"] # PV와 같게
    storageClassName: manual # PV와 같게. PV에 클래스가 없으면 ""
    volumeName: pv-data
    resources:
    requests:
    storage: 1Gi # PV 용량 이하
  4. Bound와 VOLUME 열을 확인한 뒤 워크로드가 이 PVC를 쓰게 한다.

    터미널 창
    kubectl get pvc data # STATUS Bound, VOLUME pv-data

삭제된 Deployment까지 되살리는 연습은 실전 과제에 있다.

PV·PVC·Pod 세 YAML을 손으로 처음부터 치는 건 낭비다 — 시험 중에는 공식 Configure a Pod to Use a PersistentVolume for Storage 페이지를 열어 뼈대를 복사해 오고, 이름·용량·경로만 문제에 맞게 고치는 게 정석이다.

아래 흐름은 단일 노드 실습 환경을 전제로 한다. 공식 예제에서 pvc.yaml과 pod.yaml을 준비하고, PVC 이름은 data, 요청은 1Gi, 클래스는 manual, Pod 이름은 web, claimName은 data, 마운트 경로는 /data로 맞춘다. 모든 명령은 같은 네임스페이스에서 실행한다.

  1. PV 생성 — 관리자의 몫

    터미널 창
    cat <<'EOF' | kubectl apply -f -
    apiVersion: v1
    kind: PersistentVolume
    metadata:
    name: pv-manual
    spec:
    capacity: { storage: 1Gi }
    accessModes: ["ReadWriteOnce"]
    persistentVolumeReclaimPolicy: Retain
    storageClassName: manual
    hostPath: { path: /mnt/data }
    EOF
  2. PVC 생성 — 개발자의 몫. Bound가 되는지 확인한다

    터미널 창
    kubectl create -f pvc.yaml
    kubectl get pvc # Bound 확인
  3. Pod에서 사용

    터미널 창
    kubectl apply -f pod.yaml
    kubectl wait --for=condition=Ready pod/web --timeout=60s
    kubectl exec web -- sh -c 'echo storage-ok > /data/probe && cat /data/probe'
  4. 정리 후 확인 — Retain이면 PV가 Released로 남는다

    터미널 창
    kubectl delete pod web # 사용 중인 Pod부터 제거
    kubectl delete pvc data
    kubectl get pv # Retain이면 Released 로 남는다
  • Retain이면 PVC 삭제 뒤 PV가 Released로 남고 데이터는 보존된다.
  • 재사용 전 데이터를 확인·정리하고, 이전 연결 정보인 claimRef를 해제한다.
  • Delete는 지원하는 저장소 구현이 PV와 백엔드를 지우는 정책이다. 실제 삭제 결과도 확인한다.