Fehlerbehebung bei der Containerlaufzeit


In diesem Dokument werden Schritte zur Fehlerbehebung von häufigen Problemen beschrieben, die bei der Containerlaufzeit auf GKE-Knoten (Google Kubernetes Engine) auftreten können.

Wenn Sie weitere Unterstützung benötigen, wenden Sie sich an den Cloud Customer Care.

Bereitstellungspfade mit einfachen Laufwerksbuchstaben schlagen bei Windows-Knotenpools mit Containerd fehl

Dieses Problem wurde ab containerd-Version 1.6.6 behoben.

Bei GKE-Clustern mit Windows Server-Knotenpools, die die containerd-Laufzeitumgebung vor Version 1.6.6 verwenden, können beim Starten von Containern Fehler wie die folgenden auftreten:

failed to create containerd task : CreateComputeSystem : The parameter is incorrect : unknown

Weitere Informationen finden Sie unter GitHub-Problem Nr. 6589.

Lösung

Aktualisieren Sie Ihre Knotenpools auf die neuesten GKE-Versionen, die containerd-Laufzeitversion 1.6.6 oder höher verwenden, um dieses Problem zu beheben.

Container-Images mit nicht als Array vorangeschriebenen Befehlszeilen CMD oder ENTRYPOINT schlagen auf Windows-Knotenpools mit Containerd fehl

Dieses Problem wurde ab containerd-Version 1.6 behoben.

Bei GKE-Clustern mit Windows Server-Knotenpools, die die containerd-Laufzeit 1.5.X verwenden, können beim Starten von Containern Fehler wie die folgenden auftreten:

failed to start containerd task : hcs::System::CreateProcess : The system cannot find the file specified.: unknown

Weitere Informationen finden Sie unter GitHub-Problem Nr. 5067 und GitHub-Problem 6300.

Lösung

Aktualisieren Sie Ihre Knotenpools auf die neuesten GKE-Versionen, die containerd-Laufzeitversion 1.6.6 oder höher verwenden, um dieses Problem zu beheben.

Container-Image-Volumes mit nicht existierenden Pfaden oder Linux-ähnlichen (Schrägstrich) Pfaden schlagen auf Windows-Knotenpools mit Containerd fehl

Dieses Problem wurde ab containerd-Version 1.6 behoben.

Bei GKE-Clustern mit Windows Server-Knotenpools, die die containerd-Laufzeit 1.5.X verwenden, können beim Starten von Containern Fehler wie die folgenden auftreten:

failed to generate spec: failed to stat "<volume_path>": CreateFile : The system cannot find the path specified.

Weitere Informationen finden Sie unter GitHub-Problem Nr. 5671.

Lösung

Aktualisieren Sie Ihre Knotenpools auf die neuesten GKE-Versionen, die containerd-Laufzeitversion 1.6.x oder höher verwenden, um dieses Problem zu beheben.

/etc/mtab: Datei oder Verzeichnis nicht vorhanden

Die Docker-Containerlaufzeit füllt diesen Symlink standardmäßig innerhalb des Containers aus, die containerd-Laufzeit aber nicht.

Weitere Informationen finden Sie unter GitHub-Problem Nr. 2419.

Lösung

Zur Behebung dieses Problems erstellen Sie manuell den Symlink /etc/mtab während des Image-Builds.

ln -sf /proc/mounts /etc/mtab

Image-Pull-Fehler: kein Verzeichnis

Betroffene GKE-Versionen: alle

Wenn Sie ein Image mit kaniko erstellen, kann es sein, dass es mit containerd mit der Fehlermeldung "kein Verzeichnis" nicht abgerufen werden kann. Dieser Fehler tritt auf, wenn das Image speziell erstellt wird: Wenn ein vorheriger Befehl ein Verzeichnis entfernt und der nächste Befehl dieselben Dateien in diesem Verzeichnis neu erstellt.

Das folgende Dockerfile-Beispiel mit npm, das dieses Problem veranschaulicht.

RUN npm cache clean --force
RUN npm install

Weitere Informationen finden Sie unter GitHub-Problem Nr. 4659.

Lösung

Um dieses Problem zu beheben, erstellen Sie Ihr Image mit docker build, das von dem Problem nicht betroffen ist.

Wenn docker build nicht für Sie geeignet ist, kombinieren Sie die Befehle in einem Befehl. Das folgende Dockerfile-Beispiel kombiniert RUN npm cache clean --force und RUN npm install:

RUN npm cache clean --force && npm install

Einige Dateisystem-Messwerte fehlen und das Messwertformat ist unterschiedlich

Betroffene GKE-Versionen: alle

Der Kubelet-/metrics/cadvisor-Endpunkt bietet Prometheus-Messwerte, wie unter Messwerte für Kubernetes-Systemkomponenten dokumentiert. Wenn Sie einen Messwert-Collector installieren, der von diesem Endpunkt abhängt, werden möglicherweise die folgenden Probleme angezeigt:

  • Das Messwertformat auf dem Docker-Knoten ist k8s_<container-name>_<pod-name>_<namespace>_<pod-uid>_<restart-count>, aber das Format auf dem containerd-Knoten ist <container-id>.
  • Einige Dateisystem-Messwerte fehlen so auf dem containerd-Knoten:

    container_fs_inodes_free
    container_fs_inodes_total
    container_fs_io_current
    container_fs_io_time_seconds_total
    container_fs_io_time_weighted_seconds_total
    container_fs_limit_bytes
    container_fs_read_seconds_total
    container_fs_reads_merged_total
    container_fs_sector_reads_total
    container_fs_sector_writes_total
    container_fs_usage_bytes
    container_fs_write_seconds_total
    container_fs_writes_merged_total
    

Lösung

Sie können dieses Problem umgehen, indem Sie cAdvisor als eigenständiges Daemonset verwenden.

  1. Suchen Sie die neueste cAdvisor-Version mit dem Namensmuster vX.Y.Z-containerd-cri (z. B. v0.42.0-containerd-cri).
  2. Führen Sie die Schritte unter cAdvisor Kubernetes Daemonset aus, um das Daemonset zu erstellen.
  3. Verweisen Sie den installierten Messwert-Collector auf die Verwendung des cAdvisor-Endpunkts /metrics, der den vollständigen Satz von Prometheus-Containermesswerten enthält.

Alternativen

  1. Migrieren Sie Ihre Monitoring-Lösung zu Cloud Monitoring, die den vollständigen Satz von Containermesswerten bietet.
  2. Erfassen Sie Messwerte aus der Kubelet Summary API mit dem Endpunkt /stats/summary.

Anhangsbasierte Vorgänge funktionieren nicht korrekt, nachdem die Containerlaufzeit unter GKE Windows neu gestartet wurde

Betroffene GKE-Versionen: 1.21 bis 1.21.5-gke.1802, 1.22 bis 1.22.3-gke.700

Bei GKE-Clustern, auf denen Windows Server-Knotenpools ausgeführt werden, die die containerd-Laufzeit (Version 1.5.4 und 1.5.7-gke.0) verwenden, können Probleme auftreten, wenn die Containerlaufzeit zwangsweise neu gestartet wird, wobei Vorgänge an vorhandene ausgeführte Container angehängt, die E/A nicht wieder binden können. Das Problem führt nicht zu Fehlern bei API-Aufrufen. Es werden jedoch keine Daten gesendet oder empfangen. Dazu gehören auch Daten zum Anhängen von Log-Befehlszeilen und APIs über den Cluster-API-Server.

Lösung

Führen Sie zur Behebung dieses Problems ein Upgrade auf die gepatchte Containerversion (1.5.7-gke.1) mit neueren GKE-Releases durch.

Pods zeigen failed to allocate for range 0: no IP addresses available in range set-Fehlermeldung an

Betroffene GKE-Versionen: 1.24.6-gke.1500 oder früher, 1.23.14-gke.1800 oder früher und 1.22.16-gke.2000 oder früher

Bei GKE-Clustern, in denen Knotenpools ausgeführt werden, die containerd verwenden, kann es zu IP-Datenlecks kommen, sodass alle Pod-IP-Adressen auf einem Knoten erschöpft sind. Ein Pod, der auf einem betroffenen Knoten geplant ist, zeigt eine Fehlermeldung ähnlich der folgenden an:

failed to allocate for range 0: no IP addresses available in range set: 10.48.131.1-10.48.131.62

