Veröffentlicht am

ContainerCreating hängt: Ursachen finden und beheben

Teilen:
Authors

Kubernetes ContainerCreating hängt: Ursachen und Fix

TL;DR

Ein Pod im Status ContainerCreating wartet darauf, dass Kubernetes die Container-Infrastruktur bereitstellt. Die drei häufigsten Blocker: Image kann nicht gepullt werden, Volume lässt sich nicht mounten oder ein Init Container hängt fest. kubectl describe pod zeigt unter Events die exakte Ursache.


Ihr Pod steckt fest:

kubectl get pods
NAME        READY   STATUS              RESTARTS   AGE
my-app      0/1     ContainerCreating   0          8m

Der entscheidende Befehl:

kubectl describe pod my-app

Scrollen Sie direkt zum Abschnitt Events am Ende der Ausgabe. Dort steht, woran es hängt. Die folgenden Abschnitte decken die häufigsten Ursachen ab.

Ursache 1: Image Pull schlägt fehl oder ist langsam

Wenn das Container-Image nicht heruntergeladen werden kann, bleibt der Pod in ContainerCreating (oder wechselt zu ErrImagePull/ImagePullBackOff).

Private Registry ohne Pull Secret

Events:
  Warning  Failed   pull access denied for registry.example.de/my-app, repository does not exist or may require 'docker login'

Lösung -- Pull Secret erstellen und im Pod referenzieren:

# Pull Secret erstellen
kubectl create secret docker-registry my-registry-secret \
  --docker-server=registry.example.de \
  --docker-username=deploy-user \
  --docker-password='s3cret' \
  -n production
spec:
  imagePullSecrets:
    - name: my-registry-secret
  containers:
    - name: my-app
      image: registry.example.de/my-app:v1.2.3

Image existiert nicht oder Tag ist falsch

# Image-Name und Tag prüfen
kubectl get pod my-app -o jsonpath='{.spec.containers[0].image}'

# Vom Node aus testen (SSH auf den Node)
crictl pull registry.example.de/my-app:v1.2.3

Häufiger Fehler: latest-Tag wird verwendet, aber die imagePullPolicy steht auf IfNotPresent. Der Node hat ein altes Image gecacht und zieht kein neues.

# Fix: Immer ein spezifisches Tag verwenden
containers:
  - name: my-app
    image: registry.example.de/my-app:v1.2.3  # NICHT :latest
    imagePullPolicy: Always  # Oder IfNotPresent mit spezifischem Tag

Langsamer Image Pull

Große Images (>1 GB) können Minuten brauchen. Prüfen Sie den Fortschritt:

# Events zeigen den Pull-Status
kubectl get events --field-selector involvedObject.name=my-app --sort-by='.lastTimestamp'
Image-GrößeTypische Pull-Dauer (100 Mbit/s)Empfehlung
< 100 MB< 10 SekundenOptimal
100 - 500 MB10 - 40 SekundenAkzeptabel
500 MB - 1 GB40 - 80 SekundenImage verkleinern
> 1 GB> 80 SekundenMulti-Stage Build, distroless

Ursache 2: Volume Mount Probleme

Volume-Probleme sind die zweithäufigste Ursache für hängende ContainerCreating Pods.

PVC ist nicht Bound

Events:
  Warning  FailedMount  Unable to attach or mount volumes: timed out waiting for the condition
# PVC-Status prüfen
kubectl get pvc -n production

# Typische Ausgabe bei einem Problem:
# NAME        STATUS    VOLUME   CAPACITY   STORAGECLASS   AGE
# my-data     Pending                       standard       5m

Eine PVC im Status Pending bedeutet: kein PersistentVolume verfügbar oder der StorageClass Provisioner funktioniert nicht.

# StorageClass prüfen
kubectl get storageclass

# Provisioner-Pods laufen?
kubectl get pods -n kube-system | grep -i provisioner

# PVC Events anschauen
kubectl describe pvc my-data -n production

Volume ist bereits an einen anderen Node gemountet

Bei ReadWriteOnce (RWO) Volumes kann das Volume nur an einem Node gleichzeitig gemountet sein. Wenn der Pod auf einen anderen Node gescheduled wird:

Warning  FailedAttachVolume  Multi-Attach error for volume "pvc-abc123": Volume is already exclusively attached to one node
# Welcher Node hat das Volume?
kubectl get volumeattachments | grep pvc-abc123

# Lösung: alten Pod auf dem anderen Node beenden
kubectl delete pod old-pod -n production

