Soluciona problemas del entorno de ejecución del contenedor


En este documento, se proporcionan pasos para solucionar problemas comunes que puedes encontrar con el entorno de ejecución del contenedor en tus nodos de Google Kubernetes Engine (GKE).

Si necesitas asistencia adicional, comunícate con Atención al cliente de Cloud.

Las rutas de activación con letras de unidad simples fallan en los grupos de nodos de Windows con containerd

Este problema se resolvió en la versión 1.6.6 de containerd y posteriores.

Los clústeres de GKE que ejecutan grupos de nodos de Windows Server que usan el entorno de ejecución de containerd anterior a la versión 1.6.6 pueden experimentar errores cuando se inician contenedores como los siguientes:

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

Para obtener más detalles, consulta el problema #6589 de GitHub.

Solución

Para resolver este problema, actualiza tus grupos de nodos a las últimas versiones de GKE que usan la versión 1.6.6 o superior del entorno de ejecución de containerd.

Las imágenes de contenedor con líneas de comandos de CMD o ENTRYPOINT sin escape previo de arrays fallan en los grupos de nodos de Windows con containerd

Este problema se resolvió en la versión 1.6 de containerd y posteriores.

Los clústeres de GKE que ejecutan grupos de nodos de Windows Server que usan el entorno de ejecución de containerd 1.5.X pueden experimentar errores cuando inician contenedores como los siguientes:

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

Para obtener más detalles, consulta los problemas de GitHub #5067 y #6300.

Solución

Para resolver este problema, actualiza tus grupos de nodos a las últimas versiones de GKE que usan la versión 1.6.6 o superior del entorno de ejecución de containerd.

Los volúmenes de imágenes de contenedor con rutas de acceso no existentes o rutas de acceso similares a Linux (diagonal) fallan en los grupos de nodos de Windows con containerd

Este problema se resolvió en la versión 1.6 de containerd y posteriores.

Los clústeres de GKE que ejecutan grupos de nodos de Windows Server que usan el entorno de ejecución de containerd 1.5.X pueden experimentar errores cuando inician contenedores como los siguientes:

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

Para obtener más detalles, consulta el problema #5671 de GitHub.

Solución

Para resolver este problema, actualiza tus grupos de nodos a las últimas versiones de GKE que usan la versión 1.6.x o superior del entorno de ejecución de containerd.

/etc/mtab: El archivo o directorio no existe

El entorno de ejecución del contenedor de Docker propaga este symlink dentro del contenedor de forma predeterminada, pero el entorno de ejecución de containerd no lo hace.

Para obtener más detalles, consulta el problema #2419 de GitHub.

Solución

Para resolver este problema, crea manualmente el symlink /etc/mtab durante la compilación de la imagen.

ln -sf /proc/mounts /etc/mtab

Error de extracción de imagen: no es un directorio

Versiones afectadas de GKE: todas

Cuando compilas una imagen con kaniko, es posible que no se pueda extraer con containerd con el mensaje de error "no es un directorio". Este error ocurre si la imagen se compila de una forma especial: cuando un comando anterior quita un directorio y el siguiente comando vuelve a crear los mismos archivos en ese directorio.

En el siguiente ejemplo de Dockerfile con npm, se ilustra este problema.

RUN npm cache clean --force
RUN npm install

Para obtener más detalles, consulta el problema #4659 de GitHub.

Solución

Para resolver este problema, compila tu imagen con docker build, que no se verá afectada por este problema.

Si docker build no es una opción para ti, combina los comandos en uno. En el siguiente ejemplo de Dockerfile, se combinan RUN npm cache clean --force y RUN npm install:

RUN npm cache clean --force && npm install

Faltan algunas métricas del sistema de archivos y el formato de las métricas es diferente

Versiones afectadas de GKE: todas

El extremo /metrics/cadvisor de Kubelet proporciona métricas de Prometheus, como se documenta en Métricas para los componentes del sistema de Kubernetes. Si instalas un colector de métricas que depende de ese extremo, es posible que veas los siguientes problemas:

  • El formato de las métricas en el nodo de Docker es k8s_<container-name>_<pod-name>_<namespace>_<pod-uid>_<restart-count>, pero el formato en el nodo en container es <container-id>.
  • Faltan algunas métricas del sistema de archivos en el nodo containerd, como se muestra a continuación:

    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
    

Solución

Puedes mitigar este problema a través del uso de cAdvisor como un daemonset independiente.

  1. Busca la versión de cAdvisor más reciente con el patrón de nombre vX.Y.Z-containerd-cri (por ejemplo, v0.42.0-containerd-cri).
  2. Sigue los pasos en cAdvisor Kubernetes Daemonset para crear el daemonset.
  3. Apunta el recopilador de métricas instalado para usar el extremo /metrics de cAdvisor, que proporciona el conjunto completo de métricas de contenedor de Prometheus.

Alternativas

  1. Migra tu solución de supervisión a Cloud Monitoring, que proporciona el conjunto completo de métricas de contenedor.
  2. Recopila métricas de la API de resumen de Kubelet con un extremo de /stats/summary.

Las operaciones basadas en conexiones no funcionan de forma correcta después de que el entorno de ejecución de contenedores se reinicie en GKE Windows.

Versiones de GKE afectadas: 1.21 a 1.21.5-gke.1802, 1.22 a 1.22.3-gke.700

Es posible que los clústeres de GKE que ejecutan grupos de nodos de Windows Server que usan el entorno de ejecución de containerd (versiones 1.5.4 y 1.5.7-gke.0) tengan problemas si el entorno de ejecución del contenedor se reinicia de manera forzada, con operaciones de conexión a contenedores en ejecución existentes que no se pueden volver a vincular a IO. El problema no causará fallas en las llamadas a la API. Sin embargo, los datos no se enviarán ni se recibirán. Esto incluye los datos para adjuntar y registrar las CLI y las API a través del servidor de la API del clúster.

Solución

Para resolver este problema, actualiza a la versión del entorno de ejecución del contenedor (1.5.7-gke.1) con la versión más reciente de GKE.

Los Pods muestran un mensaje de error de failed to allocate for range 0: no IP addresses available in range set

Versiones de GKE afectadas: 1.24.6-gke.1500 o anteriores, 1.23.14-gke.1800 o anteriores, y 1.22.16-gke.2000 o anteriores

Los clústeres de GKE que ejecutan grupos de nodos que usan containerd podrían experimentar problemas de filtración de IP y agotar todas las direcciones IP de Pods en un nodo. Un Pod programado en un nodo afectado muestra un mensaje de error similar al siguiente:

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

Para obtener más información sobre el problema, consulta el problema #5438 de GitHub y el problema #5768 de GitHub.

Existe un problema conocido en GKE Dataplane V2 que puede activar este problema. Sin embargo, este problema se puede activar por otras causas, como runc atascado.

Solución

A fin de resolver este problema, sigue las soluciones alternativas que se mencionan en Soluciones para clústeres de GKE estándar para GKE Dataplane V2.

Diferencia en el comportamiento del sondeo de ejecución cuando el sondeo excede el tiempo de espera

Versiones afectadas de GKE: todas

El comportamiento del sondeo de ejecución en las imágenes de Containerd es diferente del comportamiento en las imágenes dockershim. Cuando el sondeo de ejecución, definido para el Pod, excede el umbral declarado de timeoutSeconds de Kubernetes, en imágenes de dockershim, se trata como una falla de sondeo. En las imágenes de containerd, se ignoran los resultados de sondeo que se muestran después del umbral de timeoutSeconds declarado.

Solución

En GKE, el interruptor de función ExecProbeTimeout se establece en false y no se puede cambiar. A fin de resolver este problema, aumenta el umbral de timeoutSeconds para todos los sondeos de ejecución afectados o implementa la funcionalidad de tiempo de espera como parte de la lógica del sondeo.

Soluciona problemas de registros privados

En esta sección, se proporciona información sobre la solución de problemas para las opciones de configuración de registro privado en containerd.

La extracción de la imagen falla con el error x509: certificado firmado por autoridad desconocida

Este problema se produce si GKE no pudo encontrar un certificado para un dominio de registro privado específico. Puedes verificar este error en Cloud Logging mediante la siguiente consulta:

  1. Ve al Explorador de registros en la consola de Google Cloud:

    Ir al Explorador de registros

  2. Ejecuta la siguiente consulta:

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