Weitere Informationen zu dem Problem finden Sie unter GitHub-Problem Nr. 5438 und GitHub-Problem 5768.

In GKE Dataplane V2 gibt es ein bekanntes Problem, das dieses Problem auslösen kann. Dieses Problem kann jedoch auch durch andere Ursachen ausgelöst werden, einschließlich runc hängen.

Lösung

Folgen Sie zur Behebung dieses Problems den Problemumgehungen, die unter Problemumgehungen für GKE-Standardcluster für GKE Dataplane V2 erwähnt werden.

Unterschiedliches Verhalten der Exec-Prüfung, wenn die Prüfung das Zeitlimit überschreitet

Betroffene GKE-Versionen: alle

Das Verhalten von Exec-Prüfung bei containerd-Images unterscheidet sich vom Verhalten bei dockershim-Images. Wenn die für den Pod definierte Exec-Prüfung den deklarierten Schwellenwert Kubernetes-timeoutSeconds für dockershim-Images überschreitet, wird dies als Prüfungsfehler behandelt. Bei containerd-Images werden nach dem deklarierten Schwellenwert timeoutSeconds zurückgegebene Prüfergebnisse ignoriert.

Lösung

In GKE ist das Feature Gate ExecProbeTimeout auf false festgelegt und kann nicht geändert werden. Erhöhen Sie zur Behebung dieses Problems den Schwellenwert timeoutSeconds für alle betroffenen Exec-Prüfungen oder implementieren Sie die Zeitüberschreitungsfunktion als Teil der Prüfungslogik.

Probleme mit privaten Registrys beheben

Dieser Abschnitt enthält Informationen zur Fehlerbehebung für private Registry-Konfigurationen in containerd.

Das Abrufen von Images schlägt mit dem Fehler x509 fehl: Zertifikat wurde von einer unbekannten Behörde signiert

Dieses Problem tritt auf, wenn GKE kein Zertifikat für eine bestimmte private Registry-Domain finden konnte. Mit der folgenden Abfrage können Sie in Cloud Logging auf diesen Fehler prüfen:

  1. Rufen Sie in der Google Cloud Console die Seite Log-Explorer auf.

    Zum Log-Explorer

  2. Führen Sie die folgende Abfrage aus:

    ("Internal error pulling certificate" OR
    "Failed to get credentials from metadata server" OR
    "Failed to install certificate")
    

Versuchen Sie Folgendes, um dieses Problem zu beheben:

  1. Öffnen Sie in GKE Standard die Konfigurationsdatei im folgenden Pfad:

    /etc/containerd/hosts.d/DOMAIN/config.toml
    

    Ersetzen Sie DOMAIN durch den FQDN für die Registry.

  2. Prüfen Sie, ob Ihre Konfigurationsdatei den richtigen FQDN enthält.

  3. Prüfen Sie, ob der Pfad zum Zertifikat im Feld secretURI der Konfigurationsdatei korrekt ist.

  4. Prüfen Sie, ob das Zertifikat in Secret Manager vorhanden ist.

Zertifikat nicht vorhanden

Dieses Problem tritt auf, wenn GKE das Zertifikat nicht aus Secret Manager abrufen konnte, um containerd auf Ihren Knoten zu konfigurieren.

Versuchen Sie Folgendes, um dieses Problem zu beheben:

  1. Stellen Sie sicher, dass auf dem betroffenen Knoten Container-Optimized OS ausgeführt wird. Ubuntu- und Windows-Knoten werden nicht unterstützt.
  2. Achten Sie darauf, dass in Ihrer Konfigurationsdatei der Pfad zum Secret im Feld secretURI korrekt ist.
  3. Prüfen Sie, ob das IAM-Dienstkonto Ihres Clusters die richtigen Berechtigungen für den Zugriff auf das Secret hat.
  4. Prüfen Sie, ob der Cluster den Zugriffsbereich cloud-platform hat. Eine Anleitung finden Sie unter Zugriffsbereiche prüfen.

Option für eine unsichere Registry für das lokale Netzwerk (10.0.0.0/8) ist nicht konfiguriert

Betroffene GKE-Versionen: alle

Bei containerd-Images ist die Option für eine unsichere Registry nicht für das lokale Netzwerk 10.0.0.0/8 konfiguriert. Wenn Sie unsichere private Registrys verwenden, können Fehler wie die folgenden auftreten:

pulling image: rpc error: code = Unknown desc = failed to pull and unpack image "IMAGE_NAME": failed to do request: Head "IMAGE_NAME": http: server gave HTTP response to HTTPS client

Versuchen Sie Folgendes, um dieses Problem zu beheben:

  • Artifact Registry verwenden
  • Konfigurieren Sie TLS in Ihren privaten Registrys, wenn Ihr Anwendungsfall diese Option unterstützt. Sie können eine containerd-Konfigurationsdatei verwenden, um GKE anzuweisen, Zertifikate zu verwenden, die Sie in Secret Manager speichern, um auf Ihre private Registry zuzugreifen. Eine Anleitung finden Sie unter Auf private Registrys mit privaten CA-Zertifikaten zugreifen.

Privilegierte DaemonSets konfigurieren, um Ihre containerd-Konfiguration zu ändern

Führen Sie für Standardcluster die folgenden Schritte aus. Diese Problemumgehung ist in Autopilot nicht verfügbar, da privilegierte Container ein Sicherheitsrisiko darstellen. Wenn Ihre Umgebung dem Internet ausgesetzt ist, sollten Sie Ihre Risikotoleranz berücksichtigen, bevor Sie diese Lösung bereitstellen. In allen Fällen empfehlen wir dringend, TLS für Ihre private Registry zu konfigurieren und stattdessen die Option „Secret Manager“ zu verwenden.

  1. Prüfen Sie das folgende Manifest:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: insecure-registries
      namespace: default
      labels:
        k8s-app: insecure-registries
    spec:
      selector:
        matchLabels:
          name: insecure-registries
      updateStrategy:
        type: RollingUpdate
      template:
        metadata:
          labels:
            name: insecure-registries
        spec:
          nodeSelector:
            cloud.google.com/gke-container-runtime: "containerd"
          hostPID: true
          containers:
            - name: startup-script
              image: registry.k8s.io/startup-script:v2
              imagePullPolicy: Always
              securityContext:
                privileged: true
              env:
              - name: ADDRESS
                value: "REGISTRY_ADDRESS"
              - name: STARTUP_SCRIPT
                value: |
                  set -o errexit
                  set -o pipefail
                  set -o nounset
    
                  if [[ -z "$ADDRESS" || "$ADDRESS" == "REGISTRY_ADDRESS" ]]; then
                    echo "Error: Environment variable ADDRESS is not set in containers.spec.env"
                    exit 1
                  fi
    
                  echo "Allowlisting insecure registries..."
                  containerd_config="/etc/containerd/config.toml"
                  hostpath=$(sed -nr 's;  config_path = "([-/a-z0-9_.]+)";\1;p' "$containerd_config")
                  if [[ -z "$hostpath" ]]; then
                    echo "Node uses CRI config model V1 (deprecated), adding mirror under $containerd_config..."
                    grep -qxF '[plugins."io.containerd.grpc.v1.cri".registry.mirrors."'$ADDRESS'"]' "$containerd_config" || \
                      echo -e '[plugins."io.containerd.grpc.v1.cri".registry.mirrors."'$ADDRESS'"]\n  endpoint = ["http://'$ADDRESS'"]' >> "$containerd_config"
                  else
                    host_config_dir="$hostpath/$ADDRESS"
                    host_config_file="$host_config_dir/hosts.toml"
                    echo "Node uses CRI config model V2, adding mirror under $host_config_file..."
                    if [[ ! -e "$host_config_file" ]]; then
                      mkdir -p "$host_config_dir"
                      echo -e "server = \"https://$ADDRESS\"\n" > "$host_config_file"
                    fi
                    echo -e "[host.\"http://$ADDRESS\"]\n  capabilities = [\"pull\", \"resolve\"]\n" >> "$host_config_file"
                  fi
                  echo "Reloading systemd management configuration"
                  systemctl daemon-reload
                  echo "Restarting containerd..."
                  systemctl restart containerd

    Ersetzen Sie im Feld .spec.containers.env den REGISTRY_ADDRESS-Wert der Variablen ADDRESS durch die Adresse Ihrer lokalen HTTP-Registry im Format DOMAIN_NAME:PORT. Beispiel:

    containers:
    - name: startup-script
      ...
      env:
      - name: ADDRESS
        value: "example.com:5000"
    
  2. Stellen Sie das DaemonSet bereit:

    kubectl apply -f insecure-registry-ds.yaml
    

