۲۹ مهر ۲۵۸۴
توضیح Finalizers در Kubernetes: چرا Namespaceها در وضعیت Terminating گیر میکنند
مقدمه
تلاش برای حذف یک Namespace در Kubernetes و مشاهده اینکه بهطور مداوم در وضعیت «Terminating» گیر کرده است، یکی از آزاردهندهترین مشکلات تکراری در دنیای DevOps است. عامل اصلی معمولاً finalizers هستند — فیلدهای خاص metadata که تا تکمیل عملیات پاکسازی، از حذف منبع جلوگیری میکنند.
Finalizers در Kubernetes چیستند؟
یک finalizer بهعنوان یک «لیست وظایف» برای controllerهای Kubernetes عمل میکند. قبل از اینکه Kubernetes API Server یک شیء را واقعاً از etcd (پایگاه داده کلاستر) حذف کند، لیست finalizers متصل به آن منبع را بررسی میکند.
هر ورودی finalizer نمایانگر یک controller است که مسئول عملیات پاکسازی قبل از اجازه حذف واقعی توسط Kubernetes API میباشد.
چرا Finalizers وجود دارند
Finalizers پاکسازی امن و قابل پیشبینی منابع را با جلوگیری از باقی ماندن منابع یتیم — مانند persistent volumes، رابطهای شبکه، یا IAM roles — پس از حذف، ممکن میسازند.
موارد استفاده رایج شامل:
- PersistentVolumeClaims (PVCs) – اطمینان از جدا شدن PersistentVolumes مرتبط قبل از حذف
- Namespaces – تضمین حذف تمام منابع زیرمجموعه قبل از حذف namespace
- Custom Resource Definitions (CRDs) – فعالسازی پاکسازی operator قبل از حذف نمونه
- Service Controllers – یکپارچهسازیهای ابری که حذف load balancer را مدیریت میکنند
نحوه عملکرد Finalizers
چرخه حیات این مراحل را دنبال میکند:
- دستور
kubectl deleteروی یک شیء اجرا میشود - Kubernetes یک
deletionTimestampبه شیء اضافه میکند - Controllerهای مدیریتکننده finalizers، timestamp را شناسایی کرده و پاکسازی را آغاز میکنند
- پس از تکمیل پاکسازی، controller مربوطه finalizer خود را حذف میکند
- پس از خالی شدن لیست finalizers، Kubernetes شیء را حذف میکند
زمانی که مشکلات رخ میدهند
گاهی اوقات controllerها از کار میافتند، حذف میشوند یا دچار اختلال میشوند. وقتی این اتفاق رخ میدهد، Kubernetes بهطور نامحدود منتظر پاکسازیای میماند که هرگز انجام نمیشود و منابع در وضعیت «Terminating» گیر میکنند.
علائم معمول:
- منبع در وضعیت «Terminating» گیر کرده است
- دستور
kubectl deleteهرگز تکمیل نمیشود - Finalizers همچنان در YAML شیء موجود هستند
- لاگهای controller خطاها یا ارجاعات گمشده را نمایش میدهند
عیبیابی یک Namespace یا منبع گیرکرده
مرحله ۱: بررسی منبع
kubectl get ns my-namespace -o yaml
این دستور فیلد finalizers که مانع حذف شده را نمایان میکند.
مرحله ۲: شناسایی Finalizer گیرکرده
لاگهای controller مربوطه را بررسی کنید تا بفهمید کدام finalizer مانع حذف شده و چرا پاکسازی پیشرفت نمیکند.
مرحله ۳: حذف Finalizer
پس از اطمینان از اینکه حذف بیخطر است، منبع را patch کنید:
kubectl patch ns my-namespace -p '{"metadata":{"finalizers":[]}}' --type=merge
همچنین میتوانید مستقیماً از طریق kubectl edit ns my-namespace ویرایش کرده و خطوط finalizer را حذف کنید.
هشدار مهم: finalizers را فقط پس از تأیید عدم نیاز به پاکسازی حذف کنید — در غیر این صورت ممکن است منابع ابری یتیم باقی بمانند.
مثال واقعی
فرض کنید یک namespace توسط AWS Load Balancer Controller مدیریت میشود. هنگام حذف مشاهده میشود:
metadata:
finalizers:
- service.kubernetes.io/load-balancer-cleanup
اگر controller در دسترس نباشد یا مجوزهای لازم را نداشته باشد، نمیتواند finalizer را حذف کند و namespace بهطور دائم در حال terminating باقی میماند.
راهحل: controller را ریاستارت کنید یا مجوزها را اصلاح کنید؛ اگر موفق نشدید و مطمئن هستید هیچ منبعی باقی نمانده، finalizer را بهصورت دستی حذف کنید.
بهترین شیوهها
- از حذف دستی finalizer خودداری کنید مگر اینکه ضروری باشد — ابتدا مشکلات controller را برطرف کنید
- لاگهای controller را برای یافتن دلایل اصلی بررسی کنید
- توجه داشته باشید که برخی finalizers پاکسازی حیاتی انجام میدهند که از نشت منابع جلوگیری میکند
- در استفاده از اسکریپتهای پاکسازی خودکار احتیاط کنید و حفاظهای ایمنی پیادهسازی کنید
- برای توسعهدهندگان CRD: finalizers را با مسئولیت ثبت کنید، پاکسازی را در منطق Reconcile انجام دهید و پس از موفقیت حذف کنید
نتیجهگیری
Finalizers مکانیزمهای ظریف اما قدرتمند Kubernetes هستند که پاکسازی امن منابع را تضمین میکنند. آنها «قراردادهای پاکسازی» بین controllerها و API server برقرار میکنند. وقتی controllerها دچار اختلال میشوند، منابع گیر میکنند — اما درک مکانیک finalizers، عیبیابی مطمئن و حذف ایمن را ممکن میسازد.