Découvrez les étapes de dépannage qui pourraient vous être utiles si vous rencontrez des problèmes avec Google Kubernetes Engine (GKE).
Si vous avez besoin d'aide supplémentaire, contactez l'assistance Cloud Customer Care.Déboguer les ressources Kubernetes
Si vous rencontrez un problème lié à votre cluster, reportez-vous à la section relative au dépannage des clusters dans la documentation de Kubernetes.
Si vous rencontrez un problème avec votre application, ses pods ou son objet contrôleur, reportez-vous à la section relative au dépannage des applications.
Si vous rencontrez un problème lié à la connectivité entre les VM Compute Engine qui se trouvent dans le même réseau cloud privé virtuel (VPC) ou deux réseaux VPC connectés à l'aide de l'appairage de réseaux VPC, reportez-vous à la section Dépannage de la connectivité entre les instances de machines virtuelles (VM) avec des adresses IP internes
Si vous constatez une perte de paquets lors de l'envoi de trafic depuis un cluster vers une adresse IP externe à l'aide de Cloud NAT, de clusters de VPC natif ou de l'agent de masquage d'adresses IP, consultez la section Dépannage de la perte de paquets Cloud NAT à partir d'un cluster GKE.
Résoudre les problèmes liés à la commande kubectl
La commande kubectl
est introuvable.
Installez le binaire
kubectl
en exécutant la commande suivante :gcloud components update kubectl
Répondez "Oui" lorsque le programme d'installation vous invite à modifier votre variable d'environnement
$PATH
. La modification de cette variable vous permet d'utiliser les commandeskubectl
sans avoir besoin de saisir leur chemin d'accès complet.Vous pouvez également ajouter la ligne suivante à
~/.bashrc
(ou à~/.bash_profile
sous macOS, ou dans tout fichier où votre interface système stocke les variables d'environnement) :export PATH=$PATH:/usr/local/share/google/google-cloud-sdk/bin/
Exécutez la commande suivante pour charger votre fichier
.bashrc
ou.bash_profile
mis à jour :source ~/.bashrc
Les commandes kubectl
renvoient une erreur de connexion refusée
Définissez le contexte du cluster avec la commande suivante :
gcloud container clusters get-credentials CLUSTER_NAME
Si vous ne savez pas quoi indiquer pour CLUSTER_NAME
, utilisez la commande suivante pour répertorier vos clusters :
gcloud container clusters list
La commande kubectl
expire
Après la création d'un cluster, la tentative d'exécution de la commande kubectl
sur le cluster renvoie une erreur du type Unable to connect to the server: dial
tcp IP_ADDRESS: connect: connection timed out
ou Unable to connect to the
server: dial tcp IP_ADDRESS: i/o timeout
.
Cela peut se produire lorsque kubectl
ne parvient pas à communiquer avec le plan de contrôle du cluster.
Pour résoudre ce problème, vérifiez que le contexte du cluster est bien défini:
Accédez à
$HOME/.kube/config
ou exécutez la commandekubectl config view
pour vérifier que le fichier de configuration contient le contexte du cluster et l'adresse IP externe du plan de contrôle.Définissez les identifiants du cluster:
gcloud container clusters get-credentials CLUSTER_NAME \ --location=COMPUTE_LOCATION \ --project=PROJECT_ID
Remplacez les éléments suivants :
CLUSTER_NAME
: nom du clusterCOMPUTE_LOCATION
: emplacement Compute Engine.PROJECT_ID
: ID du projet dans lequel le cluster GKE a été créé.
Si le cluster est un cluster GKE privé, assurez-vous que l'adresse IP sortante de la machine à partir de laquelle vous essayez de vous connecter est incluse dans la liste des réseaux autorisés existants. Les réseaux autorisés existants sont visibles dans la console ou au moyen de la commande suivante :
gcloud container clusters describe CLUSTER_NAME \ --location=COMPUTE_LOCATION \ --project=PROJECT_ID \ --format "flattened(masterAuthorizedNetworksConfig.cidrBlocks[])"
Si l'adresse IP sortante de la machine ne figure pas dans la liste des réseaux autorisés à partir du résultat de la commande ci-dessus, suivez les étapes décrites dans la section Impossible d'atteindre le plan de contrôle d'un cluster privé ou Utilisation de Cloud Shell pour accéder à un cluster privé si vous vous connectez depuis Cloud Shell.
Les commandes kubectl
renvoient une erreur d'échec de négociation d'une version d'API
Assurez-vous que kubectl dispose d'identifiants d'authentification :
gcloud auth application-default login
Les commandes kubectl
logs
, attach
, exec
et port-forward
cessent de répondre
Ces commandes dépendent de la capacité du plan de contrôle du cluster à communiquer avec les nœuds du cluster. Toutefois, comme le plan de contrôle ne fait pas partie du même réseau Compute Engine que les nœuds de votre cluster, nous nous appuyons sur les tunnels SSH ou proxy Konnectivity pour activer la communication sécurisée.
GKE enregistre un fichier de clé publique SSH dans les métadonnées de votre projet Compute Engine. Toutes les VM Compute Engine utilisant des images fournies par Google vérifient régulièrement les métadonnées communes de leur projet et celles de leur instance pour détecter les clés SSH à ajouter à la liste des utilisateurs autorisés de la VM. GKE ajoute également à votre réseau Compute Engine une règle de pare-feu qui autorise l'accès SSH à chaque nœud du cluster à partir de l'adresse IP du plan de contrôle.
Si l'une des commandes kubectl
ci-dessus ne s'exécute pas, il est probable que le serveur d'API n'est pas en mesure de communiquer avec les nœuds. Penchez-vous sur ces causes potentielles :
Le cluster ne comporte aucun nœud.
Si vous avez réduit à zéro le nombre de nœuds du cluster, les commandes ne fonctionnent pas.
Pour résoudre ce problème, redimensionnez le cluster afin de disposer d'au moins un nœud.
SSH
Les règles de pare-feu de votre réseau n'autorisent pas l'accès SSH depuis le plan de contrôle.
Tous les réseaux Compute Engine sont créés avec une règle de pare-feu appelée
default-allow-ssh
qui autorise l'accès SSH à partir de toutes les adresses IP (clé privée valide requise). GKE insère également une règle SSH pour chaque cluster public sous la formegke-CLUSTER_NAME-RANDOM_CHARACTERS-ssh
. Cette règle autorise l'accès SSH spécifiquement à partir de l'adresse IP du plan de contrôle vers les nœuds du cluster. Si aucune de ces règles n'existe, le plan de contrôle ne peut pas ouvrir les tunnels SSH.Pour résoudre ce problème, ajoutez à nouveau une règle de pare-feu permettant d'accéder aux VM avec le tag présent sur tous les nœuds du cluster à partir de l'adresse IP du plan de contrôle.
L'entrée des métadonnées communes de votre projet pour "ssh-keys" est saturée.
Si l'entrée des métadonnées du projet nommée "ssh-keys" est proche de la limite de taille, GKE ne peut pas ajouter sa propre clé SSH permettant l'ouverture des tunnels SSH. Vous pouvez voir les métadonnées de votre projet en exécutant la commande suivante :
gcloud compute project-info describe [--project=PROJECT_ID]
Ensuite, vérifiez la longueur de la liste des clés SSH.
Pour résoudre ce problème, supprimez des clés SSH dont vous n'avez plus besoin.
Vous avez défini un champ de métadonnées avec la clé "ssh-keys" sur les VM du cluster.
L'agent de nœud sur les VM utilise préférentiellement les clés SSH propres à une instance plutôt que celles définies à l'échelle du projet. Par conséquent, si vous avez défini des clés SSH spécifiquement sur les nœuds du cluster, la clé SSH du plan de contrôle dans les métadonnées du projet n'est pas respectée par les nœuds. Pour effectuer une vérification, exécutez
gcloud compute instances describe VM_NAME
et recherchez un champssh-keys
dans les métadonnées.Pour résoudre ce problème, supprimez les clés SSH d'instance des métadonnées de l'instance.
Proxy Konnectivity
Déterminez si votre cluster utilise le proxy Konnectivity en vérifiant le déploiement système suivant:
kubectl get deployments konnectivity-agent --namespace kube-system
Les règles de pare-feu de votre réseau n'autorisent pas l'agent Konnectivity à accéder au plan de contrôle.
Lors de la création du cluster, les pods de l'agent Konnectivity établissent et maintiennent une connexion au plan de contrôle sur le port
8132
. Lorsque l'une des commandeskubectl
est exécutée, le serveur d'API utilise cette connexion pour communiquer avec le cluster.Si les règles de pare-feu de votre réseau contiennent une ou plusieurs règles de refus du trafic sortant, l'agent peut empêcher la connexion. Vous devez autoriser le trafic de sortie vers le plan de contrôle du cluster sur le port 8132. (Par exemple, le serveur d'API utilise 443.)
Notez que ces fonctionnalités ne sont pas requises au fonctionnement correct du cluster. Si vous préférez empêcher tout accès extérieur au réseau de votre cluster, sachez que ces fonctionnalités ne sont pas opérationnelles.
Résoudre les problèmes liés à l'erreur 4xx
Erreurs d'authentification et d'autorisation lors de la connexion aux clusters GKE
Ce problème peut se produire lorsque vous essayez d'exécuter une commande kubectl
dans votre cluster GKE à partir d'un environnement local. La commande échoue et affiche un message d'erreur, généralement avec le code d'état HTTP 401 (Opération non autorisée).
La cause de ce problème peut être l'une des suivantes:
- Le plug-in d'authentification
gke-gcloud-auth-plugin
n'est pas correctement installé ou configuré. - Vous ne disposez pas des autorisations nécessaires pour vous connecter au serveur d'API du cluster et exécuter des commandes
kubectl
.
Pour diagnostiquer la cause, procédez comme suit:
Connectez-vous au cluster à l'aide de curl
.
L'utilisation de curl
contourne la CLI kubectl
et le plug-in gke-gcloud-auth-plugin
.
Définissez les variables d'environnement :
APISERVER=https://$(gcloud container clusters describe CLUSTER_NAME --location=COMPUTE_LOCATION --format "value(endpoint)") TOKEN=$(gcloud auth print-access-token)
Vérifiez que votre jeton d'accès est valide:
curl https://oauth2.googleapis.com/tokeninfo?access_token=$TOKEN
Vérifiez que vous pouvez vous connecter au point de terminaison de l'API principal sur le serveur d'API:
gcloud container clusters describe CLUSTER_NAME --location=COMPUTE_LOCATION --format "value(masterAuth.clusterCaCertificate)" | base64 -d > /tmp/ca.crt curl -s -X GET "${APISERVER}/api/v1/namespaces" --header "Authorization: Bearer $TOKEN" --cacert /tmp/ca.crt
Si la commande curl
échoue et affiche un résultat semblable à celui-ci, vérifiez que vous disposez des autorisations appropriées pour accéder au cluster:
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {},
"status": "Failure",
"message": "Unauthorized",
"reason": "Unauthorized",
"code": 401
}
Si la commande curl
réussit, vérifiez si le plug-in est à l'origine de l'incident.
Configurer le plug-in dans kubeconfig
Les étapes suivantes permettent de configurer votre environnement local pour qu'il ignore le binaire gke-gcloud-auth-plugin
lors de l'authentification auprès du cluster. Dans les clients Kubernetes exécutant la version 1.25 ou ultérieure, le binaire gke-gcloud-auth-plugin
est obligatoire. Suivez donc ces étapes si vous souhaitez accéder à votre cluster sans avoir besoin du plug-in.
Installez la version 1.24 de la CLI
kubectl
à l'aide decurl
:curl -LO https://dl.k8s.io/release/v1.24.0/bin/linux/amd64/kubectl
Vous pouvez utiliser n'importe quelle version 1.24 de la CLI
kubectl
ou version antérieure.Ouvrez votre fichier de script de démarrage shell, tel que
.bashrc
pour l'interface système Bash, dans un éditeur de texte:vi ~/.bashrc
Ajoutez la ligne suivante au fichier et enregistrez-le:
export USE_GKE_GCLOUD_AUTH_PLUGIN=False
Exécutez le script de démarrage:
source ~/.bashrc
Obtenez les identifiants de votre cluster, qui configure votre fichier
.kube/config
:gcloud container clusters get-credentials CLUSTER_NAME \ --location=COMPUTE_LOCATION
Remplacez les éléments suivants :
CLUSTER_NAME
: nom du cluster.COMPUTE_LOCATION
: emplacement Compute Engine.
Exécutez une commande
kubectl
:kubectl cluster-info
Si vous obtenez une erreur 401 ou une erreur d'autorisation similaire, assurez-vous de disposer des autorisations appropriées pour effectuer l'opération.
Erreur 400: le pool de nœuds nécessite la recréation
Le problème suivant se produit lorsque vous essayez d'effectuer une action qui recrée votre plan de contrôle et vos nœuds, par exemple lorsque vous effectuez une rotation des identifiants en cours.
L'opération échoue, car GKE n'a pas recréé un ou plusieurs pools de nœuds dans votre cluster. Sur le backend, les pools de nœuds sont marqués pour recréation, mais l'opération de recréation réelle peut prendre un certain temps.
Le message d'erreur ressemble à ceci :
ERROR: (gcloud.container.clusters.update) ResponseError: code=400, message=Node pool "test-pool-1" requires recreation.
Pour résoudre ce problème, effectuez l'une des opérations suivantes :
- Attendez que la recréation ait lieu. Cette opération peut prendre plusieurs heures, jours ou semaines, en fonction de facteurs tels que les intervalles de maintenance et les exclusions existants.
Démarrez manuellement une recréation des pools de nœuds concernés en démarrant une mise à niveau de version vers la même version que le plan de contrôle. Pour lancer une recréation, exécutez la commande suivante:
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=POOL_NAME
Une fois la mise à niveau terminée, relancez l'opération.
Erreur 403: autorisations insuffisantes
L'erreur suivante se produit lorsque vous essayez de vous connecter à un cluster GKE à l'aide de gcloud container clusters get-credentials
, mais que le compte n'est pas autorisé à accéder au serveur d'API Kubernetes.
ERROR: (gcloud.container.clusters.get-credentials) ResponseError: code=403, message=Required "container.clusters.get" permission(s) for "projects/<your-project>/locations/<region>/clusters/<your-cluster>".
Pour résoudre ce problème, procédez comme suit :
Identifiez le compte présentant le problème d'accès:
gcloud auth list
Accordez l'accès requis au compte en suivant les instructions de la section S'authentifier auprès du serveur d'API Kubernetes.
Erreur 404 : ressource introuvable lors de l'appel des commandes gcloud container
Ré-authentifiez-vous sur Google Cloud CLI:
gcloud auth login
Erreur 400/403 : le compte n'est pas autorisé à apporter des modifications
Votre compte de service Compute Engine par défaut, l'agent de service des API Google ou le compte de service associé à GKE a été supprimé ou modifié manuellement.
Lorsque vous activez l'API Compute Engine ou Kubernetes Engine, Google Cloud crée les comptes de service et les agents suivants:
- Compte de service Compute Engine par défaut : dispose de droits de modification sur votre projet.
- Agent de service des API Google avec des autorisations de modification sur votre projet.
- Compte de service Google Kubernetes Engine avec le rôle Agent de service Kubernetes Engine sur votre projet.
Si, à un moment donné, vous modifiez ces autorisations, supprimez les liaisons de rôles sur le projet, supprimez entièrement le compte de service ou désactivez l'API, alors la création du cluster et toutes les fonctionnalités de gestion échouent.
Le nom de votre compte de service Google Kubernetes Engine se présente comme suit, où PROJECT_NUMBER
est votre numéro de projet :
service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
La commande suivante permet de vérifier que le compte de service Google Kubernetes Engine dispose du rôle Agent de service Kubernetes Engine sur le projet:
gcloud projects get-iam-policy PROJECT_ID
Remplacez PROJECT_ID
par l'ID du projet.
Pour résoudre le problème, si vous avez supprimé le rôle Agent de service Kubernetes Engine de votre compte de service Google Kubernetes Engine, ajoutez-le à nouveau. Sinon, vous pouvez réactiver l'API Kubernetes Engine afin de restaurer correctement vos comptes de service et vos autorisations.
Console
Accédez à la page API et services de la console Google Cloud.
Sélectionnez votre projet.
Cliquez sur Activer les API et les services.
Recherchez Kubernetes, puis sélectionnez l'API dans les résultats de la recherche.
Cliquez sur Activer. Si vous avez déjà activé l'API, vous devez d'abord la désactiver, puis la réactiver. L'activation de l'API et des services associés peut prendre plusieurs minutes.
gcloud
Exécutez la commande suivante dans gcloud CLI pour rajouter le compte de service:
PROJECT_NUMBER=$(gcloud projects describe "PROJECT_ID" --format 'get(projectNumber)')
gcloud projects add-iam-policy-binding PROJECT_ID \
--member "serviceAccount:service-${PROJECT_NUMBER?}@container-engine-robot.iam.gserviceaccount.com" \
--role roles/container.serviceAgent
Résoudre les problèmes de création de clusters GKE
Erreur CONDITION_NOT_MET: la contrainte constraints/compute.vmExternalIpAccess a été enfreinte
La contrainte de règle d'administration constraints/compute.vmExternalIpAccess est configurée sur Deny All
ou pour limiter les adresses IP externes à des instances de VM spécifiques au niveau de l'organisation, du dossier ou du projet dans lequel vous essayez de créer une cluster GKE public.
Lorsque vous créez des clusters GKE publics, des adresses IP externes sont attribuées aux VM Compute Engine sous-jacentes, qui constituent les nœuds de calcul de ce cluster. Si vous configurez la contrainte de règle d'administration constraints/compute.vmExternalIpAccess sur Deny All
ou pour limiter les adresses IP externes à des instances de VM spécifiques, la règle empêche les nœuds de calcul GKE d'obtenir des adresses IP externes, ce qui entraîne l'échec de la création du cluster.
Pour trouver les journaux de l'opération de création de cluster, vous pouvez consulter les journaux d'audit des opérations de cluster GKE à l'aide de l'explorateur de journaux avec une requête de recherche semblable à la suivante:
resource.type="gke_cluster"
logName="projects/test-last-gke-sa/logs/cloudaudit.googleapis.com%2Factivity"
protoPayload.methodName="google.container.v1beta1.ClusterManager.CreateCluster"
resource.labels.cluster_name="CLUSTER_NAME"
resource.labels.project_id="PROJECT_ID"
Pour résoudre ce problème, assurez-vous que la règle en vigueur pour la contrainte constraints/compute.vmExternalIpAccess
est Allow All
sur le projet dans lequel vous essayez de créer un cluster public GKE. Pour plus d'informations sur l'utilisation de cette contrainte, consultez la page Limiter les adresses IP externes à des instances de VM spécifiques. Après avoir défini cette contrainte sur Allow All
, supprimez le cluster défaillant et créez-en un autre. Cette étape est nécessaire, car il n'est pas possible de réparer le cluster défaillant.
Résoudre les problèmes liés aux charges de travail déployées
GKE renvoie une erreur en cas de problème avec les pods d'une charge de travail.
Vous pouvez vérifier l'état d'un pod à l'aide de l'outil de ligne de commande kubectl
ou de la console Google Cloud.
kubectl
Pour afficher tous les pods exécutés dans votre cluster, utilisez la commande suivante :
kubectl get pods
Résultat :
NAME READY STATUS RESTARTS AGE
POD_NAME 0/1 CrashLoopBackOff 23 8d
Pour obtenir plus d'informations sur un pod spécifique, exécutez la commande suivante :
kubectl describe pod POD_NAME
Remplacez POD_NAME
par le nom du pod souhaité.
Console
Procédez comme suit :
Accédez à la page Charges de travail dans la console Google Cloud.
Sélectionnez la charge de travail souhaitée. L'onglet Aperçu affiche l'état de la charge de travail.
Dans la section Pods gérés, cliquez sur le message d'état d'erreur.
Les sections suivantes expliquent certaines erreurs courantes renvoyées par les charges de travail et indiquent comment les corriger.
CrashLoopBackOff
CrashLoopBackOff
indique qu'un conteneur plante de manière répétée après le redémarrage. Un conteneur peut planter pour plusieurs raisons. La consultation des journaux d'un pod peut aider à en identifier la cause.
Par défaut, les conteneurs qui ont planté redémarrent avec un délai exponentiel limité à cinq minutes. Vous pouvez modifier ce comportement en définissant la spécification de pod du déploiement de champ restartPolicy
sous spec: restartPolicy
. La valeur par défaut du champ est Always
.
Vous pouvez résoudre les erreurs CrashLoopBackOff
à l'aide de la console Google Cloud:
Accédez au playbook interactif sur le plantage en boucle des pods :
Pour
Cluster, saisissez le nom du cluster que vous souhaitez dépanner.Pour l'espace de noms
, saisissez l'espace de noms que vous souhaitez dépanner.(Facultatif) Créez une alerte pour être informé des futures erreurs de
CrashLoopBackOff
:- Dans la section Conseils d'atténuation futurs, sélectionnez Créer une alerte.
Journaux d'inspection
Vous pouvez déterminer la raison pour laquelle le conteneur de votre pod plante en utilisant l'outil de ligne de commande kubectl
ou la console Google Cloud.
kubectl
Pour afficher tous les pods exécutés dans votre cluster, utilisez la commande suivante :
kubectl get pods
Recherchez le pod avec l'erreur CrashLoopBackOff
.
Pour obtenir les journaux du pod, exécutez la commande suivante :
kubectl logs POD_NAME
Remplacez POD_NAME
par le nom du pod qui pose problème.
Vous pouvez également transmettre l'option -p
pour obtenir les journaux de l'instance précédente du conteneur d'un pod, si elle existe.
Console
Procédez comme suit :
Accédez à la page Charges de travail dans la console Google Cloud.
Sélectionnez la charge de travail souhaitée. L'onglet Aperçu affiche l'état de la charge de travail.
Dans la section Pods gérés, cliquez sur le pod qui pose problème.
Dans le menu du pod, cliquez sur l'onglet Journaux.
Vérifier le code de sortie du conteneur qui plante
Vous pouvez trouver le code de sortie en effectuant les tâches suivantes :
Exécutez la commande suivante :
kubectl describe pod POD_NAME
Remplacez
POD_NAME
par le nom du pod.Vérifiez la valeur du champ
containers: CONTAINER_NAME: last state: exit code
:- Si le code de sortie est 1, le conteneur a planté car l'application a planté.
- Si le code de sortie est 0, vérifiez la durée d'exécution de l'application.
Les conteneurs se ferment à la fin du processus principal de l'application. Si l'exécution de l'application se termine très rapidement, il arrive que le conteneur continue à redémarrer.
Se connecter à un conteneur en cours d'exécution
Ouvrez une interface système sur le pod :
kubectl exec -it POD_NAME -- /bin/bash
Si le pod comporte plusieurs conteneurs, ajoutez -c CONTAINER_NAME
.
Vous pouvez maintenant exécuter les commandes bash à partir du conteneur : vous pouvez tester le réseau, ou vérifier si vous avez accès aux fichiers ou aux bases de données qu'utilise votre application.
ImagePullBackOff et ErrImagePull
ImagePullBackOff
et ErrImagePull
indiquent que l'image utilisée par un conteneur ne peut pas être chargée à partir du registre d'images.
Vous pouvez examiner ce problème à l'aide de la console Google Cloud ou de l'outil de ligne de commande kubectl
.
kubectl
Pour obtenir plus d'informations sur l'image de conteneur d'un pod, exécutez la commande suivante :
kubectl describe pod POD_NAME
Console
Procédez comme suit :
Accédez à la page Charges de travail dans la console Google Cloud.
Sélectionnez la charge de travail souhaitée. L'onglet Aperçu affiche l'état de la charge de travail.
Dans la section Pods gérés, cliquez sur le pod qui pose problème.
Dans le menu du pod, cliquez sur l'onglet Événements.
Si l'image est introuvable
Si votre image est introuvable :
- Vérifiez que le nom de l'image est correct.
- Vérifiez que le tag de l'image est correct. (Essayez
:latest
ou aucun tag pour extraire la dernière image). - Si le chemin d'accès au registre de l'image est complet, vérifiez qu'il existe dans le registre Docker que vous utilisez. Si vous ne fournissez que le nom de l'image, vérifiez le registre Docker Hub.
Essayez d'extraire l'image Docker manuellement :
Connectez-vous en SSH sur le nœud :
Par exemple, pour vous connecter en SSH à une VM:
gcloud compute ssh VM_NAME --zone=ZONE_NAME
Remplacez les éléments suivants :
VM_NAME
: nom de la VM.ZONE_NAME
: une zone Compute Engine.
Exécutez
docker-credential-gcr configure-docker
. Cette commande génère un fichier de configuration dans/home/[USER]/.docker/config.json
. Assurez-vous que ce fichier inclut le registre de l'image dans le champcredHelpers
. Par exemple, le fichier suivant inclut des informations d'authentification pour les images hébergées dans les régions asia.gcr.io, eu.gcr.io, gcr.io, marketplace.gcr.io et us.gcr.io:{ "auths": {}, "credHelpers": { "asia.gcr.io": "gcr", "eu.gcr.io": "gcr", "gcr.io": "gcr", "marketplace.gcr.io": "gcr", "us.gcr.io": "gcr" } }
Exécutez
docker pull IMAGE_NAME
.
Si cette option fonctionne, vous devrez probablement spécifier ImagePullSecrets sur un pod. Les pods ne peuvent référencer que des codes secrets d'extraction d'image dans leur propre espace de noms. Ce processus doit donc être effectué une fois par espace de noms.
Erreur de permission refusée
Si vous rencontrez une erreur "Autorisation refusée" ou "Aucun accès en extraction", vérifiez que vous êtes connecté et/ou que vous avez accès à l'image. Essayez l'une des méthodes suivantes en fonction du registre dans lequel vous hébergez vos images.
Artifact Registry
Si votre image se trouve dans Artifact Registry, le compte de service de votre pool de nœuds doit disposer d'un accès en lecture au dépôt contenant l'image.
Attribuez le rôle artifactregistry.reader
au compte de service :
gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \
--location=REPOSITORY_LOCATION \
--member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
--role="roles/artifactregistry.reader"
Remplacez les éléments suivants :
REPOSITORY_NAME
: nom de votre dépôt Artifact RegistryREPOSITORY_LOCATION
: région de votre dépôt Artifact RegistrySERVICE_ACCOUNT_EMAIL
: adresse e-mail du compte de service IAM associé à votre pool de nœuds.
Container Registry
Si votre image se trouve dans Container Registry, le compte de service de votre pool de nœuds doit disposer d'un accès en lecture au bucket Cloud Storage contenant l'image.
Attribuez le rôle roles/storage.objectViewer
au compte de service afin qu'il puisse lire le contenu du bucket:
gsutil iam ch \
serviceAccount:SERVICE_ACCOUNT_EMAIL:roles/storage.objectViewer \
gs://BUCKET_NAME
Remplacez les éléments suivants :
SERVICE_ACCOUNT_EMAIL
: adresse e-mail du compte de service associé à votre pool de nœuds. Vous pouvez répertorier tous les comptes de service de votre projet à l'aide degcloud iam service-accounts list
.BUCKET_NAME
: nom du bucket Cloud Storage contenant vos images. Vous pouvez répertorier tous les buckets de votre projet à l'aide de la commandegsutil ls
.
Si votre administrateur de registre a configuré des dépôts gcr.io dans Artifact Registry pour stocker des images pour le domaine gcr.io
au lieu de Container Registry, vous devez accorder un accès en lecture à Artifact Registry plutôt que Container Registry.
Registre privé
Si votre image se trouve dans un registre privé, vous devrez peut-être disposer de clés pour y accéder. Pour plus d'informations, consultez la page Utiliser des registres privés.
401 Opération non autorisée: impossible d'extraire des images du dépôt de registre de conteneurs privé
Une erreur semblable à la suivante peut se produire lorsque vous extrayez une image d'un dépôt Container Registry privé:
gcr.io/PROJECT_ID/IMAGE:TAG: rpc error: code = Unknown desc = failed to pull and
unpack image gcr.io/PROJECT_ID/IMAGE:TAG: failed to resolve reference
gcr.io/PROJECT_ID/IMAGE]:TAG: unexpected status code [manifests 1.0]: 401 Unauthorized
Warning Failed 3m39s (x4 over 5m12s) kubelet Error: ErrImagePull
Warning Failed 3m9s (x6 over 5m12s) kubelet Error: ImagePullBackOff
Normal BackOff 2s (x18 over 5m12s) kubelet Back-off pulling image
Identifiez le nœud exécutant le pod:
kubectl describe pod POD_NAME | grep "Node:"
Vérifiez que le nœud dispose du champ d'application de stockage:
gcloud compute instances describe NODE_NAME \ --zone=COMPUTE_ZONE --format="flattened(serviceAccounts[].scopes)"
Le niveau d'accès du nœud doit contenir au moins l'un des éléments suivants:
serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/devstorage.read_only serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/cloud-platform
Recréez le pool de nœuds auquel le nœud appartient avec un champ d'application suffisant. Vous ne pouvez pas modifier les nœuds existants. Vous devez les recréer avec le champ d'application approprié.
Recommandé: Créez un pool de nœuds avec le champ d'application
gke-default
:gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --zone=COMPUTE_ZONE \ --scopes="gke-default"
Créez un pool de nœuds avec uniquement un champ d'application de stockage:
gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --zone=COMPUTE_ZONE \ --scopes="https://www.googleapis.com/auth/devstorage.read_only"
PodUnschedulable
PodUnschedulable
indique que votre pod ne peut pas être planifié en raison de ressources insuffisantes ou d'une erreur de configuration.
Si vous avez configuré votre cluster GKE pour envoyer des métriques de serveur d'API Kubernetes et de programmeur Kubernetes à Cloud Monitoring, vous trouverez plus d'informations sur ces erreurs dans les sections métriques du programmeur et métriques du serveur d'API.
Vous pouvez résoudre les erreurs PodUnschedulable
à l'aide de la console Google Cloud:
Accédez au playbook interactif des pods non programmables:
Pour
Cluster, saisissez le nom du cluster que vous souhaitez dépanner.Pour l'espace de noms
, saisissez l'espace de noms que vous souhaitez dépanner.(Facultatif) Créez une alerte pour être informé des futures erreurs de
PodUnschedulable
:- Dans la section Conseils d'atténuation futurs, sélectionnez Créer une alerte.
Ressources insuffisantes
Vous pouvez rencontrer une erreur indiquant un manque de ressources processeur, de mémoire ou autre. Par exemple : "Aucun nœud disponible ne correspond à tous les prédicats : processeur insuffisant (2)" indique que sur deux nœuds, le processeur disponible est insuffisant pour répondre aux requêtes d'un pod.
Si les demandes de ressources de pod dépassent celles d'un seul nœud d'un pool de nœuds éligibles, GKE ne programme pas le pod et ne déclenche pas non plus le scaling à la hausse pour ajouter un nœud. Pour que GKE planifie le pod, vous devez soit demander moins de ressources pour le pod, soit créer un pool de nœuds disposant de suffisamment de ressources.
Vous pouvez également activer le provisionnement automatique des nœuds afin que GKE puisse créer automatiquement des pools de nœuds avec des nœuds sur lesquels les pods non planifiés peuvent s'exécuter.
Le nombre de requêtes par défaut sur le processeur est de 100 millions ou 10 % d'un processeur (ou un cœur).
Si vous souhaitez demander plus ou moins de ressources, indiquez la valeur dans la spécification de pod sous spec: containers: resources: requests
.
MatchNodeSelector
MatchNodeSelector
indique qu’aucun nœud ne correspond au sélecteur de libellés du pod.
Pour vous en assurer, vérifiez les libellés indiqués dans le champ nodeSelector
de la spécification de pod, sous spec: nodeSelector
.
Pour savoir comment les nœuds de votre cluster sont libellés, exécutez la commande suivante :
kubectl get nodes --show-labels
Pour associer un libellé à un nœud, exécutez la commande suivante :
kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE
Remplacez les éléments suivants :
NODE_NAME
: nœud souhaité.LABEL_KEY
: clé de libellé.LABEL_VALUE
: valeur du libellé.
Pour plus d'informations, reportez-vous à l'article Affecter des pods à des nœuds.
PodToleratesNodeTaints
PodToleratesNodeTaints
indique que le pod ne peut pas être planifié sur un nœud, car aucun nœud ne tolère actuellement sa propriété de rejet.
Pour vous en assurer, exécutez la commande suivante :
kubectl describe nodes NODE_NAME
Dans le résultat, examinez le champ Taints
, qui répertorie les paires valeur/clé et les effets de planification.
Si l'effet indiqué est NoSchedule
, alors aucun pod ne peut être planifié sur ce nœud sans la tolérance correspondante.
Pour résoudre ce problème, vous pouvez supprimer la propriété de rejet. Par exemple, pour supprimer le rejet NoSchedule, exécutez la commande suivante :
kubectl taint nodes NODE_NAME key:NoSchedule-
PodFitsHostPorts
PodFitsHostPorts
indique qu'un port qu'un nœud tente d'utiliser est déjà en cours d'utilisation.
Pour résoudre ce problème, vérifiez la valeur hostPort
de la spécification de pod sous spec: containers: ports: hostPort
. Vous devrez peut-être remplacer cette valeur par un autre port.
Aucune disponibilité minimale
Si un nœud dispose de ressources suffisantes mais que vous obtenez toujours le message Does not have minimum availability
, vérifiez l'état du pod. Si l'état est SchedulingDisabled
ou Cordoned
, le nœud ne peut pas planifier de nouveaux pods. Vous pouvez vérifier l'état d'un nœud à l'aide de la console Google Cloud ou de l'outil de ligne de commande kubectl
.
kubectl
Pour obtenir l'état de vos nœuds, exécutez la commande suivante :
kubectl get nodes
Pour activer la planification sur le nœud, exécutez cette commande :
kubectl uncordon NODE_NAME
Console
Procédez comme suit :
Accédez à la page Google Kubernetes Engine dans Google Cloud Console.
Sélectionnez le cluster souhaité. L'onglet Nœuds affiche les nœuds et leur état.
Pour activer la planification sur le nœud, procédez comme suit :
Dans la liste, cliquez sur le nœud souhaité.
Dans les détails du nœud, cliquez sur le bouton Reprendre l'ordonnancement.
Nombre maximal de pods par nœud atteint
Si la limite Nombre maximal de pods par nœud est atteinte par tous les nœuds du cluster, les pods sont bloqués dans l'état non programmable. Sous l'onglet Événements du pod, un message contenant l'expression Too many pods
s'affiche.
Vérifiez la configuration
Maximum pods per node
à partir de l'onglet "Nœuds" dans les détails du cluster GKE dans la console Google Cloud.Obtenez la liste des nœuds:
kubectl get nodes
Pour chaque nœud, vérifiez le nombre de pods en cours d'exécution sur le nœud:
kubectl get pods -o wide | grep NODE_NAME | wc -l
Si la limite est atteinte, ajoutez un pool de nœuds ou ajoutez des nœuds supplémentaires au pool de nœuds existant.
Taille maximale du pool de nœuds atteinte avec l'autoscaler de cluster activé
Si le pool de nœuds a atteint sa Taille maximale Selon sa configuration d'autoscaler de cluster, GKE ne déclenche pas de scaling à la hausse pour le pod qui serait autrement programmé avec ce pool de nœuds. Si vous souhaitez que le pod soit planifié sur ce pool de nœuds, modifiez la configuration de l'autoscaler de cluster.
Taille maximale du pool de nœuds atteinte avec l'autoscaler de cluster désactivé
Si le pool de nœuds a atteint son nombre maximal de nœuds et que l'autoscaler de cluster est désactivé, GKE ne peut pas planifier le pod avec le pool de nœuds. Augmentez la taille de votre pool de nœuds ou activez l'autoscaler de cluster pour que GKE redimensionne automatiquement votre cluster.
PersistantVolumeClaim non lié
Unbound PersistentVolumeClaims
indique que le pod fait référence à un objet PersistantVolumeClaim non lié. Cette erreur peut se produire en cas d'échec du provisionnement du PersistentVolume. Vous pouvez vérifier si le provisionnement a échoué en récupérant les événements associés au PersistentVolumeClaim et en examinant s'ils signalent un échec.
Pour obtenir la liste des événements, exécutez la commande suivante :
kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0
Remplacez les éléments suivants :
STATEFULSET_NAME
: nom de l'objet StatefulSet.PVC_NAME
: nom de l'objet PersistentVolumeClaim.
Cette erreur peut également être causée par une erreur de configuration lors du provisionnement manuel préalable d'un PersistentVolume et de sa liaison à un PersistentVolumeClaim. Dans ce cas, vous pouvez essayer de préprovisionner le volume à nouveau.
Quota insuffisant
Vérifiez que votre projet dispose d'un quota Compute Engine suffisant pour que GKE puisse effectuer le scaling à la hausse de votre cluster. Si GKE tente d'ajouter un nœud à votre cluster pour planifier le pod et que le scaling à la hausse dépasse le quota disponible de votre projet, vous recevez le message d'erreur scale.up.error.quota.exceeded
.
Pour en savoir plus, consultez la section Erreurs liées au scaling à la hausse.
API obsolètes
Assurez-vous de ne pas utiliser d'API obsolètes qui sont supprimées dans la version mineure de votre cluster. Pour en savoir plus, consultez la page Abandons de GKE.
Problèmes de connectivité
Comme indiqué dans la partie Présentation du réseau, il est important de comprendre comment les pods sont connectés entre leurs espaces de noms réseau et l'espace de noms racine sur le nœud afin de procéder au dépannage de façon efficace. Dans la démonstration suivante, sauf indication contraire, nous supposerons que le cluster utilise la CNI native (Container Network Interface) de GKE plutôt que celle de Calico. C'est-à-dire qu'aucune stratégie réseau n'a été appliquée.
Les pods sur les nœuds sélectionnés n'ont pas de disponibilité
Si les pods sur certains nœuds ne disposent pas d'une connectivité réseau, assurez-vous que le pont Linux est actif :
ip address show cbr0
Si le pont Linux est arrêté, activez-le :
sudo ip link set cbr0 up
Assurez-vous que le nœud apprend les adresses MAC du pod associées à cbr0 :
arp -an
La connectivité des pods sur certains nœuds est minimale
Si les pods sur certains nœuds ont une connectivité minimale, vous devez d’abord rechercher une perte de paquets éventuelle en exécutant la commande tcpdump
dans le conteneur de la boîte à outils :
sudo toolbox bash
Installez tcpdump
dans la boîte à outils si ce n'est déjà fait :
apt install -y tcpdump
Exécutez tcpdump
sur cbr0 :
tcpdump -ni cbr0 host HOSTNAME and port PORT_NUMBER and [TCP|UDP|ICMP]
Si vous constatez que des paquets volumineux sont rejetés en aval du pont (par exemple, le handshake TCP a bien lieu, mais aucun "hello" SSL n'est reçu), assurez-vous que la MTU de chaque interface de pod Linux est correctement définie sur la MTU deRéseau VPC du cluster.
ip address show cbr0
En cas d'utilisation de superpositions (par exemple, Weave ou Flannel), cette MTU doit être encore réduite pour tolérer la surcharge d'encapsulation sur la superposition.
MTU GKE
La MTU sélectionnée pour une interface de pod dépend de l'interface CNI (Container Network Interface) utilisée par les nœuds du cluster et du paramètre de MTU sous-jacent du VPC. Pour en savoir plus, consultez la section Pods.
La valeur de la MTU de l'interface de pod est 1460
ou héritée de l'interface principale du nœud.
CNI | MTU | GKE Standard |
---|---|---|
kubenet | 1460 | Par défaut |
kubenet (version 1.26.1 de GKE et versions ultérieures) |
Hérité | Par défaut |
Calico | 1460 |
Activation à l'aide de Pour en savoir plus, consultez la page Contrôler la communication entre les pods et les services à l'aide de règles de réseau. |
netd | Hérité | Activation à l'aide de l'une des options suivantes : |
GKE Dataplane V2 | Hérité |
Activation à l'aide de Pour en savoir plus, consultez la page Utiliser GKE Dataplane V2. |
Échecs de connexion intermittents
Les connexions vers et depuis les pods sont transférées au moyen de règles iptables. Les flux sont suivis en tant qu'entrées dans la table conntrack et, lorsqu'il existe de nombreuses charges de travail par nœud, l'épuisement de la table conntrack peut se traduire par un échec. Ceux-ci peuvent être enregistrés dans la console série du nœud, par exemple :
nf_conntrack: table full, dropping packet
Si vous parvenez à déterminer que les déconnexions intermittentes sont liées à l'épuisement de conntrack, augmentez la taille du cluster (réduisant ainsi le nombre de charges de travail et de flux par nœud), ou augmentez nf_conntrack_max
:
new_ct_max=$(awk '$1 == "MemTotal:" { printf "%d\n", $2/32; exit; }' /proc/meminfo)
sysctl -w net.netfilter.nf_conntrack_max="${new_ct_max:?}" \
&& echo "net.netfilter.nf_conntrack_max=${new_ct_max:?}" >> /etc/sysctl.conf
Vous pouvez également utiliser NodeLocal DNSCache pour réduire les entrées de suivi de connexion.
"Liaison : adresse déjà utilisée" signalé pour un conteneur
Un conteneur dans un pod ne parvient pas à démarrer car, d'après les journaux du conteneur, le port auquel l'application tente de se connecter est déjà réservé. Le conteneur est bloqué dans une boucle de plantage. Par exemple, dans Cloud Logging :
resource.type="container"
textPayload:"bind: Address already in use"
resource.labels.container_name="redis"
2018-10-16 07:06:47.000 CEST 16 Oct 05:06:47.533 # Creating Server TCP listening socket *:60250: bind: Address already in use
2018-10-16 07:07:35.000 CEST 16 Oct 05:07:35.753 # Creating Server TCP listening socket *:60250: bind: Address already in use
Lorsque Docker plante, un conteneur en cours d'exécution est parfois laissé de côté et n'est plus actualisé. Le processus est toujours en cours d'exécution dans l'espace de noms réseau attribué au pod et en écoute sur son port. Comme Docker et le kubelet ignorent que le conteneur est obsolète, ils tentent de démarrer un nouveau conteneur avec un nouveau processus, qui ne peut pas se connecter au port puisqu'il est ajouté à l'espace de nom réseau déjà associé au pod.
Pour diagnostiquer ce problème, procédez comme suit :
Vous avez besoin de l'UUID du pod dans le champ
.metadata.uuid
:kubectl get pod -o custom-columns="name:.metadata.name,UUID:.metadata.uid" ubuntu-6948dd5657-4gsgg name UUID ubuntu-6948dd5657-4gsgg db9ed086-edba-11e8-bdd6-42010a800164
Obtenez le résultat des commandes suivantes à partir du nœud :
docker ps -a ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep [Pod UUID]
Vérifiez les processus en cours depuis ce pod. Comme l'UUID des espaces de noms cgroup contient l'UUID du pod, vous pouvez utiliser une commande grep pour le pod UUID dans le résultat
ps
. Appliquez également une commande grep à la ligne précédente, de façon à obtenir les processusdocker-containerd-shim
qui contiennent aussi l'identifiant du conteneur dans l'argument. Coupez le reste de la colonne cgroup pour simplifier la sortie obtenue :# ps -eo pid,ppid,stat,wchan:20,netns,comm,args:50,cgroup --cumulative -H | grep -B 1 db9ed086-edba-11e8-bdd6-42010a800164 | sed s/'blkio:.*'/''/ 1283089 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim 276e173b0846e24b704d4 12: 1283107 1283089 Ss sys_pause 4026532393 pause /pause 12: 1283150 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim ab4c7762f5abf40951770 12: 1283169 1283150 Ss do_wait 4026532393 sh /bin/sh -c echo hello && sleep 6000000 12: 1283185 1283169 S hrtimer_nanosleep 4026532393 sleep sleep 6000000 12: 1283244 959 Sl futex_wait_queue_me 4026531993 docker-co docker-containerd-shim 44e76e50e5ef4156fd5d3 12: 1283263 1283244 Ss sigsuspend 4026532393 nginx nginx: master process nginx -g daemon off; 12: 1283282 1283263 S ep_poll 4026532393 nginx nginx: worker process
Dans cette liste, les identifiants de conteneur s'affichent et devraient également être visibles dans
docker ps
.Dans ce cas :
docker-containerd-shim 276e173b0846e24b704d4
pour la mise en pausedocker-containerd-shim ab4c7762f5abf40951770
pour sh avec mise en veille (sleep-ctr)docker-containerd-shim 44e76e50e5ef4156fd5d3
pour nginx (echoserver-ctr)
Vérifiez les identifiants dans le résultat de
docker ps
:# docker ps --no-trunc | egrep '276e173b0846e24b704d4|ab4c7762f5abf40951770|44e76e50e5ef4156fd5d3' 44e76e50e5ef4156fd5d383744fa6a5f14460582d0b16855177cbed89a3cbd1f gcr.io/google_containers/echoserver@sha256:3e7b182372b398d97b747bbe6cb7595e5ffaaae9a62506c725656966d36643cc "nginx -g 'daemon off;'" 14 hours ago Up 14 hours k8s_echoserver-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0 ab4c7762f5abf40951770d3e247fa2559a2d1f8c8834e5412bdcec7df37f8475 ubuntu@sha256:acd85db6e4b18aafa7fcde5480872909bd8e6d5fbd4e5e790ecc09acc06a8b78 "/bin/sh -c 'echo hello && sleep 6000000'" 14 hours ago Up 14 hours k8s_sleep-cnt_ubuntu-6948dd5657-4gsgg_default_db9ed086-edba-11e8-bdd6-42010a800164_0 276e173b0846e24b704d41cf4fbb950bfa5d0f59c304827349f4cf5091be3327 registry.k8s.io/pause-amd64:3.1
Normalement, tous les identifiants de conteneur de
ps
apparaissent dansdocker ps
. Si l'un d'entre eux n'apparaît pas, il s'agit d'un conteneur obsolète, et vous verrez probablement un processus enfant dedocker-containerd-shim process
en écoute sur le port TCP signalé comme déjà utilisé.Pour le vérifier, exécutez la commande
netstat
dans l'espace de noms réseau du conteneur. Récupérez le pid d'un processus de conteneur pour le pod (et NONdocker-containerd-shim
).Dans l'exemple ci-dessus :
- 1283107 - pause
- 1283169 - sh
- 1283185 - veille
- 1283263 - maître nginx
- 1283282 - nœud de calcul nginx
# nsenter -t 1283107 --net netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mast gke-zonal-110-default-pool-fe00befa-n2hx ~ # nsenter -t 1283169 --net netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mast
Vous pouvez également exécuter
netstat
en utilisantip netns
, mais vous devez relier manuellement l'espace de noms réseau du processus, car Docker n'effectue par la liaison :# ln -s /proc/1283169/ns/net /var/run/netns/1283169 gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns list 1283169 (id: 2) gke-zonal-110-default-pool-fe00befa-n2hx ~ # ip netns exec 1283169 netstat -anp Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1283263/nginx: mast Active UNIX domain sockets (servers and established) Proto RefCnt Flags Type State I-Node PID/Program name Path unix 3 [ ] STREAM CONNECTED 3097406 1283263/nginx: mast unix 3 [ ] STREAM CONNECTED 3097405 1283263/nginx: mast gke-zonal-110-default-pool-fe00befa-n2hx ~ # rm /var/run/netns/1283169
Atténuation :
L'atténuation à court terme consiste à identifier les processus obsolètes à l'aide de la méthode décrite ci-dessus, puis à les éliminer en exécutant la commande kill [PID]
.
L'atténuation à long terme consiste à identifier l'origine des plantages de Docker et à y remédier. Voici les différents motifs possibles :
- Les processus zombies s'empilent et les espaces de noms PID deviennent insuffisants
- Bug dans Docker
- Ressource saturée/OOM
Erreur: "Échec de l'allocation pour la plage 0: aucune adresse IP dans la plage définie"
Les versions 1.18.17 et ultérieures de GKE ont résolu un problème où des événements de mémoire saturée (OOM, Out Of Memory) entraînent une éviction de pod incorrecte si le pod était supprimé avant le démarrage de ses conteneurs. Cette éviction incorrecte peut entraîner des pods orphelins qui ont continué à posséder des adresses IP réservées de la plage de nœuds allouée.
Au fil du temps, GKE a épuisé ses adresses IP pour allouer de nouveaux pods en raison de l'accumulation de pods orphelins. Cela a généré le message d'erreur failed
to allocate for range 0: no IP addresses in range set
, car la plage de nœuds allouée n'avait pas d'adresses IP disponibles à attribuer à de nouveaux pods.
Pour résoudre ce problème, mettez à niveau le cluster et les pools de nœuds vers GKE 1.18.17 ou une version ultérieure.
Pour éviter ce problème et le résoudre sur les clusters avec des versions de GKE antérieures à 1.18.17, augmentez vos limites de ressources pour éviter les événements OOM à l'avenir, puis récupérez les adresses IP en supprimant les pods orphelins.
Vous pouvez également consulter les insights sur l'utilisation des adresses IP GKE.
Supprimer les pods orphelins des nœuds concernés
Vous pouvez supprimer les pods orphelins en drainant le nœud, en mettant à niveau le pool de nœuds ou en déplaçant les répertoires concernés.
Drainer le nœud (recommandé)
Marquez le nœud comme non programmable pour empêcher que de nouveaux pods se programment dans celui-ci:
kubectl cordon NODE
Remplacez
NODE
par le nom du nœud que vous souhaitez drainer.Drainez le nœud. GKE replanifie automatiquement les pods gérés par les déploiements sur d'autres nœuds. Utilisez l'option
--force
pour drainer les pods orphelins qui ne disposent pas d'une ressource de gestion.kubectl drain NODE --force
Marquez le nœud comme non programmable pour permettre à GKE de planifier de nouveaux pods sur celui-ci:
kubectl uncordon NODE
Déplacer des répertoires concernés
Vous pouvez identifier les répertoires de pods orphelins dans /var/lib/kubelet/pods
et les déplacer hors du répertoire principal pour permettre à GKE d'arrêter les pods.
Résoudre les problèmes d'arrêt des ressources
Espace de noms bloqué à l'état Terminating
Les espaces de noms utilisent des finaliseurs Kubernetes pour empêcher la suppression lorsqu'une ou plusieurs ressources d'un espace de noms existent toujours.
Lorsque vous supprimez un espace de noms à l'aide de la commande kubectl delete
, celui-ci passe à l'état Terminating
jusqu'à ce que Kubernetes supprime ses ressources dépendantes et efface tous les finaliseurs. Le contrôleur de cycle de vie des espaces de noms répertorie d'abord toutes les ressources de l'espace de noms à supprimer par GKE. Si GKE ne peut pas supprimer une ressource dépendante ou si le contrôleur de cycle de vie de l'espace de noms ne peut pas vérifier que l'espace de noms est vide, l'espace de noms reste à l'état Terminating
jusqu'à ce que le problème soit résolu.
Pour résoudre un problème d'espace de noms bloqué à l'état Terminating
, vous devez identifier et supprimer le ou les composants non opérationnels qui bloquent la suppression. Essayez l'une des solutions suivantes.
Rechercher et supprimer des services d'API indisponibles
Répertoriez les services d'API indisponibles:
kubectl get apiservice | grep False
Résolvez les problèmes liés aux services qui ne répondent pas:
kubectl describe apiservice API_SERVICE
Remplacez
API_SERVICE
par le nom du service qui ne répond pas.Vérifiez si l'espace de noms est toujours en cours d'arrêt :
kubectl get ns | grep Terminating
Rechercher et supprimer des ressources restantes
Répertoriez toutes les ressources restantes dans l'espace de noms en cours d'arrêt :
kubectl api-resources --verbs=list --namespaced -o name | xargs -n 1 kubectl get -n NAMESPACE
Remplacez
NAMESPACE
par le nom de l'espace de noms que vous souhaitez supprimer.Supprimez toutes les ressources affichées dans le résultat.
Vérifiez si l'espace de noms est toujours en cours d'arrêt :
kubectl get ns | grep Terminating
Forcer la suppression de l'espace de noms
Vous pouvez supprimer les finaliseurs bloquant la suppression de l'espace de noms afin de forcer l'arrêt de celui-ci.
Enregistrez le fichier manifeste d'espace de noms en tant que fichier YAML :
kubectl get ns NAMESPACE -o yaml > ns-terminating.yml
Ouvrez le fichier manifeste dans un éditeur de texte et supprimez toutes les valeurs du champ
spec.finalizers
:vi ns-terminating.yml
Vérifiez que le champ des finaliseurs est vide :
cat ns-terminating.yml
Le résultat doit se présenter sous la forme suivante :
apiVersion: v1 kind: Namespace metadata: annotations: name: NAMESPACE spec: finalizers: status: phase: Terminating
Démarrez un proxy HTTP pour accéder à l'API Kubernetes:
kubectl proxy
Remplacez le fichier manifeste de l'espace de noms par
curl
:curl -H "Content-Type: application/yaml" -X PUT --data-binary @ns-terminating.yml http://127.0.0.1:8001/api/v1/namespaces/NAMESPACE/finalize
Vérifiez si l'espace de noms est toujours en cours d'arrêt :
kubectl get ns | grep Terminating
Résoudre les problèmes de perte de paquets Cloud NAT à partir d'un cluster GKE
Les VM de nœud dans les clusters privés GKE du VPC natif ne disposent pas d'adresses IP externes et ne peuvent pas se connecter à Internet seules. Vous pouvez utiliser Cloud NAT pour allouer les adresses IP et ports externes qui permettent aux clusters privés d'établir des connexions publiques.
Si une VM de nœud manque d'allocation de ports et d'adresses IP externes de Cloud NAT, les paquets risquent d'être supprimés. Pour éviter cela, vous pouvez réduire le débit de paquets sortants ou augmenter l'allocation des adresses IP et des ports sources Cloud NAT disponibles. Les sections suivantes expliquent comment diagnostiquer et résoudre les problèmes de perte de paquets issus de Cloud NAT dans le contexte de clusters privés GKE.
Diagnostiquer la perte de paquet
Cette section explique comment consigner les paquets supprimés à l'aide de Cloud Logging et diagnostiquer la cause de ces paquets supprimés à l'aide de Cloud Monitoring.
Journalisation des paquets supprimés
Vous pouvez consigner les paquets supprimés à l'aide de la requête suivante dans Cloud Logging:
resource.type="nat_gateway" resource.labels.region=REGION resource.labels.gateway_name=GATEWAY_NAME jsonPayload.allocation_status="DROPPED"
REGION
: nom de la région dans laquelle se trouve le clusterGATEWAY_NAME
: nom de la passerelle Cloud NAT.
Cette commande renvoie la liste de tous les paquets supprimés par une passerelle Cloud NAT, mais n'identifie pas la cause.
Surveiller les causes de perte de paquets
Pour identifier les causes des paquets supprimés, interrogez l'observateur de métriques dans Cloud Monitoring. Les paquets sont supprimés pour l'une des trois raisons suivantes:
Pour identifier les paquets supprimés en raison de codes d'erreur OUT_OF_RESOURCES
ou ENDPOINT_ALLOCATION_FAILED
, utilisez la requête suivante:
fetch nat_gateway metric 'router.googleapis.com/nat/dropped_sent_packets_count' filter (resource.gateway_name == NAT_NAME) align rate(1m) every 1m group_by [metric.reason], [value_dropped_sent_packets_count_aggregate: aggregate(value.dropped_sent_packets_count)]
Pour identifier les paquets supprimés en raison du code d'erreur NAT_ALLOCATION_FAILED
, utilisez la requête suivante:
fetch nat_gateway metric 'router.googleapis.com/nat/nat_allocation_failed' group_by 1m, [value_nat_allocation_failed_count_true: count_true(value.nat_allocation_failed)] every 1m
Résoudre les problèmes liés à Cloud NAT avec le masquage d'adresses IP GKE
Si les requêtes précédentes renvoient des résultats vides et que les pods GKE ne parviennent pas à communiquer avec des adresses IP externes, résolvez les problèmes de votre configuration:
Configuration | Dépannage |
Cloud NAT configuré pour s'appliquer uniquement à la plage d'adresses IP principale du sous-réseau. |
Lorsque Cloud NAT est configuré uniquement pour la plage d'adresses IP principale du sous-réseau, les paquets envoyés depuis le cluster vers des adresses IP externes doivent disposer d'une adresse IP de nœud source. Dans cette configuration Cloud NAT :
|
Cloud NAT configuré pour s'appliquer uniquement à la plage d'adresses IP secondaire du sous-réseau utilisée pour les adresses IP des pods. |
Lorsque Cloud NAT est configuré uniquement pour la plage d'adresses IP secondaire du sous-réseau utilisée par les adresses IP des pods du cluster, les paquets envoyés depuis le cluster vers les adresses IP externes doivent disposer d'une adresse IP de pod source. Dans cette configuration Cloud NAT:
|
Optimisations pour éviter de perdre des paquets
Vous pouvez arrêter la perte de paquets grâce aux opérations suivantes :
Configurer la passerelle Cloud NAT pour qu'elle utilise l'allocation de ports dynamique et augmentez le nombre maximal de ports par VM.
Augmentez le nombre minimal de ports par VM si vous utilisez l'allocation de ports statique.
Optimisez votre application
Lorsqu'une application établit plusieurs connexions sortantes vers la même adresse IP et le même port de destination, elle peut rapidement utiliser toutes les connexions que Cloud NAT peut établir vers cette destination en utilisant le nombre de tuples d'adresses sources NAT allouées et de ports sources. Dans ce scénario, la réduction du débit de paquets sortant de l'application permet de réduire la perte de paquets.
Pour plus d'informations sur la manière dont Cloud NAT utilise les adresses sources et les ports sources NAT pour établir des connexions, y compris les limites du nombre de connexions simultanées à une destination, consultez la page Ports et connexions.
Réduire le taux de connexions sortantes de l'application peut aider à réduire la perte de paquets. Pour ce faire, vous pouvez réutiliser des connexions ouvertes. Les méthodes courantes de réutilisation des connexions incluent le regroupement de connexions, le multiplexage de connexions à l'aide de protocoles tels que HTTP/2 ou l'établissement de connexions persistantes réutilisées pour plusieurs requêtes. Pour plus d'informations, consultez la section Ports et connexions.
La version du nœud n'est pas compatible avec la version du plan de contrôle
Vérifiez la version de Kubernetes exécutée par le plan de contrôle de votre cluster, puis vérifiez la version de Kubernetes exécutée par les pools de nœuds de votre cluster. Si l'un des pools de nœuds du cluster a plus de deux versions mineures antérieures au plan de contrôle, cela peut être dû à des problèmes avec votre cluster.
L'équipe GKE effectue régulièrement des mises à niveau du plan de contrôle du cluster en votre nom. Les plans de contrôle sont mis à niveau vers les versions stables les plus récentes de Kubernetes. Par défaut, la mise à niveau automatique est activée sur les nœuds d'un cluster. Nous vous recommandons de ne pas la désactiver.
Si la mise à niveau automatique est désactivée pour les nœuds d'un cluster et que vous ne mettez pas à niveau manuellement la version du pool de nœuds vers une version compatible avec le plan de contrôle, votre plan de contrôle finira par être incompatible avec vos nœuds, car le plan de contrôle est automatiquement mis à niveau au fil du temps. Une incompatibilité entre le plan de contrôle de votre cluster et les nœuds peut provoquer des problèmes inattendus.
Les règles de compatibilité de la version de Kubernetes et du décalage de version garantissent que les plans de contrôle sont compatibles avec les nœuds jusqu'à deux versions mineures antérieures à celle du plan de contrôle. Par exemple, les plans de contrôle Kubernetes 1.19 sont compatibles avec les nœuds Kubernetes 1.19, 1.18 et 1.17. Pour résoudre ce problème, mettez à niveau manuellement la version du pool de nœuds vers une version compatible avec le plan de contrôle.
Si vous craignez que le processus de mise à niveau entraîne des perturbations pour les charges de travail s'exécutant sur les nœuds concernés, procédez comme suit pour migrer vos charges de travail vers un nouveau pool de nœuds:
- Créez un pool de nœuds avec une version compatible.
- Marquez les nœuds du pool existant comme non programmables.
- Vous pouvez également mettre à jour vos charges de travail exécutées sur le pool de nœuds existant pour ajouter un sélecteur de nœuds pour le libellé
cloud.google.com/gke-nodepool:NEW_NODE_POOL_NAME
, oùNEW_NODE_POOL_NAME
est le nom du nouveau pool de nœuds. Cela garantit que GKE place ces charges de travail sur les nœuds du nouveau pool de nœuds. - Drainez le pool de nœuds existant.
- Vérifiez que les charges de travail s'exécutent correctement dans le nouveau pool de nœuds. Si tel est le cas, vous pouvez supprimer l'ancien pool de nœuds. Si vous remarquez des interruptions de charge de travail, reprogrammez les charges de travail sur les nœuds existants en marquant les nœuds du pool de nœuds existant comme non programmables et en drainant les nouveaux nœuds. Résolvez le problème et réessayez.
Les métriques de votre cluster n'apparaissent pas dans Cloud Monitoring
Vérifiez que vous avez activé l'API Cloud Monitoring et l'API Cloud Logging sur votre projet, et que vous pouvez afficher votre projet dans Cloud Monitoring.
Si le problème persiste, penchez-vous sur les causes potentielles suivantes :
Assurez-vous que vous avez activé la surveillance sur votre cluster.
La surveillance est activée par défaut pour les clusters créés à partir de la console Google Cloud et de Google Cloud CLI, mais vous pouvez vérifier que c'est bien le cas en exécutant la commande suivante ou en cliquant sur les détails du cluster dans la console Google Cloud :
gcloud container clusters describe CLUSTER_NAME
Le résultat de cette commande doit inclure
SYSTEM_COMPONENTS
dans la liste deenableComponents
dans la sectionmonitoringConfig
de la manière suivante:monitoringConfig: componentConfig: enableComponents: - SYSTEM_COMPONENTS
Si la surveillance n'est pas activée, exécutez la commande suivante pour l'activer :
gcloud container clusters update CLUSTER_NAME --monitoring=SYSTEM
Depuis combien de temps votre cluster a-t-il été créé ou sa surveillance activée ?
L'apparition des métriques d'un nouveau cluster dans Cloud Monitoring peut prendre jusqu'à une heure.
Est-ce qu'un pod
heapster
ougke-metrics-agent
(OpenTelemetry Collector) s'exécute dans votre cluster dans l'espace de noms "kube-system" ?Ce pod ne parvient peut-être pas à planifier les charges de travail parce que votre cluster manque de ressources. Vérifiez que Heapster ou OpenTelementry est en cours d'exécution en ayant recours à la commande
kubectl get pods --namespace=kube-system
et en recherchant les pods dont le nom contientheapster
ougke-metrics-agent
.Le plan de contrôle de votre cluster est-il capable de communiquer avec les nœuds ?
Cloud Monitoring s'appuie sur cette capacité. Pour vérifier que Cloud Monitoring n'est pas bloqué par un problème de communication, exécutez la commande suivante :
kubectl logs POD_NAME
Si cette commande renvoie une erreur, le problème peut être causé par les tunnels SSH. Pour en savoir plus, consultez cette section.
Si vous rencontrez un problème lié à l'agent Cloud Logging, consultez sa documentation de dépannage.
Pour en savoir plus, consultez la documentation de Logging.
Autorisations manquantes sur le compte pour les clusters de VPC partagé
Pour les clusters de VPC partagé, assurez-vous que le compte de service GKE du projet est lié au rôle Utilisateur de l'agent de service hôte dans le projet hôte. Pour ce faire, vous pouvez utiliser gcloud CLI.
Pour vérifier si la liaison de rôle existe, exécutez la commande suivante dans votre projet hôte :
gcloud projects get-iam-policy PROJECT_ID \
--flatten="bindings[].members" \
--format='table(bindings.role)' \
--filter="bindings.members:SERVICE_ACCOUNT_NAME
Remplacez les éléments suivants :
PROJECT_ID
: ID de votre projet hôte.SERVICE_ACCOUNT_NAME
: nom du compte de service GKE.
Dans le résultat, recherchez le champ roles/container.hostServiceAgentUser
.
ROLE
...
roles/container.hostServiceAgentUser
...
Si le rôle hostServiceAgentUser
ne figure pas dans la liste, suivez les instructions de la section Attribuer le rôle utilisateur de l'agent de service hôte pour ajouter la liaison au compte de service.
Restaurer le compte de service par défaut sur votre projet Google Cloud
Le compte de service par défaut de GKE, container-engine-robot
, peut être dissocié accidentellement d'un projet. Le rôle d'agent de service GKE est un rôle Identity and Access Management (IAM) qui accorde au compte de service les autorisations nécessaires pour gérer les ressources du cluster. Si vous supprimez cette liaison de rôle du compte de service, le compte de service par défaut est dissocié du projet, ce qui peut vous empêcher de déployer des applications et d'effectuer d'autres opérations sur le cluster.
Vous pouvez vérifier si le compte de service a été supprimé de votre projet à l'aide de gcloud CLI ou de la console Google Cloud.
gcloud
Exécutez la commande suivante :
gcloud projects get-iam-policy PROJECT_ID
Remplacez PROJECT_ID
par l'ID du projet.
Console
Ouvrez la page IAM et administration dans la console Google Cloud.
Si la commande ou le tableau de bord n'affiche pas container-engine-robot
parmi vos comptes de service, c'est que ce compte a été dissocié.
Si vous avez supprimé la liaison de rôle d'agent de service GKE, exécutez les commandes suivantes pour la restaurer :
PROJECT_NUMBER=$(gcloud projects describe "PROJECT_ID" --format 'get(projectNumber)')
gcloud projects add-iam-policy-binding PROJECT_ID \
--member "serviceAccount:service-${PROJECT_NUMBER?}@container-engine-robot.iam.gserviceaccount.com" \
--role roles/container.serviceAgent
Pour confirmer que la liaison de rôle a été activée :
gcloud projects get-iam-policy $PROJECT_ID
Si vous voyez le nom du compte de service avec le rôle container.serviceAgent
, la liaison de rôle a été activée. Exemple :
- members:
- serviceAccount:service-1234567890@container-engine-robot.iam.gserviceaccount.com
role: roles/container.serviceAgent
Activer le compte de service Compute Engine par défaut
Vos nœuds peuvent ne pas s'enregistrer auprès du cluster si le compte de service utilisé pour le pool de nœuds est désactivé, qui est généralement le compte de service Compute Engine par défaut.
Vous pouvez vérifier si le compte de service a été désactivé dans votre projet à l'aide de gcloud CLI ou de la console Google Cloud.
gcloud
Exécutez la commande suivante :
gcloud iam service-accounts list --filter="NAME~'compute' AND disabled=true"
Console
Accédez à la page IAM et administration de la console Google Cloud.
Si la commande ou le tableau de bord indique que le compte de service est désactivé, exécutez la commande suivante pour l'activer:
gcloud iam service-accounts enable PROJECT_ID-compute@developer.gserviceaccount.com
Remplacez PROJECT_ID
par l'ID du projet.
Si le problème persiste, consultez la section Résoudre les problèmes d'enregistrement des nœuds pour obtenir des instructions de dépannage supplémentaires.
Pods bloqués à l'état "en attente" après l'activation des ressources pouvant être allouées aux nœuds
Si vous rencontrez un problème avec des pods bloqués à l'état en attente après avoir activé des ressources pouvant être allouées aux nœuds, veuillez noter les points suivants :
À partir de la version 1.7.6, GKE réserve le processeur et la mémoire pour les frais généraux de Kubernetes, y compris Docker et le système d'exploitation. Consultez la section Architecture de cluster pour connaître la quantité de chaque type de machine pouvant être programmé par les pods.
Si les pods sont en attente après une mise à niveau, nous vous suggérons de suivre les conseils suivants :
Assurez-vous que les demandes de ressources mémoire et de processeur pour vos pods ne dépassent pas leur pic d'utilisation. Étant donné que GKE réserve le processeur et la mémoire pour les frais généraux, les pods ne peuvent pas demander ces ressources. Les pods qui demandent plus de ressources mémoire et de processeur qu'ils n'en utilisent empêchent les autres pods de demander ces ressources et peuvent laisser le cluster sous-exploité. Pour en savoir plus, consultez la section Programmation des pods avec des demandes de ressources.
Envisagez de redimensionner votre cluster. Pour obtenir des instructions, consultez la page Redimensionner un cluster.
Pour annuler cette modification, faites revenir votre cluster à une version antérieure. Pour obtenir des instructions, consultez la page Mettre à jour manuellement un cluster ou un pool de nœuds.
- Configurez votre cluster pour envoyer les métriques du programmeur Kubernetes à Cloud Monitoring et afficher les métriques du programmeur.
L'autorité de certification racine du cluster arrive bientôt à expiration
L'autorité de certification racine de votre cluster arrive bientôt à expiration. Pour éviter toute interruption des opérations normales sur les clusters, vous devez effectuer une rotation des identifiants.
L'erreur "Instance 'Foo' ne contient pas les métadonnées 'instance-template" s'affiche
Il est possible que l'erreur "Instance 'Foo' ne contienne pas de métadonnées instance-template" s'affiche en tant qu'état d'un pool de nœuds qui ne parvient pas à mettre à se mettre à niveau, à évoluer ou à effectuer une réparation automatique de nœuds.
Ce message indique que les métadonnées des instances de VM, allouées par GKE, ont été corrompues. Cela se produit généralement lorsque des opérations de création d'automatisation ou de scripts personnalisés tentent d'ajouter des métadonnées d'instance (telles que block-project-ssh-keys
). Au lieu d'ajouter ou de mettre à jour des valeurs, elle supprime également les métadonnées existantes.
Pour en savoir plus sur les métadonnées d'instance de VM, consultez la page Définir des métadonnées personnalisées.
Dans le cas où une des valeurs de métadonnées critiques (entre autres :instance-template
,kube-labels
,kubelet-config
,kubeconfig
,cluster-name
,configure-sh
,cluster-uid
) a été supprimée, le nœud ou le pool de nœuds entier peut s'afficher dans un état instable, car ces valeurs sont essentielles aux opérations GKE.
Si les métadonnées d'instance ont été corrompues, le meilleur moyen de récupérer les métadonnées consiste à recréer le pool de nœuds contenant les instances de VM corrompues. Vous devez ajouter un pool de nœuds à votre cluster et augmenter le nombre de nœuds du nouveau pool de nœuds, tout en marquant les nœuds comme non programmables et en supprimant les nœuds d'un autre. Consultez les instructions pour migrer des charges de travail entre des pools de nœuds.
Pour déterminer qui et quand les métadonnées d'instance ont été modifiées, vous pouvez consulter les informations sur les journaux d'audit Compute Engine ou rechercher des journaux à l'aide de l'explorateur de journaux à l'aide d'une requête semblable à celle-ci:
resource.type="gce_instance_group_manager"
protoPayload.methodName="v1.compute.instanceGroupManagers.setInstanceTemplate"
Dans les journaux, vous pouvez trouver l'adresse IP de l'utilisateur d'origine de la requête et le user-agent:
requestMetadata: {
callerIp: "REDACTED"
callerSuppliedUserAgent: "google-api-go-client/0.5 GoogleContainerEngine/v1"
}
La clé Cloud KMS est désactivée
Le message d'erreur suivant se produit si le compte de service par défaut de GKE ne peut pas accéder à la clé Cloud KMS.
Cluster problem detected (Kubernetes Engine Service Agent account unable to use CloudKMS key configured for Application Level encryption).
Pour résoudre ce problème, réactivez la clé désactivée.
Pour en savoir plus sur les secrets dans GKE, consultez la page Chiffrer des secrets au niveau de la couche d'application.