Auto Clean Up
Auto Clean Up은 미사용 PersistentVolume을 식별하고 제거하여 스토리지 비용을 줄이고, 클러스터에 고아 리소스가 쌓이는 것을 방지합니다. 수동 정리 스크립트나 주기적인 감사 대신, Wave는 미사용 PV를 지속적으로 모니터링하고 여러 겹의 보호 메커니즘을 통해 안전하게 제거합니다.
Auto Clean Up이란?
Auto Clean Up은 고아 PersistentVolume, 즉 바인딩된 PVC가 없는 Released 또는 Available phase의 PV를 자동으로 탐지하고 제거하는 Wave의 지능형 PV 정리 시스템입니다.
이 시스템은 finalizer 탐지, PVC 바인딩 확인, 어노테이션 기반 opt-out(PV 레벨 및 StorageClass 레벨), 볼륨 연결 확인 등 여러 보호 메커니즘을 사용합니다. 탐지 메타데이터는 감사 준수와 운영 가시성을 위해 타임스탬프와 함께 기록됩니다.
동작 방식
Auto Clean Up은 지속적인 탐지 및 정리 사이클로 동작합니다.
탐지 단계
- 모든 PV 스캔: 클러스터의 모든 PersistentVolume을 확인합니다
- Phase 확인: PV가 미사용 상태일 가능성이 있는지 평가합니다:
- Phase가 Released인 경우 (이전 PVC가 삭제됨, reclaim policy = Retain)
- Phase가 Available인 경우 (한 번도 PVC에 바인딩된 적 없음)
- Phase가 Bound이지만 참조하는 PVC가 더 이상 존재하지 않는 경우
- 보호 검사 적용: PV에 활성 보호 장치가 없는지 확인합니다 (아래 보호 메커니즘 참고)
- 탐지 세부 정보 기록: PV 이름, namespace, storage class, 용량, phase, 탐지 사유, 타임스탬프를 기록합니다
보호 메커니즘
Wave는 실수로 삭제되는 것을 막기 위해 여러 겹의 보호 장치를 적용합니다.
1. 커스텀 Finalizer 보호
- 커스텀 finalizer를 탐지합니다 (예:
velero.io/*,backup.company.com/*) - 표준 Kubernetes/CSI 자동 관리 finalizer는 제외합니다 (
kubernetes.io/*,k8s.io/*,external-attacher/*,external-provisioner.*) - 커스텀 finalizer가 있는 PV는 절대 미사용으로 표시되지 않습니다
2. PVC 바인딩 확인
- 바인딩된 PVC가 클러스터에 여전히 존재하는지 확인합니다
- 실시간 검증을 위해 효율적인 HashMap 조회를 사용합니다
- 기존 PVC가 있는 PV는 자동으로 보호됩니다
3. PV 레벨 어노테이션
- 어노테이션:
waveautoscale.io/pv-cleanup: disabled - 관리자가 개별 PV를 보호할 수 있습니다
- 다른 모든 설정보다 우선 적용됩니다
4. StorageClass 레벨 어노테이션
- StorageClass에 동일한 어노테이션(
waveautoscale.io/pv-cleanup: disabled)을 적용합니다 - 해당 StorageClass를 사용하는 모든 PV를 보호합니다
- 광범위하게 제외할 때는 PV별 어노테이션보다 효율적입니다
5. Volume Attachment 확인
- 활성 CSI
VolumeAttachment리소스를 탐지합니다 - 현재 연결되어 있는 PV의 삭제를 방지합니다
- Pod 스케줄링 중 발생할 수 있는 경쟁 상태(race condition)를 방지합니다
6. 전역 활성화/비활성화 토글
- Settings → PV Lifecycle의 마스터 스위치입니다
- 비활성화 시: 탐지는 계속되지만 삭제는 발생하지 않습니다
- 정리를 활성화하기 전에 안전하게 테스트하고 감사할 수 있습니다
정리 단계 (활성화된 경우)
Auto Clean Up이 전역으로 활성화되어 있고 PV가 모든 보호 검사를 통과하면:
- 전역 토글 확인: Settings → PV Lifecycle에서 정리가 활성화되어 있는지 확인합니다
- 보호 검사 적용: PV가 어떤 보호 메커니즘에도 해당하지 않는지 확인합니다
- 삭제 API 호출: Kubernetes API에 삭제 요청을 제출합니다
- 상태 기록: InProgress, Completed, 또는 Failed(오류 세부 정보 포함)로 기록합니다
- 해결 상태 추적: PV가 다시 바인딩되면 해결됨으로 표시합니다 (정리를 방지합니다)
설정
Auto Clean Up은 전역 설정과 세부 설정을 모두 사용합니다.
| 설정 | 설명 | 위치 | 기본값 |
|---|---|---|---|
| Enable Cleanup | 전역 켜기/끄기 토글 | Storage → PV Auto Cleanup | Disabled |
| PV Opt-out Annotation | PV별 정리 비활성화 | PV 메타데이터: waveautoscale.io/pv-cleanup: disabled | 설정 안 됨 |
| StorageClass Opt-out | 특정 StorageClass의 모든 PV에 대해 정리 비활성화 | StorageClass 메타데이터: waveautoscale.io/pv-cleanup: disabled | 설정 안 됨 |
명시적 설정을 통한 보호
Wave는 시간 기반 지연이 아니라 명시적 메커니즘(finalizer, 어노테이션, 바인딩, attachment)을 통해 PV를 보호합니다.
정리 전 PV를 임시로 보호하려면:
- PV 레벨 어노테이션을 사용합니다:
kubectl annotate pv <name> waveautoscale.io/pv-cleanup=disabled - StorageClass 레벨 어노테이션으로 해당 스토리지 타입의 모든 PV를 보호합니다
- 정리 대상으로 삼을 준비가 되면 어노테이션을 제거합니다
Auto Clean Up 활성화하기
K8s Storage 화면에서 클러스터 전체 정리를 설정합니다.
1단계: Storage로 이동
- Wave 콘솔에서 Storage로 이동합니다
- PV Auto Cleanup 탭을 선택합니다
- 전역 정리 토글과 탐지 로그가 표시됩니다
2단계: 정리 활성화
- Enable Auto Cleanup 토글을 켭니다
- 시스템은 즉시 (다음 작업 사이클, 약 10분 후) 다음을 시작합니다:
- 미사용 PV 탐지
- 모든 탐지 내역 기록
- 모든 보호 검사를 통과한 대상 PV에 대해 삭제 API 호출 제출
- PV 제거는 일반적으로 2번의 작업 사이클(총 약 20분)이 걸립니다:
- 사이클 1: 탐지 + 삭제 API 호출 (상태: InProgress)
- 사이클 2: 삭제 완료 여부 검증 (상태: Completed)
3단계: 탐지 로그 모니터링
정리를 활성화하기 전에도 탐지된 미사용 PV를 확인할 수 있습니다.
- Insights → Cost Efficiency로 이동합니다
- Unused PV Detection 탭을 선택합니다
- 탐지된 모든 미사용 PV를 탐지 사유 및 상태와 함께 확인합니다
이를 통해 실제 정리를 활성화하기 전에 탐지된 PV를 감사할 수 있습니다.
보호 설정
Wave는 PV와 StorageClass 레벨 모두에서 유연한 opt-out 메커니즘을 제공합니다.
PV 레벨 보호
Kubernetes 어노테이션을 사용해 개별 PV를 정리 대상에서 보호합니다.
Opt-Out 어노테이션 추가하기
정리에서 제외하고 싶은 PV에 다음 어노테이션을 추가합니다.
apiVersion: v1
kind: PersistentVolume
metadata:
name: important-backup-pv
annotations:
waveautoscale.io/pv-cleanup: disabled
spec:
capacity:
storage: 100Gi
# ... rest of PV spec어노테이션 적용:
# Method 1: Patch existing PV
kubectl annotate pv important-backup-pv waveautoscale.io/pv-cleanup=disabled
# Method 2: Apply YAML with annotation
kubectl apply -f pv-with-annotation.yaml
# Verify annotation
kubectl get pv important-backup-pv -o jsonpath='{.metadata.annotations}'Opt-Out을 사용해야 할 때
다음의 경우 opt-out 어노테이션을 사용하세요:
- 백업 볼륨: 주기적으로 백업에 사용되어 일시적으로 바인딩 해제될 수 있는 PV
- 수동으로 관리되는 스토리지: 관리자가 정기적으로 바인딩/해제하는 PV
- 재해 복구: 비상 페일오버 시나리오를 위해 예약된 PV
- 테스트/개발: 수동 제어가 선호되는 개발 클러스터의 PV
어노테이션이 우선 적용됩니다
전역 정리가 활성화되어 있더라도, opt-out 어노테이션이 있는 PV는 절대 자동으로 삭제되지 않습니다. 이러한 PV는 탐지 로그에 계속 표시되지만 정리에서 제외되었다는 메모가 함께 표시됩니다.
PV에 대해 자동 정리를 다시 활성화하려면 어노테이션을 제거하세요:
kubectl annotate pv important-backup-pv waveautoscale.io/pv-cleanup-StorageClass 레벨 보호
StorageClass 자체에 어노테이션을 추가하여 특정 StorageClass를 사용하는 모든 PV를 보호합니다.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: backup-storage
annotations:
waveautoscale.io/pv-cleanup: disabled
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp3
fsType: ext4기존 StorageClass에 어노테이션 적용:
# Annotate StorageClass to protect all its PVs
kubectl annotate storageclass backup-storage waveautoscale.io/pv-cleanup=disabled
# Verify annotation
kubectl get storageclass backup-storage -o jsonpath='{.metadata.annotations}'
# View all PVs using this StorageClass
kubectl get pv -o json | jq -r '.items[] | select(.spec.storageClassName=="backup-storage") | .metadata.name'StorageClass 레벨 보호를 사용해야 할 때
다음의 경우 StorageClass 어노테이션을 사용하세요:
- 백업 스토리지 티어: PV를 자주 순환시키는 백업 워크로드 전용 StorageClass
- 개발/테스트 스토리지: PV 라이프사이클을 수동으로 관리하는 개발팀이 사용하는 StorageClass
- 특수 스토리지: 수동 관리가 필요한 프리미엄 또는 아카이브 스토리지 클래스
- 마이그레이션 기간: 클러스터 마이그레이션이나 스토리지 재구성 중 모든 PV를 일시적으로 보호
StorageClass vs. PV 어노테이션
| 방식 | 사용 사례 | 범위 | 효율성 |
|---|---|---|---|
| StorageClass 어노테이션 | 특정 스토리지 타입의 모든 PV 보호 | 해당 클래스의 모든 PV | 높음 (어노테이션 1개) |
| PV 어노테이션 | 개별 PV 보호 | 단일 PV | 낮음 (PV별로 설정) |
모범 사례: 광범위한 보호에는 StorageClass 어노테이션을, 예외 처리에는 PV 어노테이션을 사용하세요.
StorageClass 전체에 대해 정리를 다시 활성화하려면:
kubectl annotate storageclass backup-storage waveautoscale.io/pv-cleanup-Static PV (수동 생성)
Static PV란? Static PV는 StorageClass(동적 프로비저닝)를 사용하지 않고 관리자가 수동으로 생성한 PersistentVolume입니다.
Auto Clean Up 동작:
- Static PV는 동적으로 프로비저닝된 PV와 동일하게 처리됩니다
- 모든 보호 메커니즘이 적용됩니다: finalizer, PV 레벨 어노테이션, volume attachment, PVC 바인딩 확인
- StorageClass 레벨 어노테이션 보호는 적용되지 않습니다 (어노테이션을 붙일 StorageClass가 없음)
- 보호 장치 없이 Available 또는 Released phase인 경우 정리 대상이 됩니다
Static PV 보호하기:
StorageClass 레벨 보호가 적용되지 않으므로 다음을 사용하세요:
-
PV 레벨 어노테이션 (권장):
kubectl annotate pv my-static-pv waveautoscale.io/pv-cleanup=disabled -
커스텀 Finalizer (백업 도구를 사용하는 경우):
apiVersion: v1 kind: PersistentVolume metadata: name: my-static-pv finalizers: - velero.io/my-backup-finalizer
Static PV 사용자를 위한 중요 안내
NFS 공유나 iSCSI LUN 등을 위해 정기적으로 static PV를 생성한다면, PVC 바인딩을 기다리는 동안 실수로 정리되지 않도록 생성 직후 opt-out 어노테이션을 추가하세요.
동적 프로비저닝의 경우에는 관리가 더 쉬운 StorageClass 레벨 어노테이션을 사용하세요.
탐지 사유
Auto Clean Up은 각 PV를 미사용으로 표시하는 구체적인 사유를 기록합니다.
| 탐지 사유 | 의미 | 일반적인 원인 |
|---|---|---|
| PV phase is Released | 이전 PVC가 삭제되었고 볼륨이 회수되지 않음 | Retain reclaim policy를 사용하는 StatefulSet이 삭제됨 |
| PV phase is Available | PV가 생성되었지만 한 번도 바인딩되지 않음 | 클레임을 기다리는 수동 생성 PV |
| Associated PVC {name} no longer exists | PVC 참조는 있지만 PVC가 존재하지 않음 | PV는 삭제하지 않고 PVC만 삭제됨 |
| No PVC is bound to this PV | PV에 클레임 참조가 없음 | 프로비저닝 실패로 생긴 고아 PV |
하나의 PV에 여러 탐지 사유가 동시에 적용될 수 있습니다. 모든 사유는 감사 목적으로 기록됩니다.
보호 사유 (PV가 미사용이 아닌 것으로 표시됨):
| 보호 사유 | 의미 | 필요한 조치 |
|---|---|---|
| PV has custom finalizers | 외부 시스템(백업 도구, 오퍼레이터)이 PV를 관리 중 | 안전할 때 finalizer를 제거하거나 그대로 보호 상태 유지 |
| PV cleanup explicitly disabled via annotation | 관리자가 이 특정 PV를 opt-out 처리함 | 정리를 다시 활성화하려면 어노테이션 제거 |
| Storage class has cleanup disabled | 전체 StorageClass가 opt-out 처리됨 | 다시 활성화하려면 StorageClass 어노테이션 제거 |
| PV has active volume attachments | CSI 볼륨이 현재 노드에 연결되어 있음 | Pod 종료 및 연결 해제를 기다림 |
| PVC still exists | 클러스터에 바인딩된 PVC가 존재함 | PV가 실제로 사용 중이며 정상적으로 보호됨 |
보호 상태 확인하기
PV가 왜 정리되고 있는지, 또는 왜 정리되지 않는지 확인합니다.
모든 보호 메커니즘 확인
PV_NAME="your-pv-name"
echo "=== PV Phase ==="
kubectl get pv $PV_NAME -o jsonpath='{.status.phase}'
echo -e "\n\n=== PV Annotations ==="
kubectl get pv $PV_NAME -o jsonpath='{.metadata.annotations.waveautoscale\.io/pv-cleanup}'
echo -e "\n\n=== StorageClass ==="
SC_NAME=$(kubectl get pv $PV_NAME -o jsonpath='{.spec.storageClassName}')
echo "StorageClass: $SC_NAME"
kubectl get storageclass $SC_NAME -o jsonpath='{.metadata.annotations.waveautoscale\.io/pv-cleanup}'
echo -e "\n\n=== Finalizers ==="
kubectl get pv $PV_NAME -o jsonpath='{.metadata.finalizers}'
echo -e "\n\n=== Bound PVC ==="
PVC_NAME=$(kubectl get pv $PV_NAME -o jsonpath='{.spec.claimRef.name}')
PVC_NS=$(kubectl get pv $PV_NAME -o jsonpath='{.spec.claimRef.namespace}')
echo "Claim: $PVC_NS/$PVC_NAME"
kubectl get pvc -n $PVC_NS $PVC_NAME 2>&1
echo -e "\n\n=== Volume Attachments ==="
kubectl get volumeattachment -o json | jq -r ".items[] | select(.spec.source.persistentVolumeName==\"$PV_NAME\") | .metadata.name"이 스크립트는 여섯 가지 보호 메커니즘을 모두 확인하여 PV가 정리 대상인지 아닌지 파악합니다.
정리 상태
각 정리 시도는 다음 상태 값을 거칩니다.
| 상태 | 의미 | 설명 |
|---|---|---|
| NULL / Detection Only | 추적되었지만 정리되지 않음 | 정리가 전역으로 비활성화되었거나, 보호 메커니즘이 적용되었거나, 삭제가 실패함 |
| InProgress | 삭제가 제출됨 | Kubernetes API 호출은 성공했고 volume controller의 처리를 기다리는 중 |
| Completed | 성공적으로 삭제됨 | PV가 클러스터에 더 이상 존재하지 않음 |
삭제 실패는 어떻게 추적되나요
삭제 실패에는 별도의 "Failed" 상태가 없습니다. 대신 다음과 같이 기록됩니다:
Status: NULL(정리 상태가 설정되지 않음)Error flag: trueError reason: <구체적인 오류 메시지>
이를 통해 다음을 구분할 수 있습니다:
- 아직 시도되지 않은 PV (정리가 비활성화되었거나 보호됨)
- 정리를 시도했지만 실패한 PV (오류 사유와 함께 오류 플래그가 설정됨)
로그의 Error Reason 열에서 구체적인 삭제 실패 사유를 확인하세요.
정리 로그 확인하기
탐지된 미사용 PV와 정리 활동을 모니터링합니다. 탐지 로그는 두 곳에서 확인할 수 있습니다.
옵션 1: Storage → PV Auto Cleanup (권장)
- Storage로 이동합니다
- PV Auto Cleanup 탭을 선택합니다
- 이 화면에서 확인할 수 있는 내용:
- 상단의 Enable Auto Cleanup 토글
- 하단의 상세 탐지 로그 테이블
- 모든 PV 세부 정보, 탐지 사유, 정리 상태
설정과 로그 확인을 한 곳에서 모두 하고 싶다면 이 화면을 사용하세요.
옵션 2: Insights → Cost Efficiency
- Insights → Cost Efficiency로 이동합니다
- Unused PV Detection 탭을 선택합니다
- 이 화면에서 볼 수 있는 내용:
- 탐지 로그 테이블만 표시 (읽기 전용)
- 비용 분석 및 효율성 지표에 초점
- Storage 화면과 동일한 데이터
여러 영역의 효율성 인사이트를 검토하며 비용을 분석하고 싶다면 이 화면을 사용하세요.
로그 테이블 열
| 열 | 정보 | 사용 사례 |
|---|---|---|
| Timestamp | 로그 항목이 생성된 시각 | 탐지 시간순 정렬 |
| Namespace | Kubernetes namespace | 관련 워크로드 파악 |
| PV Name | PersistentVolume 이름 | 특정 볼륨 식별 |
| PVC Name | 바인딩된 PersistentVolumeClaim 이름 | PV-PVC 관계 추적 |
| Storage Class | storage class 이름 | 스토리지 티어별 비용 분석 |
| Capacity | GiB/TiB 단위 PV 크기 | 잠재적 비용 절감액 계산 |
| Phase | 현재 K8s phase | PV 라이프사이클 상태 파악 |
| Reclaim Policy | Retain, Delete, 또는 Recycle | 정리 동작 방식 파악 |
| Access Modes | ReadWriteOnce, ReadWriteMany 등 | 스토리지 접근 특성 |
| Detection Reason | 미사용으로 표시된 사유 (JSON 목록) | 감사 추적 및 트러블슈팅 |
| First Detected | 최초 탐지 타임스탬프 | PV가 미사용이 된 시점 추적 |
| Last Detected | 가장 최근 스캔 타임스탬프 | 지속적인 모니터링 검증 |
| Resolved At | PV가 더 이상 미사용이 아니게 된 시점 | 해결 이벤트 추적 |
| Clean Up Status | InProgress, Completed, 또는 Pending | 정리 진행 상황 추적 |
| Enabled | 정리 활성화 여부 | 설정 확인 |
| Deleted | PV가 성공적으로 삭제되었는지 여부 | 삭제 확인 |
| Deletion Error | 삭제 실패 시 오류 플래그 | 실패 사유 식별 |
| Error Reason | 구체적인 오류 메시지 | 삭제 문제 트러블슈팅 |
Detection Reason 형식: 여러 사유를 불릿 포인트로 보여주는 JSON 파싱 목록으로 표시됩니다 (예: "PV is in Released/Available phase", "No active volume attachments").
이 테이블은 정렬, 필터링(상태, 오류 여부별), 페이지네이션을 지원하여 대규모 클러스터에서도 쉽게 탐색할 수 있습니다.
자주 발생하는 시나리오
Auto Clean Up이 실제 상황을 어떻게 처리하는지 살펴봅니다.
💾 PVC는 삭제되고 PV는 유지되는 경우
시나리오: StatefulSet이 삭제되고 PVC도 제거되었지만, Retain reclaim policy 때문에 PV는 남아있는 경우
동작:
Cycle N: PVC deleted → PV phase changes to Released
Cycle N+1 (10 min later): Auto Clean Up detects unused PV, logs detection, and calls deletion API if cleanup enabled
Cycle N+2 (20 min later): Verifies PV deletion completed제거까지 걸리는 총 시간: 약 20분 (기본 10분 간격으로 2번의 작업 사이클)
발생 이유: Retain reclaim policy는 Kubernetes의 자동 삭제를 막습니다 비용 영향: 정리되기 전까지 PV는 스토리지 비용이 발생합니다 수동 조치: PV를 즉시 수동으로 삭제하거나, 어노테이션을 추가해 일시적으로 보호할 수 있습니다
🔄 StatefulSet 스케일 다운
시나리오: StatefulSet을 5개에서 2개 레플리카로 스케일 다운
동작:
PVCs for replicas 2-4 remain (not deleted by scale-down)
PVs remain bound to existing PVCs
Auto Clean Up does NOT detect as unused발생 이유: StatefulSet 스케일 다운은 PVC를 삭제하지 않습니다 비용 영향: 미사용 PVC와 PV가 계속 비용을 발생시킵니다 수동 조치: 불필요한 PVC를 수동으로 삭제하여 정리 탐지를 트리거하세요
⚠️ 수동 PV 생성
시나리오: 관리자가 향후 PVC와 바인딩할 목적으로 PV를 수동 생성
동작:
Cycle N: PV created in Available phase
Cycle N+1 (10 min later): Auto Clean Up detects unused PV and calls deletion API if cleanup enabled
Cycle N+2 (20 min later): Verifies PV deletion completed제거까지 걸리는 총 시간: 약 20분 (기본 10분 간격으로 2번의 작업 사이클)
예방법: 초기 사이클 동안 보호하려면 생성 직후 opt-out 어노테이션을 추가하세요.
kubectl annotate pv manual-pv waveautoscale.io/pv-cleanup=disabled대안: 특정 유형의 수동 PV를 정기적으로 생성한다면 StorageClass 어노테이션을 사용하세요:
kubectl annotate storageclass manual-storage waveautoscale.io/pv-cleanup=disabled✅ 탐지 후 다시 바인딩된 PV
시나리오: PV가 미사용으로 탐지된 후 다음 정리 사이클 전에 다시 바인딩됨
동작:
Cycle 1: PVC deleted, PV Released
Cycle 1: Auto Clean Up detects unused, records detection
Cycle 2: New PVC claims the PV (rebound)
Cycle 2: Auto Clean Up detects PV is now bound
Cycle 2: Marks PV as resolved_at=now(), closes detection log
Result: PV NOT deleted (resolution tracking prevented cleanup)발생 이유: 수동 재바인딩, PVC 재생성, 또는 운영상의 복구 결과: 해결 상태 추적 덕분에 불필요한 삭제를 성공적으로 방지함
트러블슈팅
자주 발생하는 문제와 해결 방법
PV가 정리되지 않음
PV가 미사용으로 탐지되었지만 전역 정리가 활성화되어 있는데도 삭제되지 않는 경우입니다.
체크리스트:
- Storage → PV Auto Cleanup에서 전역 정리가 활성화되어 있는지 확인
- PV 레벨 opt-out 어노테이션 확인:
kubectl get pv <pv-name> -o jsonpath='{.metadata.annotations.waveautoscale\.io/pv-cleanup}' - StorageClass 레벨 보호 확인:
# Get the StorageClass name for the PV kubectl get pv <pv-name> -o jsonpath='{.spec.storageClassName}' # Check if StorageClass has opt-out annotation kubectl get storageclass <sc-name> -o jsonpath='{.metadata.annotations.waveautoscale\.io/pv-cleanup}' - 커스텀 finalizer 확인:
Kubernetes 표준이 아닌 finalizer를 확인하세요 (예:
kubectl get pv <pv-name> -o jsonpath='{.metadata.finalizers}'velero.io/*,backup.company.com/*) - PVC가 존재하지 않는지 확인:
# Check if the bound PVC still exists kubectl get pvc -A | grep <pv-claim-ref-name> - volume attachment 확인:
kubectl get volumeattachment -o json | jq -r '.items[] | select(.spec.source.persistentVolumeName=="<pv-name>")' - Unused PV Detection 로그에서 오류 메시지가 있는지 정리 상태를 검토하세요
- RBAC 권한 확인:
kubectl auth can-i delete pv --as=system:serviceaccount:wave-autoscale:wave-autoscale-sa
PV가 예상치 못하게 정리됨
PV가 삭제되지 말아야 했는데 삭제되어 우려되는 경우입니다.
확인 방법:
- 탐지 로그를 확인하여 PV가 왜 미사용으로 표시되었는지 확인합니다
- 삭제 시점의 보호 상태를 확인합니다:
- PV에 opt-out 어노테이션이 있었나요?
- StorageClass에 opt-out 어노테이션이 있었나요?
- 커스텀 finalizer가 있었나요?
- PVC가 실제로 삭제되었나요?
- volume attachment가 있었나요?
- 정리 로그를 검토하여 삭제 타임스탬프와 상태를 확인합니다
- Wave 감사 로그를 확인하여 설정 변경 이력을 확인합니다
- 중요한 데이터라면 백업에서 복원하고 근본 원인을 조사합니다
- 재발 방지를 위해 유사한 PV에 적절한 보호 조치를 추가합니다
잘못된 PV가 삭제됨
제외되었어야 할 PV가 삭제된 경우입니다.
단계:
- 삭제 전에 PV에 opt-out 어노테이션이 있었는지 확인합니다
- 로그에서 탐지 사유를 검토합니다 (타당한 사유였나요?)
- 정리가 의도적으로 전역 활성화되어 있었는지 확인합니다
- 중요한 데이터라면 백업에서 PV를 복원합니다
- 재발 방지를 위해 유사한 PV에 opt-out 어노테이션을 추가합니다
정리가 오류와 함께 실패함
PV가 정리 대상으로 표시되었지만 상태가 Failed로 나타나는 경우입니다.
일반적인 오류:
- RBAC 권한: ServiceAccount에 PV에 대한
delete권한이 없음- 해결책: ClusterRole에 PV delete 권한 추가
- 스토리지 프로바이더 잠금: 하위 스토리지에 활성 마운트나 스냅샷이 있음
- 해결책: 마운트/스냅샷을 제거하면 정리가 재시도됨
- API 타임아웃: Kubernetes API가 일시적으로 응답하지 않음
- 해결책: 다음 사이클에서 정리가 재시도됨 (일반적으로 몇 분마다)
- Finalizer가 막고 있음: PV에 삭제를 막는 finalizer가 있음
- 해결책: 안전하다면 finalizer를 검토하고 제거합니다:
kubectl patch pv <pv-name> -p '{"metadata":{"finalizers":null}}'
- 해결책: 안전하다면 finalizer를 검토하고 제거합니다:
로그의 error_reason 필드에서 구체적인 오류 메시지를 확인하세요.
비용 절감 분석
Auto Clean Up은 실질적인 비용 절감 효과를 제공합니다.
예시 클러스터:
- 미사용 PV 50개 탐지 (평균 100GiB씩)
- 총합: 5000GiB (5TiB)의 낭비된 스토리지
- 스토리지 비용: $0.10/GiB/월
월간 절감액:
5000 GiB × $0.10/GiB/month = $500/month saved
Annual savings = $6,000/year콘솔에서 탐지된 미사용 PV를 확인하여 사용 중인 스토리지 티어 요금 기준으로 잠재적 절감액을 계산해보세요.
관련 문서
- PV Lifecycle 개요: PV Lifecycle Management 전체 시스템 이해하기
- 시작하기: Auto Clean Up 단계별 설정 가이드
- Auto Expansion: 자동 PVC 확장에 대해 알아보기