ESC را فشار دهید تا بسته شود

رفع خطای ImagePullBackOff در Kubernetes؛ عیب‌یابی Image Tag، Registry و imagePullSecrets

فهرست

اگر Pod در Kubernetes با ImagePullBackOff بالا نمی‌آید، ابتدا خطای واقعی را در بخش Events با kubectl describe pod بخوانید. این وضعیت یعنی kubelet نتوانسته Image کانتینر را دریافت کند و بین تلاش‌های بعدی مکث می‌کند؛ علت می‌تواند نام یا Tag اشتباه، مجوز Registry خصوصی، محدودیت نرخ دریافت، DNS، TLS یا ارتباط شبکه Node باشد. صرفاً Restart کردن Pod یا زیاد کردن Timeout راه‌حل عمومی نیست.

ImagePullBackOff و ErrImagePull چه تفاوتی دارند؟

ErrImagePull معمولاً هنگام شکست تلاش دریافت Image دیده می‌شود و ImagePullBackOff نشان‌دهنده انتظار پیش از تلاش مجدد است. هر دو در وضعیت انتظار کانتینر دیده می‌شوند و با CrashLoopBackOff فرق دارند: در CrashLoopBackOff کانتینر شروع شده و سپس خارج می‌شود، ولی در ImagePullBackOff معمولاً هنوز Image لازم دریافت نشده است. اگر کانتینر واقعاً اجرا و Restart می‌شود، راهنمای عیب‌یابی CrashLoopBackOff، Exit Code و Probe مسیر مناسب‌تری است.

پیش‌نیاز و سناریوی نمونه

در مثال‌ها Namespace برابر production، Deployment برابر web، نام Container برابر app و Registry برابر registry.example.com است. قبل از کپی کردن، نام‌ها را با محیط خود جایگزین کنید. به دسترسی kubectl با مجوز مشاهده Pod/Events نیاز دارید؛ تغییر Deployment و Secret به RBAC جداگانه نیاز دارد. قبل از تغییر، Manifest را ذخیره کنید:

kubectl config current-context
kubectl get namespaces
kubectl get deployment web -n production -o yaml > web.before.yaml
kubectl get pods -n production -o wide

فایل web.before.yaml ممکن است تنظیمات حساس داشته باشد؛ آن را در مسیر امن نگه دارید و عمومی منتشر نکنید. اگر هنوز خوشه را راه‌اندازی نکرده‌اید، آموزش نصب و پیکربندی Kubernetes روی لینوکس پیش‌نیاز مفیدی است.

مرحله ۱: علت واقعی را از Events پیدا کنید

ابتدا نام Pod مشکل‌دار را از خروجی دستور اول بردارید و به جای POD_NAME قرار دهید:

kubectl get pods -n production -o wide
kubectl describe pod POD_NAME -n production
kubectl get events -n production --field-selector involvedObject.name=POD_NAME --sort-by=.lastTimestamp

در انتهای describe به پیام‌های Failed to pull image، Back-off pulling image و FailedToRetrieveImagePullSecret دقت کنید. اگر Eventهای قدیمی پاک شده‌اند، رویدادهای تازه را بعد از یک تلاش مجدد مشاهده کنید؛ بدون دیدن متن دقیق خطا حدس نزنید.

پیام خطا چه چیزی را نشان می‌دهد؟

  • manifest unknown یا not found: نام Repository، Tag یا Digest وجود ندارد یا مسیر اشتباه است.
  • unauthorized، denied یا HTTP 401/403: احراز هویت، سطح دسترسی Token یا مجوز Repository را بررسی کنید.
  • toomanyrequests یا HTTP 429: محدودیت Rate Limit رجیستری؛ سیاست Pull و اعتبارنامه را بررسی کنید.
  • no such host، i/o timeout یا connection refused: DNS، مسیر خروجی، Firewall، Proxy یا خود Registry را بررسی کنید.
  • x509: certificate signed by unknown authority: زنجیره گواهی یا CA مورد اعتماد Node/Runtime مشکل دارد؛ اعتبارسنجی TLS را خاموش نکنید.

مرحله ۲: نام Image، Tag و Pull Policy را بررسی کنید

Image واقعی تعریف‌شده در Pod و Deployment را بخوانید:

