Résoudre les problèmes de sécurité des clusters


Cette page explique comment résoudre les problèmes liés aux configurations de sécurité dans vos clusters Google Kubernetes Engine (GKE) Autopilot et Standard.

RBAC et IAM

Les comptes IAM authentifiés ne parviennent pas à effectuer des actions dans le cluster

Le problème suivant se produit lorsque vous essayez d'effectuer une action dans le cluster, mais que GKE ne trouve pas de stratégie RBAC autorisant cette action. GKE tente de trouver une stratégie IAM qui accorde la même autorisation. Si cette opération échoue, un message d'erreur semblable à celui-ci s'affiche:

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

Pour résoudre ce problème, utilisez une stratégie RBAC afin d'accorder les autorisations pour l'action tentée. Par exemple, pour résoudre le problème dans l'exemple précédent, attribuez un rôle disposant de l'autorisation list sur les objets roles de l'espace de noms kube-system. Pour obtenir des instructions, consultez la page Autoriser les actions dans les clusters à l'aide du contrôle des accès basé sur les rôles.

Workload Identity

Un pod ne peut pas s'authentifier auprès de Google Cloud

Si votre application ne peut pas s'authentifier auprès de Google Cloud, assurez-vous que les paramètres suivants sont correctement configurés :

  1. Assurez-vous d'avoir activé l'API des identifiants de compte de service IAM dans le projet contenant le cluster GKE.

    Activer l'API des identifiants IAM

  2. Vérifiez que Workload Identity est activé sur le cluster en vérifiant qu'il possède un pool d'identités de charge de travail défini :

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

    Si vous n'avez pas encore spécifié une zone ou une région par défaut pour gcloud, vous devrez peut-être également spécifier une option --region ou --zone lors de l'exécution de cette commande.

  3. Assurez-vous que le serveur de métadonnées GKE est configuré sur le pool de nœuds dans lequel votre application s'exécute :

    gcloud container node-pools describe NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --format="value(config.workloadMetadataConfig.mode)"
    
  4. Assurez-vous que le compte de service Kubernetes est correctement annoté :

    kubectl describe serviceaccount \
        --namespace NAMESPACE KSA_NAME
    

    Le résultat contient une annotation semblable à celle-ci :

    iam.gke.io/gcp-service-account: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
    
  5. Assurez-vous que le compte de service IAM est correctement configuré.

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

    Le résultat contient une liaison semblable à celle-ci :

    - members:
      - serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]
      role: roles/iam.workloadIdentityUser
    
  6. Si vous disposez d'une règle de réseau de cluster, assurez-vous d'avoir autorisé la sortie vers 127.0.0.1/32 sur le port 988 pour les clusters exécutant des versions GKE antérieures à 1.21.0-gke.1000, ou 169.254.169.252/32 sur le port 988 pour les clusters exécutant une version GKE 1.21.0-gke.1000 ou ultérieure. Pour les clusters exécutant GKE Dataplane V2, assurez-vous d'avoir autorisé la sortie vers 169.254.169.254/32 sur le port 80.

    kubectl describe networkpolicy NETWORK_POLICY_NAME
    

Erreurs d'expiration au démarrage du pod

Le serveur de métadonnées GKE a besoin de quelques secondes pour pouvoir commencer à accepter des requêtes sur un nouveau pod. Par conséquent, les tentatives d'authentification à l'aide de Workload Identity dans les premières secondes de la vie d'un pod peuvent échouer pour les applications et les bibliothèques clientes Google Cloud configurées avec un délai avant expiration court.

Si vous rencontrez des erreurs d'expiration de délai, procédez comme suit :

  • Mettez à jour les bibliothèques clientes Google Cloud utilisées par vos charges de travail.
  • Modifiez le code d'application pendant quelques secondes, puis réessayez.
  • Déployez un initContainer qui attend que le serveur de métadonnées GKE soit prêt avant d'exécuter le conteneur principal du pod.

    Par exemple, le fichier manifeste suivant concerne un pod avec un conteneur 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
    

