- Authors

- Name
- Phillip Pham
- @ddppham
ImagePullBackOff beheben: Name, Auth und Rate-Limit
TL;DR
ImagePullBackOff heißt: das Image ist nie auf dem Node angekommen. Der Container ist nicht gestartet, deshalb bringen kubectl logs nichts. Die Ursache steht in den Events:
kubectl describe pod POD
Drei Meldungen decken fast alles ab. manifest unknown oder not found ist ein falscher Name oder Tag. unauthorized oder 401 fehlt imagePullSecrets. toomanyrequests ist das Rate-Limit der Registry, meist Docker Hub.
Läuft der Container und stirbt danach, ist das CrashLoopBackOff, nicht ein Pull-Problem.
Was der Status wirklich sagt
Kubernetes versucht den Pull, scheitert, wartet, versucht es wieder. Der erste Fehlversuch heißt oft ErrImagePull, die Wiederholungen ImagePullBackOff. Beides ist derselbe Fehler. Der Backoff schützt die Registry, er versteckt die Ursache nicht. Sie steht bei Failed to pull image im describe-Output, inklusive der Registry-Antwort.
Restart Count bleibt 0. Wer trotzdem --previous aufruft, bekommt keinen Lauf, weil keiner existiert.
Falscher Name, falscher Tag, falsche Registry
Die Meldung enthält not found oder manifest unknown. Prüfen Sie die Zeile image: gegen das, was die Registry wirklich hat.
Häufige Abweichungen:
- Tag
latestexistiert in dem Repository nicht. Private Registries haben oft nur feste Tags. nginxwird alsdocker.io/library/nginxgezogen.mein-nginxohne Registry-Prefix sucht unterdocker.io/library/und findet nichts. Der volle Name lautetdocker.io/<user>/mein-nginxoder die Adresse Ihrer Registry.- Ein Tippfehler in einem Pfadsegment. Die Registry unterscheidet Groß- und Kleinschreibung.
Den Namen prüfen Sie außerhalb des Clusters, mit demselben String wie im Pod:
kubectl get pod POD -o jsonpath='{.spec.containers[*].image}{"\n"}'
Wenn crane digest oder docker manifest inspect mit diesem String scheitert, ist der Pod nicht das Problem.
unauthorized: das Secret fehlt oder gilt nicht für diese Registry
401, 403 oder unauthorized heißt: die Registry hat den Request gesehen und abgelehnt. Auf gemanagten Clustern zieht ein öffentliches Image ohne Secret. Ein privates Image braucht eines.
apiVersion: v1
kind: Secret
metadata:
name: registry-pull
namespace: APP
type: kubernetes.io/dockerconfigjson
data:
.dockerconfigjson: <base64 von ~/.docker/config.json>
---
spec:
imagePullSecrets:
- name: registry-pull
containers:
- name: app
image: registry.example.com/team/app:1.4.2
Das Secret muss im selben Namespace liegen wie der Pod. Ein Secret in default gilt nicht für prod. Bei einem ServiceAccount tragen Sie das Secret unter imagePullSecrets des Accounts ein, sonst gilt es nur für Pods, die es selbst nennen.
Ein abgelaufenes Token sieht aus wie ein falsches Passwort: dieselbe 401. Robots und Cloud-Tokens rotieren. Wenn der Pull gestern ging und heute nicht, ist das Token der erste Verdacht, nicht der Image-Name.
toomanyrequests: anonymes Limit
Docker Hub begrenzt anonyme Pulls pro IP. Viele Nodes hinter einer NAT-Adresse teilen sich das Kontingent. Die Meldung enthält toomanyrequests oder 429.
Der stabile Weg ist ein eigener Account und ein imagePullSecrets auch für öffentliche Images, oder ein Mirror in Ihrer Registry. Ein neuer Pod auf einem anderen Node hilft nur, bis das Limit wieder voll ist.
Node zieht, der Pod nicht
kubectl debug node/NODE -it --image=busybox und ein Pull von dort zeigen, ob der Node die Registry überhaupt erreicht. Timeout statt 401 ist Netz oder DNS, nicht das Passwort. Prüfen Sie dann die Egress-Regel und den Registry-Host, nicht das Deployment.
Wenn nur ein Node scheitert und die anderen dasselbe Image laufen haben, ist der Image-Name richtig. Dann ist der Node der Unterschied: alte containerd-Config, volles Dateisystem unter /var/lib/containerd, oder eine Registry-Mirror-Config nur auf den übrigen Nodes.
Quellen
📖 Verwandte Artikel
Weitere interessante Beiträge zu ähnlichen Themen
kubectl connection refused 6443 beheben
kubectl connection refused auf Port 6443: der API-Server antwortet nicht. kubeconfig, Kontext, Firewall, API-Prozess. Der Pod-Status kommt erst danach.
Error from server Forbidden: RBAC-Recht
kubectl Forbidden: Error from server (Forbidden) nennt User, Verb und Ressource. kubectl auth can-i zeigt das Recht, bevor jemand cluster-admin vergibt.
Exit Code 1: die erste Zeile im Previous-Log
Exit Code 1 auf Kubernetes: die Anwendung beendet sich selbst. kubectl logs --previous zeigt die Zeile. Speicher, Image-Pull und SIGKILL sind andere Codes.
Pod startet nicht: Status lesen, dann der Fix
Pod startet nicht: ein kubectl get pod, dann der Status. Pending, ImagePull, CrashLoop, Evicted und die Befehle, die den jeweiligen Fehler wirklich zeigen.
CrashLoopBackOff beheben: Logs, Probes, Exit-Code
CrashLoopBackOff beheben: kubectl logs --previous, Exit-Codes 1, 137 und 139, Liveness-Probes. Der Unterschied zu ImagePullBackOff in wenigen Minuten.
Pod Terminating hängt: Finalizer entfernen
Pod Terminating hängt: Finalizer finden, Grace-Period abwarten, Force-Delete nur wenn der Node weg ist. Der kubectl-Patch, und wann er ein Volume beschädigt.
ContainerCreating hängt: Volume, Sandbox, CNI
ContainerCreating hängt: der Pod hat einen Node, der Container startet nicht. FailedMount, Pod-Sandbox und CNI stehen in den Events, nicht in den Logs.
CreateContainerConfigError: Secret und ConfigMap
CreateContainerConfigError: fehlendes Secret, falscher Key oder Namespace. Der Container startet nicht, logs --previous bleibt leer. Das Event nennt das Objekt.