Soluciona problemas relacionados con las cargas de trabajo y las listas de entidades permitidas de Autopilot con privilegios

Las cargas de trabajo con privilegios en los clústeres de Autopilot de Google Kubernetes Engine (GKE) deben configurarse correctamente para evitar problemas. Las configuraciones incorrectas pueden provocar errores de sincronización con las listas de entidades permitidas o hacer que se rechace la carga de trabajo. Estos problemas pueden impedir que los agentes o servicios esenciales se ejecuten con los permisos necesarios.

Usa este documento para solucionar problemas relacionados con la implementación de cargas de trabajo con privilegios en Autopilot. Encuentra orientación para resolver errores de sincronización de la lista de entidades permitidas y diagnosticar por qué se podría rechazar una carga de trabajo privilegiada.

Esta información es importante para los administradores y operadores de la plataforma, y para los equipos de seguridad que implementan cargas de trabajo con permisos elevados en clústeres de Autopilot. Para obtener más información sobre los roles comunes y las tareas de ejemplo a las que hacemos referencia en el contenido de Google Cloud , consulta Roles y tareas comunes del usuario de GKE.

Problemas de sincronización de la lista de entidades permitidas

Cuando implementas un AllowlistSynchronizer, GKE intenta instalar y sincronizar los archivos de la lista de entidades permitidas que especificas. Si falla esta sincronización, el campo status de AllowlistSynchronizer informa el error.

Obtén el estado del objeto AllowlistSynchronizer:

kubectl get allowlistsynchronizer ALLOWLIST_SYNCHRONIZER_NAME -o yaml

Reemplaza ALLOWLIST_SYNCHRONIZER_NAME por el nombre de AllowlistSynchronizer.

El resultado es similar a lo siguiente:

...
status:
  conditions:
  - type: Ready
    status: "False"
    reason: "SyncError"
    message: "some allowlists failed to sync: example-allowlist-1.yaml"
    lastTransitionTime: "2024-10-12T10:00:00Z"
    observedGeneration: 2
  managedAllowlistStatus:
    - filePath: "gs://path/to/allowlist1.yaml"
      generation: 1
      phase: Installed
      lastSuccessfulSync: "2024-10-10T10:00:00Z"
    - filePath: "gs://path/to/allowlist2.yaml"
      phase: Failed
      lastError: "Initial install failed: invalid contents"
      lastSuccessfulSync: "2024-10-08T10:00:00Z"

Los campos conditions.message y managedAllowlistStatus.lastError proporcionan información detallada sobre el error. Usa esta información para resolver el problema.

Varios AllowlistSynchronizers

En los clústeres de GKE en versiones anteriores a la 1.33.4-gke.1035000, es posible que no se instale WorkloadAllowlists si hay más de un AllowlistSynchronizer.

Para resolver el problema, usa solo un AllowlistSynchronizer que contenga varios allowlistPaths.

Como alternativa, puedes actualizar tu clúster a una versión más reciente.

Ordenamiento de contenedores de cargas de trabajo

En los clústeres de GKE en versiones anteriores a 1.34.0-gke.0000000, si una o más imágenes de contenedor de carga de trabajo coinciden con una imagen de contenedor especificada en una WorkloadAllowlist dentro del clúster, es posible que los contenedores de carga de trabajo se creen y ordenen en orden alfabético inverso.

Para resolver este problema, puedes probar las siguientes opciones:

  • Actualiza tu clúster a la versión 1.34.0-gke.0000000 o posterior.
  • Cambia el nombre de los contenedores de tu carga de trabajo para que se ordenen en el orden correcto.

Problemas de implementación de cargas de trabajo privilegiadas

Después de instalar correctamente una lista de entidades permitidas, implementa la carga de trabajo privilegiada correspondiente en tu clúster. En algunos casos, GKE podría rechazar la carga de trabajo.

Prueba las siguientes opciones de resolución:

  • Asegúrate de que la versión de GKE de tu clúster cumpla con el requisito de versión de la carga de trabajo.
  • Asegúrate de que la carga de trabajo que implementas sea aquella a la que se aplica el archivo de la lista de entidades permitidas.