# Oder: AccessMode auf ReadWriteMany (RWX) ändern (nur bei NFS/CephFS)

ConfigMap oder Secret als Volume nicht gefunden

Warning  FailedMount  MountVolume.SetUp failed: configmap "app-config" not found
# Existiert die ConfigMap im richtigen Namespace?
kubectl get configmap app-config -n production

# Falls nicht: erstellen
kubectl create configmap app-config \
  --from-file=config.yaml=./config.yaml \
  -n production

Wichtig: ConfigMaps und Secrets müssen im selben Namespace wie der Pod existieren.

Ursache 3: Init Container hängt

Init Container laufen vor den eigentlichen Containern. Wenn ein Init Container nicht abschließt, bleibt der Pod in ContainerCreating.

# Init Container Status prüfen
kubectl get pod my-app -o jsonpath='{.status.initContainerStatuses}' | jq .

# Logs des Init Containers
kubectl logs my-app -c init-wait-for-db

Ein typisches Muster: Der Init Container wartet auf einen Service, der nicht erreichbar ist:

initContainers:
  - name: init-wait-for-db
    image: busybox:1.36
    command: ['sh', '-c', 'until nc -z postgres.production.svc.cluster.local 5432; do sleep 2; done']

Wenn der PostgreSQL-Service nicht läuft, wartet dieser Init Container endlos.

# Prüfen ob der Service existiert und Endpoints hat
kubectl get svc postgres -n production
kubectl get endpoints postgres -n production

Ursache 4: Sandbox oder CNI Fehler

Seltener, aber schwieriger zu debuggen:

Warning  FailedCreatePodSandBox  Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network

Das deutet auf ein Problem mit dem CNI-Plugin (Calico, Cilium, Flannel) hin:

# CNI Pods prüfen
kubectl get pods -n kube-system -l k8s-app=calico-node
# oder
kubectl get pods -n kube-system -l k8s-app=cilium

# CNI Logs auf dem betroffenen Node
kubectl logs -n kube-system -l k8s-app=calico-node --tail=50

Debugging-Entscheidungsbaum

Arbeiten Sie diese Reihenfolge durch:

# 1. Events lesen (zeigt die Ursache in 90% der Fälle)
kubectl describe pod my-app | tail -20

# 2. Bei Volume-Problemen: PVC-Status
kubectl get pvc -n production

# 3. Bei Image-Problemen: Image-Name und Pull Secret
kubectl get pod my-app -o jsonpath='{.spec.containers[0].image}'
kubectl get pod my-app -o jsonpath='{.spec.imagePullSecrets}'

# 4. Bei Init Container: Status und Logs
kubectl get pod my-app -o jsonpath='{.status.initContainerStatuses[0].state}'
kubectl logs my-app -c <init-container-name>

# 5. Bei Sandbox/CNI: Node-Status und CNI Pods
kubectl get nodes
kubectl get pods -n kube-system | grep -E 'calico|cilium|flannel'

FAQ

Wie lange wartet Kubernetes bei ContainerCreating bevor es aufgibt?

Kubernetes gibt nicht auf. Der Pod bleibt endlos in ContainerCreating, bis das Problem gelöst ist. Es gibt kein automatisches Timeout. Sie müssen die Ursache manuell beheben.

Was ist der Unterschied zwischen ContainerCreating und Pending?

Pending bedeutet: Der Scheduler hat noch keinen Node für den Pod gefunden (Ressourcen, Affinity, Taints). ContainerCreating bedeutet: Der Pod ist einem Node zugewiesen, aber die Container-Infrastruktur (Image, Volumes, Netzwerk) ist noch nicht bereit.

Kann ein Pod von ContainerCreating direkt in CrashLoopBackOff wechseln?

Nein. Ein Pod geht erst von ContainerCreating nach Running. Erst wenn der Container startet und dann crasht, wechselt der Status zu CrashLoopBackOff. Wenn der Pod nie aus ContainerCreating herauskommt, liegt das Problem vor dem Container-Start.

Wie beschleunige ich den Image Pull?

Drei Ansätze: (1) Kleinere Images durch Multi-Stage Builds und distroless Base Images. (2) Image Pre-Pulling auf die Nodes mit einem DaemonSet. (3) Eine Registry im lokalen Netzwerk als Mirror verwenden.


Wenn Ihre Pods regelmäßig in ContainerCreating hängen bleiben oder Sie Unterstützung bei der Optimierung Ihrer Container-Infrastruktur brauchen, helfen wir gerne -- Kontakt aufnehmen.


Weiterführende Artikel:

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen