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.
Si vous avez besoin d'une aide supplémentaire, contactez Cloud Customer Care.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 d'autorisation 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.
Fédération d'identité de charge de travail pour GKE
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 :
Assurez-vous d'avoir activé l'API IAM Service Account Credentials dans le projet contenant le cluster GKE.
Vérifiez que la fédération d'identité de charge de travail pour GKE est activée sur le cluster en vérifiant qu'un pool d'identités de charge de travail est défini :
gcloud container clusters describe CLUSTER_NAME \ --format="value(workloadIdentityConfig.workloadPool)"
Remplacez
CLUSTER_NAME
par le nom de votre cluster GKE.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.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)"
Remplacez les éléments suivants :
NODEPOOL_NAME
par le nom de votre pool de nœuds.CLUSTER_NAME
par le nom de votre cluster GKE.
Assurez-vous que le compte de service Kubernetes est correctement annoté :
kubectl describe serviceaccount \ --namespace NAMESPACE KSA_NAME
Remplacez les éléments suivants :
NAMESPACE
par l'espace de noms de votre cluster GKE.KSA
par le nom de votre compte de service Kubernetes.
Le résultat attendu contient une annotation semblable à celle-ci :
iam.gke.io/gcp-service-account: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
Vérifiez 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 attendu contient une liaison semblable à celle-ci :
- members: - serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME] role: roles/iam.workloadIdentityUser
Si vous disposez d'une règle de réseau de cluster, vous devez autoriser la sortie vers
127.0.0.1/32
sur le port988
pour les clusters exécutant des versions GKE antérieures à 1.21.0-gke.1000, ou169.254.169.252/32
sur le port988
pour les clusters exécutant une version GKE 1.21.0-gke.1000 ou ultérieure. Pour les clusters exécutant GKE Dataplane V2, vous devez autoriser la sortie vers169.254.169.254/32
sur le port80
.kubectl describe networkpolicy NETWORK_POLICY_NAME
Remplacez
NETWORK_POLICY_NAME
par le nom de votre règle de réseau GKE.
Problèmes de résolution DNS
Certaines bibliothèques clientes Google Cloud sont configurées pour se connecter aux serveurs de métadonnées GKE et Compute Engine en résolvant le nom DNS metadata.google.internal
. Pour ces bibliothèques, la résolution DNS opérationnelle interne au cluster est une dépendance critique pour que vos charges de travail s'authentifient auprès des services Google Cloud.
La méthode de détection de ce problème dépend des détails de votre application déployée, y compris la configuration de sa journalisation. Recherchez les messages d'erreur qui :
- vous indiquent de configurer GOOGLE_APPLICATION_CREDENTIALS ; ou
- vous indiquent que vos requêtes adressées à un service Google Cloud ont été refusées du fait que la requête ne contienne pas d'identifiants.
Si vous rencontrez des problèmes avec la résolution DNS de metadata.google.internal
, certaines bibliothèques clientes Google Cloud peuvent être invitées à ignorer la résolution DNS en définissant la variable d'environnement GCE_METADATA_HOST
sur 169.254.169.254
:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
namespace: default
spec:
containers:
- image: debian
name: main
command: ["sleep", "infinity"]
env:
- name: GCE_METADATA_HOST
value: "169.254.169.254"
Il s'agit de l'adresse IP codée en dur sur laquelle le service de métadonnées est toujours disponible sur les plates-formes de calcul Google Cloud.
Bibliothèques Google Cloud compatibles :
- Python
- Java
- Node.js
- Golang (Notez cependant que la bibliothèque cliente Golang préfère déjà se connecter par adresse IP plutôt que par nom DNS.)
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. Les tentatives d'authentification à l'aide de la fédération d'identité de charge de travail pour GKE 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 conteneur 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 la fédération d'identité de charge de travail pour GKE en raison de l'indisponibilité du plan de contrôle
Le serveur de métadonnées ne peut pas renvoyer la fédération d'identité de charge de travail pour GKE 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.
Une entrée de journal peut ressembler à l'exemple suivant dans l'explorateur de journaux :
dial tcp 35.232.136.58:443: connect: connection refused
Ce comportement entraîne une indisponibilité de la fédération d'identité de charge de travail pour GKE.
Le plan de contrôle peut être indisponible sur les clusters zonaux pendant les opérations de maintenance du cluster, telles 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 élimine ce problème.
Échec de l'authentification de la fédération d'identité de charge de travail pour GKE dans les clusters utilisant Istio
Si le serveur de métadonnées GKE est bloqué pour une raison quelconque, la fédération d'identité de charge de travail pour GKE échoue.
Si vous utilisez Istio ou Anthos Service Mesh, ajoutez l'annotation suivante au niveau du pod à toutes les charges de travail qui utilisent la fédération d'identité de charge de travail pour GKE afin d'exclure l'adresse IP de la redirection :
traffic.sidecar.istio.io/excludeOutboundIPRanges: 169.254.169.254/32
Vous pouvez également modifier la clé global.proxy.excludeIPRanges
ConfigMap Istio.
Vous pouvez aussi ajouter l'annotation suivante au niveau du pod à toutes les charges de travail qui utilisent la fédération d'identité de charge de travail pour GKE afin de retarder le démarrage du conteneur d'application jusqu'à ce que le side-car soit prêt :
proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
Vous pouvez également modifier la clé global.proxy.holdApplicationUntilProxyStarts
ConfigMap Istio.
Plantage du pod gke-metadata-server
Le pod DaemonSet système gke-metadata-server
facilite la fédération d'identité de charge de travail pour GKE 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 :
Recherchez les pods
gke-metadata-server
qui plantent dans l'espace de nomskube-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
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
Remplacez
POD_NAME
par le nom du pod à vérifier.
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 la fédération d'identité de charge de travail pour GKE échoue avec le message d'erreur "DeployPatch failed"
GKE utilise l'agent de service Kubernetes Engine géré par Google Cloud pour faciliter la fédération d'identité de charge de travail pour GKE 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 la fédération d'identité de charge de travail pour GKE 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 :
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. Pour accorder ce rôle, suivez la procédure suivante.
Obtenez votre numéro de projet Google Cloud :
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"
Le résultat ressemble à ce qui suit :
123456789012
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 la fédération d'identité de charge de travail pour GKE.