Échec de Workload Identity en raison de l'indisponibilité du plan de contrôle

Le serveur de métadonnées ne peut pas renvoyer l'identité Workload Identity lorsque le plan de contrôle du cluster n'est pas disponible. Les appels au serveur de métadonnées renvoient le code d'état 500.

L'entrée de journal peut ressembler à l'exemple suivant dans l'explorateur de journaux :

dial tcp 35.232.136.58:443: connect: connection refused

Cela entraînera une indisponibilité attendue de Workload Identity.

Le plan de contrôle peut être indisponible sur les clusters zonaux pendant les opérations de maintenance du cluster, telle que le renouvellement des adresses IP, la mise à niveau des VM du plan de contrôle, ou le redimensionnement des clusters ou des pools de nœuds. Pour en savoir plus sur la disponibilité du plan de contrôle, consultez la page Choisir un plan de contrôle régional ou zonal. Le passage à un cluster régional permet d'éliminer ce problème.

Échec de Workload Identity

Si le serveur de métadonnées GKE est bloqué pour une raison quelconque, Workload Identity échouera.

Si vous utilisez Istio, vous devez ajouter l'annotation au niveau de l'application suivante à toutes les charges de travail utilisant Workload Identity :

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

Vous pouvez également modifier la clé global.proxy.excludeIPRanges ConfigMap Istio.

Plantage du pod gke-metadata-server

Le pod DaemonSet système gke-metadata-server facilite l'utilisation de Workload Identity sur vos nœuds. Le pod utilise des ressources de mémoire proportionnellement au nombre de comptes de service Kubernetes dans votre cluster.

Le problème suivant se produit lorsque l'utilisation des ressources du pod gke-metadata-server dépasse ses limites. Le kubelet supprime le pod avec une erreur de mémoire insuffisante. Vous pouvez rencontrer ce problème si votre cluster possède plus de 3 000 comptes de service Kubernetes.

Pour identifier le problème, procédez comme suit :

  1. Recherchez les pods gke-metadata-server qui plantent dans l'espace de noms kube-system :

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

    Le résultat ressemble à ce qui suit :

    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. Décrivez le pod qui plante pour vérifier que la cause était une suppression avec mémoire insuffisante :

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

Pour restaurer la fonctionnalité du serveur de métadonnées GKE, réduisez le nombre de comptes de service de votre cluster à moins de 3 000.

L'activation de Workload Identity échoue avec le message d'erreur "DeployPatch failed"

GKE utilise l'agent de service Kubernetes Engine géré par Google Cloud pour faciliter l'utilisation de Workload Identity dans vos clusters. Google Cloud attribue automatiquement à cet agent de service le rôle d'agent de service Kubernetes Engine (roles/container.serviceAgent) sur votre projet lorsque vous activez l'API Google Kubernetes Engine.

Si vous essayez d'activer Workload Identity sur des clusters dans un projet où l'agent de service ne dispose pas du rôle d'agent de service Kubernetes Engine, l'opération échoue avec un message d'erreur semblable à celui-ci :

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

Essayez les solutions suivantes pour résoudre ce problème :

  1. Vérifiez si l'agent de service existe dans votre projet et s'il est configuré correctement :

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

    Remplacez PROJECT_ID par l'ID de votre projet Google Cloud.

    Si l'agent de service est correctement configuré, le résultat affiche l'identité complète de l'agent de service :

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

    Si le résultat n'affiche pas l'agent de service, vous devez lui attribuer le rôle d'agent de service Kubernetes Engine.

  2. Obtenez votre numéro de projet Google Cloud :

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

    Le résultat ressemble à ce qui suit :

    123456789012
    
  3. Attribuez le rôle à l'agent de service :

    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
    

    Remplacez PROJECT_NUMBER par votre numéro de projet Google Cloud.

Essayez d'activer à nouveau Workload Identity.