Résoudre les problèmes de serveur d’API et etcd dans Azure Kubernetes Services
Ce guide est conçu pour vous aider à identifier et à résoudre les problèmes improbables que vous pourriez rencontrer au sein du serveur d’API dans les déploiements Microsoft Azure Kubernetes Services (AKS).
Microsoft a testé la fiabilité et les performances du serveur d’API à une échelle de 5 000 nœuds et de 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 (SLO) Kubernetes. Si vous rencontrez des latences ou des délais d’attente élevés, c’est probablement parce qu’il y a une fuite de ressources sur le répertoire distribué etc
(etcd) ou qu’un client incriminé a des appels d’API excessifs.
Configuration requise
Outil Kubernetes kubectl . Pour installer kubectl à l’aide d’Azure CLI, exécutez la commande az aks install-cli .
AKS diagnostics journaux (en particulier, événements kube-audit) qui sont activés et envoyés à un espace de travail Log Analytics. Pour déterminer si les journaux sont collectés à l’aide du mode diagnostics spécifique à la ressource ou Azure, case activée 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 des problèmes liés au serveur d’API et etcd.
Plug-in kubectl-aks pour l’exécution de commandes directement sur les nœuds AKS sans utiliser le plan de contrôle Kubernetes.
Symptômes
Le tableau suivant décrit les symptômes courants des défaillances de serveur d’API :
Symptôme | Description |
---|---|
Délais d’attente du serveur d’API | Des délais d’attente 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 SLO Kubernetes. Par exemple, la kubectl commande prend plus de 30 secondes pour répertorier les pods. |
Pod de serveur d’API dans CrashLoopbackOff les échecs d’appel de webhook status ou de 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 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 par le nombre de demandes
Pour identifier les clients qui génèrent le plus de demandes (et potentiellement le plus de charge du serveur d’API), exécutez une requête qui ressemble au code suivant. La requête suivante répertorie les 10 principaux agents utilisateur en fonction du 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_
Remarque
Si votre requête ne retourne aucun résultat, vous avez peut-être sélectionné la mauvaise table pour interroger diagnostics journaux. 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 Journaux des ressources 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é à lui seul peut ne pas être une source 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’il rencontre.
Étape 2 : Identifier et tracer la latence moyenne des demandes de serveur d’API par agent utilisateur
Pour identifier la latence moyenne des demandes de serveur d’API par agent utilisateur comme tracé sur un graphique temporel, 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 demandes ». 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 vos 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 entraînent 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 du 99e centile (P99) des appels d’API sur 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 aux SLO amont Kubernetes. 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é matérielle n’est disponible pour guider les utilisateurs sur la scalabilité 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 de réseau bloque le trafic des nœuds de l’agent vers le serveur d’API
Une règle de 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 config import récupère les informations du groupe de machines virtuelles identiques pour tous les nœuds du cluster. Ensuite, la commande case activée-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 groupe identique sous-jacent instance.
Remarque
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’un échec de connexion s’est produit, 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é fuite les objets etcd et entraîne un ralentissement de etcd
Un problème courant est la création continue d’objets sans supprimer ceux inutilisés dans la base de données etcd. Cela peut entraîner des problèmes de performances lorsque etcd traite un trop grand nombre d’objets (plus de 10 000) de tout 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 case activée 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"
Remarque
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 qui occupent des ressources, envisagez de les supprimer. Par exemple, vous pouvez supprimer des 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 des valeurs de durée de vie (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’étiquette. 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 LIST
ou PUT
d’appels au serveur d’API.
Solution 3a : Régler 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 envahit le plan de contrôle
Si vous ne pouvez pas paramétrer le client, vous pouvez utiliser la fonctionnalité Priorité et impartialité 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 d’échouer.
La procédure suivante vous montre comment limiter l’API LIST Pods d’un client incriminé défini sur cinq appels simultanés :
Create 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
Create 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 provoquer un interblocage dans les pods de serveur d’API
Un webhook personnalisé, tel que Kyverno, peut provoquer un interblocage au sein des pods de serveur d’API.
Vérifiez les événements liés à votre serveur d’API. Vous pouvez voir des messages d’événement qui ressemblent au texte suivant :
Une erreur interne s’est produite : é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 de serveur d’API. Étant donné que ce scénario peut se produire au moment du 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 les 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 sur la résolution des problèmes 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 être modifiées 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.