## Introduction

Les baux Kubernetes (Leases) sont une primitive de coordination sur laquelle s'appuient les composants du plan de contrôle et les contrôleurs personnalisés pour l'élection de leader, la signalisation par battement de cœur et le verrouillage de ressources. Lorsqu'un bail se brise, le rayon d'impact peut être large : scénarios de split-brain, contrôleurs bloqués ou battements de cœur de nœuds en échec. Le dépannage de ces échecs exige une approche systématique qui examine les journaux, l'état de l'objet Lease et les événements du cluster. Ce guide fournit des étapes pratiques, des commandes et des flux de travail de récupération pour diagnostiquer et résoudre les problèmes courants de baux Kubernetes. En suivant les méthodes décrites ici, vous pouvez réduire les temps d'arrêt et prévenir les problèmes récurrents.

## Inventaire de la version et de l'environnement

Avant de procéder au dépannage, établissez la version de Kubernetes, la topologie du plan de contrôle et les composants impliqués dans l'utilisation des baux. Ces informations aident à identifier les problèmes connus et les lacunes de compatibilité. Exécutez les commandes suivantes pour recueillir les détails de l'environnement :

```bash
kubectl version --short
kubectl get nodes -o wide
kubectl get leases --all-namespaces
```

Sortie typique de `kubectl version --short` (exemple) :

```text
Client Version: v1.28.3
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.28.3
```

La sortie de `kubectl get nodes -o wide` affiche l'état des nœuds, les rôles et la version de Kubernetes par nœud. La commande `kubectl get leases --all-namespaces` liste tous les objets Lease du cluster, y compris ceux utilisés par kube-controller-manager, kube-scheduler et les contrôleurs personnalisés. Par exemple :

```text
NAMESPACE     NAME                      HOLDER                           AGE
kube-system   kube-controller-manager   node1                            3d
kube-system   kube-scheduler            node2                            3d
my-app        my-controller             my-controller-5f8b7c9d-abcde     1h
```

Identifiez le bail problématique et notez son espace de noms, son nom et son détenteur. Consultez également la documentation Kubernetes pour le comportement spécifique à la version, car les changements de l'API des baux peuvent affecter les étapes de dépannage.

## Chemin de configuration sûr

Lorsque vous modifiez des configurations liées aux baux, procédez de manière contrôlée. Commencez par une portée étroite, comme un seul espace de noms ou un contrôleur non critique, pour valider l'impact. Cela correspond au principe d'un pilote étroit et mesurable avant un déploiement plus large.

Les points de configuration courants incluent :

- **Durée du bail et temps de renouvellement pour les contrôleurs** : De nombreux contrôleurs exposent des drapeaux comme `--leader-elect-lease-duration` et `--leader-elect-renew-deadline`. Ajustez-les seulement après avoir compris les implications temporelles.
- **Permissions RBAC** : Les contrôleurs ont besoin des permissions `get`, `create` et `update` sur les baux. Une permission manquante cause souvent des échecs.
- **Quotas de ressources** : Dans les environnements contraints, les objets Lease peuvent être empêchés d'être créés en raison des quotas de l'espace de noms.

Pour inspecter la configuration d'un bail spécifique, utilisez :

```bash
kubectl get lease <lease-name> -n <namespace> -o yaml
```

Exemple de sortie (abrégé) :

```yaml
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:
  name: my-controller
  namespace: my-app
spec:
  holderIdentity: my-controller-5f8b7c9d-abcde
  leaseDurationSeconds: 15
  acquireTime: "2025-03-10T10:00:00Z"
  renewTime: "2025-03-10T10:05:00Z"
  leaseTransitions: 0
```

Si le `renewTime` est ancien par rapport à l'heure actuelle, le détenteur a probablement échoué à renouveler. Avant de modifier toute configuration, sauvegardez l'état actuel et planifiez un chemin de retour en arrière. Par exemple, enregistrer le YAML du bail permet une restauration si nécessaire.

## Vérification et diagnostics

Commencez les diagnostics en examinant l'état et les événements liés au bail et à son contrôleur.

### Vérifier l'état du bail

```bash
kubectl describe lease <lease-name> -n <namespace>
```

Recherchez le `Renew Time` et le `Holder Identity`. Si le temps de renouvellement ne se met pas à jour, le détenteur est en mauvaise santé.

### Examiner les journaux du contrôleur

```bash
kubectl logs -n <namespace> deployment/<controller-deployment> | grep -i lease
```

Exemples de lignes de journal indiquant un échec :

```text
E0310 10:05:12.345678       1 leaderelection.go:330] error retrieving resource lock kube-system/my-controller: leases.coordination.k8s.io "my-controller" is forbidden: User "system:serviceaccount:my-app:my-controller" cannot get resource "leases" in API group "coordination.k8s.io" in the namespace "kube-system"
```

Cette erreur pointe vers un problème RBAC. Une autre erreur courante :

```text
W0310 10:05:12.345678       1 leaderelection.go:340] Failed to update lock: Operation cannot be fulfilled on leases.coordination.k8s.io "my-controller": the object has been modified; please apply your changes to the latest version and try again
```

Cela indique un conflit dû à plusieurs prétendants ou à un cache obsolète.

### Vérifier les événements

```bash
kubectl get events -n <namespace> --field-selector involvedObject.name=<lease-name>
```

Exemple de sortie :

```text
LAST SEEN   TYPE     REASON                 OBJECT              MESSAGE
5m          Warning  FailedToUpdateLease   lease/my-controller  Failed to update lease my-controller: ...
```

### Vérifier la disponibilité de l'API des baux

```bash
kubectl api-resources | grep leases
```

Sortie attendue :

```text
leases   coordination.k8s.io/v1   true   Lease
```

Si les baux ne sont pas listés, le groupe API peut ne pas être activé (rare dans les distributions standard).

### Simuler une vérification d'accès au bail

```bash
kubectl auth can-i get leases -n <namespace> --as=system:serviceaccount:<namespace>:<serviceaccount>
```

La sortie `yes` ou `no` indique la permission.

Lors du diagnostic des problèmes d'élection de leader, inspectez les journaux du pod détenteur pour les messages d'élection de leader :

```text
I0310 10:05:12.345678       1 leaderelection.go:250] successfully acquired lease kube-system/my-controller
```

Si le pod journalise de façon répétée « attempting to acquire leader lease » et échoue, cela suggère un problème avec l'objet Lease ou le réseau.

## Modes de défaillance et récupération

Modes de défaillance courants et étapes de récupération :

### 1. Détenteur de bail obsolète

**Symptômes** : Le pod détenteur du bail est terminé ou ne répond pas, mais le bail le liste toujours comme détenteur. Les autres réplicas ne peuvent pas acquérir le leadership.

**Diagnostic** :

```bash
kubectl get lease <lease-name> -n <namespace> -o jsonpath='{.spec.holderIdentity}{"\n"}'
kubectl get pods -n <namespace> | grep <holder-prefix>
```

Si le pod détenteur n'existe plus, le bail est obsolète.

**Récupération** : Supprimez le bail pour permettre la réélection (assurez-vous qu'aucun détenteur actif n'existe) :

```bash
kubectl delete lease <lease-name> -n <namespace>
```

Un nouveau leader sera élu par un réplica en cours d'exécution. Alternativement, patchez manuellement le bail pour effacer le détenteur :

```bash
kubectl patch lease <lease-name> -n <namespace> --type merge -p '{"spec":{"holderIdentity":""}}'
```

### 2. Mauvaise configuration RBAC

**Symptômes** : Les journaux affichent des erreurs « forbidden » lors de l'accès aux baux.

**Diagnostic** : Utilisez `kubectl auth can-i` comme ci-dessus. Examinez le Role/RoleBinding ou ClusterRole/ClusterRoleBinding pour le compte de service.

**Récupération** : Corrigez les règles RBAC. Exemple de Role minimal pour les baux :

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: lease-access
  namespace: my-app
rules:
- apiGroups: ["coordination.k8s.io"]
  resources: ["leases"]
  verbs: ["get", "create", "update", "patch"]
```

Appliquez et vérifiez :

```bash
kubectl apply -f role.yaml
kubectl auth can-i update leases -n my-app --as=system:serviceaccount:my-app:my-controller
```

Sortie attendue : `yes`

### 3. Dérive d'horloge

**Symptômes** : Les renouvellements de bail échouent avec « lease duration expired » ou les leaders vacillent.

**Diagnostic** : Vérifiez la synchronisation horaire des nœuds :

```bash
kubectl get nodes -o custom-columns=NAME:.metadata.name,STATUS:.status.conditions[-1].type,REASON:.status.conditions[-1].reason
```

Vérifiez manuellement `timedatectl` ou `chronyc tracking` sur les nœuds.

**Récupération** : Configurez correctement NTP sur tous les nœuds et redémarrez les composants affectés.

### 4. Épuisement du quota de ressources

**Symptômes** : La création du bail échoue avec `exceeded quota`.

**Diagnostic** :

```bash
kubectl describe resourcequota -n <namespace>
```

Vérifiez si le quota inclut `count/leases`.

**Récupération** : Augmentez le quota ou supprimez les baux inutilisés après avoir confirmé qu'aucun détenteur actif n'existe.

### Conseils de retour en arrière

Ayez toujours un plan de retour en arrière. Pour les changements de configuration, gardez une sauvegarde des manifestes originaux. Pour la suppression d'un bail, notez le détenteur précédent et assurez-vous qu'au moins un réplica est en cours d'exécution pour prendre le relais. En cas de mauvais changement, restaurez le bail à partir de la sauvegarde ou revenez à la configuration précédente et redémarrez le contrôleur.

## Pièges courants et comment les éviter

Le dépannage des baux révèle souvent des erreurs récurrentes. Voici les plus fréquentes et comment les prévenir ou s'en remettre.

**Piège 1 : Supposer que le bail est le problème alors qu'il s'agit d'un symptôme.**

Le bail peut être obsolète parce que le pod détenteur est dans une boucle de crash, non parce que le bail lui-même est corrompu. Vérifiez toujours l'état et les journaux du pod détenteur avant de supprimer le bail.

**Comment éviter** : Corrélez les problèmes de bail avec la santé du pod. Utilisez `kubectl describe pod` et `kubectl logs` pour comprendre pourquoi le détenteur a échoué. Supprimer un bail sain sans corriger le pod sous-jacent entraînera le même échec après la réélection.

**Piège 2 : RBAC mal configuré pour les contrôleurs personnalisés.**

De nombreux contrôleurs personnalisés utilisent un compte de service dans leur propre espace de noms mais tentent d'accéder aux baux dans `kube-system` ou un autre espace de noms. Un Role qui fonctionne dans `my-app` n'accorde pas l'accès dans `kube-system` ; vous avez besoin d'un ClusterRole ou d'un Role dans l'espace de noms cible.

**Comment éviter** : Vérifiez l'espace de noms exact dans le message d'erreur. Utilisez `kubectl auth can-i --namespace=<target-ns>` pour confirmer les permissions avant d'appliquer des correctifs.

**Piège 3 : Ignorer la dérive d'horloge.**

Le timing du bail dépend d'horloges précises. Même quelques secondes de dérive peuvent amener les leaders à libérer le bail prématurément ou à échouer à renouveler. C'est courant sur les clusters bare-metal sans NTP.

**Comment éviter** : Implémentez NTP sur tous les nœuds dans le cadre du provisionnement du cluster. Surveillez la dérive temporelle avec des outils comme `chrony` et alertez sur les décalages supérieurs à 100 ms.

**Piège 4 : Supprimer un bail pendant une élection de leader active.**

Si vous supprimez un bail alors qu'un leader sain le renouvelle activement, vous forcez inutilement une nouvelle élection. Cela provoque une brève période sans leader et peut perturber les opérations.

**Comment éviter** : Vérifiez le `renewTime` et l'état du pod détenteur avant de supprimer. Si le détenteur est en cours d'exécution et que le temps de renouvellement est récent, ne supprimez pas le bail ; examinez plutôt la logique du contrôleur.

**Piège 5 : Durées de bail trop courtes.**

Régler `leaseDurationSeconds` trop bas (par exemple, 2 secondes) peut provoquer un flottement sous charge. Le détenteur peut ne pas renouveler à temps, provoquant des changements fréquents de leader.

**Comment éviter** : Utilisez les valeurs par défaut (15 secondes pour de nombreux contrôleurs) sauf si vous comprenez les implications temporelles. Si vous devez ajuster, augmentez proportionnellement le délai de renouvellement et testez sous charge.

## Liste de contrôle des opérations

Utilisez cette liste de contrôle pour les vérifications de routine de la santé des baux et les revues post-incident. Attribuez un propriétaire (par exemple, ingénieur plateforme) et une fréquence de revue (mensuelle ou après toute mise à niveau du cluster).

| Vérification | Commande ou action | Résultat attendu |
|---|---|---|
| Tous les baux listés | `kubectl get leases --all-namespaces` | Aucune erreur, baux attendus présents |
| Temps de renouvellement du bail actuel | `kubectl get lease <name> -n <ns> -o jsonpath='{.spec.renewTime}'` | Horodatage dans la durée du bail |
| L'identité du détenteur correspond au pod actif | Comparer le détenteur avec la liste des pods | Le pod détenteur est en cours d'exécution |
| Journaux du contrôleur exempts d'erreurs de bail | `kubectl logs <pod> \| grep -i lease \| grep -i error` | Aucune sortie ou seulement des avertissements transitoires |
| RBAC autorise les opérations sur les baux | `kubectl auth can-i --list -n <ns> \| grep leases` | Les règles incluent get, create, update |
| Les événements ne montrent pas d'échecs répétés | `kubectl get events -n <ns> --field-selector reason=FailedToUpdateLease` | Aucun événement récent |
| Ressource API disponible | `kubectl api-resources \| grep leases` | Ligne avec coordination.k8s.io/v1 |
| Synchronisation de l'horloge sur les nœuds | `kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="InternalIP")].address}'` puis vérification SSH | Aucune dérive au-delà de quelques ms |

Effectuez ces vérifications mensuellement et après toute mise à niveau du cluster ou modification du contrôleur. Consignez les résultats dans un document partagé et examinez-les avec l'équipe pour suivre les tendances. Pour les grandes équipes, envisagez d'automatiser ces vérifications avec une tâche cron ou un outil de surveillance comme les alertes Prometheus.

## Conclusion

Le dépannage des baux Kubernetes est essentiel pour maintenir la stabilité du cluster. En rassemblant systématiquement les détails de l'environnement, en vérifiant les configurations, en utilisant des commandes de diagnostic et en appliquant des étapes de récupération ciblées, vous pouvez résoudre efficacement les échecs de baux. N'oubliez pas de commencer par des changements étroits, de vérifier les résultats et de maintenir une liste de contrôle des opérations pour prévenir les problèmes futurs. Les exemples pratiques de ce guide fournissent une base pour gérer les problèmes courants de baux et peuvent être adaptés à votre environnement spécifique. Continuez à surveiller la santé des baux et restez à jour avec les versions de Kubernetes pour assurer un fonctionnement fluide.