kubectl get pod POD_NAME -n production -o jsonpath='{range .spec.containers[*]}{.name}{" | "}{.image}{"; "}{end}'
kubectl get deployment web -n production -o jsonpath='{range .spec.template.spec.containers[*]}{.name}{" | "}{.image}{"; "}{end}'
kubectl get pod POD_NAME -n production -o jsonpath='{range .spec.containers[*]}{.name}{" | "}{.imagePullPolicy}{"; "}{end}'

مطمئن شوید Registry، Namespace/Repository، نام Image و Tag دقیقاً مطابق Artifact منتشرشده هستند. به‌جای تکیه بر latest، برای استقرارهای قابل بازتولید از Tag نسخه مشخص یا Digest معتبر استفاده کنید. رفتار imagePullPolicy را هم بررسی کنید؛ تغییر Tag لزوماً مقدار Policy ذخیره‌شده را خودکار اصلاح نمی‌کند.

اگر Image درست در Registry وجود دارد ولی Deployment به Tag اشتباه اشاره می‌کند، بعد از تأیید نسخه و تهیه نسخه پشتیبان می‌توانید Image کانتینر نمونه را اصلاح کنید:

kubectl set image deployment/web app=registry.example.com/team/web:1.2.3 -n production
kubectl rollout status deployment/web -n production --timeout=180s

هشدار: این دستور یک Rollout واقعی ایجاد می‌کند. در سرویس حساس، نسخه صحیح و پنجره تغییر را از قبل تأیید کنید.

مرحله ۳: Registry خصوصی و imagePullSecrets را بررسی کنید

Secret باید در همان Namespace پاد وجود داشته باشد. ابتدا بدون چاپ محتویات Secret بررسی کنید:

kubectl get secret regcred -n production -o jsonpath='{.type}{"; "}'
kubectl get pod POD_NAME -n production -o jsonpath='{.spec.imagePullSecrets[*].name}{"; "}'
kubectl get serviceaccount default -n production -o yaml

نوع معمول Secret برای احراز هویت Registry برابر kubernetes.io/dockerconfigjson است. نام Secret در imagePullSecrets باید دقیقاً با نام Secret موجود یکی باشد. اگر ServiceAccount سفارشی دارید، به‌جای default نام واقعی serviceAccountName پاد را بررسی کنید.

برای ساخت Secret از فایل معتبر Docker config که قبلاً در محل امن آماده شده، می‌توانید از روش مستند رسمی استفاده کنید:

kubectl create secret generic regcred --from-file=.dockerconfigjson=/secure/path/config.json --type=kubernetes.io/dockerconfigjson -n production

این دستور را فقط زمانی اجرا کنید که Secret همنام وجود ندارد و فایل واقعاً دارای اعتبارنامه مجاز است. مجوز فایل را محدود کنید و آن را در Git یا لاگ CI قرار ندهید. در Template مربوط به Pod یا Deployment، Secret را ارجاع دهید:

spec:
  template:
    spec:
      imagePullSecrets:
        - name: regcred
      containers:
        - name: app
          image: registry.example.com/team/web:1.2.3

قطعه YAML بالا فقط بخش مرتبط از Deployment است، نه Manifest کامل؛ آن را در جای درست Template موجود قرار دهید. تغییر ServiceAccount نیز روی Podهای موجود الزاماً اثر فوری ندارد. برای جزئیات، راهنمای رسمی Kubernetes برای Private Registry را ملاک قرار دهید.

مرحله ۴: DNS، TLS و دسترسی شبکه Node به Registry

اگر Events خطای DNS یا Timeout نشان می‌دهد، تست باید از همان Node یا مسیر شبکه‌ای معادل آن انجام شود؛ موفقیت مرورگر لپ‌تاپ مدیر سرور کافی نیست. روی Node خودمدیریت و با مجوز مناسب:

getent hosts registry.example.com
curl -sS -o /dev/null -w '%{http_code}' https://registry.example.com/v2/
date -u

