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

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 fallas 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 listas de entidades permitidas y diagnosticar por qué se podría rechazar una carga de trabajo con privilegios.

Esta información es importante para los administradores y operadores de la plataforma, y 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 Google Cloud contenido de, consulta Roles y tareas comunes del usuario de GKE tasks.

Problemas de sincronización de listas 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 del 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 del AllowlistSynchronizer.

El resultado es similar a este:

...
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 presente.

Para resolver el problema, usa solo un AllowlistSynchronizer que contenga varias 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 la 1.34.0-gke.0000000, si una o más imágenes de contenedor de cargas de trabajo coinciden con una imagen de contenedor que se especifica en una WorkloadAllowlist dentro del clúster, es posible que los contenedores de cargas 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 con privilegios

Después de instalar correctamente una lista de entidades permitidas, implementas la carga de trabajo con privilegios correspondiente en tu clúster. En algunos casos, es posible que GKE rechace 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 la carga de trabajo a la que se aplica el archivo de la lista de entidades permitidas.

Para ver por qué se rechazó una carga de trabajo con privilegios, solicita información detallada de GKE sobre las infracciones 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 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 la 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 del resultado 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 las siguientes infracciones:

    • La carga de trabajo especifica hostNetwork: true, pero la lista de entidades permitidas no especifica hostNetwork: true.
    • La carga de trabajo especifica hostPID: true, pero la lista de entidades permitidas no especifica 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 especifica estas variables de entorno.
    • 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 un montaje de volumen llamado data, pero la lista de entidades permitidas no especifica un montaje de volumen llamado data.

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

Versión de GKE incompatible

Es posible que GKE rechace una carga de trabajo si la lista de entidades permitidas especifica una versión mínima de GKE que es posterior a la versión de GKE del clúster.

  1. Verifica 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: la Google Cloud ubicación del clúster

    El resultado es similar a este:

    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 una 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.

Incoincidencias de cadenas

Los campos específicos de la especificación de WorkloadAllowlist deben ser coincidencias exactas de cadenas de los campos correspondientes en la especificación de la carga de trabajo.

  1. Abre la página de referencia de la CustomResourceDefinition (CRD) de WorkloadAllowlist.
  2. Para cada campo de la especificación de WorkloadAllowlist, verifica si la CRD requiere una coincidencia exacta de cadenas.
  3. Para cada campo que requiera una coincidencia exacta de cadenas, verifica si el valor de 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 genera un rechazo.

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

Incoincidencias de expresiones regulares

Los campos específicos de la especificación de 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. La CRD de WorkloadAllowlist admite la sintaxis de expresiones regulares 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$.
    • Cada carácter especial se escapa 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 la carga de trabajo en el clúster.

Escapa 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 diferentes requisitos de escape que 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 archivos YAML.

Escapa cada carácter especial en los campos commands y args de la especificación de 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 que coincida con una lista de entidades permitidas, es posible que GKE la rechace. Esta situación puede ocurrir si otro controlador de admisión (webhook) de tu clúster modifica los Pods creados por el controlador de la carga de trabajo después de que la lista de entidades permitidas los haya permitido. Estas modificaciones pueden hacer que la especificación del Pod ya no coincida con la lista de entidades permitidas, lo que provoca 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 la carga de trabajo (como un DaemonSet o una 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 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: El nombre de tu Pod de prueba.
    • ALLOWLIST_NAME: 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 al 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 fuerte indicio de que otro webhook está modificando tus Pods.

Para resolver este problema, debes configurar el webhook en conflicto para excluirlo de la modificación de los Pods de tu carga de trabajo 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 externo específico que usas para obtener información sobre cómo excluir cargas de trabajo de su controlador de admisión.

Si evitas que el otro webhook modifique los Pods, puedes asegurarte de que sigan coincidiendo con la lista de entidades permitidas y 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 que proporciona 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 o una lista de entidades permitidas con privilegios de un socio o de terceros, comunícate con el proveedor.

¿Qué sigue?