Veröffentlicht am

ImagePullBackOff beheben: Auth, Name, Limit

Teilen:
Authors

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 latest existiert in dem Repository nicht. Private Registries haben oft nur feste Tags.
  • nginx wird als docker.io/library/nginx gezogen. mein-nginx ohne Registry-Prefix sucht unter docker.io/library/ und findet nichts. Der volle Name lautet docker.io/<user>/mein-nginx oder 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