Résoudre les problèmes liés à l'environnement d'exécution du conteneur


Ce document fournit des étapes de dépannage pour les problèmes courants que vous pouvez rencontrer avec l'environnement d'exécution des conteneurs sur vos nœuds Google Kubernetes Engine (GKE).

Si vous avez besoin d'une aide supplémentaire, contactez Cloud Customer Care.

Installer des chemins d'accès avec des lettres de lecteur simples sur des pools de nœuds Windows avec containerd

Ce problème a été résolu à partir de la version 1.6.6 de containerd.

Les clusters GKE exécutant des pools de nœuds Windows Server qui utilisent l'environnement d'exécution containerd avant la version 1.6.6 peuvent rencontrer des erreurs lors du démarrage de conteneurs comme suit :

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

Pour en savoir plus, reportez-vous au problème GitHub n°6589.

Solution

Pour résoudre ce problème, mettez à niveau vos pools de nœuds vers les dernières versions de GKE utilisant la version 1.6.6 ou une version ultérieure de l'environnement d'exécution containerd.

Les images de conteneurs comportant une ligne de commande CMD ou ENTRYPOINT pré-échappée échouent dans les pools de nœuds Windows avec containerd

Ce problème a été résolu à partir de la version 1.6 de containerd.

Les clusters GKE exécutant des pools de nœuds Windows Server qui utilisent l'environnement d'exécution containerd 1.5.X peuvent rencontrer des erreurs lors du démarrage de conteneurs comme suit :

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

Pour en savoir plus, reportez-vous au problème GitHub n°5067 et au problème GitHub n°6300.

Solution

Pour résoudre ce problème, mettez à niveau vos pools de nœuds vers les dernières versions de GKE utilisant la version 1.6.6 ou une version ultérieure de l'environnement d'exécution containerd.

Les volumes d'images de conteneurs comportant des chemins d'accès inexistants ou des chemins d'accès de type Linux (barre oblique) génèrent une erreur sur les pools de nœuds Windows avec containerd

Ce problème a été résolu à partir de la version 1.6 de containerd.

Les clusters GKE exécutant des pools de nœuds Windows Server qui utilisent l'environnement d'exécution containerd 1.5.X peuvent rencontrer des erreurs lors du démarrage de conteneurs comme suit :

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

Pour en savoir plus, reportez-vous au problème GitHub n°5671.

Solution

Pour résoudre ce problème, mettez à niveau vos pools de nœuds vers les dernières versions de GKE utilisant la version 1.6 ou une version ultérieure de l'environnement d'exécution containerd.

/etc/mtab : fichier ou répertoire inexistant

Par défaut, l'environnement d'exécution du conteneur Docker renseigne ce lien symbolique à l'intérieur du conteneur, contrairement à l'environnement d'exécution containerd.

Pour en savoir plus, reportez-vous au problème GitHub n°2419.

Solution

Pour résoudre ce problème, créez manuellement le lien symbolique /etc/mtab lors de la création de l'image.

ln -sf /proc/mounts /etc/mtab

Erreur d'extraction d'image : aucun répertoire

Versions de GKE concernées : toutes

Lorsque vous créez une image avec kaniko, il se peut que son extraction échoue avec containerd et renvoie le message d'erreur "aucun répertoire". Cette erreur se produit si l'image est créée de manière spécifique : lorsqu'une commande précédente supprime un répertoire et que la commande suivante recrée les mêmes fichiers dans ce répertoire.

L'exemple Dockerfile suivant avec npm illustre ce problème.

RUN npm cache clean --force
RUN npm install

Pour en savoir plus, reportez-vous au problème GitHub n°4659.

Solution

Pour résoudre ce problème, créez votre image à l'aide de docker build, qui n'est pas affecté par ce problème.

Si vous n'avez pas la possibilité d'utiliser docker build, combinez les commandes. L'exemple Dockerfile suivant combine RUN npm cache clean --force et RUN npm install :

RUN npm cache clean --force && npm install

Certaines métriques du système de fichiers sont manquantes et le format des métriques est différent

Versions de GKE concernées : toutes

Le point de terminaison kubelet /metrics/cadvisor fournit des métriques Prometheus, comme indiqué sur la page Métriques pour les composants système Kubernetes. Si vous installez un collecteur de métriques qui dépend de ce point de terminaison, vous pouvez rencontrer les problèmes suivants :

  • Le format des métriques sur le nœud Docker est k8s_<container-name>_<pod-name>_<namespace>_<pod-uid>_<restart-count>, mais celui du nœud containerd est <container-id>.
  • Certaines métriques du système de fichiers sont manquantes sur le nœud containerd, comme suit :

    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
    

Solution

Vous pouvez atténuer ce problème en utilisant cAdvisor en tant que daemonset autonome.

  1. Recherchez la dernière version cAdvisor avec le modèle de nom vX.Y.Z-containerd-cri (par exemple, v0.42.0-containerd-cri).
  2. Suivez les étapes décrites dans cAdvisor Kubernetes Daemonset pour créer le daemonset.
  3. Indiquez le collecteur de métriques installé pour utiliser le point de terminaison /metrics cAdvisor qui fournit l'ensemble complet de métriques du conteneur Prometheus.

Alternatives

  1. Migrez votre solution de surveillance vers Cloud Monitoring, qui fournit l'ensemble complet des métriques de conteneur.
  2. Collectez des métriques à partir de l'API récapitulative de Kubelet avec un point de terminaison /stats/summary.

Les opérations basées sur des rattachements ne fonctionnent pas correctement après le redémarrage de l'environnement d'exécution des conteneurs sur GKE Windows

Versions de GKE concernées : 1.21 à 1.21.5-gke.1802, 1.22 à 1.22.3-gke.700

Les clusters GKE exécutant des pools de nœuds Windows Server qui utilisent l'environnement d'exécution containerd (versions 1.5.4 et 1.5.7-gke.0) peuvent rencontrer des problèmes si l'environnement d'exécution du conteneur est redémarré de manière forcée, avec des associations d'opérations aux conteneurs en cours d'exécution ne pouvant pas lier les E/S. Le problème n'entraîne pas d'échec dans les appels d'API, mais les données ne sont ni envoyées, ni reçues. Cela inclut les données relatives aux CLI d'association et de journalisation via le serveur d'API du cluster.

Solution

Pour résoudre ce problème, effectuez une mise à niveau vers la version corrigée de l'environnement d'exécution des conteneurs (1.5.7-gke.1) avec les versions les plus récentes de GKE.

Les pods affichent le message d'erreur failed to allocate for range 0: no IP addresses available in range set

Versions de GKE concernées : version 1.24.6-gke.1500 ou antérieure, version 1.23.14-gke.1800 ou antérieure et version 1.22.16-gke.2000 ou antérieure

Les clusters GKE exécutant des pools de nœuds qui utilisent containerd peuvent rencontrer des problèmes de fuite d'adresses IP et épuiser toutes les adresses IP de pods sur un nœud. Un pod planifié sur un nœud affecté affiche un message d'erreur semblable à celui-ci :

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

Pour en savoir plus sur le problème, consultez le problème GitHub n°5438 et le problème GitHub n°5768 de containerd.

Il existe un problème connu dans GKE Dataplane V2 qui peut provoquer ce problème. Toutefois, ce problème peut être dû à d'autres causes, y compris un blocage de runc.

Solution

Pour résoudre ce problème, suivez les solutions mentionnées dans la section Solutions pour les clusters GKE standards pour GKE Dataplane V2.

Différence de comportement de la vérification d'exécution en cas d'expiration du délai avant expiration

Versions de GKE concernées : toutes

Le comportement de la vérification d'exécution sur les images containerd est différent du comportement sur les images dockershim. Lorsqu'une vérification d'exécution définie pour le pod dépasse le seuil Kubernetes timeoutSeconds déclaré sur les images dockershim, elle est traitée comme un échec de vérification. Sur les images containerd, les résultats de vérification renvoyés après le seuil timeoutSeconds déclaré sont ignorés.

Solution

Dans GKE, la feature gate ExecProbeTimeout est définie sur false et ne peut pas être modifiée. Pour résoudre ce problème, augmentez le seuil timeoutSeconds pour toutes les vérifications d'exécution affectées ou mettez en œuvre la fonctionnalité de délai avant expiration dans la logique de vérification.

Résoudre les problèmes liés aux registres privés

Cette section fournit des informations de dépannage pour les configurations de registre privé dans containerd.

Échec d'extraction d'image avec l'erreur x509 : certificat signé par une autorité inconnue

Ce problème se produit si GKE ne trouve pas de certificat pour un domaine de registre privé spécifique. Vous pouvez rechercher cette erreur dans Cloud Logging à l'aide de la requête suivante :

  1. Accédez à l'explorateur de journaux dans la console Google Cloud :

    Accéder à l'explorateur de journaux

  2. Exécutez la requête suivante :

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