Para resolver este problema, realiza las siguientes acciones:

  1. En GKE Standard, abre el archivo de configuración que existe en la siguiente ruta de acceso:

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

    Reemplaza DOMAIN por el FQDN del registro.

  2. Verifica que el archivo de configuración contenga el FQDN correcto.

  3. Verifica que la ruta al certificado en el campo secretURI del archivo de configuración sea correcta.

  4. Verifica que el certificado exista en Secret Manager.

El certificado no está presente

Este problema se produce si GKE no pudo extraer el certificado de Secret Manager para configurar containerd en tus nodos.

Para resolver este problema, realiza las siguientes acciones:

  1. Asegúrate de que el nodo afectado ejecute Container-Optimized OS. Los nodos de Ubuntu y Windows no son compatibles.
  2. En el archivo de configuración, asegúrate de que la ruta de acceso al Secret en el campo secretURI sea correcta.
  3. Verifica que la cuenta de servicio de IAM de tu clúster tenga los permisos correctos para acceder al Secret.
  4. Comprueba que el clúster tenga el permiso de acceso cloud-platform. Para obtener instrucciones, consulta Verifica los permisos de acceso.

La opción de registro no seguro no está configurada para la red local (10.0.0.0/8)

Versiones afectadas de GKE: todas

En las imágenes en contenedores, la opción de registro no seguro no está configurada para la red local 10.0.0.0/8. Si usas registros privados no seguros, es posible que veas errores similares a los siguientes:

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

Para resolver este problema, realiza las siguientes acciones:

Configura DaemonSets con privilegios para modificar tu configuración de containerd

Para los clústeres estándar, prueba los siguientes pasos. Esta solución alternativa no está disponible en Autopilot porque los contenedores privilegiados son un riesgo de seguridad. Si tu entorno está expuesto a Internet, considera tu tolerancia al riesgo antes de implementar esta solución. En todos los casos, se recomienda que configures TLS para tu registro privado y uses la opción de Secret Manager en su lugar.

  1. Revisa el siguiente manifiesto:

    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

    En el campo .spec.containers.env, reemplaza el valor REGISTRY_ADDRESS de la variable ADDRESS por la dirección de tu registro HTTP local en el formato DOMAIN_NAME:PORT. Por ejemplo,

    containers:
    - name: startup-script
      ...
      env:
      - name: ADDRESS
        value: "example.com:5000"
    
  2. Implementa el DaemonSet:

    kubectl apply -f insecure-registry-ds.yaml
    

El DaemonSet agrega tu registro no seguro a la configuración de containerd en cada nodo.

containerd ignora todas las asignaciones de dispositivos para pods con privilegios

Versiones afectadas de GKE: todas

Para los Pods con privilegios, el entorno de ejecución del contenedor ignora las asignaciones de dispositivos que volumeDevices.devicePath le pasa y, en su lugar, hace que todos los dispositivos del host estén disponibles para el contenedor en /dev.

Los procesos de corrección de compatibilidad con containerd filtran los nodos cuando están bajo presión de E/S

Versiones de GKE afectadas: 1.25.0 a 1.25.15-gke.1040000, 1.26.0 a 1.26.10-gke.1030000, 1.27.0 a 1.27.6-gke.1513000 y 1.28.0 a 1.28.3-gke.1061000

Cuando un nodo de GKE está bajo presión de E/S, es posible que containerd no borre los procesos containerd-shim-runc-v2 cuando se borra un Pod, lo que genera filtraciones de procesos. Cuando se produzca una pérdida en un nodo, verás más procesos containerd-shim-runc-v2 en el nodo que la cantidad de Pods en ese nodo. También es posible que notes un aumento en el uso de memoria y CPU, junto con PID adicionales. Para obtener más detalles, consulta el problema de GitHub Corrige la corrección filtrada causada por la alta presión de E/S.

Para resolver este problema, actualiza tus nodos a las siguientes versiones o una posterior:

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

La familia de direcciones IPv6 está habilitada en pods que ejecutan containerd

Versiones afectadas de GKE: 1.18, 1.19, 1.20.0 a 1.20.9

La familia de imágenes IPv6 está habilitada para los pods que se ejecutan con Containerd. La imagen dockershim inhabilita IPv6 en todos los Pods, mientras que la imagen de containerd no. Por ejemplo, localhost se resuelve primero en la dirección IPv6 ::1. Por lo general, esto no es un problema, pero podría causar un comportamiento inesperado en ciertos casos.

Solución

A fin de resolver este problema, usa una dirección IPv4 como 127.0.0.1 de manera explícita o configura una aplicación que se ejecute en el Pod para que funcione en ambas familias de direcciones.

El aprovisionamiento automático de nodos solo aprovisiona Container-Optimized OS con los grupos de nodos de Docker

Versiones de GKE afectadas: 1.18, 1.19, 1.20.0 a 1.20.6-gke.1800

El aprovisionamiento automático de nodos permite el ajuste de escala automático de los grupos de nodos con cualquier tipo de imagen compatible, pero solo puede crear grupos de nodos nuevos por medio del tipo de imagen Container-Optimized OS con Docker.

Solución

Para resolver este problema, actualiza tus clústeres de GKE a la versión 1.20.6-gke.1800 o una posterior. En estas versiones de GKE, el tipo de imagen predeterminado se puede configurar para el clúster.

Conflicto con el rango de direcciones IP 172.17/16

Versiones afectadas de GKE: 1.18.0 a 1.18.14

El rango de direcciones IP 172.17/16 está ocupado por la interfaz docker0 en la VM de nodo con containerd habilitado. Es posible que el tráfico que se envía a ese rango o proveniente de él no se enrute de forma correcta (por ejemplo, es posible que un Pod no pueda conectarse a un host conectado a una VPN con una dirección IP dentro de 172.17/16).

No se recopilan las métricas de GPU

Versiones afectadas de GKE: 1.18.0 a 1.18.18

Las métricas de uso de GPU no se recopilan cuando se usa containerd como entorno de ejecución en las versiones de GKE anteriores a 1.18.18.

Solución

Para resolver este problema, actualiza tus clústeres a las versiones 1.18.18 o posteriores de GKE.

Las imágenes con config.mediaType configurado como application/octet-stream no se pueden usar en containerd.

Versiones afectadas de GKE: todas

Las imágenes con config.mediaType configurado como "application/octet-stream" no se pueden usar en containerd. Para obtener más información, consulta problema #4756 de GitHub. Estas imágenes no son compatibles con la especificación de Open Container Initiative y se consideran incorrectas. Estas imágenes funcionan con Docker para proporcionar retrocompatibilidad, mientras que en containerd estas imágenes no son compatibles.

Síntoma y diagnóstico

Ejemplo de error en los registros de nodos:

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"

Por lo general, el manifiesto de la imagen se puede encontrar en el registro donde se aloja. Una vez que tengas el manifiesto, verifica config.mediaType para determinar si tienes este problema:

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

Solución

Dado que la comunidad de containerd decidió no admitir esas imágenes, todas las versiones de containerd se verán afectadas y no habrá solución. La imagen del contenedor se debe volver a compilar con la versión 1.11 de Docker o una posterior, y debes asegurarte de que el campo config.mediaType no esté configurado como "application/octet-stream".

Configuración de CNI no inicializada

Versiones afectadas de GKE: todas

GKE no puede crear nodos durante una actualización, un cambio de tamaño o alguna otra acción.

Síntoma y diagnóstico

Ejemplo de error en la consola de Google Cloud:

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

Este error puede ocurrir en las siguientes situaciones:

  • Durante el arranque de nodos en archivos de registro mientras GKE instala la configuración de CNI.
  • Como estado de error de nodo en la consola de Google Cloud si un webhook personalizado que intercepta el comando del controlador DaemonSet para crear un Pod tiene errores. Esto evita que GKE cree un Pod netd o calico-node. Si los Pods netd o calico-node se iniciaron de forma correcta mientras persiste el error, comunícate con el equipo de asistencia.

Solución

Para resolver este problema, prueba con las siguientes soluciones:

  • Espera a que GKE termine de instalar la configuración de CNI.
  • Sigue estas instrucciones para quitar los webhooks mal configurados:

    1. Enumera los webhooks:

          $ kubectl get mutatingwebhookconfigurations
          $ kubectl get validatingwebhookconfigurations
      
    2. Quita los webhooks mal configurados:

          kubectl delete mutatingwebhookconfigurations WEBHOOK_NAME
          kubectl delete validatingwebhookconfigurations WEBHOOK_NAME
      

    Reemplaza WEBHOOK_NAME por el nombre del webhook mal configurado que deseas quitar.

  • Configura webhooks para ignorar los Pods del sistema.

¿Qué sigue?

Si necesitas asistencia adicional, comunícate con Atención al cliente de Cloud.