Das DaemonSet fügt der Containerd-Konfiguration auf jedem Knoten Ihre unsichere Registry hinzu.

containerd ignoriert alle Gerätezuordnungen für privilegierte Pods

Betroffene GKE-Versionen: alle

Bei privilegierten Pods ignoriert die Containerlaufzeit alle Gerätezuordnungen, die volumeDevices.devicePath an sie übergeben hat. Stattdessen wird jedes Gerät auf dem Host unter /dev für den Container verfügbar.

Containerd leitet Shim-Prozesse weiter, wenn die Knoten unter E/A-Auslastung stehen

Betroffene GKE-Versionen: 1.25.0 bis 1.25.15-gke.1040000, 1.26.0 bis 1.26.10-gke.1030000, 1.27.0 bis 1.27.6-gke.1513000 und 1.28.0 bis 1.28.0 3-gke.1061000

Wenn ein GKE-Knoten unter E/A-Auslastung steht, kann containerd die containerd-shim-runc-v2-Prozesse beim Löschen eines Pods möglicherweise nicht löschen, was zu Datenlecks führt. Wenn das Datenleck auf einem Knoten auftritt, werden Sie mehr containerd-shim-runc-v2-Prozesse auf dem Knoten sehen als Pods auf diesem Knoten vorhanden sind. Möglicherweise stellen Sie auch eine höhere Speicher- und CPU-Auslastung sowie zusätzliche PIDs fest. Weitere Informationen finden Sie im GitHub-Problem Datenlecks aufgrund hoher E/A-Auslastung beheben.

Aktualisieren Sie Ihre Knoten auf die folgenden Versionen oder höher, um dieses Problem zu beheben:

  • 1.25.15-gke.1040000
  • 1.26.10-gke.1030000
  • 1.27.6-gke.1513000
  • 1.28.3-gke.1061000

IPv6-Adressfamilie ist auf Pods aktiviert, auf denen containerd ausgeführt wird

Betroffene GKE-Versionen: 1.18, 1.19, 1.20.0 bis 1.20.9

Die IPv6-Image-Familie ist für Pods aktiviert, die mit containerd ausgeführt werden. Das dockershim-Image deaktiviert IPv6 auf allen Pods, das containerd-Image jedoch nicht. Beispielsweise wird localhost in die IPv6-Adresse ::1 zuerst aufgelöst. In der Regel ist dies kein Problem, in bestimmten Fällen kann dies jedoch zu unerwartetem Verhalten führen.

Lösung

Verwenden Sie zur Behebung dieses Problems explizit eine IPv4-Adresse wie 127.0.0.1 oder konfigurieren Sie eine im Pod ausgeführte Anwendung so, dass sie bei beiden Adressfamilien funktioniert.

Bei der automatischen Knotenbereitstellung wird ein Container-optimiertes OS nur mit Docker-Knotenpools bereitgestellt

Betroffene GKE-Versionen: 1.18, 1.19, 1.20.0 bis 1.20.6-gke.1800

Die automatische Knotenbereitstellung ermöglicht die automatische Skalierung von Knotenpools mit beliebigen unterstützten Image-Typen, kann jedoch nur neue Knotenpools mit dem Image-Typ Container-Optimized OS mit Docker erstellen.

Lösung

Aktualisieren Sie Ihre GKE-Cluster auf Version 1.20.6-gke.1800 oder höher, um dieses Problem zu beheben. In diesen GKE-Versionen kann der Standard-Image-Typ für den Cluster festgelegt werden.

Konflikt mit dem IP-Adressbereich 172.17/16

Betroffene GKE-Versionen: 1.18.0 bis 1.18.14