Para ver por qué se rechazó una carga de trabajo privilegiada, solicita información detallada a GKE sobre los incumplimientos de la lista de entidades permitidas:

  1. Obtén una lista de las listas de entidades permitidas instaladas en el clúster:

    kubectl get workloadallowlist
    

    Busca el nombre de la lista de entidades permitidas que se debe aplicar a la carga de trabajo con privilegios.

  2. Abre el manifiesto YAML de la carga de trabajo con privilegios en un editor de texto. Si no puedes acceder a los manifiestos de YAML, por ejemplo, si el proceso de implementación de la carga de trabajo usa otras herramientas, comunícate con el proveedor de la carga de trabajo para abrir un problema. Omite los pasos restantes.

  3. Agrega la siguiente etiqueta a la sección spec.metadata.labels de la especificación del Pod de carga de trabajo con privilegios:

    labels:
      cloud.google.com/matching-allowlist: ALLOWLIST_NAME
    

    Reemplaza ALLOWLIST_NAME por el nombre de la lista de entidades permitidas que obtuviste en el paso anterior. Usa el nombre de la salida del comando kubectl get workloadallowlist, no la ruta de acceso al archivo de la lista de entidades permitidas.

  4. Guarda el manifiesto y aplica la carga de trabajo al clúster:

    kubectl apply -f WORKLOAD_MANIFEST_FILE
    

    Reemplaza WORKLOAD_MANIFEST_FILE por la ruta de acceso al archivo de manifiesto.

    El resultado proporciona información detallada sobre qué campos de la carga de trabajo no coincidieron con la lista de entidades permitidas especificada, como en el siguiente ejemplo:

    Error from server (GKE Warden constraints violations): error when creating "STDIN": admission webhook "warden-validating.common-webhooks.networking.gke.io" denied the request:
    
    ===========================================================================
    Workload Mismatches Found for Allowlist (example-allowlist-1):
    ===========================================================================
    HostNetwork Mismatch: Workload=true, Allowlist=false
    HostPID Mismatch: Workload=true, Allowlist=false
    Volume[0]: data
             - data not found in allowlist. Verify volume with matching name exists in allowlist.
    Container[0]:
    - Envs Mismatch:
            - env[0]: 'ENV_VAR1' has no matching string or regex pattern in allowlist.
            - env[1]: 'ENV_VAR2' has no matching string or regex pattern in allowlist.
    - Image Mismatch: Workload=k8s.gcr.io/diff/image, Allowlist=k8s.gcr.io/pause2. Verify that image string or regex match.
    - SecurityContext:
            - Capabilities.Add Mismatch: the following added capabilities are not permitted by the allowlist: [SYS_ADMIN SYS_PTRACE]
    - VolumeMount[0]: data
            - data not found in allowlist. Verify volumeMount with matching name exists in allowlist.
    

    En este ejemplo, se producen los siguientes incumplimientos:

    • La carga de trabajo especifica hostNetwork: true, pero la lista de entidades permitidas no lo hace.hostNetwork: true
    • La carga de trabajo especifica hostPID: true, pero la lista de entidades permitidas no lo hace.hostPID: true
    • La carga de trabajo especifica un volumen llamado data, pero la lista de entidades permitidas no especifica un volumen llamado data.
    • El contenedor especifica variables de entorno llamadas ENV_VAR1 y ENV_VAR2, pero la lista de entidades permitidas no las especifica.
    • El contenedor especifica la imagen k8s.gcr.io/diff/image, pero la lista de entidades permitidas especifica k8s.gcr.io/pause2.
    • El contenedor agrega las capacidades SYS_ADMIN y SYS_PTRACE, pero la lista de entidades permitidas no permite agregar estas capacidades.
    • El contenedor especifica una activación de volumen llamada data, pero la lista de entidades permitidas no especifica una activación de volumen llamada data.

Si implementas una carga de trabajo que pertenece a un proveedor externo, abre un problema con ese proveedor para resolver los incumplimientos. Proporciona el resultado del paso anterior en el problema.

Versión de GKE incompatible

GKE podría rechazar una carga de trabajo si la lista de entidades permitidas especifica una versión mínima de GKE que sea posterior a la versión de GKE del clúster.

  1. Comprueba si la lista de entidades permitidas especifica una versión mínima de GKE:

    kubectl describe workloadallowlist ALLOWLIST_NAME | grep "minGKEVersion"
    

    Reemplaza ALLOWLIST_NAME por el nombre de la lista de entidades permitidas.

    Si el resultado está vacío, la lista de entidades permitidas no especifica una versión mínima de GKE. Omite esta sección. Si el resultado es un valor, la lista de entidades permitidas especifica una versión mínima de GKE.

  2. Verifica la versión de GKE del clúster:

    gcloud container clusters describe CLUSTER_NAME \
        --location=CLUSTER_LOCATION \
        --format="value(currentMasterVersion)"
    

    Reemplaza lo siguiente:

    • CLUSTER_NAME: el nombre del clúster
    • CLUSTER_LOCATION: Es la Google Cloud ubicación del clúster.

    El resultado es similar a lo siguiente:

    1.32.3-gke.1006000
    
  3. Si la versión de GKE del clúster es anterior a la versión mínima de GKE de la lista de entidades permitidas, actualiza el clúster a la versión mínima de GKE de la lista de entidades permitidas o a una versión posterior. Para obtener más información, consulta Actualiza el clúster.

Una vez completada la actualización, intenta implementar la carga de trabajo en el clúster.

No coinciden las cadenas

Los campos específicos de la especificación WorkloadAllowlist deben coincidir exactamente con los campos correspondientes de la especificación de la carga de trabajo.

  1. Abre la página de referencia de la definición de recurso personalizado (CRD) WorkloadAllowlist.
  2. Para cada campo de la especificación de WorkloadAllowlist, verifica si el CRD requiere una coincidencia exacta de la cadena.
  3. Para cada campo que requiere una coincidencia exacta de la cadena, verifica si el valor en la especificación de WorkloadAllowlist coincide con el valor correspondiente en la especificación de la carga de trabajo.

    Por ejemplo, cada comando que ejecuta un contenedor debe coincidir exactamente con un comando de la lista de entidades permitidas. Cualquier desviación del comando exacto generará un rechazo.

Si hay una discrepancia, actualiza la especificación de WorkloadAllowlist para que coincida con la especificación de la carga de trabajo.

Discrepancias en las expresiones regulares

Los campos específicos de la especificación WorkloadAllowlist admiten la coincidencia de expresiones regulares.

  1. En la especificación de WorkloadAllowlist, busca los campos que especifican expresiones regulares.
  2. Asegúrate de que la sintaxis de la expresión regular sea correcta. El CRD de WorkloadAllowlist admite la sintaxis de expresión regular de RE2 de Google. Valida que tus expresiones tengan las siguientes propiedades:

    • La expresión regular comienza con el carácter ^ y termina con el carácter $. Por ejemplo, ^example-auth\.google\.com\/go_[a-z0-9]+\/google\/path$.
    • Todos los caracteres especiales se escapan con el carácter de escape \. Busca caracteres \ adicionales o faltantes.
    • Las rutas de acceso de imágenes en la lista de entidades permitidas no incluyen etiquetas ni resúmenes. Por ejemplo, usa k8s.gcr.io/pause en lugar de k8s.gcr.io/pause:3.1 o k8s.gcr.io/pause@sha256:1234567890.

Después de corregir cualquier problema de expresión regular, intenta implementar tu carga de trabajo en el clúster.

Cómo escapar caracteres en comandos y argumentos

GKE no puede hacer coincidir comandos y argumentos si no escapas los caracteres especiales. Los requisitos para escapar caracteres dependen de cómo apliques la lista de entidades permitidas. Por ejemplo, aplicar una lista de entidades permitidas como un archivo YAML o JSON tiene requisitos de escape diferentes a los de crear una especificación de lista de entidades permitidas con una herramienta de línea de comandos. En esta sección, se describen los requisitos de escape para los archivos YAML.

Incluye un carácter de escape para cada carácter especial en los campos commands y args de la especificación WorkloadAllowlist, incluso si no usas una expresión regular. Para escapar caracteres especiales, usa el carácter \, como en los siguientes ejemplos:

  • Comando: kubectl describe \$\{POD_NAME\}
  • Argumento: hostname \$NODE_NAME; dcgm-exporter --remote-hostengine-info \$\(NODE_IP\) --collectors /etc/dcgm-exporter/counters.csv

Interferencia de webhook con cargas de trabajo en una lista de entidades permitidas

En algunos casos, incluso si una carga de trabajo está configurada correctamente para coincidir con una lista de entidades permitidas, GKE podría rechazarla. Esta situación puede ocurrir si otro controlador de admisión (webhook) de tu clúster modifica los Pods creados por el controlador de cargas de trabajo después de que se hayan permitido en la lista de entidades permitidas. Estas modificaciones pueden hacer que la especificación del Pod ya no coincida con la lista de entidades permitidas, lo que provocará el rechazo por parte del webhook de admisión de GKE Warden.

Este problema es común con los agentes de seguridad y supervisión de terceros que insertan contenedores sidecar o variables de entorno en los Pods.

El síntoma más común es que el controlador de carga de trabajo (como un DaemonSet o Deployment) se crea correctamente, pero no puede crear ningún Pod. Cuando inspecciones los eventos del controlador, verás mensajes que indican que el webhook de admisión rechazó los Pods.

  1. Sigue los pasos de la sección Problemas de implementación de cargas de trabajo con privilegios para agregar la etiqueta cloud.google.com/matching-allowlist a tu carga de trabajo.
  2. Copia el spec.template del manifiesto YAML de tu carga de trabajo.
  3. Crea un manifiesto de Pod nuevo y pega la especificación copiada en el campo spec.
  4. Establece los campos apiVersion, kind y metadata.name en el manifiesto del Pod:

    apiVersion: v1
    kind: Pod
    metadata:
      name: POD_NAME
      labels:
        cloud.google.com/matching-allowlist: ALLOWLIST_NAME
    spec:
      # Paste the content of spec.template here
    

    Reemplaza lo siguiente:

    • POD_NAME: Es el nombre del Pod de prueba.
    • ALLOWLIST_NAME: Es el nombre de la lista de entidades permitidas.
  5. Aplica el manifiesto del Pod:

    kubectl apply -f YOUR_POD_MANIFEST_FILE
    

    Reemplaza YOUR_POD_MANIFEST_FILE por la ruta de acceso a tu archivo de manifiesto del Pod.

  6. Inspecciona el resultado del paso anterior. Si ves campos inesperados en la sección "Workload Mismatches", como variables de entorno adicionales (por ejemplo, DD_AGENT_HOST), contenedores o volúmenes, es un indicador claro de que otro webhook está modificando tus Pods.

Para resolver este problema, debes configurar el webhook en conflicto para que no modifique los Pods de tu carga de trabajo incluida en la lista de entidades permitidas. Por lo general, esto se hace agregando una etiqueta o anotación a la carga de trabajo o a su espacio de nombres para indicarle al webhook que se debe excluir de la mutación. Por ejemplo, con Datadog, agregarías la etiqueta admission.datadoghq.com/enabled: "false" al espacio de nombres de tu carga de trabajo.

Consulta la documentación del software de terceros específico que usas para saber cómo excluir cargas de trabajo de su controlador de admisión.

Si evitas que el otro webhook modifique los Pods, puedes ayudar a garantizar que sigan coincidiendo con la lista de entidades permitidas y que se implementen correctamente en tu clúster de Autopilot.

Errores y solicitudes de funciones para cargas de trabajo con privilegios y listas de entidades permitidas

Si ejecutas una carga de trabajo con privilegios proporcionada por un socio de GKE o un proveedor externo, ese proveedor es responsable de crear, desarrollar y mantener sus cargas de trabajo con privilegios y listas de entidades permitidas. Si encuentras un error o tienes una solicitud de función para una carga de trabajo privilegiada o una lista de entidades permitidas de un socio o tercero, comunícate con el proveedor.

¿Qué sigue?