Introduction
L'optimisation des performances des baux Kubernetes avec des exemples pratiques devrait aider les opérateurs à passer d'un problème observé à un résultat vérifié. Commencez par identifier la version installée, la topologie de déploiement, les prérequis et le composant exact inspecté.
Cet article se concentre sur les performances des baux Kubernetes pour les développeurs, les consultants DevOps et les équipes techniques de startups. Il relie l'optimisation des baux Kubernetes, le réglage des baux Kubernetes, la latence des baux Kubernetes et les goulots d'étranglement des baux Kubernetes à des commandes, des sorties attendues, des signaux d'échec et des décisions de récupération correspondant à la technologie choisie.
L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier le résultat et documenter la récupération si l'état attendu n'est pas atteint.
Comprendre les objets Lease de Kubernetes
Avant de procéder au réglage, vous devez comprendre ce qu'est un Lease et où il est utilisé. Un Lease est une primitive de coordination légère dans l'API Kubernetes. Il permet à un composant de détenir un verrou nommé pendant une durée limitée. Le détenteur renouvelle périodiquement le bail. Si le bail expire parce que le détenteur n'a pas réussi à le renouveler à temps, un autre composant peut prendre le relais.
Les baux sont utilisés par plusieurs composants principaux :
- kube-controller-manager : élection de leader pour les contrôleurs tels que le contrôleur de nœuds, le contrôleur de jobs et le contrôleur de comptes de service.
- kube-scheduler : élection de leader pour le planificateur.
- kube-apiserver : coordination de la migration des versions de stockage.
- Battement de cœur des nœuds : les versions récentes de Kubernetes utilisent des objets
Leaseau lieu des mises à jourNodeStatuspour les battements de cœur des nœuds, ce qui réduit la charge sur etcd.
Chaque bail possède une spec avec holderIdentity, leaseDurationSeconds, acquireTime, renewTime et leaseTransitions. Le champ leaseDurationSeconds indique au système la durée de validité d'un bail avant qu'il ne soit considéré comme expiré. Le champ holderIdentity identifie le détenteur actuel, comme un nom de pod ou un nom d'hôte.
Les problèmes de performance liés aux baux se manifestent généralement par :
- Élection de leader lente : lorsqu'un leader échoue, les nouvelles élections prennent trop de temps, entraînant des temps d'arrêt.
- Charge excessive sur etcd : trop de renouvellements de baux ou de battements de cœur trop fréquents peuvent surcharger etcd.
- Fluctuation de l'état des nœuds : si les battements de cœur des nœuds sont retardés, le plan de contrôle peut marquer un nœud sain comme
NotReady. - Blocage des contrôleurs : si un contrôleur perd son bail, les contrôleurs peuvent cesser de traiter jusqu'à l'élection d'un nouveau leader.
Comprendre ces symptômes vous aide à cibler le bon composant et à régler les paramètres appropriés.
Inventaire des versions et de l'environnement
Pour les performances des baux Kubernetes, l'inventaire des versions et de l'environnement doit nommer le composant concerné, la plage de versions prise en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat.
Identifier votre version de Kubernetes et l'utilisation des baux
Les baux ont été introduits en tant qu'API v1 dans Kubernetes 1.14. Ils sont stables dans Kubernetes 1.19 et versions ultérieures, mais leur implémentation diffère selon les versions. En tant qu'opérateur, vous devez connaître :
- La version du serveur Kubernetes et la distribution (par exemple,
v1.27.3,v1.28.2, EKS, GKE, Kubeadm). - Quels composants utilisent des baux. Par exemple, les battements de cœur des nœuds utilisant des baux sont activés par défaut à partir de Kubernetes 1.17, mais peuvent être désactivés dans certaines distributions.
- La version d'etcd et le backend de stockage, car les taux de renouvellement des baux affectent directement etcd.
- Le nombre de nœuds et de pods, qui détermine le taux de rotation des baux.
- Tout contrôleur ou opérateur personnalisé utilisant l'API
coordination.k8s.iopour sa propre élection de leader.
Prérequis pour une observation sûre :
kubectlconfiguré avec un accès en lecture seule au cluster, idéalement un compte de service avec les autorisationsget,listetwatchsurcoordination.k8s.io/leases.jqinstallé localement si vous souhaitez analyser la sortie JSON.- Metrics Server ou Prometheus si vous souhaitez surveiller les métriques liées aux baux.
- Accès en écriture à un espace de noms de test si vous prévoyez d'expérimenter avec des baux personnalisés.
Commandes d'observation en lecture seule
La première étape consiste à observer l'état actuel sans rien modifier. Utilisez ces commandes :
# Lister tous les baux dans l'espace de noms kube-system (où s'exécutent les composants du plan de contrôle)
kubectl get leases -n kube-system
# Décrire un bail spécifique pour voir l'identité du détenteur et les heures de renouvellement
kubectl describe lease -n kube-system kube-controller-manager
# Lister les baux dans tous les espaces de noms (peut être nombreux)
kubectl get leases --all-namespaces
# Examiner les baux de battement de cœur des nœuds (un par nœud dans l'espace de noms kube-node-lease)
kubectl get leases -n kube-node-lease
Exemple de sortie pour kubectl get leases -n kube-system :
NAME HOLDER AGE
kube-controller-manager ip-10-0-12-34.eu-west-1.compute.internal 5d
kube-scheduler ip-10-0-12-34.eu-west-1.compute.internal 5d
Pour une vue détaillée, utilisez :
kubectl get lease -n kube-system kube-controller-manager -o yaml
Une sortie réduite pourrait ressembler à ceci :
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:
name: kube-controller-manager
namespace: kube-system
spec:
holderIdentity: ip-10-0-12-34.eu-west-1.compute.internal
leaseDurationSeconds: 15
acquireTime: "2024-01-15T10:00:00Z"
renewTime: "2024-01-15T10:05:23Z"
leaseTransitions: 1
Ici, la durée du bail est de 15 secondes, ce qui signifie que le détenteur doit renouveler au moins toutes les 15 secondes. Si le détenteur ne renouvelle pas dans les 15 secondes, un autre prétendant peut acquérir le bail. Le champ renewTime indique le dernier renouvellement ; s'il est plus ancien que 15 secondes, le bail est expiré.
Garder le test local petit
Pour l'inventaire des versions et de l'environnement, gardez le test local petit. Appliquez un seul manifeste, inspectez les ressources générées et vérifiez le trafic avec kubectl port-forward ou un type de service local avant de passer à un équilibreur de charge cloud ou à un contrôleur d'entrée.
Par exemple, pour tester un bail personnalisé dans un espace de noms de bac à sable :
# Créer un espace de noms de test
kubectl create namespace lease-test
# Créer un manifeste de bail simple
cat <<EOF | kubectl apply -f -
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:
name: test-lease
namespace: lease-test
spec:
holderIdentity: "test-holder-1"
leaseDurationSeconds: 30
EOF
# Vérifier que le bail existe et l'inspecter
kubectl get lease test-lease -n lease-test -o yaml
Ce test local vous permet d'apprendre l'API sans risquer la production. Utilisez toujours un espace de noms dédié et évitez les charges de travail réelles tant que vous n'avez pas validé vos modifications.
Chemin de configuration sûr
Pour les performances des baux Kubernetes, le chemin de configuration sûr doit nommer le composant concerné, la plage de versions prise en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat.
Régler les paramètres du bail d'élection de leader
Si vous rencontrez une élection de leader lente, vous devrez peut-être régler la durée du bail et l'échéance de renouvellement pour les composants du plan de contrôle. Cela se fait généralement via des indicateurs de composant.
Pour kube-controller-manager et kube-scheduler, les indicateurs pertinents sont :
--leader-elect-lease-duration: la durée pendant laquelle les candidats non-leaders attendront pour forcer l'acquisition du leadership. La valeur par défaut est de 15 secondes.--leader-elect-renew-deadline: la durée pendant laquelle le leader en exercice retentera de rafraîchir le leadership avant d'abandonner. La valeur par défaut est de 10 secondes.--leader-elect-retry-period: la durée entre les tentatives des clients LeaderElector. La valeur par défaut est de 2 secondes.
Une durée de bail plus courte garantit un basculement plus rapide, mais augmente la fréquence de renouvellement et la charge sur etcd. Une durée de bail plus longue réduit la charge sur etcd mais ralentit le basculement. Le compromis dépend de vos exigences de disponibilité.
Exemple d'ajustement pour un basculement plus rapide (pour un plan de contrôle avec des exigences de haute disponibilité) :
# kube-controller-manager.yaml (manifeste de pod statique sur un nœud du plan de contrôle)
spec:
containers:
- command:
- kube-controller-manager
- --leader-elect=true
- --leader-elect-lease-duration=10s
- --leader-elect-renew-deadline=7s
- --leader-elect-retry-period=2s
Avant d'appliquer, observez les valeurs actuelles dans le composant en cours d'exécution :
# Sur un nœud du plan de contrôle, vérifiez les indicateurs de kube-controller-manager
ps aux | grep kube-controller-manager
# Ou vérifiez le manifeste de pod statique
cat /etc/kubernetes/manifests/kube-controller-manager.yaml
La sortie attendue montre les indicateurs actuels. Après avoir modifié le manifeste, le kubelet redémarre le pod statique. Vérifiez que le composant devient prêt :
kubectl get pods -n kube-system | grep kube-controller-manager
# Attendez que le pod soit Running et READY 1/1
# Vérifiez à nouveau le bail pour confirmer la nouvelle durée de détention
kubectl describe lease -n kube-system kube-controller-manager
Recherchez une mise à jour fréquente de renewTime. Si le composant n'est pas stable, revenez au manifeste précédent.
Régler les baux de battement de cœur des nœuds
Pour les grands clusters, les battements de cœur des nœuds via des baux peuvent entraîner une pression d'écriture sur etcd. La fréquence des battements de cœur des nœuds est contrôlée par le kubelet :
--node-status-update-frequency: à quelle fréquence le kubelet publie l'état du nœud au maître. La valeur par défaut est de 10 s.--node-status-report-frequency: à quelle fréquence le kubelet signale l'état du nœud lorsqu'il n'y a pas de changement. La valeur par défaut est de 1 m (mais les battements de cœur des nœuds via des baux sont envoyés à chaquenode-status-update-frequency).
Si vous souhaitez réduire la charge sur etcd due aux battements de cœur, vous pouvez augmenter la fréquence de mise à jour (par exemple, à 20 s). Cependant, cela augmente également le temps nécessaire au plan de contrôle pour remarquer un nœud mort. Une valeur équilibrée est souvent de 15 à 20 s pour les grands clusters.
Exemple de modification de la configuration du kubelet :
# /var/lib/kubelet/config.yaml
nodeStatusUpdateFrequency: "20s"
nodeStatusReportFrequency: "5m"
Appliquez la modification en redémarrant le kubelet (sur les nœuds basés sur systemd) :
sudo systemctl restart kubelet
Vérifiez l'intervalle de battement de cœur en vérifiant le renewTime d'un bail de nœud :
# Choisissez un nœud et surveillez ses heures de renouvellement de bail
kubectl get lease -n kube-node-lease ip-10-0-1-100.eu-west-1.compute.internal -w
Vous devriez voir renewTime se mettre à jour environ toutes les 20 secondes.
Configurer les baux des contrôleurs personnalisés
Les contrôleurs personnalisés construits avec client-go utilisent souvent l'élection de leader. Vous pouvez configurer les trois mêmes paramètres via la structure LeaderElectionConfig dans le code du contrôleur. Par exemple :
leaderelection.LeaderElectionConfig{
LeaseDuration: 15 * time.Second,
RenewDeadline: 10 * time.Second,
RetryPeriod: 2 * time.Second,
}
Si vous exploitez un contrôleur, assurez-vous que les valeurs sont appropriées. Une LeaseDuration trop courte peut faire fluctuer le contrôleur s'il ne peut pas renouveler à temps en raison d'une limitation du processeur. Surveillez les journaux du contrôleur pour les messages d'élection de leader :
kubectl logs -n my-controller deploy/my-controller | grep -i leader
Recherchez des lignes telles que successfully acquired lease ou failed to renew lease. Si vous voyez des échecs de renouvellement fréquents, envisagez d'augmenter les durées.
Vérification et diagnostics
Pour les performances des baux Kubernetes, la vérification et les diagnostics doivent nommer le composant concerné, la plage de versions prise en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat.
Surveiller les taux de renouvellement des baux
Vous pouvez surveiller les taux de renouvellement des baux à l'aide des métriques Kubernetes. Le kube-controller-manager et le kube-scheduler exposent des métriques sur l'élection de leader. Vous pouvez les collecter via Prometheus.
Pour kube-controller-manager, la métrique leader_election_master_status indique si l'instance est leader (1) ou non (0). La métrique leader_election_renewals_total compte les renouvellements.
Exemples de requêtes PromQL :
# Statut actuel de l'élection de leader
leader_election_master_status{job="kube-controller-manager"}
# Taux de renouvellements de bail par minute
rate(leader_election_renewals_total{job="kube-controller-manager"}[5m]) * 60
Si le taux de renouvellement est beaucoup plus élevé que prévu (par exemple, plus de 1 par seconde), vous devrez peut-être augmenter LeaseDuration.
Pour afficher ces métriques sans Prometheus, vous pouvez accéder directement au point de terminaison des métriques :
# Faire suivre le port vers le pod kube-controller-manager (s'il s'exécute comme un pod statique)
kubectl port-forward -n kube-system pod/kube-controller-manager-<node-name> 10257:10257
# Dans un autre terminal
curl -k https://localhost:10257/metrics | grep leader_election
(Remarque : le port et les paramètres TLS varient selon le cluster ; vérifiez les indicateurs --secure-port et --bind-address.)
Diagnostiquer les problèmes de battement de cœur des nœuds
Si les nœuds fluctuent entre Ready et NotReady, le problème peut être dû à des retards de renouvellement du bail. Vérifiez les horodatages du bail du nœud :
# Obtenir le renewTime actuel pour un bail de nœud spécifique
kubectl get lease -n kube-node-lease <node-name> -o jsonpath='{.spec.renewTime}{"\n"}'
# Obtenir l'heure système sur le nœud (via SSH ou kubectl node-shell)
date -u
Si le renewTime est plus ancien que la fréquence de mise à jour de l'état du nœud, le kubelet peut être incapable de mettre à jour le bail. Vérifiez les journaux du kubelet pour les erreurs :
# Sur le nœud
journalctl -u kubelet -n 50 --no-pager
Recherchez des messages tels que Failed to update lease, etcdserver: request timed out ou connection refused. Ceux-ci indiquent des problèmes etcd ou réseau.
Vérifier le basculement de l'élection de leader
Pour tester le basculement, vous pouvez simuler une défaillance du leader en supprimant le pod leader (dans un environnement de test). Par exemple, pour le kube-scheduler :
# Déterminer le leader actuel à partir du bail
kubectl get lease -n kube-system kube-scheduler -o jsonpath='{.spec.holderIdentity}{"\n"}'
# Identifier le pod correspondant à cette identité
kubectl get pods -n kube-system -o wide | grep <holder-identity>
# Supprimer ce pod pour forcer une nouvelle élection
kubectl delete pod -n kube-system <scheduler-leader-pod>
# Surveiller le bail pour voir quand le détenteur change
kubectl get lease -n kube-system kube-scheduler -w
Comportement attendu : en quelques secondes, le holderIdentity du bail passe au réplica suivant du planificateur et leaseTransitions s'incrémente. Si le basculement prend trop de temps, vérifiez les durées du bail et l'état de préparation des autres réplicas.
Modes de défaillance et récupération
Pour les performances des baux Kubernetes, les modes de défaillance et la récupération doivent nommer le composant concerné, la plage de versions prise en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat.
Modes de défaillance courants
- Surcharge d'etcd : trop de renouvellements de baux de la part de nombreux contrôleurs peuvent submerger etcd, entraînant une latence élevée et des délais d'attente de requête. Les symptômes comprennent une augmentation de
etcd_disk_wal_fsync_duration_seconds, une utilisation élevée du processeur sur etcd et des réponses lentes de l'API.
- Dérive d'horloge : si les horloges des nœuds dérivent, les horodatages de renouvellement du bail peuvent être erronés, entraînant une expiration prématurée ou un basculement retardé. Ceci est particulièrement problématique dans les clusters multi-datacenters.
- Partitionnement du réseau : si le leader est isolé du réseau etcd, il ne peut pas renouveler son bail. Après l'expiration du bail, un autre nœud peut prendre le relais, mais l'ancien leader peut encore penser qu'il est actif, entraînant un comportement de split-brain. Ceci est atténué par un cloisonnement approprié (pas toujours mis en œuvre).
- Épuisement des ressources : si le composant détenant le bail est limité en processeur ou manque de mémoire, il peut échouer à renouveler à temps. Cela peut provoquer des changements de leader fréquents et un comportement instable.
Étapes de récupération
Si vous rencontrez des défaillances liées aux baux, suivez ces étapes de récupération :
Étape 1 : Arrêter l'hémorragie - Si un contrôleur fluctue, réduisez la charge ou suspendez les opérations non critiques. Par exemple, réduisez le nombre de réplicas ou suspendez temporairement les tâches cron.
Étape 2 : Inspecter les journaux et les métriques - Examinez les journaux du composant et les métriques etcd. Pour etcd, vérifiez :
# Métriques etcd (via port-forward ou directement)
curl http://localhost:2379/metrics | grep -E 'etcd_server_leader_changes_seen_total|etcd_disk_wal_fsync_duration_seconds'
Un etcd_server_leader_changes_seen_total élevé indique une instabilité du leader etcd.
Étape 3 : Ajuster les paramètres du bail - Augmentez temporairement leaseDurationSeconds et renewDeadline pour réduire la pression de renouvellement. Par exemple, définissez leaseDurationSeconds sur 30 s et renewDeadline sur 20 s. Cela donne au composant plus de temps pour récupérer.
Étape 4 : Corriger la cause profonde - Si etcd est surchargé, envisagez de déplacer les objets de bail vers un cluster etcd séparé ou de régler etcd. Si la dérive d'horloge est un problème, configurez correctement NTP.
Étape 5 : Vérifier la stabilité - Après les modifications, surveillez pendant au moins 15 minutes. Vérifiez que le renouvellement du bail est régulier et qu'aucun basculement inattendu ne se produit.
Annuler les modifications
Ayez toujours un plan de restauration. Pour les composants de pod statique, conservez une sauvegarde du fichier manifeste :
cp /etc/kubernetes/manifests/kube-controller-manager.yaml /root/kube-controller-manager.yaml.bak
Si une modification cause des problèmes, restaurez la sauvegarde et redémarrez le kubelet :
cp /root/kube-controller-manager.yaml.bak /etc/kubernetes/manifests/kube-controller-manager.yaml
sudo systemctl restart kubelet
Pour les modifications de configuration du kubelet, revenez au fichier de configuration et redémarrez le kubelet.
Liste de contrôle des opérations
Pour les performances des baux Kubernetes, la liste de contrôle des opérations doit nommer le composant concerné, la plage de versions prise en charge, les prérequis, une observation en lecture seule, le plus petit changement justifié et la commande ou le signal qui vérifie le résultat.
Utilisez cette liste de contrôle avant et après le réglage :
- [ ] Confirmer la version et la distribution de Kubernetes (
kubectl version --shortoukubectl version). - [ ] Identifier les composants utilisant des baux : lister les baux dans
kube-systemetkube-node-lease. - [ ] Capturer les heures de renouvellement de bail de référence et l'état de l'élection de leader.
- [ ] Déterminer si le problème de performance est lié aux baux (vérifier les journaux, les métriques et les symptômes).
- [ ] Sélectionner le plus petit changement : ajuster un paramètre à la fois.
- [ ] Appliquer le changement dans un environnement de test d'abord, si possible.
- [ ] Vérifier le changement avec des commandes concrètes (par exemple, vérifier
renewTime, l'état du leader). - [ ] Surveiller pendant au moins 15 minutes pour la stabilité.
- [ ] Documenter le changement, le résultat attendu et les étapes de restauration.
- [ ] En cas d'échec, exécuter la restauration et réévaluer.
De plus, tenez compte des points pratiques suivants :
- Utiliser un accès en lecture seule : commencez toujours par des commandes en lecture seule ; évitez de faire des modifications sans comprendre l'état actuel.
- Protéger les valeurs sensibles : évitez de mettre des secrets dans les commandes de configuration ; utilisez des variables d'environnement ou des cartes de configuration.
- Limiter le rayon d'impact : modifiez un composant à la fois ; évitez les modifications simultanées du gestionnaire de contrôleurs et du planificateur.
- Vérifier avec des signaux : utilisez
kubectl get lease -o yamlpour confirmer les mises à jour derenewTime; utilisez les métriques pour vérifier les taux de renouvellement. - Conserver la documentation : enregistrez les valeurs d'origine pour pouvoir revenir rapidement.
Conclusion
L'optimisation des performances des baux Kubernetes avec des exemples pratiques n'est utile que si chaque recommandation est versionnée, observable et réversible lorsque la technologie le permet. Copier une commande sans vérifier les prérequis et la sortie attendue n'est pas une procédure d'exploitation.
Comme prochaine étape, choisissez une vérification à faible risque pour les performances des baux Kubernetes, enregistrez l'état actuel, exécutez la vérification documentée, comparez le résultat avec le signal attendu et examinez les dépendances telles que Node, Kubectl et Event.
Un flux de travail technique fiable rend les défaillances visibles, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision.
Rappelez-vous : les baux sont des primitives de coordination qui assurent le bon fonctionnement du plan de contrôle de votre cluster. En comprenant leur comportement et en les réglant avec soin, vous pouvez améliorer les temps de basculement, réduire la charge sur etcd et garantir que le rapport de santé des nœuds fonctionne comme prévu. Utilisez les commandes et les vérifications de ce guide pour construire une pratique opérationnelle solide autour des performances des baux.