Pour résoudre ce problème, procédez comme suit :

  1. Dans GKE Standard, ouvrez le fichier de configuration existant au chemin suivant :

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

    Remplacez DOMAIN par le nom de domaine complet du registre.

  2. Vérifiez que votre fichier de configuration contient le nom de domaine complet correct.

  3. Vérifiez que le chemin d'accès au certificat dans le champ secretURI du fichier de configuration est correct.

  4. Vérifiez que le certificat existe dans Secret Manager.

Certificat manquant

Ce problème se produit si GKE n'a pas pu extraire le certificat de Secret Manager pour configurer containerd sur vos nœuds.

Pour résoudre ce problème, procédez comme suit :

  1. Assurez-vous que le nœud concerné exécute Container-Optimized OS. Les nœuds Ubuntu et Windows ne sont pas acceptés.
  2. Dans votre fichier de configuration, assurez-vous que le chemin d'accès du secret dans le champ secretURI est correct.
  3. Vérifiez que le compte de service IAM de votre cluster dispose des autorisations appropriées pour accéder au secret.
  4. Vérifiez que le cluster dispose du niveau d'accès cloud-platform. Pour obtenir des instructions, consultez la section Vérifier les niveaux d'accès.

L'option "Registre non sécurisé" n'est pas configurée pour le réseau local (10.0.0.0/8)

Versions de GKE concernées : toutes

Sur les images containerd, l'option de registre non sécurisé n'est pas configurée pour le réseau local 10.0.0.0/8. Si vous utilisez des registres privés non sécurisés, vous remarquerez peut-être des erreurs semblables à celles-ci :

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

Pour résoudre ce problème, procédez comme suit :

  • Utilisez Artifact Registry.
  • Configurez TLS sur vos registres privés si votre cas d'utilisation le permet. Vous pouvez utiliser un fichier de configuration containerd pour indiquer à GKE d'utiliser les certificats que vous stockez dans Secret Manager afin d'accéder à votre registre privé. Pour obtenir des instructions, consultez la section Accéder aux registres privés avec des certificats CA privés.

Configurer des DaemonSets privilégiés pour modifier votre configuration containerd

Pour les clusters standards, procédez comme suit. Cette solution n'est pas disponible dans Autopilot, car les conteneurs privilégiés présentent un risque de la sécurité. Si votre environnement est exposé à Internet, tenez compte de la tolérance aux risques avant de déployer cette solution. Dans tous les cas, nous vous recommandons vivement de configurer TLS pour votre registre privé et d'utiliser plutôt l'option Secret Manager.

  1. Examinez le fichier manifeste suivant :

    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

    Dans le champ .spec.containers.env, remplacez la valeur REGISTRY_ADDRESS de la variable ADDRESS par l'adresse de votre registre HTTP local au format DOMAIN_NAME:PORT. Par exemple,

    containers:
    - name: startup-script
      ...
      env:
      - name: ADDRESS
        value: "example.com:5000"
    
  2. Déployez le DaemonSet :

    kubectl apply -f insecure-registry-ds.yaml
    

Le DaemonSet ajoute votre registre non sécurisé à la configuration containerd sur chaque nœud.

containerd ignore tous les mappages d'appareils pour les pods privilégiés

Versions de GKE concernées : toutes

Pour les pods Kubernetes privilégiés, l'environnement d'exécution du conteneur ignore les mappages d'appareils que volumeDevices.devicePath lui transmet et place tous les appareils de l'hôte à la disposition du conteneur sous /dev.

containerd fuit les processus du shim lorsque les nœuds sont soumis à une pression d'E/S

Versions de GKE concernées : 1.25.0 à 1.25.15-gke.1040000, 1.26.0 à 1.26.10-gke.1030000, 1.27.0 à 1.27.6-gke.1513000 et 1.28.0 à 1.28.3-gke.1061000

Lorsqu'un nœud GKE est soumis à une pression d'E/S, containerd peut ne pas réussir à supprimer les processus containerd-shim-runc-v2 lorsqu'un pod est supprimé, ce qui entraîne des fuites de processus. En cas de fuite sur un nœud, les processus containerd-shim-runc-v2 s'affichent plus que le nombre de pods sur ce nœud. Vous risquez également d'augmenter l'utilisation de la mémoire et des processeurs, ainsi que des PID supplémentaires. Pour en savoir plus, consultez le problème GitHub Corriger les fuites de shim causées par une pression élevée sur les E/S.

Pour résoudre ce problème, mettez à niveau les nœuds vers les versions suivantes ou ultérieures :

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

La famille d'adresses IPv6 est activée sur les pods exécutant containerd

Versions de GKE concernées : 1.18, 1.19, 1.20.0 à 1.20.9

