Soluciona problemas de seguridad de clústeres


En esta página, se muestra cómo resolver problemas relacionados con las configuraciones de seguridad en los clústeres de Google Kubernetes Engine (GKE) Autopilot y Standard.

RBAC y IAM

Las cuentas de IAM autenticadas no pueden realizar acciones en el clúster

El siguiente problema ocurre cuando intentas realizar una acción en el clúster, pero GKE no puede encontrar una política de RBAC que autorice la acción. GKE intenta encontrar una política de IAM que otorgue el mismo permiso. Si eso falla, verás un mensaje de error similar al siguiente:

Error from server (Forbidden): roles.rbac.authorization.k8s.io is forbidden:
User "example-account@example-project.iam.gserviceaccount.com" cannot list resource "roles" in
API group "rbac.authorization.k8s.io" in the namespace "kube-system": requires
one of ["container.roles.list"] permission(s).

Para resolver este problema, usa una política de RBAC para otorgar los permisos de la acción que se intentó. Por ejemplo, para resolver el problema en la muestra anterior, otorga un rol que tenga el permiso list en los objetos roles del espacio de nombres kube-system. Para obtener instrucciones, consulta Autoriza acciones en clústeres mediante el control de acceso basado en roles.

Workload Identity

El Pod no se puede autenticar en Google Cloud

Si la aplicación no puede autenticarse en Google Cloud, asegúrate de que las siguientes opciones estén configuradas de forma correcta:

  1. Asegúrate de tener habilitada la API de credenciales de la cuenta de servicio de IAM en el proyecto que contiene el clúster de GKE.

    Habilitar la API de credenciales IAM

  2. Asegúrate de que Workload Identity esté habilitado en el clúster mediante la verificación de que tiene un grupo de identidades de cargas de trabajo configurado:

    gcloud container clusters describe CLUSTER_NAME \
        --format="value(workloadIdentityConfig.workloadPool)"
    

    Si aún no especificaste una zona o región predeterminada para gcloud, es posible que también debas especificar una marca --region o --zone cuando ejecutes este comando.

  3. Asegúrate de que el servidor de metadatos de GKE esté configurado en el grupo de nodos en el que se ejecuta la aplicación:

    gcloud container node-pools describe NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --format="value(config.workloadMetadataConfig.mode)"
    
  4. Asegúrate de que la cuenta de servicio de Kubernetes esté anotada de forma correcta:

    kubectl describe serviceaccount \
        --namespace NAMESPACE KSA_NAME
    

    El resultado contiene una anotación similar a la siguiente:

    iam.gke.io/gcp-service-account: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
    
  5. Asegúrate de que la cuenta de servicio de IAM esté configurada de forma correcta

    gcloud iam service-accounts get-iam-policy \
        GSA_NAME@GSA_PROJECT.iam.gserviceaccount.com
    

    El resultado contiene una vinculación similar a la siguiente:

    - members:
      - serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]
      role: roles/iam.workloadIdentityUser
    
  6. Si tienes una política de red del clúster, asegúrate de que permitiste la salida a 127.0.0.1/32 en el puerto 988 para los clústeres que ejecutan versiones de GKE anteriores a 1.21.0-gke.1000, o a 169.254.169.252/32 en el puerto 988 para clústeres que ejecutan la versión 1.21.0-gke.1000 de GKE y versiones posteriores. Para los clústeres que ejecutan GKE Dataplane V2, asegúrate de que permitiste la salida a 169.254.169.254/32 en el puerto 80.

    kubectl describe networkpolicy NETWORK_POLICY_NAME
    

Errores de tiempo de espera en el inicio del Pod

El servidor de metadatos de GKE necesita unos segundos antes de poder comenzar a aceptar solicitudes en un pod nuevo. Por lo tanto, los intentos de autenticarse con Workload Identity en los primeros segundos de la vida del Pod pueden fallar para aplicaciones y bibliotecas cliente de Google Cloud configuradas con un tiempo de espera breve.

Si encuentras errores de tiempo de espera, intenta lo siguiente:

  • Actualiza las bibliotecas cliente de Google Cloud que usan tus cargas de trabajo.
  • Cambia el código de la aplicación para que espere unos segundos y vuelve a intentarlo.
  • Implementa un initContainer que espere hasta que el servidor de metadatos de GKE esté listo antes de ejecutar el contenedor principal del Pod.

    Por ejemplo, el siguiente manifiesto es para un pod con un initContainer:

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-with-initcontainer
    spec:
      serviceAccountName: KSA_NAME
      initContainers:
      - image:  gcr.io/google.com/cloudsdktool/cloud-sdk:alpine
        name: workload-identity-initcontainer
        command:
        - '/bin/bash'
        - '-c'
        - |
          curl -sS -H 'Metadata-Flavor: Google' 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token' --retry 30 --retry-connrefused --retry-max-time 60 --connect-timeout 3 --fail --retry-all-errors > /dev/null && exit 0 || echo 'Retry limit exceeded. Failed to wait for metadata server to be available. Check if the gke-metadata-server Pod in the kube-system namespace is healthy.' >&2; exit 1
      containers:
      - image: gcr.io/your-project/your-image
        name: your-main-application-container
    

