วิธีการลบ namespace ที่ติดสถานะ terminating ใน k8s
29 Aug 2025 11:15
Written by: Yosapol Jitrak
เคยไหมครับ Kubernetes ลบ Namespace ไม่ออก
ลอง Get namespace ดูว่าสถานะจะติด Terminating
kubectl get ns
NAME STATUS AGE
atlas-test-primary-failover Active 22d
default Active 2y214d
grafana-k8s-monitoring Terminating 66m
ingress-nginx Active 212d
kafbat-ui Active 14d
keda Active 198d
kube-node-lease Active 2y214d
kube-public Active 2y214d
kube-state-metrics Active 2y214d
kube-system Active 2y214d
production Active 2y214d
redis Active 363d
ทั้งที่ใช้ Option force รวมถึงใส่ Grace period เป็น 0 แล้วก็ยังลบไม่ออก โดยคำสั่งจะมีหน้าตาประมาณนี้
kubectl delete namespace <namespace-name> --grace-period=0 --force
แน่นอนปัญหานี้ไม่ได้มีเราเจอกันคนเดียวแน่นอน และผมก็เจอปัญหานี้มาตั้งแต่ปี 2019-2020 แล้ว ซึ่งสมัยนั้นผมเจอปัญหากับ Cert-manager บ่อยสุด แหล่งข้อมูลสมัยนั้นก็คือ deleting namespace stuck at “Terminating” state บอกว่าหลัก ๆ จะมาจากปัญหา Finalizers มีของอยู่
ตัวอย่างของ namespace ที่ Finalizers มีของอยู่คือ
kubectl get ns grafana-k8s-monitoring -o yaml
apiVersion: v1
kind: Namespace
metadata:
creationTimestamp: '2025-08-15T18:44:06Z'
deletionTimestamp: '2025-08-15T19:49:51Z'
labels:
kubernetes.io/metadata.name: grafana-k8s-monitoring
name: grafana-k8s-monitoring
name: grafana-k8s-monitoring
resourceVersion: '587594176'
uid: 38809b07-14ea-46ee-a4cb-9b0eb7a97633
spec:
finalizers:
- kubernetes
status:
conditions: ...
phase: Terminating
วิธีแรกคือ Edit โดยตรง แล้วลบ kubernetes ออกจาก List ของ Finalizers ออกเอง ให้กลายเป็น Empty list หรือเปลี่ยนค่าเป็น null ซึ่งบางครั้งก็ยังลบไม่ออกอยู่ดี
วิธีถัดมาก็คือสารพัดยิง Curl เช่น
ซึ่งวิธีนี้ต้องไปหา IP ของ Master Node ของคุณที่สามารถยิงได้ หรือต้องเปิด kube-proxy ไว้ก่อน ซึ่งวิธีนี้ผมไม่เคยใช้ครับ
วิธีถัดมาคือ Patch เช่น
วิธีนี้คล้ายกับวิธีแรก แต่ไม่ต้องเข้าไป Edit โดยตรง ยิงคำสั่งเดียวจบ
อีกวิธีคือ Patch raw เช่น
วิธีนี้ลบออกแน่นอน แต่…
ซึ่งคำตอบนี้ให้แก้ปัญหาที่ต้นเหตุ ซึ่งมาจาก Aggregated API group ที่ไม่พร้อมใช้งานแล้ว จึงทำให้ไม่สามารถลบ Resource นั้นออกได้ Namespace จึงรอให้ลบออกได้ก่อน จึงจะลบ Namespace ได้
หา API service ที่ไม่พร้อมใช้งานแล้ว
kubectl get apiservice --namespaced | grep False
หลังจากนั้นก็ลบ API service นั้นออก
kubectl delete apiservice <api-service-name>
เพียงเท่านี้ Namespace ก็จะลบออกได้ในทันทีครับ
ถ้าอยากลงลึกมากกว่านี้ลองดูวิดีโอนี้เลยครับ
ตอนนี้ทาง Google ก็มี Document สำหรับวิธีแก้ปัญหานี้แล้วเหมือนกัน แต่สมัยนั้นผมยังหาไม่เจอ Troubleshoot namespace stuck in the Terminating state
แต่ถ้ายังไม่ลบไม่ออกจริง ๆ แล้วต้องการลบ Namespace ก็ต้องยอมลบ Finalizers ผมจะใช้คำสั่งนี้
export NAMESPACE=<namespace>
kubectl get namespace $NAMESPACE-o json \
| jq 'del(.spec.finalizers)' \
| kubectl replace --raw "/api/v1/namespaces/$NAMESPACE/finalize" -f -
แต่ถ้าเครื่องไม่มี jq ก็ใช้อันนี้แทนครับ
export NAMESPACE=<namespace>
kubectl get namespace $NAMESPACE -o json \
| tr -d "\n" | sed "s/\"finalizers\": \[[^]]\+\]/\"finalizers\": []/" \
| kubectl replace --raw /api/v1/namespaces/$NAMESPACE/finalize -f -
ปล. Finalizers ไม่จำเป็นจะต้องเป็น Namespace เท่านั้นนะครับ Resource อื่นก็มีโอกาสติดได้เหมือนกัน แต่ส่วนใหญ่จะเจอปัญหากับ Namespace
จริง ๆ ยังมีคนใช้วิธีผิด ๆ เยอะกันอยู่ครับ หลายบทความ และหลายโพสก็ยังบอกว่าวิธีการคือให้ลองลบ Finalizers ออกเลย โดนไม่ได้แก้ปัญหาที่ต้นเหตุเลย อยากมาเขียนวิธีที่ถูกต้อง
อย่างของผมตัวอย่างที่ยกไว้ตอนต้นคือตอน Helm uninstall แล้วลบของให้ไม่หมด ซึ่งผมต้องการลบให้เกลี้ยง โดยการลบ Namespace ก่อน จากนั้นค่อยติดตั้งใหม่อีกครั้ง
จบแล้วครับ เจอกันใหม่บทความหน้าครับ
Credits: