Introduction
L'architecture des baux Kubernetes est un mécanisme fondamental mais souvent négligé qui coordonne les composants distribués sans couplage étroit. Un bail (Lease) est un objet léger du groupe d'API coordination.k8s.io/v1 qui accorde à un détenteur des droits exclusifs ou limités dans le temps sur une ressource partagée. En pratique, les baux alimentent des fonctions critiques telles que l'élection de leader des contrôleurs, les battements de cœur des nœuds et les verrous distribués personnalisés.
Ce guide s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui doivent exploiter Kubernetes de manière fiable. Nous irons au-delà de la théorie pour vous montrer exactement comment les baux sont structurés, comment ils circulent dans le système et comment les dépanner avec des commandes concrètes et des sorties attendues. L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, éviter les secrets dans les commandes, vérifier chaque résultat et documenter les chemins de récupération.
Nous couvrirons l'inventaire des versions et de l'environnement, le chemin de configuration sûr, la vérification et le diagnostic, les modes de défaillance et la récupération, ainsi qu'une liste de contrôle des opérations. Chaque section comprend des commandes kubectl pratiques, des exemples et des signaux à surveiller.
Inventaire des versions et de l'environnement
Avant de toucher à toute configuration liée aux baux, vous devez connaître la version de votre cluster, l'implémentation du bail utilisée et les composants qui en dépendent. Les baux sont activés par défaut dans Kubernetes 1.14+ via le groupe d'API coordination.k8s.io. Cependant, le comportement de l'élection de leader peut changer entre les versions, alors vérifiez toujours.
Commandes d'inventaire rapides :
kubectl version --short
kubectl api-versions | grep coordination
kubectl get --raw /apis/coordination.k8s.io/v1 | jq .
La sortie attendue inclut coordination.k8s.io/v1 et une liste de ressources comme leases. Si vous voyez uniquement coordination.k8s.io/v1beta1, vous êtes sur une version plus ancienne (pré-1.19) et devriez planifier une mise à niveau.
Inspectez les baux existants dans tous les espaces de noms :
kubectl get leases --all-namespaces
Exemple de sortie :
NAMESPACE NAME HOLDER AGE
kube-system kube-controller-manager ip-10-0-0-10.ec2.internal_12345678-1234-... 10d
kube-system kube-scheduler ip-10-0-0-11.ec2.internal_87654321-4321-... 10d
kube-node-lease ip-10-0-0-20 ip-10-0-0-20 5m
Cela vous indique quels composants utilisent des baux et qui les détient actuellement. Notez les noms des baux : kube-controller-manager, kube-scheduler et les baux par nœud dans l'espace de noms kube-node-lease. L'identité du détenteur est généralement un nom de pod ou de nœud avec un suffixe UUID unique pour l'élection de leader.
Vérifiez les prérequis pour votre modification prévue. Par exemple, si vous souhaitez ajouter un bail personnalisé pour votre application, vous avez besoin des autorisations RBAC pour créer des leases dans votre espace de noms. Vérifiez avec :
kubectl auth can-i create leases -n your-namespace
Si le résultat est no, vous devez créer un Role et un RoleBinding. Gardez le test local petit : appliquez un manifeste ciblé et inspectez son effet.
Chemin de configuration sûr
Un objet de bail est simple, mais une mauvaise configuration de sa durée, de son temps de renouvellement ou de son identité peut provoquer un split-brain ou des problèmes de vivacité. La spécification comporte quatre champs :
holderIdentity: chaîne qui identifie le détenteur actuel (par exemple, le nom du pod).leaseDurationSeconds: durée pendant laquelle un détenteur peut conserver le bail sans le renouveler.acquireTime: horodatage de l'acquisition du bail.renewTime: horodatage du dernier renouvellement par le détenteur.leaseTransitions: nombre de fois où le bail a changé de détenteur.
Voici un manifeste minimal pour un bail d'élection de leader personnalisé :
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:
name: my-app-leader
namespace: default
spec:
holderIdentity: "my-app-pod-0"
leaseDurationSeconds: 15
acquireTime: "2025-03-01T10:00:00Z"
renewTime: "2025-03-01T10:00:00Z"
leaseTransitions: 0
Appliquez-le avec kubectl apply -f lease.yaml et vérifiez la création :
kubectl get lease my-app-leader -o yaml
Le holderIdentity doit correspondre au nom de votre pod. En production, vous ne définiriez pas ces valeurs manuellement ; votre code d'application utiliserait une bibliothèque d'élection de leader (par exemple, le package leaderelection de client-go) pour créer et renouveler le bail.
Bonnes pratiques de configuration :
leaseDurationSecondsdoit être 2 à 3 fois l'intervalle de renouvellement. Si l'intervalle de renouvellement est de 5 secondes, définissez la durée à 15 secondes.- Utilisez des identités uniques : les noms de pod sont bons, mais ajoutez un UUID si les pods peuvent être replanifiés avec le même nom.
- Ne codez jamais en dur des secrets dans les annotations du bail ou dans
holderIdentity.
Approche de changement sûr :
Commencez en lecture seule :
kubectl get lease my-app-leader -o json | jq .spec
Capturez l'état actuel et les horodatages. Ensuite, effectuez une petite modification, comme ajuster leaseDurationSeconds de 15 à 20, et appliquez. Surveillez le temps de renouvellement pour vous assurer que le détenteur continue de renouveler.
Pour les tests locaux, vous pouvez utiliser kubectl port-forward pour accéder à un service qui expose le statut de leader. Mais d'abord, vérifiez que l'objet de bail lui-même est mis à jour.
Vérification et diagnostic
Vérifier le comportement du bail nécessite d'observer à la fois l'état de l'objet et les journaux de l'application. Commencez par le bail :
kubectl get lease my-app-leader -o jsonpath='{.spec.holderIdentity}{"\n"}'
Sortie attendue : my-app-pod-0. Si vide, aucun leader n'est élu.
Vérifiez les horodatages de renouvellement :
kubectl get lease my-app-leader -o jsonpath='{.spec.renewTime}{"\n"}'
Comparez avec l'heure actuelle. Si renewTime est plus ancien que leaseDurationSeconds, le bail a expiré et le leader doit se retirer.
Diagnostic de l'élection de leader des contrôleurs :
Pour les contrôleurs intégrés comme kube-controller-manager, vous pouvez consulter les journaux pour les événements d'élection :
kubectl logs -n kube-system kube-controller-manager-ip-10-0-0-10 | grep -i "leader"
Recherchez des lignes comme :
I0301 10:00:00.123456 1 leaderelection.go:258] successfully acquired lease kube-system/kube-controller-manager
Si vous voyez des échecs répétés d'acquisition, inspectez l'objet de bail :
kubectl get lease -n kube-system kube-controller-manager -o yaml
Vérifiez si l'identité du détenteur est un pod qui n'existe plus. Si c'est le cas, le nouveau pod peut être incapable de prendre le relais si l'ancien bail n'a pas expiré. Vous pouvez supprimer le bail pour forcer une réélection (avec prudence, car cela perturbe brièvement le contrôleur).
Utilisez kubectl describe pour le contexte des événements :
kubectl describe lease my-app-leader
Bien que les baux aient peu d'événements, la sortie de description montre la spécification et le statut actuels. Pour les pods utilisant des baux, kubectl describe pod peut afficher des événements liés, tels que LeaderElection ou FailedToUpdateLease.
Vérifiez les journaux de votre application pour les mises à jour du bail :
Si vous utilisez l'élection de leader de client-go, activez la journalisation verbeuse pour voir les tentatives de renouvellement. Par exemple, avec klog niveau 4 :
I0301 10:00:05.000000 1 leaderelection.go:268] successfully renewed lease default/my-app-leader
Si vous voyez des messages failed to renew lease, vérifiez la connectivité réseau au serveur API et le décalage d'horloge entre les nœuds.
Modes de défaillance et récupération
Les baux peuvent échouer de plusieurs manières, conduisant à l'absence de leader, à plusieurs leaders ou à des détenteurs obsolètes. Nous couvrons les scénarios les plus courants et comment récupérer.
1. Bail expiré et non renouvelé
Cause : Le pod leader s'est écrasé ou a perdu la connectivité, et la durée du bail est passée.
Symptôme : renewTime est plus ancien que leaseDurationSeconds ; un nouveau pod ne parvient pas à acquérir car il attend l'expiration.
Récupération :
# Vérifiez si le pod leader est en cours d'exécution
kubectl get pods -l app=my-app
# Si non, supprimez le bail obsolète pour permettre une acquisition immédiate
kubectl delete lease my-app-leader
Vérifiez ensuite que le nouveau pod devient détenteur :
kubectl get lease my-app-leader -o jsonpath='{.spec.holderIdentity}{"\n"}'
2. Split-brain dû au décalage d'horloge
Cause : Les nœuds ont des différences de temps significatives, ce qui fait qu'un nœud pense que le bail a expiré tandis qu'un autre pense qu'il est encore valide.
Symptôme : Deux pods croient tous deux être leaders, entraînant des actions conflictuelles.
Récupération :
- Synchronisez les horloges avec NTP sur tous les nœuds.
- Augmentez
leaseDurationSecondspour tolérer le décalage, mais pas trop. - Utilisez un mécanisme de fencing si votre application nécessite une exclusivité stricte.
3. Objet de bail supprimé accidentellement
Cause : kubectl delete lease sans sauvegarde, ou un nettoyage d'espace de noms l'a supprimé.
Symptôme : Tous les prétendants ne trouvent pas le bail et peuvent générer des erreurs.
Récupération : Recréez le bail. Si votre application utilise client-go, elle créera automatiquement le bail s'il n'existe pas, bien qu'elle puisse perdre un cycle d'élection. Pour accélérer, créez un bail vide avec le bon nom et l'espace de noms :
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:
name: my-app-leader
namespace: default
spec: {}
Observez ensuite que le leader le met à jour.
4. Erreurs de permission refusée lors de la mise à jour du bail
Cause : Les politiques RBAC ont changé, ou le compte de service n'a pas la permission update sur les baux.
Symptôme : Les journaux montrent 403 Forbidden lors de la tentative de mise à jour du bail.
Récupération : Vérifiez et corrigez RBAC :
kubectl auth can-i update leases -n default --as=system:serviceaccount:default:my-app-sa
# Si non, créez un Role avec la permission de mise à jour et liez-le
kubectl create role lease-updater --verb=update,get,list --resource=leases -n default
kubectl create rolebinding lease-updater-binding --role=lease-updater --serviceaccount=default:my-app-sa
5. Pic de transitions de bail
Cause : Changements fréquents de leader dus à un battement ou une expiration prématurée.
Symptôme : Le compteur leaseTransitions augmente rapidement.
Diagnostic :
kubectl get lease my-app-leader -o jsonpath='{.spec.leaseTransitions}{"\n"}'
Consultez les journaux pour les événements d'acquisition et de perte. Envisagez d'augmenter leaseDurationSeconds ou d'enquêter sur les problèmes réseau.
Vérification de la récupération : après toute intervention, confirmez que le bail est stable :
watch -n 5 "kubectl get lease my-app-leader -o jsonpath='{.spec.holderIdentity}{"\n"} {@.spec.renewTime}{"\n"}'"
Assurez-vous que le même détenteur persiste et que renewTime se met à jour régulièrement.
Liste de contrôle des opérations
Utilisez cette liste de contrôle pour les opérations de bail de routine et la réponse aux incidents.
| Étape | Action | Sortie attendue |
|---|---|---|
| 1. Vérification de l'environnement | kubectl version --short et kubectl api-versions | grep coordination | coordination.k8s.io/v1 présent |
| 2. Lister les baux | kubectl get leases -A | Noms, détenteurs, âges |
| 3. Inspecter un bail spécifique | kubectl get lease <nom> -o yaml | Spec avec détenteur, durées, temps |
| 4. Vérifier que le détenteur est vivant | kubectl get pods -l <sélecteur> | Statut du pod Running |
| 5. Vérifier la fraîcheur du renouvellement | kubectl get lease <nom> -o jsonpath='{.spec.renewTime}' | Horodatage dans la durée du bail |
| 6. Tester les permissions | kubectl auth can-i update leases -n <ns> --as=<sa> | yes |
| 7. Simuler une défaillance | kubectl delete lease <nom> (dans un environnement de test) | Un nouveau détenteur acquiert après suppression |
| 8. Surveiller les transitions | watch "kubectl get lease <nom> -o jsonpath='{.spec.leaseTransitions}'" | Nombre stable 0-1 |
| 9. Documenter la récupération | Pour chaque mode de défaillance, enregistrez les commandes exactes exécutées et leurs sorties | Runbook mis à jour |
| 10. Examiner RBAC | kubectl get role,rolebinding -n <ns> | grep lease | Permissions minimales requises |
Exemple concret : Le déploiement d'une startup avait un bug d'élection de leader provoquant des redémarrages fréquents des pods. En vérifiant kubectl get lease -n app et en remarquant leaseTransitions: 42 en une heure, ils ont identifié un leaseDurationSeconds mal configuré (5 secondes) et l'ont augmenté à 15 secondes. Les transitions se sont stabilisées à 1 par jour.
Liste de contrôle pour les changements :
- Capturez la spécification actuelle du bail avant modification.
- Effectuez un changement à la fois.
- Utilisez
kubectl applyavec un manifeste versionné, paskubectl editpour la production. - Vérifiez le changement avec les commandes ci-dessus.
- Ayez un plan de rollback : soit réappliquez le manifeste précédent, soit supprimez le bail pour forcer une réélection.
Conclusion
L'architecture des baux Kubernetes est un travailleur silencieux. Elle permet l'élection de leader pour les contrôleurs, les battements de cœur des nœuds pour le contrôleur de cycle de vie des nœuds et une coordination personnalisée pour vos applications. En comprenant ses champs, en observant son comportement et en suivant des pratiques opérationnelles sûres, vous pouvez prévenir les scénarios de split-brain et garantir une haute disponibilité.
Commencez par une vérification à faible risque : listez tous les baux de votre cluster, identifiez les détenteurs et confirmez qu'ils se renouvellent. Ensuite, si vous exécutez une élection de leader personnalisée, examinez la durée du bail par rapport à votre intervalle de renouvellement. Utilisez les commandes de ce guide pour documenter votre état actuel et tester les changements d'abord dans un espace de noms non productif.
Un flux de travail fiable rend la défaillance visible : capturez les horodatages, protégez les identités, limitez les changements et définissez la vérification de récupération avant qu'un incident ne vous force la main. Avec les baux, quelques minutes d'inspection proactive peuvent économiser des heures de débogage des problèmes de coordination distribuée.