La famille d'images IPv6 est activée pour les pods exécutés avec containerd. L'image dockershim désactive IPv6 sur tous les pods, contrairement à l'image containerd. Par exemple, localhost résout d'abord l'adresse IPv6 ::1. Cela ne pose généralement pas de problème, mais peut cependant entraîner un comportement inattendu.

Solution

Pour résoudre ce problème, utilisez explicitement une adresse IPv4 telle que 127.0.0.1, ou configurez une application qui s'exécute dans le pod pour qu'elle fonctionne sur les deux familles d'adresses.

Le provisionnement automatique des nœuds ne provisionne que des pools de nœuds Docker sur Container-Optimized OS.

Versions de GKE concernées : 1.18, 1.19, 1.20.0 à 1.20.6-gke.1800

Le provisionnement automatique des nœuds permet d'effectuer l'autoscaling des pools de nœuds avec n'importe quel type d'image accepté. Cependant, vous ne pouvez créer de nouveaux pools de nœuds qu'avec le type d'image Container-Optimized OS avec Docker.

Solution

Pour résoudre ce problème, mettez à niveau vos clusters GKE vers la version 1.20.6-gke.1800 ou ultérieure. Dans ces versions de GKE, le type d'image par défaut peut être défini pour le cluster.

Conflit avec la plage d'adresses IP 172.17/16

Versions de GKE concernées : 1.18.0, à 1.18.14

La plage d'adresses IP 172.17/16 est occupée par l'interface docker0 sur la VM de nœud avec containerd activé. Le trafic en provenance ou à destination de cette plage peut ne pas être correctement routé (par exemple, un pod peut ne pas être en mesure de se connecter à un hôte connecté au VPN avec une adresse IP comprise dans 172.17/16).

Métriques du GPU non collectées

Versions de GKE concernées : 1.18.0 à 1.18.18

Les métriques d'utilisation du GPU ne sont pas collectées lors de l'utilisation de containerd comme environnement d'exécution sur des versions de GKE antérieures à 1.18.18.

Solution

Pour résoudre ce problème, mettez à niveau vos clusters vers la version de GKE 1.18.18 ou ultérieure.

Impossible d'utiliser des images dont le paramètre config.mediaType est défini sur application/octet-stream sur containerd

Versions de GKE concernées : toutes

Impossible d'utiliser des images dont le paramètre config.mediaType est défini sur "application/octet-stream" sur des conteneurs Pour en savoir plus, consultez le problème GitHub n°4756. Ces images ne sont pas compatibles avec la spécification Open Container Initiative et sont considérées comme incorrectes. Ces images fonctionnent avec Docker pour assurer la rétrocompatibilité, tandis qu'elles ne sont pas compatibles avec containerd.

Problème constaté et diagnostic

Exemple d'erreur dans les journaux de nœuds :

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"

Le fichier manifeste de l'image se trouve généralement dans le registre où il est hébergé. Une fois que vous disposez du fichier manifeste, vérifiez config.mediaType pour déterminer si vous rencontrez ce problème :

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

Solution

Comme la communauté de containerd a décidé de ne pas accepter de telles images, toutes les versions de containerd sont affectées et il n'existe pas de correctif. L'image du conteneur doit être recréée avec Docker version 1.11 ou ultérieure et vous devez vous assurer que le champ config.mediaType n'est pas défini sur "application/octet-stream".

Configuration CNI non initialisée

Versions de GKE concernées : toutes

GKE ne parvient pas à créer des nœuds lors d'une mise à niveau, d'un redimensionnement ou d'une autre action.

Problème constaté et diagnostic

Exemple d'erreur dans la console Google Cloud :

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

Cette erreur peut se produire dans les situations suivantes :

  • Pendant l'amorçage des nœuds dans les fichiers journaux pendant que GKE installe la configuration CNI.
  • En tant qu'état d'erreur de nœud dans la console Google Cloud si un webhook personnalisé qui intercepte la commande de contrôleur DaemonSet pour créer un pod comporte des erreurs. Cela empêche GKE de créer un pod netd ou calico-node. Si les pods netd ou calico-node ont démarré correctement alors que l'erreur persiste, contactez l'assistance.

Solution

Pour résoudre ce problème, procédez comme suit :

  • Attendez que GKE ait fini d'installer la configuration CNI.
  • Supprimez tous les webhooks mal configurés.
  • Configurez des webhooks de sorte qu'ils ignorent les pods système.

Étapes suivantes

Si vous avez besoin d'une aide supplémentaire, contactez Cloud Customer Care.