پاسخ HTTP 401 از endpoint /v2/ یک Registry خصوصی می‌تواند طبیعی باشد و نشان دهد اتصال و TLS برقرار است، اما هنوز احراز هویت لازم است. خطای x509 به بررسی CA و گواهی، و Timeout به DNS، Firewall، NAT، Proxy و Egress اشاره می‌کند. روی Nodeهای مدیریت‌شده بدون دسترسی SSH، از لاگ Runtime و ابزارهای رسمی سرویس‌دهنده استفاده کنید؛ تغییر سراسری Firewall یا CA را بدون طرح بازگشت انجام ندهید.

اگر مشکل به مسیر شبکه داخل خوشه یا CNI مربوط شد، آموزش Container Networking در Kubernetes برای تفکیک شبکه Pod از ارتباط خروجی Node کمک می‌کند؛ توجه کنید که Pull Image معمولاً توسط kubelet/Runtime روی Node انجام می‌شود، نه توسط کانتینر برنامه.

اگر Nodeهای Kubernetes روی VPS خودمدیریت هستند

در خوشه‌ای که Nodeهای آن را خودتان روی VPS مدیریت می‌کنید، پس از تشخیص واقعی مشکل، امکان دسترسی مدیریتی به Node، بررسی DNS و Egress، ظرفیت دیسک Image و سیاست Firewall در تصمیم درباره زیرساخت اهمیت دارد. هنگام انتخاب یا تغییر زیرساخت می‌توانید پلن‌های سرور مجازی وان‌سرور را از نظر منابع و سطح کنترل موردنیاز مقایسه کنید؛ اما خرید VPS جدید، ImagePullBackOff ناشی از Tag اشتباه یا اعتبارنامه نامعتبر را خودکار رفع نمی‌کند و سازگاری با معماری خوشه باید جداگانه بررسی شود.

مرحله ۵: Verify و مشاهده Rollout

بعد از اصلاح علت اصلی، وضعیت Podهای جدید و رویدادهای مرتبط را دوباره بررسی کنید:

kubectl rollout status deployment/web -n production --timeout=180s
kubectl get pods -n production -o wide
kubectl describe deployment web -n production
kubectl get events -n production --sort-by=.lastTimestamp

نتیجه مطلوب این است که Podهای جدید از وضعیت انتظار Image Pull خارج شوند و Container به حالت Running برسد. Running شدن به‌تنهایی سلامت اپلیکیشن را تضمین نمی‌کند؛ Readiness و رفتار سرویس را هم جداگانه Verify کنید. اگر هنوز خطا وجود دارد، متن Event جدید را با خطای قبلی مقایسه کنید.

Rollback امن در صورت اصلاح اشتباه

اگر تغییر Image یا Template باعث مشکل تازه شده و Deployment تاریخچه Rollout دارد، Revision قبلی را بررسی و در صورت تأیید به آن بازگردید:

kubectl rollout history deployment/web -n production
kubectl rollout undo deployment/web -n production
kubectl rollout status deployment/web -n production --timeout=180s

Rollback مربوط به Deployment الزاماً تغییرات Secret، CA یا Firewall را برنمی‌گرداند؛ این موارد باید با نسخه پشتیبان و روش تغییر اختصاصی خودشان بازگردانده شوند. Secret را برای تست عمومی چاپ نکنید، TLS verification را غیرفعال نکنید و از imagePullPolicy: Never برای پنهان کردن خطای Registry استفاده نکنید.

خطاهای رایج در عیب‌یابی ImagePullBackOff

  • تغییر دادن Secret در Namespace دیگر و انتظار رفع خطای Pod فعلی.
  • استفاده از kubectl logs به‌عنوان تنها روش تشخیص، درحالی‌که کانتینر هنوز اجرا نشده است.
  • اشتباه گرفتن ImagePullBackOff با CrashLoopBackOff یا مشکل Healthcheck.
  • فرض اینکه HTTP 401 از /v2/ حتماً خرابی شبکه است؛ ممکن است پاسخ معمول Registry خصوصی باشد.
  • رفع ظاهری خطای TLS با غیرفعال‌سازی اعتبارسنجی یا استفاده از اعتبارنامه دارای دسترسی بیش از نیاز.

مبنای فنی این راهنما مستندات رسمی Kubernetes درباره Images و Image Pull Policy و راهنمای Debug Pods است. دستورها را با Namespace، نام Deployment و سیاست امنیتی محیط خود تطبیق دهید.

Rate this post
اشتراک گذاری نوشته در:

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *