본문 바로가기
IT/리눅스

kubernetes에서 PVC 삭제(그리고 생성)가 안될 때

by 라떼야가자 2024. 9. 13.

쿠버네티스(kubernetes)에서 PVC를 삭제할 때 멈춰 있는 경우가 있다. PVC가 "Terminating" 상태에서 멈춘 이유는 대개 PVC와 연결된 리소스(Pod 또는 Finalizer)가 삭제되지 않았기 때문이고, Finalizer를 삭제하고 Pod를 삭제하는 방법으로 해결할 수 있다.

참고로 앞으로 이 글에 등장하는 "<PVC>"와 "<PV>"는 각자 사용하는 PVC의 이름으로 바꾸면 된다.

 

 

PVC 삭제

$ kubectl delete pvc <PVC>
persistentvolumeclaim "<PVC>" deleted

 

분명히 deleted라고 나오긴 하지만 실제로 kubectl get pvc 명령어로 확인하면 남아있고, 저 상태로 끝나지 않고 계속 실행 중이다.

 

이럴 때는 SSH 창을 추가로 열고, 상태를 확인해 보면 STATUS가 Terminating으로 조회된다.

$ kubectl get pvc
NAME            STATUS        VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
task-pv-claim   Terminating   <PVC>   100Mi      RWO            manual         <unset>                 3h8m

 

 

이제 Finalizer를 제거해 본다.

kubectl patch pvc <PVC> -p '{"metadata":{"finalizers":null}}'

 

 

위의 명령어를 실행한 후에 이전 창으로 돌아가면 삭제 작업이 완료된 것을 볼 수 있다. (쉘 프롬프트로 돌아옴.)

$ kubectl delete pvc <PVC>
persistentvolumeclaim "<PVC>" deleted
$

 

삭제된 것을 확인하기 위해 PVC 조회하면 아무것도 없다.

$ kubectl get pvc
No resources found in default namespace.

 

 

여기까지 하면 PVC 삭제는 완료된다.

 

 

PVC 생성

 

삭제한 다음에 PVC를 새로 다시 생성할 때 Pending으로 생성이 되지 않는 현상이 있다.

$ kubectl get pvc <PVC>
NAME            STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
task-pv-claim   Pending                                      expandable-storage   <unset>                 16s

 

 

describe로 PVC를 살펴보면 제일 마지막 줄 Message에 "waiting for first consumer to be created before binding"로 출력하고 있다.

$ kubectl describe pvc <PVC>
Name:          <PVC>
Namespace:     default
StorageClass:  expandable-storage
Status:        Pending
Volume:
Labels:        <none>
Annotations:   <none>
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode:    Filesystem
Used By:       demo-6bcf9885fd-kkwzv
Events:
  Type    Reason                Age                   From                         Message
  ----    ------                ----                  ----                         -------
  Normal  WaitForFirstConsumer  13s (x11 over 2m35s)  persistentvolume-controller  waiting for first consumer to be created before binding

 

 

이것은 스토리지클래스의 "volumeBindingMode" 값이 "WaitForFirstConsumer"으로 설정했을 경우에는 PVC가 바인딩되기 전에 파드가 스케줄링되어야 하기 때문이다.

 

따라서 파드를 새로 띄우기 위해 기존 파드를 삭제해야 하며, 그 대상은 위에 "Used By"로 나타난 파드이다.

kubectl get pod demo-6bcf9885fd-kkwzv

 

Deployment나 ReplicaSet으로 생성된 파드라면 저렇게 삭제해도 바로 다시 생성된다.

 

 

 


PV 바인딩

 

파드에 PVC 연결은 위의 단계에서 완료되었지만 여전히 파드의 상태는 Pending 상태로 보이는 현상이 있다.

이때 kubectl describe pod 명령어로 확인해 보면 마지막 줄 메시지가 아까와 달라져있다.

 

"0/2 nodes are available: 1 node(s) didn't find available persistent volumes to bind, 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling."

 

 

이번에는 PV와 PVC의 바인딩이 문제다.

PV의 STATUS가 Released로 되어 있으면 새로운 PVC와 바인딩을 하지 않는다.

$ kubectl get pv
NAME             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM                   STORAGECLASS         VOLUMEATTRIBUTESCLASS   REASON   AGE
<PV>   20Gi       RWO            Retain           Released   default/<PVC>   expandable-storage   <unset>                          21m
$

$ kubectl get pvc <PVC>
NAME            STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
<PVC>   Pending                                      expandable-storage   <unset>                 2m8s

 

PV의 상태를 Released에서 Available로 바꾸기 위해 claimRef 필드를 삭제한다.

kubectl patch pv <PV> -p '{"spec":{"claimRef": null}}'

 

이제 PVC의 상태가 Bound로 변경되었다.

$ kubectl get pvc <PVC>
NAME            STATUS   VOLUME           CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
<PVC>   Bound    <PV>   20Gi       RWO            expandable-storage   <unset>                 10m

 

 

여기까지 하면 파드도 Pending상태에서 Running으로 변경되어 있다!!

 

끝.