Workload Identity falla debido a la falta de disponibilidad del plano de control

El servidor de metadatos no puede mostrar Workload Identity cuando el plano de control del clúster no está disponible. Las llamadas al servidor de metadatos muestran el código de estado 500.

La entrada de registro puede ser similar a la siguiente en el Explorador de registros:

dial tcp 35.232.136.58:443: connect: connection refused

Esto generará una falta de disponibilidad esperada de Workload Identity.

Es posible que el plano de control no esté disponible en clústeres zonales durante el mantenimiento de los clústeres, como la rotación de las IP, la actualización de las VM del plano de control o el cambio de tamaño de clústeres o grupos de nodos. Consulta Elige un plano de control regional o zonal para obtener información sobre la disponibilidad del plano de control. Cambiar al clúster regional elimina este problema.

Workload Identity falla

Si el servidor de metadatos de GKE se bloquea por algún motivo, Workload Identity fallará.

Si usas Istio, debes agregar la siguiente anotación a nivel de la aplicación a todas las cargas de trabajo que usan Workload Identity:

"traffic.sidecar.istio.io/excludeOutboundIPRanges=169.254.169.254/32"

Como alternativa, puedes cambiar la clave global.proxy.excludeIPRanges de ConfigMap de Istio para hacer lo mismo.

El pod gke-metadata-server falla

El pod DaemonSet del sistema gke-metadata-server facilita Workload Identity en tus nodos. El pod usa recursos de memoria proporcionales a la cantidad de cuentas de servicio de Kubernetes en tu clúster.

El siguiente problema se produce cuando el uso de recursos del pod gke-metadata-server excede sus límites. kubelet expulsa el pod con un error de memoria insuficiente. Es posible que tengas este problema si el clúster tiene más de 3,000 cuentas de servicio de Kubernetes.

Para identificar el problema, haz lo siguiente:

  1. Busca Pods de gke-metadata-server con fallas en el espacio de nombres kube-system:

    kubectl get pods -n=kube-system | grep CrashLoopBackOff
    

    El resultado es similar a este:

    NAMESPACE     NAME                        READY     STATUS             RESTARTS   AGE
    kube-system   gke-metadata-server-8sm2l   0/1       CrashLoopBackOff   194        16h
    kube-system   gke-metadata-server-hfs6l   0/1       CrashLoopBackOff   1369       111d
    kube-system   gke-metadata-server-hvtzn   0/1       CrashLoopBackOff   669        111d
    kube-system   gke-metadata-server-swhbb   0/1       CrashLoopBackOff   30         136m
    kube-system   gke-metadata-server-x4bl4   0/1       CrashLoopBackOff   7          15m
    
  2. Describe el Pod que falla para confirmar que la causa fue una expulsión de memoria insuficiente:

    kubectl describe pod POD_NAME --namespace=kube-system | grep OOMKilled
    

Para restablecer la funcionalidad en el servidor de metadatos de GKE, reduce la cantidad de cuentas de servicio en el clúster a menos de 3,000.

Workload Identity no se pudo habilitar con el mensaje de error de DeployPatch con errores

GKE usa el agente de servicio de Kubernetes Engine administrado por Google Cloud para facilitar Workload Identity en los clústeres. Google Cloud otorga de forma automática a este agente de servicio la función de agente de servicio de Kubernetes Engine (roles/container.serviceAgent) en tu proyecto cuando habilitas la API de Google Kubernetes Engine.

Si intentas habilitar Workload Identity en clústeres en un proyecto en el que el agente de servicio no tiene la función de agente de servicio de Kubernetes Engine, la operación falla con un mensaje de error similar al siguiente:

Error waiting for updating GKE cluster workload identity config: DeployPatch failed

Para resolver este problema, realiza las siguientes acciones:

  1. Comprueba si el agente de servicio existe en el proyecto y está configurado de forma correcta:

    gcloud projects get-iam-policy PROJECT_ID \
        --flatten=bindings \
        --filter=bindings.role=roles/container.serviceAgent \
        --format="value[delimiter='\\n'](bindings.members)"
    

    Reemplaza PROJECT_ID por el ID del proyecto de Google Cloud.

    Si el agente de servicio está configurado de forma correcta, el resultado muestra la identidad completa del agente de servicio:

    serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
    

    Si el resultado no muestra el agente de servicio, debes otorgarle la función de agente de servicio de Kubernetes Engine.

  2. Obtén tu número de proyecto de Google Cloud:

    gcloud projects describe PROJECT_ID \
        --format="value(projectNumber)"
    

    El resultado es similar a este:

    123456789012
    
  3. Otorga el rol al agente de servicio:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com \
        --role=roles/container.serviceAgent \
        --condition=None
    

    Reemplaza PROJECT_NUMBER por el número de proyecto de Google Cloud.

Vuelve a habilitar Workload Identity.