Der IP-Adressbereich 172.17/16 wird von der Schnittstelle docker0 auf der Knoten-VM mit aktiviertem containerd belegt. Traffic, der an diesen Bereich gesendet wird oder von diesem stammt, wird möglicherweise nicht korrekt weitergeleitet (z. B. kann ein Pod möglicherweise keine Verbindung zu einem mit VPN verbundenen Host mit einer IP-Adresse innerhalb von 172.17/16 herstellen).

Nicht erfasste GPU-Messwerte

Betroffene GKE-Versionen: 1.18.0 to 1.18.18

GPU-Nutzungsmesswerte werden bei der Verwendung von containerd als Laufzeit in GKE-Versionen vor 1.18.18 nicht erfasst.

Lösung

Aktualisieren Sie Ihre Cluster auf die GKE-Version 1.18.18 oder höher, um dieses Problem zu beheben.

Images mit config.mediaType festgelegt auf application/octet-stream kann nicht für "containerd" verwendet werden

Betroffene GKE-Versionen: alle

Images mit config.mediaType festgelegt auf "application/octet-stream" können nicht für "containerd" verwendet werden Weitere Informationen finden Sie unter GitHub-Problem Nr. 4756. Diese Images sind nicht mit der Open Container Initiative-Spezifikation kompatibel und werden als falsch angesehen. Diese Images sind mit Docker kompatibel, um Abwärtskompatibilität zu gewährleisten. In containerd werden sie jedoch nicht unterstützt.

Symptom und Diagnose

Beispielfehler in Knotenlogs:

Error syncing pod <pod-uid> ("<pod-name>_<namespace>(<pod-uid>)"), skipping: failed to "StartContainer" for "<container-name>" with CreateContainerError: "failed to create containerd container: error unpacking image: failed to extract layer sha256:<some id>: failed to get reader from content store: content digest sha256:<some id>: not found"

Das Image-Manifest befindet sich normalerweise in der Registry, in der es gehostet wird. Sobald Sie das Manifest haben, prüfen Sie config.mediaType, um festzustellen, ob Sie dieses Problem haben:

"mediaType": "application/octet-stream",

Lösung

Da die containerd-Community entschieden hat, solche Images nicht zu unterstützen, sind alle Versionen von containerd betroffen und es gibt keinen Fehler. Das Container-Image muss mit Docker Version 1.11 oder höher neu erstellt werden und das Feld config.mediaType darf nicht auf "application/octet-stream" gesetzt sein.

Nicht initialisierte CNI-Konfiguration

Betroffene GKE-Versionen: alle

GKE kann während eines Upgrades, einer Größenänderung oder anderen Aktionen keine Knoten erstellen.

Symptom und Diagnose

Beispiel für einen Fehler in der Google Cloud Console:

Error: "runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized".

Dieser Fehler kann in folgenden Situationen auftreten:

  • Beim Knoten-Bootstrapping in Logdateien, während GKE die CNI-Konfiguration installiert
  • Als Knotenfehlerstatus in der Google Cloud Console, wenn ein benutzerdefinierter Webhook, der den Befehl DaemonSet-Controller zur Erstellung eines Pod abfängt, Fehler aufweist. Dadurch wird verhindert, dass GKE einen netd- oder calico-node-Pod erstellt. Wenn die netd- oder calico-node-Pods erfolgreich gestartet wurden, der Fehler aber weiter besteht, wenden Sie sich an den Support.

Lösung

Versuchen Sie Folgendes, um dieses Problem zu beheben:

  • Warten Sie, bis GKE die Installation der CNI-Konfiguration abgeschlossen hat.
  • So entfernen Sie falsch konfigurierte Webhooks:

    1. Listen Sie die Webhooks auf:

          $ kubectl get mutatingwebhookconfigurations
          $ kubectl get validatingwebhookconfigurations
      
    2. Entfernen Sie die falsch konfigurierten Webhooks:

          kubectl delete mutatingwebhookconfigurations WEBHOOK_NAME
          kubectl delete validatingwebhookconfigurations WEBHOOK_NAME
      

    Ersetzen Sie WEBHOOK_NAME durch den Namen des falsch konfigurierten Webhooks, den Sie entfernen möchten.

  • Konfigurieren Sie Webhooks so, dass System-Pods ignoriert werden.

Nächste Schritte

Wenn Sie weitere Unterstützung benötigen, wenden Sie sich an den Cloud Customer Care.