Résoudre des problèmes de serveur d’API et d’etcd dans Azure Kubernetes Services
Ce guide est conçu pour vous aider à identifier et résoudre les problèmes peu probables que vous pouvez rencontrer dans le serveur d’API dans les déploiements AKS (Microsoft Azure Kubernetes Services).
Microsoft a testé la fiabilité et les performances du serveur d’API à une échelle de 5 000 nœuds et 200 000 pods. Le cluster qui contient le serveur d’API peut effectuer automatiquement un scale-out et fournir des objectifs de niveau de service Kubernetes (SLA). Si vous rencontrez des latences ou des délais d’attente élevés, c’est probablement parce qu’il existe une fuite de ressources sur le répertoire distribué etc
(etcd) ou qu’un client incriminé a des appels d’API excessifs.
Prerequisites
Outil Kubernetes kubectl . Pour installer kubectl à l’aide d’Azure CLI, exécutez la commande az aks install-cli .
Journaux de diagnostic AKS (en particulier, événements kube-audit) activés et envoyés à un espace de travail Log Analytics. Pour déterminer si les journaux d’activité sont collectés à l’aide du mode de diagnostic spécifique aux ressources ou Azure, consultez le panneau Paramètres de diagnostic dans le Portail Azure.
Niveau Standard pour les clusters AKS. Si vous utilisez le niveau Gratuit, le serveur d’API et etcd contiennent des ressources limitées. Les clusters AKS du niveau Gratuit ne fournissent pas de haute disponibilité. Il s’agit souvent de la cause racine du serveur d’API et des problèmes etcd.
Plug-in kubectl-aks pour l’exécution de commandes directement sur des nœuds AKS sans utiliser le plan de contrôle Kubernetes.
Contrôles d'intégrité de base
Événements d’intégrité des ressources
AKS fournit des événements d’intégrité des ressources pour les temps d’arrêt des composants critiques. Avant de continuer, assurez-vous qu’aucun événement critique n’est signalé dans Resource Health.
Diagnostiquer et résoudre les problèmes
AKS fournit une catégorie de résolution des problèmes dédiée pour la disponibilité et les performances du plan de contrôle et du cluster.
Symptômes
Le tableau suivant présente les symptômes courants des défaillances du serveur d’API :
Symptôme | Description |
---|---|
Délais d’attente du serveur d’API | Délais d’expiration fréquents qui dépassent les garanties dans le contrat SLA du serveur d’API AKS. Par exemple, kubectl les commandes expirent. |
Latences élevées | Latences élevées qui font échouer les SLA Kubernetes. Par exemple, la kubectl commande prend plus de 30 secondes pour répertorier les pods. |
Échecs d’appel du serveur d’API dans CrashLoopbackOff l’état ou les échecs d’appel webhook |
Vérifiez que vous n’avez pas de webhook d’admission personnalisé (tel que le moteur de stratégie Kyverno ) qui bloque les appels au serveur d’API. |
Liste de contrôle pour la résolution des problèmes
Si vous rencontrez des temps de latence élevés, suivez ces étapes pour identifier le client incriminé et les types d’appels d’API qui échouent.
Étape 1 : Identifier les principaux agents utilisateur en fonction du nombre de requêtes
Pour identifier les clients qui génèrent le plus de requêtes (et potentiellement la charge de serveur d’API la plus élevée), exécutez une requête semblable au code suivant. La requête suivante répertorie les 10 principaux agents utilisateur par le nombre de demandes de serveur d’API envoyées.
AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| summarize count() by UserAgent
| top 10 by count_
| project UserAgent, count_
Note
Si votre requête ne retourne aucun résultat, vous avez peut-être sélectionné la table incorrecte pour interroger les journaux de diagnostic. En mode spécifique à la ressource, les données sont écrites dans des tables individuelles en fonction de la catégorie de la ressource. Les journaux de diagnostic sont écrits dans la AKSAudit
table. En mode diagnostics Azure, toutes les données sont écrites dans la AzureDiagnostics
table. Pour plus d’informations, consultez la page Journaux de ressources dans Azure.
Bien qu’il soit utile de savoir quels clients génèrent le volume de requêtes le plus élevé, un volume de requêtes élevé seul peut ne pas être une cause de préoccupation. Un meilleur indicateur de la charge réelle générée par chaque client sur le serveur d’API est la latence de réponse qu’ils rencontrent.
Étape 2 : Identifier et tracer la latence moyenne des demandes de serveur d’API par agent utilisateur
Pour identifier la latence moyenne des requêtes de serveur d’API par agent utilisateur comme tracé sur un graphique de temps, exécutez la requête suivante :
AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| extend start_time = RequestReceivedTime
| extend end_time = StageReceivedTime
| extend latency = datetime_diff('millisecond', end_time, start_time)
| summarize avg(latency) by UserAgent, bin(start_time, 5m)
| render timechart
Cette requête est un suivi de la requête dans la section « Identifier les principaux agents utilisateur par le nombre de requêtes ». Il peut vous donner plus d’informations sur la charge réelle générée par chaque agent utilisateur au fil du temps.
Conseil
En analysant ces données, vous pouvez identifier des modèles et des anomalies qui peuvent indiquer des problèmes sur votre cluster ou applications AKS. Par exemple, vous remarquerez peut-être qu’un utilisateur particulier rencontre une latence élevée. Ce scénario peut indiquer le type d’appels d’API qui provoquent une charge excessive sur le serveur d’API ou etcd.
Étape 3 : Identifier les appels d’API incorrects pour un agent utilisateur donné
Exécutez la requête suivante pour tabuler la latence de 99e centile (P99) des appels d’API entre différents types de ressources pour un client donné :
AKSAudit
| where TimeGenerated between(now(-1h)..now()) // When you experienced the problem
| extend HttpMethod = Verb
| extend Resource = tostring(ObjectRef.resource)
| where UserAgent == "DUMMYUSERAGENT" // Filter by name of the useragent you are interested in
| where Resource != ""
| extend start_time = RequestReceivedTime
| extend end_time = StageReceivedTime
| extend latency = datetime_diff('millisecond', end_time, start_time)
| summarize p99latency=percentile(latency, 99) by HttpMethod, Resource
| render table
Les résultats de cette requête peuvent être utiles pour identifier les types d’appels d’API qui échouent les slaOs Kubernetes en amont. Dans la plupart des cas, un client incriminé peut effectuer trop d’appels LIST
sur un grand ensemble d’objets ou d’objets trop volumineux. Malheureusement, aucune limite de scalabilité difficile n’est disponible pour guider les utilisateurs sur l’extensibilité du serveur d’API. Les limites de scalabilité du serveur d’API ou etcd dépendent de différents facteurs expliqués dans les seuils d’extensibilité Kubernetes.
Cause 1 : une règle réseau bloque le trafic des nœuds d’agent vers le serveur d’API
Une règle réseau peut bloquer le trafic entre les nœuds de l’agent et le serveur d’API.
Pour vérifier si une stratégie réseau mal configurée bloque la communication entre le serveur d’API et les nœuds de l’agent, exécutez les commandes kubectl-aks suivantes :
kubectl aks config import \
--subscription <mySubscriptionID> \
--resource-group <myResourceGroup> \
--cluster-name <myAKSCluster>
kubectl aks check-apiserver-connectivity --node <myNode>
La commande d’importation de configuration récupère les informations du groupe de machines virtuelles identiques pour tous les nœuds du cluster. Ensuite, la commande check-apiserver-connectivity utilise ces informations pour vérifier la connectivité réseau entre le serveur d’API et un nœud spécifié, en particulier pour son instance de groupe identique sous-jacente.
Note
Si la sortie de la check-apiserver-connectivity
commande contient le Connectivity check: succeeded
message, la connectivité réseau n’est pas bloquée.
Solution 1 : Corriger la stratégie réseau pour supprimer le blocage du trafic
Si la sortie de la commande indique qu’une défaillance de connexion s’est produite, reconfigurez la stratégie réseau afin qu’elle ne bloque pas inutilement le trafic entre les nœuds de l’agent et le serveur d’API.
Cause 2 : Un client incriminé fuites d’objets etcd et entraîne un ralentissement de etcd
Un problème courant est la création continue d’objets sans supprimer les objets inutilisés dans la base de données etcd. Cela peut entraîner des problèmes de performances lorsque etcd traite d’un trop grand nombre d’objets (plus de 10 000) de n’importe quel type. Une augmentation rapide des modifications sur ces objets peut également entraîner le dépassement de la taille de la base de données etcd (4 gigaoctets par défaut).
Pour vérifier l’utilisation de la base de données etcd, accédez à Diagnostiquer et résoudre les problèmes dans le Portail Azure. Exécutez l’outil de diagnostic des problèmes de disponibilité Etcd en recherchant « etcd » dans la zone de recherche. L’outil de diagnostic vous montre la répartition de l’utilisation et la taille totale de la base de données.
Si vous souhaitez simplement afficher rapidement la taille actuelle de votre base de données etcd en octets, exécutez la commande suivante :
kubectl get --raw /metrics | grep -E "etcd_db_total_size_in_bytes|apiserver_storage_size_bytes|apiserver_storage_db_total_size_in_bytes"
Note
Le nom de la métrique dans la commande précédente est différent pour les différentes versions de Kubernetes. Pour Kubernetes 1.25 et versions antérieures, utilisez etcd_db_total_size_in_bytes
. Pour Kubernetes 1.26 à 1.28, utilisez apiserver_storage_db_total_size_in_bytes
.
Solution 2 : Définir des quotas pour la création d’objets, supprimer des objets ou limiter la durée de vie des objets dans etcd
Pour empêcher etcd d’atteindre la capacité et de provoquer un temps d’arrêt du cluster, vous pouvez limiter le nombre maximal de ressources créées. Vous pouvez également ralentir le nombre de révisions générées pour les instances de ressources. Pour limiter le nombre d’objets qui peuvent être créés, vous pouvez définir des quotas d’objets.
Si vous avez identifié des objets qui ne sont plus utilisés, mais occupent des ressources, envisagez de les supprimer. Par exemple, vous pouvez supprimer les travaux terminés pour libérer de l’espace :
kubectl delete jobs --field-selector status.successful=1
Pour les objets qui prennent en charge le nettoyage automatique, vous pouvez définir les valeurs Time to Live (TTL) pour limiter la durée de vie de ces objets. Vous pouvez également étiqueter vos objets afin de pouvoir supprimer en bloc tous les objets d’un type spécifique à l’aide de sélecteurs d’étiquettes. Si vous établissez des références de propriétaire entre les objets, tous les objets dépendants sont automatiquement supprimés après la suppression de l’objet parent.
Cause 3 : Un client incriminé effectue des appels LIST ou PUT excessifs
Si vous déterminez que etcd n’est pas surchargé avec trop d’objets, un client incriminé peut effectuer trop d’appels ou PUT
un trop grand nombre LIST
d’appels au serveur d’API.
Solution 3a : Ajuster votre modèle d’appel d’API
Envisagez de régler le modèle d’appel d’API de votre client pour réduire la pression sur le plan de contrôle.
Solution 3b : Limiter un client qui a accablant le plan de contrôle
Si vous ne pouvez pas régler le client, vous pouvez utiliser la fonctionnalité Priorité et Équité dans Kubernetes pour limiter le client. Cette fonctionnalité peut aider à préserver l’intégrité du plan de contrôle et à empêcher d’autres applications de échouer.
La procédure suivante vous montre comment limiter l’API LIST Pods d’un client incriminé définie sur cinq appels simultanés :
Créez un FlowSchema qui correspond au modèle d’appel d’API du client incriminé :
apiVersion: flowcontrol.apiserver.k8s.io/v1beta2 kind: FlowSchema metadata: name: restrict-bad-client spec: priorityLevelConfiguration: name: very-low-priority distinguisherMethod: type: ByUser rules: - resourceRules: - apiGroups: [""] namespaces: ["default"] resources: ["pods"] verbs: ["list"] subjects: - kind: ServiceAccount serviceAccount: name: bad-client-account namespace: default
Créez une configuration de priorité inférieure pour limiter les appels d’API incorrects du client :
apiVersion: flowcontrol.apiserver.k8s.io/v1beta2 kind: PriorityLevelConfiguration metadata: name: very-low-priority spec: limited: assuredConcurrencyShares: 5 limitResponse: type: Reject type: Limited
Observez l’appel limité dans les métriques du serveur d’API.
kubectl get --raw /metrics | grep "restrict-bad-client"
Cause 4 : un webhook personnalisé peut entraîner un interblocage dans les pods du serveur d’API
Un webhook personnalisé, tel que Kyverno, peut entraîner un blocage dans les pods du serveur d’API.
Vérifiez les événements liés à votre serveur d’API. Vous pouvez voir les messages d’événement qui ressemblent au texte suivant :
Erreur interne survenue : échec de l’appel du webhook « mutate.kyverno.svc-fail » : échec de l’appel du webhook : Post « https://kyverno-system-kyverno-system-svc.kyverno-system.svc:443/mutate/fail?timeout=10s": write unix @->/tunnel-uds/proxysocket : write : broken pipe
Dans cet exemple, le webhook de validation bloque la création de certains objets serveur d’API. Étant donné que ce scénario peut se produire pendant le temps de démarrage, le serveur d’API et les pods Konnectivity ne peuvent pas être créés. Par conséquent, le webhook ne peut pas se connecter à ces pods. Cette séquence d’événements provoque l’interblocage et le message d’erreur.
Solution 4 : Supprimer des configurations de webhook
Pour résoudre ce problème, supprimez les configurations de webhook de validation et de mutation. Pour supprimer ces configurations de webhook dans Kyverno, consultez l’article de résolution des problèmes de Kyverno.
Exclusion de responsabilité sur les coordonnées externes
Microsoft fournit des informations de contacts externes afin de vous aider à obtenir un support technique sur ce sujet. Ces informations de contact peuvent changer sans préavis. Microsoft ne garantit pas l’exactitude des informations concernant les sociétés externes.
Exclusion de responsabilité de tiers
Les produits tiers mentionnés dans le présent article sont fabriqués par des sociétés indépendantes de Microsoft. Microsoft exclut toute garantie, implicite ou autre, concernant les performances ou la fiabilité de ces produits.
Contactez-nous pour obtenir de l’aide
Pour toute demande ou assistance, créez une demande de support ou posez une question au support de la communauté Azure. Vous pouvez également soumettre des commentaires sur les produits à la communauté de commentaires Azure.