브렌쏭의 Veritas_Garage

[EKS] status.Phase: Invalid value: "Active": may only be 'Terminating' if `deletionTimestamp` is not empty 본문

[Project_하다]/[TroubleShoot_문제해결]

[EKS] status.Phase: Invalid value: "Active": may only be 'Terminating' if `deletionTimestamp` is not empty

브렌쏭 2025. 5. 7. 11:10

[EKS] 네임스페이스가 Terminating 상태에서 안 사라질 때 — 실전 트러블슈팅 & 예방 가이드

TL;DR
네임스페이스를 kubectl delete ns 로 지웠는데 계속 Terminating 상태에 머문다면, 99%는 파이널라이저(Finalizer)와 남은 리소스 때문이다.
이 글은 AWS EKS 환경에서 <llm-namespace> 네임스페이스를 삭제하다 겪은 실제 사례를 바탕으로 원인 분석 → 해결 → 재발 방지 과정을 정리한다.


1. 상황 개요

항목
클러스터 AWS EKS 1.29
삭제 대상 <llm-namespace> 네임스페이스 (vLLM + KServe PoC 공간)
증상 kubectl delete ns <llm-namespace> 이후 프롬프트가 돌아오지 않고, kubectl get ns 결과는 Terminating
$ kubectl delete ns <llm-namespace>
namespace "<llm-namespace>" deleted   # ← 메시지는 보이지만…
# 커서가 멈춘 채 진행되지 않음

2. 1차 진단 — Phase & Finalizer 확인

# 현재 Phase
kubectl get ns <llm-namespace> -o jsonpath='{.status.phase}{"\n"}'
# → Terminating

# 파이널라이저 목록
kubectl get ns <llm-namespace> -o json | jq '.spec.finalizers'
# → ["kubernetes"]
  • spec.finalizers=["kubernetes"] 는 컨트롤러가 "남은 리소스를 모두 없애면 마지막으로 내가 사라진다" 는 의미다.

  • 아직 정리되지 않은 리소스 또는 파이널라이저가 있다는 신호.


3. 2차 진단 — 남은 리소스 & 상태 조건 확인

3‑1. 네임스페이스 상태 조건

kubectl get ns <llm-namespace> -o json \
  | jq -r '.status.conditions[] | "\(.type): \(.reason) – \(.message)"'

예시 출력:

NamespaceDeletionContentFailure: ContentDeletionFailed – Failed to delete all resource types, 1 remaining: Internal error occurred: failed calling webhook "validation.webhook.serving.knative.dev": failed to call webhook: Post "https://webhook.<llm-namespace>.svc:443/resource-validation?timeout=10s": service "webhook" not found

의미: Knative Serving 웹훅 서비스가 이미 사라졌거나 접근할 수 없어 네임스페이스 삭제가 멈춤.

3‑2. 네임스페이스 안 숨은 리소스 찾기

for r in $(kubectl api-resources --verbs=list --namespaced -o name); do
  kubectl -n <llm-namespace> get "$r" --ignore-not-found --no-headers
done

대부분 No resources found 가 뜨지만, inferenceservice.serving.kserve.io 인스턴스 하나가 남아 있고 그 내부에 Knative 파이널라이저가 있었음.


4. 해결 절차

4‑1. 남은 리소스 강제 삭제

# KServe InferenceService 강제 삭제
kubectl delete inferenceservice.serving.kserve.io --all \
  -n <llm-namespace> --grace-period=0 --force

웹훅 파이널라이저 때문에 위 명령조차 실패한다면:

kubectl get inferenceservice.serving.kserve.io inference-svc \
  -n <llm-namespace> -o json \
| jq 'del(.metadata.finalizers)' \
| kubectl replace --force -f -

4‑2. 마지막 단계 — 네임스페이스 Finalize

모든 리소스를 제거했는데도 Terminating이면 파이널라이저를 비워 컨트롤러에게 "정리 완료"를 알려준다.

kubectl get ns <llm-namespace> -o json > /tmp/ns.json
jq 'del(.spec.finalizers)' /tmp/ns.json > /tmp/ns-finalize.json

kubectl replace --raw "/api/v1/namespaces/<llm-namespace>/finalize" \
  -f /tmp/ns-finalize.json

주의
강제 Finalize 는 아직 남은 AWS LB/EBS 같은 클라우드 리소스를 정리하지 않는다.
네임스페이스가 사라진 뒤 AWS 콘솔에서 orphan 자원이 없는지 반드시 확인!


5. 삭제 완료 확인

kubectl get ns <llm-namespace>   # 더 이상 출력되지 않으면 성공

6. Root Cause 정리

범주 상세
CRD 인스턴스 KServe InferenceService 남아 있음
웹훅/컨트롤러 소실 Knative Serving 컨트롤러를 Helm uninstall 로 먼저 제거
Finalizer InferenceService 및 네임스페이스에 Knative 파이널라이저 존재
결과 컨트롤러가 없으므로 Finalizer 해제 실패 → 네임스페이스 삭제 대기 무한 반복

7. 재발 방지를 위한 체크리스트

체크포인트 설명
CRD → 인스턴스 순서로 삭제 Helm pre-delete 훅에서 kubectl delete <crd> --all 수행
파이널라이저 자동 해제 스크립트 컨트롤러 비가동 시 jq 로 finalizer 제거 후 replace --force
GitOps 위생 kubectl neat 또는 yqstatus, metadata.* 필드 제거 후 커밋
컨트롤러 HA 유지 핵심 컨트롤러는 Replica ≥ 2 & readiness probe 정상화
네임스페이스 Terminating 모니터링 10분 이상 Terminating → Alertmanager 알림 & 자동 스크립트
AWS LB Draining 시간 단축 service.beta.kubernetes.io/aws-load-balancer-connection-draining-enabled: "false"

8. 마무리

네임스페이스 Terminating 지옥은 강제 Finalize 한 방으로 끝낼 수도 있지만, 뒤처리(클라우드 자원 orphan)를 남긴다.
남은 리소스 → 파이널라이저 해제 → 네임스페이스 Finalize 순서를 지키면 운영 클러스터에서도 안전하게 삭제할 수 있다.

Comments