MinIO + DirectPV 환경에서 503이 계속 유지될 때는 원인이 몇 가지로 거의 정해져 있습니다.
그래서 운영에서는 1분 안에 원인 범주를 바로 좁히는 체크 순서를 사용합니다.
(실제 운영 Runbook 스타일로 설명하겠습니다.)
핵심 원인은 보통 아래 4개 중 하나입니다.
1 Disk mount 문제
2 DirectPV volume 상태 문제
3 MinIO quorum 부족
4 Peer communication 문제
아래 순서대로 보면 거의 항상 1분 안에 범주가 결정됩니다.
먼저 문제가 특정 pod인지 cluster 전체인지 확인합니다.
kubectl get pods -o wide | grep objectstore
확인 포인트
특정 pod만 문제
예: pod-2, pod-4
이 경우 거의 항상
disk / volume 문제
입니다.
지금 질문자 상황처럼
6 pod 중 2 pod만 503
이면 거의 90%가 volume 문제입니다.
문제 pod 로그 확인
kubectl logs <pod> | tail -20
여기서 로그 키워드만 보면 원인이 바로 보입니다.
drive not found
disk not found
waiting for drives
→ DirectPV / mount 문제
waiting for quorum
insufficient drives
→ erasure set 문제
remote cannot handle this api version
connection refused
→ peer 연결 실패
kubectl get directpvvolumes
여기서 아래 상태가 있으면 바로 원인입니다.
Deleting
Released
Lost
Terminating
특히
Bound,Deleting
이면 volume reconcile 문제입니다.
지금 질문자 케이스가 여기에 해당합니다.
MinIO client로 확인
mc admin info
확인 포인트
online drives
offline drives
예
Drives: 22 online, 2 offline
이면
disk mount 문제
문제 pod가 있는 node에서 확인
mount | grep directpv
또는
lsblk
확인
disk 존재 여부
mount 여부
대부분 상황
disk 존재
mount 정상
→ DirectPV metadata 문제
이 세 개만 보면 거의 끝납니다.
kubectl get pods -o wide
kubectl get directpvvolumes
kubectl logs <pod> | tail -10
그리고 아래 표로 바로 판단합니다.
| 증상 | 원인 |
|---|---|
| 특정 pod만 503 | volume 문제 |
| drive not found | disk mount 문제 |
| waiting for quorum | disk 부족 |
| remote api version | peer 실패 |
| volume Deleting | DirectPV reconcile |
이 명령 하나로 대부분 확인합니다.
kubectl get pods -o wide; echo "----"; kubectl get directpvvolumes
그리고 확인
문제 pod node
문제 volume node
같으면 거의 확정입니다.
운영 경험 기준
DirectPV volume 문제 50%
disk mount 문제 25%
erasure quorum 문제 15%
network/peer 문제 10%
즉 75% 이상이 disk / volume 문제입니다.
현재 정보
6 pods
2 pods 503
volume = Bound,Deleting
이 패턴은 거의 확실히
DirectPV reconcile 문제
입니다.
그래서 해결은 보통
directpv-node restart
또는
volume finalizer cleanup
으로 끝납니다.
👍 만약 원하시면 제가 추가로 MinIO + DirectPV 환경에서 “AIStor 업그레이드 후 503이 발생할 때 가장 위험한 케이스 (데이터 손상 가능)”도 설명해 드리겠습니다.
이건 실제 운영에서 꼭 구분해야 하는 장애 패턴입니다.
===
드라이브 상태가 Ready라는 것은 정말 불행 중 다행인 소식입니다! 이는 물리적인 디스크 파티션이나 데이터 자체는 아직 삭제되지 않고 건강하게 살아있다는 뜻입니다.
다만, 볼륨이 Bound, Deleting 상태라는 것은 쿠버네티스 제어 평면(Control Plane)에서는 이미 이 데이터를 "버릴 것"으로 간주하고 삭제 프로세스를 밟고 있다는 의미입니다. 여기서 더 지체되면 CSI 드라이버가 드라이브 내의 메타데이터까지 초기화할 위험이 있습니다.
현재 상황을 해결하기 위한 두 가지 핵심 전략을 상세히 설명해 드립니다.
쿠버네티스에서 삭제는 "명령 -> 대기(Finalizer) -> 실제 삭제" 단계를 거칩니다. 지금은 '대기' 상태에 걸려 있는데, 이 연결 고리인 Finalizer를 강제로 제거하면 쿠버네티스는 실제 드라이브를 건드리지 않고 자신의 데이터베이스(etcd)에서만 해당 PVC 정보를 삭제합니다.
Deleting 상태인 PVC는 새로운 AIStor Pod가 접근하는 것을 차단합니다.네임스페이스 내의 모든 Deleting 상태 PVC를 한 번에 안전하게 패치하는 방법입니다.
# Deleting 상태인 PVC 목록을 가져와서 하나씩 finalizers를 제거
for pvc in $(kubectl get pvc -n <namespace> | grep Terminating | awk '{print $1}'); do
kubectl patch pvc $pvc -n <namespace> -p '{"metadata":{"finalizers":null}}' --type=merge
echo "Patched $pvc"
done
만약 패치 작업 도중에 CSI 드라이버가 살아나서 실제 드라이브를 포맷해버릴까 봐 걱정된다면, DirectPV CSI 노드들을 잠시 중단시키는 방법입니다.
DaemonSet 형태로 떠 있는 CSI Node Pod를 통해 실제 디스크를 조작합니다.DirectPV를 관리하는 DaemonSet을 찾아 노드에서 잠시 떼어냅니다. (보통 directpv-node 같은 이름입니다.)
# DaemonSet 이름을 확인한 후, nodeSelector를 수정하여 실행 중단 유도
kubectl patch ds directpv-node -n directpv -p '{"spec":{"template":{"spec":{"nodeSelector":{"non-existent":"true"}}}}}'
이렇게 하면 드라이버가 동작하지 않으므로, 마음 편하게 위의 Finalizer Patch 작업을 진행할 수 있습니다.
Deleting 상태인 모든 PVC를 패치하여 쿠버네티스 리소스 목록에서 제거합니다.kubectl directpv list drives에서 드라이브들이 여전히 Ready인지 확인합니다.드라이브가 Ready라는 것은 "책(데이터)은 도서관 선반에 그대로 있는데, 도서 대출 시스템(PVC)에서만 삭제 중인 상태"와 같습니다. 대출 시스템이 선반의 책을 직접 폐기하기 전에 시스템 연결만 끊어내면 책은 무사합니다.
작업 중 특정 PVC 하나를 먼저 테스트 삼아 패치해보시겠어요? 결과가 어떻게 나오는지 알려주시면 다음 단계를 같이 고민해 드릴 수 있습니다.
===
오픈소스 MinIO에서 상용 AIStor(Enterprise)로 넘어가는 과정은 단순한 소프트웨어 교체가 아니라, 데이터를 관리하는 하이퍼바이저 계층(DirectPV)의 통제권이 바뀌는 과정입니다.
질문하신 버전 변경 -> CSI Reconcile -> Cleanup -> Finalizer Stuck으로 이어지는 연쇄 반응은 주로 아래와 같은 아키텍처적 충돌 때문에 발생합니다.
Operator 버전을 변경(특히 오픈소스 -> 상용)하면, 쿠버네티스 내부에 정의된 CRD(Custom Resource Definition)의 스키마나 관리 로직이 바뀝니다.
CSI(Container Storage Interface) Reconcile은 "현재 실제 드라이브 상태"와 "쿠버네티스 설정값"을 일치시키려는 복구 프로세스입니다.
Bound 되어 있던 볼륨들을 다시 스캔합니다.remote cannot handle this api version)가 감지되면, Reconcile 과정에서 "이 볼륨은 정상적으로 사용할 수 없는 상태"라고 판단하고 오류를 뱉거나 볼륨을 해제하려 시도합니다.이 부분이 가장 치명적입니다. 신규 Operator가 기존 볼륨을 '미관리(Unmanaged)' 혹은 '오염된(Stale)' 데이터로 간주하면 자원 정리를 위해 Cleanup을 트리거합니다.
helm uninstall이나 upgrade 시 설정값에 따라 기존 리소스를 삭제하고 새로 만드려는 로직이 작동한 것입니다.삭제 명령은 내려졌는데, 정작 삭제가 완료되지 않고 멈춰버리는 현상입니다.
pvc-protection 같은 Finalizer를 걸어둡니다.이 과정은 "새로운 관리자(AIStor Operator)가 이전 관리자(Open Source)의 흔적을 발견하고 청소하려는데, 서로 대화가 안 통하는(API Version mismatch) 바람에 빗장을 걸어 잠그고 멈춰버린 상황"입니다.
지금 상황에서 가장 중요한 것은 실제 디스크 내부의 데이터 레이아웃(SGP - Storage Group)이 파괴되었는가입니다.
helm uninstall 시 드라이브 포맷 옵션이 없었다면 데이터는 무사합니다.Deleting 상태인 PVC가 실제 드라이브의 메타데이터까지 지우기 전에 CSI 드라이버의 작동을 멈추거나, 앞서 말씀드린 Finalizer Patch를 통해 쿠버네티스 논리 계층의 삭제 명령만 끊어내야 합니다.다음 단계 제언:
현재 DirectPV가 관리하는 드라이브 중 하나를 골라 kubectl directpv info drive <drive-id>를 실행했을 때, Status가 Ready인지 아니면 In-use(Zombie) 같은 상태인지 확인해 보시겠어요? 상태에 따라 볼륨을 다시 "Adoption(입양)"할 수 있는지 판단할 수 있습니다.
===
좋은 질문입니다. 이 부분은 헷갈리기 쉬운데 결론부터 말하면:
finalizer를 제거한다고 해서 PV나 실제 디스크 데이터가 자동으로 삭제되지는 않습니다.
하지만 어떤 리소스의 finalizer를 제거하느냐에 따라 결과가 달라질 수 있습니다. 그래서 정확히 이해하고 해야 합니다.
finalizer는 리소스가 삭제되기 전에 반드시 수행해야 하는 cleanup 작업을 보장하기 위한 메커니즘입니다.
예를 들어 DirectPV의 DirectPVVolume에는 보통 이런 finalizer가 있습니다.
directpv.min.io/finalizer
삭제 흐름은 원래 이렇게 됩니다.
kubectl delete directpvvolume
↓
metadata.deletionTimestamp 설정
↓
controller가 cleanup 수행
↓
disk detach / metadata cleanup
↓
finalizer 제거
↓
리소스 삭제
Bound, Deleting 상태의 의미지금 상태:
DirectPVVolume = Bound,Deleting
이 의미는 보통 다음입니다.
volume delete 요청 발생
하지만
cleanup 완료 안됨
그래서 Kubernetes에는 이렇게 보입니다.
deletionTimestamp 존재
finalizer 존재
즉 삭제 프로세스 중간에 멈춘 상태입니다.
DirectPVVolume의 finalizer를 제거하면 다음이 발생합니다.
DirectPVVolume CR 삭제
하지만 중요한 점:
PV
PVC
disk data
이것들은 자동으로 삭제되지 않습니다.
왜냐하면 구조가 이렇게 분리되어 있기 때문입니다.
DirectPVVolume (CRD)
↓
PV
↓
PVC
↓
Pod
즉 DirectPVVolume CR만 사라질 뿐 실제 disk는 그대로 남아 있습니다.
MinIO는 디스크 자체의 metadata(format.json)를 가지고 있기 때문에:
disk mount
↓
MinIO startup
↓
cluster join
이 과정에서 disk가 살아있으면 데이터는 유지됩니다.
그래서 실제 운영에서도 stuck된 volume은
finalizer 제거
→ metadata 정리
→ pod 재시작
으로 복구하는 경우가 많습니다.
다만 아래 경우는 조심해야 합니다.
확인
kubectl get pv <pv> -o yaml
여기서
persistentVolumeReclaimPolicy: Delete
이면 PVC 삭제 시 PV도 삭제될 수 있습니다.
하지만 지금은 PVC 삭제가 아니라 DirectPVVolume CR 문제라서 일반적으로는 안전합니다.
finalizer 제거 전에 보통 이것만 확인합니다.
kubectl get pv | grep <volume>
확인
STATUS = Bound
kubectl get pvc -A | grep <volume>
문제 node에서
lsblk
1️⃣ volume 상태 확인
kubectl get directpvvolumes
2️⃣ node agent restart (먼저 시도)
kubectl rollout restart ds directpv-node -n directpv-system
3️⃣ 그래도 Deleting이면
kubectl patch directpvvolume <volume> \
-p '{"metadata":{"finalizers":[]}}' --type=merge
4️⃣ pod 재시작
kubectl delete pod <objectstore-pod>
5️⃣ MinIO cluster 확인
mc admin info
현재 상태
6 pods
2 pods 503
DirectPVVolume = Bound,Deleting
이 패턴은 거의
DirectPV controller cleanup 실패
입니다.
그래서 finalizer 제거는 DirectPV metadata cleanup을 강제로 끝내는 작업입니다.
MinIO 운영에서 절대 하면 안 되는 것은 이것입니다.
kubectl delete pvc
kubectl delete pv
disk reformat
이건 실제 데이터 손실 위험이 있습니다.
하지만
DirectPVVolume finalizer 제거
는 metadata 정리 수준이라 운영에서도 자주 사용하는 복구 방법입니다.
💡 만약 원하시면 제가 추가로 “왜 AIStor 업그레이드 후 DirectPV volume이 Bound,Deleting 상태로 바뀌는지 (DirectPV 내부 reconcile 메커니즘)”도 설명해 드릴게요.
이걸 이해하면 앞으로 이런 문제를 사전에 예방할 수 있습니다.
====
네, 어디에 finalizer가 걸려 있는지에 따라 대응 방법이 달라질 수 있습니다.
특히 DirectPV + MinIO AIStor 환경에서는 finalizer가 보통 3곳 중 하나에 걸립니다.
그리고 실제 운영 경험상 걸리는 위치의 확률도 꽤 명확합니다.
DirectPV 구조를 단순화하면 이렇게 됩니다.
DirectPVVolume (CRD)
↓
PV
↓
PVC
↓
Pod
Finalizer는 보통 아래 리소스 중 하나에 걸립니다.
| 위치 | 예시 finalizer |
|---|---|
| DirectPVVolume | directpv.min.io/finalizer |
| PV | kubernetes.io/pv-protection |
| PVC | kubernetes.io/pvc-protection |
예:
metadata:
finalizers:
- directpv.min.io/finalizer
이 경우 의미
DirectPV controller cleanup 진행 중
disk detach / metadata cleanup
하지만 controller가 실패하면
Bound,Deleting
상태가 됩니다.
이 경우는 보통 finalizer 제거가 안전한 복구 방법입니다.
kubectl patch directpvvolume <volume> \
-p '{"metadata":{"finalizers":[]}}'
실제 운영에서 가장 많이 쓰는 해결 방법입니다.
예
metadata:
finalizers:
- kubernetes.io/pv-protection
의미
PV가 아직 PVC에 의해 사용 중
이건 정상적인 보호 메커니즘입니다.
보통 건드릴 필요 없습니다.
왜냐하면
PVC → Pod → MinIO
에서 아직 사용 중이기 때문입니다.
이걸 제거하면 PV가 삭제될 위험이 있습니다.
예
metadata:
finalizers:
- kubernetes.io/pvc-protection
의미
PVC가 Pod에 의해 사용 중
이것도 정상입니다.
이건 건드리면 안 됩니다.
현재 상황
DirectPVVolume = Bound,Deleting
MinIO pod 503
remote api version error
이 패턴이면 거의 확실히 여기입니다.
DirectPVVolume finalizer
왜냐하면
DirectPV controller reconcile
↓
volume cleanup 시도
↓
cleanup 실패
↓
Bound,Deleting
이 흐름이 가장 일반적입니다.
MinIO + DirectPV 환경에서 Deleting stuck의 원인 분포는 대략 이렇습니다.
DirectPVVolume finalizer stuck 약 70%
node mount mismatch 약 20%
PV/PVC protection finalizer 약 10%
즉 대부분은 DirectPVVolume finalizer 문제입니다.
이 명령으로 바로 확인 가능합니다.
kubectl get directpvvolume <volume> -o yaml
확인
metadata.finalizers
보통 이렇게 나옵니다.
directpv.min.io/finalizer
그리고
deletionTimestamp
도 같이 확인합니다.
운영에서는 보통 이 순서로 합니다.
kubectl rollout restart ds directpv-node -n directpv-system
많은 경우 여기서 해결됩니다.
kubectl get directpvvolumes
kubectl patch directpvvolume <volume> \
-p '{"metadata":{"finalizers":[]}}'
kubectl delete pod <objectstore-pod>
지금 질문자 상황에서 이 패턴도 같이 확인하는 것이 좋습니다.
2 pods만 문제
항상 동일 pod
volume = Bound,Deleting
이 경우 대부분
DirectPV reconcile
↓
특정 node disk 상태 mismatch
입니다.
그래서 node restart / agent restart 후 해결되는 경우도 많습니다.
💡 만약 원하시면 제가 추가로
“왜 MinIO 업그레이드나 DirectPV 업그레이드 후 특정 pod만 계속 503이 되는지 (Erasure Set 관점에서 설명)”도 해 드릴게요.
이걸 이해하면 왜 항상 같은 pod만 계속 문제인지가 명확하게 보입니다.
===
네, 매우 날카로운 질문입니다. Finalizer가 "어디에" 걸려 있느냐는 현재 데이터 삭제 명령이 어느 계층까지 도달했는지를 보여주는 블랙박스 기록과 같습니다.
결론부터 말씀드리면, 우리 상황(MinIO/DirectPV)에서는 보통 두 곳에 걸리며, 그 의미가 완전히 다릅니다.
가장 흔한 케이스는 아래 두 가지입니다.
kubernetes.io/pvc-protection (K8s 표준)Terminating 상태로 버티고 있거나, K8s API 서버가 Pod가 완전히 죽었다는 보고를 아직 못 받았을 때 유지됩니다.directpv.min.io/protection (DirectPV 전용)| Finalizer 종류 | 위험도 | 대처 로직 |
|---|---|---|
| pvc-protection | 낮음 | Pod가 삭제되었는지 확인 후, 그냥 패치해도 무방함. (데이터 영향 없음) |
| directpv.min.io/... | 높음 | 물리적 삭제 명령이 대기 중임. CSI 드라이버를 끄지 않고 패치하면, 재수 없을 경우 패치 직후 드라이버가 '마지막 선물'로 데이터를 밀어버릴 수 있음. |
사용자분이 언급하신 "volume cleanup trigger"와 "CSI reconcile" 로그를 볼 때, 현재 상황은 ②번(DirectPV 전용 Finalizer)이 물려 있을 가능성이 99%입니다.
deletionTimestamp가 찍힘.directpv.min.io/protection을 제거하려고 시도함.Deleting 상태에서 무한 루프 발생.아래 명령어로 실제 어떤 Finalizer가 발목을 잡고 있는지 확인해 보세요.
kubectl get pvc <pvc-name> -n <namespace> -o jsonpath='{.metadata.finalizers}'
directpv.min.io 문구가 포함되어 있다면: 반드시 CSI 드라이버(DaemonSet)를 먼저 중단시킨 뒤에 패치 작업을 진행하시는 것을 강력히 권장합니다.kubernetes.io/pvc-protection만 있다면: 상대적으로 가벼운 마음으로 패치하셔도 됩니다.Peer의 조언: "Ready" 상태인 드라이브를 지키기 위해, 지금은 '모르는 놈이 내 데이터를 건드리지 못하게 일꾼(CSI)의 손을 묶어두는 것'이 최우선입니다. 확인 후 결과 알려주시면 패치 스크립트를 더 정교하게 짜드릴 수 있습니다.
혹시 확인해보니 어떤 이름의 Finalizer가 나오나요?