## Introduction

Les budgets de perturbation des pods Kubernetes (PDB, de l'anglais Pod Disruption Budgets) définissent le nombre minimal de pods qui doivent rester disponibles lors de perturbations volontaires telles que les drainages de nœuds, les mises à niveau de cluster ou les opérations de maintenance. Automatiser la gestion des PDB dans les pipelines CI/CD garantit que les politiques de disponibilité sont appliquées de manière cohérente dans tous les environnements, réduisant ainsi les erreurs humaines et évitant les interruptions accidentelles. Ce guide propose une approche pratique, étape par étape, pour intégrer l'automatisation des PDB dans votre flux de livraison, depuis l'inventaire initial de l'environnement jusqu'à la reprise après échec.

Nous nous adressons aux praticiens : développeurs, ingénieurs DevOps et équipes techniques qui exploitent des clusters Kubernetes en production. À la fin de cet article, vous saurez comment :

- Découvrir les PDB existants et leur statut

- Modifier en toute sécurité les PDB à l'aide de manifestes déclaratifs

- Intégrer les modifications de PDB dans les pipelines CI/CD avec validation automatisée

- Diagnostiquer les problèmes courants liés aux PDB

- Mettre en œuvre des stratégies de restauration lorsque les choses tournent mal

L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés plutôt que des secrets, vérifier les résultats et documenter les chemins de récupération.

## Inventaire des versions et de l'environnement

Avant d'automatiser les PDB, établissez une image claire de votre cluster et de vos outils. Les PDB sont pris en charge dans Kubernetes v1.21+ (stable), mais le comportement peut varier légèrement selon la version. Vérifiez la version de votre cluster avec :

kubectl version --short 
 La sortie attendue inclut les versions client et serveur. Par exemple :

Client Version: v1.27.3
Server Version: v1.27.3 
 Ensuite, faites l'inventaire des PDB existants dans tous les espaces de noms :

kubectl get pdb --all-namespaces 
 Cette commande liste tous les PDB du cluster, en indiquant l'espace de noms, le nom, le minimum disponible/maximum indisponible, les perturbations autorisées et l'âge. Exemple de sortie :

NAMESPACE NAME MIN AVAILABLE MAX UNAVAILABLE ALLOWED DISRUPTIONS AGE
default app-pdb N/A 1 1 2d
kube-system coredns-pdb 1 N/A 0 30d 
 Aucun PDB ? Vous devrez les créer dans le cadre de votre automatisation. Notez également quels contrôleurs gèrent vos charges de travail, car les PDB reposent sur des sélecteurs d'étiquettes correspondant aux pods. Pour cet article, nous supposons une application typique basée sur un déploiement appelée webapp dans l'espace de noms default .

Vérifiez les étiquettes actuelles des pods pour vous assurer que votre sélecteur PDB correspondra :

kubectl get pods -l app=webapp --show-labels 
 La sortie attendue montre des étiquettes comme app=webapp . Si les étiquettes sont incohérentes, corrigez-les avant de continuer.

Gardez votre environnement de test local petit. Utilisez un outil comme minikube ou kind pour expérimenter en toute sécurité avant de toucher à la production. Appliquez un manifeste à la fois et vérifiez avec kubectl port-forward ou un service local avant de passer aux équilibreurs de charge cloud ou aux contrôleurs d'entrée.

<style>
.eno-quiz-widget{margin:2rem 0;padding:1.5rem;border-radius:12px;background:var(--eno-surface-lowest,#f7f7f8);border:1px solid var(--eno-border-soft,#e2e2e6);font-family:var(--eno-font-body,Inter,sans-serif)}
.eno-quiz-widget .eno-quiz-kicker{font-family:var(--eno-font-label,"JetBrains Mono",monospace);font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--eno-text-muted,#5f5f68);margin:0 0 .5rem}
.eno-quiz-widget .eno-quiz-question{font-family:var(--eno-font-heading,"Hanken Grotesk",sans-serif);font-size:1.0625rem;font-weight:600;margin:0 0 1rem;color:var(--eno-text-strong,#1a1a1f)}
.eno-quiz-widget .eno-quiz-options{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.eno-quiz-widget .eno-quiz-option{display:block;width:100%;min-height:44px;text-align:left;padding:.625rem .875rem;border-radius:8px;border:1.5px solid var(--eno-border-soft,#e2e2e6);background:#fff;font-size:.9375rem;cursor:pointer;transition:border-color var(--eno-motion-base,180ms ease-out),background var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-option:hover{border-color:var(--eno-primary,#0059bb)}
.eno-quiz-widget .eno-quiz-option:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-option[aria-pressed="true"]{border-color:var(--eno-primary,#0059bb);background:rgb(0 89 187 / 0.06)}
.eno-quiz-widget .eno-quiz-option[data-correct="true"].eno-quiz-revealed{border-color:var(--eno-success,#17803a);background:rgb(23 128 58 / 0.08)}
.eno-quiz-widget .eno-quiz-option[data-correct="false"].eno-quiz-revealed.eno-quiz-was-selected{border-color:var(--eno-error,#ba1a1a);background:var(--eno-error-soft,#ffdad6)}
.eno-quiz-widget .eno-quiz-option-icon{display:inline-block;width:1.1em;margin-right:.4em;font-weight:700}
.eno-quiz-widget .eno-quiz-submit{margin-top:1rem;min-height:44px;padding:.5rem 1.25rem;border-radius:8px;border:none;background:var(--eno-primary,#0059bb);color:#fff;font-weight:600;font-size:.9375rem;cursor:pointer;transition:opacity var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-submit:disabled{opacity:.5;cursor:not-allowed}
.eno-quiz-widget .eno-quiz-submit:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-explanation{margin-top:1rem;padding:.875rem 1rem;border-radius:8px;font-size:.9375rem;line-height:1.5;display:none}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-visible{display:block}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-correct{background:rgb(23 128 58 / 0.08);color:var(--eno-success,#17803a)}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-incorrect{background:var(--eno-error-soft,#ffdad6);color:var(--eno-error,#ba1a1a)}
@media (prefers-reduced-motion: reduce){.eno-quiz-widget *{transition:none!important}}
</style><div class="eno-quiz-widget" role="group" aria-label="Question rapide">
Question rapide 1 sur 2

Que limite un PodDisruptionBudget (PDB) ?

- Le nombre de réplicas qu'un Deployment peut avoir
- Le nombre de Pods d'une application répliquée qui peuvent être indisponibles simultanément en raison de perturbations volontaires
- Le nombre de nœuds dans un cluster
- Le nombre de Pods pouvant être créés dans un namespace

<button type="button" class="eno-quiz-submit" disabled>Valider</button>
<div class="eno-quiz-explanation">D&#39;après la référence, un PDB limite le nombre de Pods d&#39;une application répliquée qui sont indisponibles simultanément en raison de perturbations volontaires.</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

## Chemin de configuration sécurisé

Les PDB sont définis à l'aide de manifestes YAML. Un PDB de base pour un déploiement avec trois réplicas, exigeant qu'au moins deux pods soient disponibles, ressemble à ceci :

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
 name: webapp-pdb
spec:
 minAvailable: 2
 selector:
 matchLabels:
 app: webapp 
 Enregistrez ceci sous webapp-pdb.yaml . Avant d'appliquer, examinez toujours l'état en direct :

kubectl get deployment webapp -o wide
kubectl get pods -l app=webapp 
 Cela confirme que le déploiement existe et que les pods sont en cours d'exécution. Appliquez ensuite le PDB :

kubectl apply -f webapp-pdb.yaml 
 Vérifiez que le PDB a été créé correctement :

kubectl get pdb webapp-pdb -o yaml 
 Consultez la section status . Elle devrait afficher currentHealthy et desiredHealthy . Par exemple :

status:
 currentHealthy: 3
 desiredHealthy: 2
 disruptionsAllowed: 1
 expectedPods: 3 
 currentHealthy doit être supérieur ou égal à desiredHealthy pour que les perturbations soient autorisées. Si disruptionsAllowed est égal à 0, le PDB bloque toutes les perturbations volontaires ; enquêtez immédiatement.

Dans un environnement versionné, stockez ce manifeste dans Git et utilisez CI/CD pour appliquer les modifications. Par exemple, dans un workflow GitHub Actions, vous pourriez avoir un job qui exécute kubectl apply à chaque push sur la branche principale. Utilisez toujours un compte de service dédié avec le moindre privilège (uniquement les autorisations de création/mise à jour de PDB) et stockez les informations d'identification du cluster dans des secrets.

Extrait CI/CD conceptuel :

- name: Apply PDB
 run: |
 kubectl apply -f deploy/webapp-pdb.yaml
 kubectl rollout status deployment/webapp --timeout=60s 
 Ne codez pas en dur les valeurs sensibles. Utilisez des variables d'environnement ou des références de secrets.

## Vérification et diagnostic

Après avoir appliqué un PDB, vérifiez qu'il fonctionne comme prévu. Simulez une perturbation volontaire à l'aide de kubectl drain sur un nœud (dans un cluster de test uniquement) :

kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data 
 Observez le processus d'éviction :

kubectl get pods -l app=webapp -w 
 Les pods doivent être évincés un par un, mais au moins minAvailable pods restent en cours d'exécution. Si la commande drain se bloque, le PDB bloque les évictions car il ne peut pas garantir la disponibilité. Vérifiez le statut du PDB :

kubectl describe pdb webapp-pdb 
 Recherchez des événements comme Evicting pod webapp-xxxxx ou Cannot evict pod as it would violate the pod's disruption budget. Ce dernier indique une inadéquation de configuration ; par exemple, minAvailable peut être défini trop haut ou le sélecteur ne correspond à aucun pod.

Commandes de diagnostic courantes :

- kubectl get pdb - liste tous les PDB et leurs perturbations autorisées

- kubectl describe pdb <name> - statut détaillé et événements

- kubectl get events --field-selector involvedObject.name=- événements récents liés au PDB

- kubectl logs --previous - vérifier les journaux de l'application si les pods sont en boucle de crash

 Utilisez kubectl rollout status deployment/webapp pour confirmer que le déploiement est sain après tout changement. Si le déploiement est bloqué, inspectez avec kubectl rollout history deployment/webapp et kubectl rollout undo deployment/webapp si nécessaire.

Pour la vérification locale, utilisez kubectl port-forward pour exposer le service et tester le trafic :

kubectl port-forward svc/webapp 8080:80 
 Ensuite, exécutez curl http://localhost:8080 depuis un autre terminal. La réponse attendue est le point de terminaison de santé de votre application.

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

L'automatisation des PDB peut échouer de plusieurs façons. Examinons les scénarios courants et comment récupérer.

### Scénario 1 : Le PDB bloque toutes les évictions en raison d'un sélecteur incorrect

Symptôme : kubectl drain se bloque, kubectl describe pdb affiche disruptionsAllowed: 0 même si les pods sont sains.

Diagnostic : Vérifiez kubectl get pdb -o yaml et assurez-vous que le sélecteur correspond aux étiquettes réelles des pods. Utilisez kubectl get pods --show-labels .

Récupération : Corrigez le sélecteur dans le manifeste, appliquez-le et réessayez. Si un déblocage immédiat est nécessaire (par exemple, maintenance critique), supprimez temporairement le PDB :

kubectl delete pdb webapp-pdb 
 Réappliquez ensuite le PDB corrigé après la maintenance.

### Scénario 2 : PDB manquant lors d'une mise à niveau de cluster

Symptôme : Lors d'une mise à niveau de nœud, tous les pods d'un service sont évincés simultanément, provoquant une panne.

Diagnostic : Après coup, kubectl get pdb ne montre aucun PDB pour la charge de travail. Examinez l'historique Git pour voir si le manifeste PDB a été accidentellement supprimé.

Récupération : Réappliquez immédiatement le PDB depuis le contrôle de version. Ensuite, augmentez le nombre de réplicas du déploiement et vérifiez la santé. Empêchez la récurrence en ajoutant une vérification CI : si un espace de noms a des charges de travail, assurez-vous qu'un PDB existe.

### Scénario 3 : minAvailable défini plus haut que le nombre de réplicas

Symptôme : kubectl apply réussit mais kubectl describe pdb affiche currentHealthy inférieur à desiredHealthy , et disruptionsAllowed reste à 0. De plus, les déploiements ne peuvent pas réduire leur échelle.

Diagnostic : Comparez minAvailable dans la spécification du PDB avec le nombre réel de réplicas dans le déploiement.

Récupération : Soit augmentez le nombre de réplicas pour satisfaire minAvailable , soit réduisez minAvailable à une valeur raisonnable (par exemple, replicas - 1 ). Appliquez le changement et vérifiez que currentHealthy >= desiredHealthy .

### Stratégies de restauration

Comme les PDB sont des objets Kubernetes, la restauration est simple :

- Identifiez le dernier bon manifeste PDB connu dans l'historique Git.

- Appliquez-le avec kubectl apply -f <dernier-bon-manifeste>.yaml .

- Vérifiez le statut.

Pour l'automatisation, envisagez de stocker les manifestes PDB avec des balises de version dans un dépôt Git. En CI/CD, utilisez une stratégie de déploiement qui peut revenir à une balise précédente en cas d'échec. Par exemple, dans une configuration GitOps avec Argo CD ou Flux, les modifications de PDB font partie de la configuration de l'application ; revenir à un commit précédent dans le dépôt Git rétablit automatiquement le PDB.

Si un PDB a été supprimé par erreur, recréez-le immédiatement depuis le contrôle de source. Ne comptez pas sur une reconstruction manuelle.

<style>
.eno-quiz-widget{margin:2rem 0;padding:1.5rem;border-radius:12px;background:var(--eno-surface-lowest,#f7f7f8);border:1px solid var(--eno-border-soft,#e2e2e6);font-family:var(--eno-font-body,Inter,sans-serif)}
.eno-quiz-widget .eno-quiz-kicker{font-family:var(--eno-font-label,"JetBrains Mono",monospace);font-size:.75rem;letter-spacing:.05em;text-transform:uppercase;color:var(--eno-text-muted,#5f5f68);margin:0 0 .5rem}
.eno-quiz-widget .eno-quiz-question{font-family:var(--eno-font-heading,"Hanken Grotesk",sans-serif);font-size:1.0625rem;font-weight:600;margin:0 0 1rem;color:var(--eno-text-strong,#1a1a1f)}
.eno-quiz-widget .eno-quiz-options{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.eno-quiz-widget .eno-quiz-option{display:block;width:100%;min-height:44px;text-align:left;padding:.625rem .875rem;border-radius:8px;border:1.5px solid var(--eno-border-soft,#e2e2e6);background:#fff;font-size:.9375rem;cursor:pointer;transition:border-color var(--eno-motion-base,180ms ease-out),background var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-option:hover{border-color:var(--eno-primary,#0059bb)}
.eno-quiz-widget .eno-quiz-option:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-option[aria-pressed="true"]{border-color:var(--eno-primary,#0059bb);background:rgb(0 89 187 / 0.06)}
.eno-quiz-widget .eno-quiz-option[data-correct="true"].eno-quiz-revealed{border-color:var(--eno-success,#17803a);background:rgb(23 128 58 / 0.08)}
.eno-quiz-widget .eno-quiz-option[data-correct="false"].eno-quiz-revealed.eno-quiz-was-selected{border-color:var(--eno-error,#ba1a1a);background:var(--eno-error-soft,#ffdad6)}
.eno-quiz-widget .eno-quiz-option-icon{display:inline-block;width:1.1em;margin-right:.4em;font-weight:700}
.eno-quiz-widget .eno-quiz-submit{margin-top:1rem;min-height:44px;padding:.5rem 1.25rem;border-radius:8px;border:none;background:var(--eno-primary,#0059bb);color:#fff;font-weight:600;font-size:.9375rem;cursor:pointer;transition:opacity var(--eno-motion-base,180ms ease-out)}
.eno-quiz-widget .eno-quiz-submit:disabled{opacity:.5;cursor:not-allowed}
.eno-quiz-widget .eno-quiz-submit:focus-visible{outline:none;box-shadow:0 0 0 3px rgb(0 89 187 / 0.15)}
.eno-quiz-widget .eno-quiz-explanation{margin-top:1rem;padding:.875rem 1rem;border-radius:8px;font-size:.9375rem;line-height:1.5;display:none}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-visible{display:block}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-correct{background:rgb(23 128 58 / 0.08);color:var(--eno-success,#17803a)}
.eno-quiz-widget .eno-quiz-explanation.eno-quiz-incorrect{background:var(--eno-error-soft,#ffdad6);color:var(--eno-error,#ba1a1a)}
@media (prefers-reduced-motion: reduce){.eno-quiz-widget *{transition:none!important}}
</style><div class="eno-quiz-widget" role="group" aria-label="Question rapide">
Question rapide 2 sur 2

Comment le nombre prévu de pods pour un PDB est-il calculé ?

- À partir de .spec.replicas de la ressource de charge de travail
- À partir du nombre de nœuds du cluster
- À partir du champ .spec.minAvailable du PDB
- À partir du .metadata.name du PDB

<button type="button" class="eno-quiz-submit" disabled>Valider</button>
<div class="eno-quiz-explanation">La référence indique que le nombre prévu de pods est calculé à partir de .spec.replicas de la ressource de charge de travail qui gère ces pods.</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
  document.querySelectorAll('.eno-quiz-widget:not([data-eno-quiz-bound])').forEach(function (widget) {
    widget.setAttribute('data-eno-quiz-bound', '1');
    var options = Array.prototype.slice.call(widget.querySelectorAll('.eno-quiz-option'));
    var submitBtn = widget.querySelector('.eno-quiz-submit');
    var explanation = widget.querySelector('.eno-quiz-explanation');
    var selected = null;
    options.forEach(function (opt) {
      opt.addEventListener('click', function () {
        if (widget.hasAttribute('data-eno-quiz-answered')) return;
        options.forEach(function (o) { o.setAttribute('aria-pressed', 'false'); });
        opt.setAttribute('aria-pressed', 'true');
        selected = opt;
        submitBtn.disabled = false;
      });
    });
    submitBtn.addEventListener('click', function () {
      if (!selected || widget.hasAttribute('data-eno-quiz-answered')) return;
      widget.setAttribute('data-eno-quiz-answered', '1');
      submitBtn.disabled = true;
      var correct = selected.getAttribute('data-correct') === 'true';
      options.forEach(function (o) {
        o.classList.add('eno-quiz-revealed');
        if (o === selected) o.classList.add('eno-quiz-was-selected');
        var icon = o.querySelector('.eno-quiz-option-icon');
        if (o.getAttribute('data-correct') === 'true') icon.textContent = '\u2713';
        else if (o === selected) icon.textContent = '\u2717';
      });
      explanation.classList.add('eno-quiz-visible', correct ? 'eno-quiz-correct' : 'eno-quiz-incorrect');
    });
  });
});
</script>

## Intégration aux pipelines CI/CD

Une fois que vous avez testé manuellement les modifications de PDB, intégrez-les à votre pipeline. L'objectif est de garantir que toute modification des manifestes PDB passe par une validation automatisée avant d'atteindre la production.

### Étapes du pipeline

- Lint et validation : Utilisez kubectl apply --dry-run=client ou server pour valider les manifestes sans les appliquer. Par exemple :

kubectl apply -f webapp-pdb.yaml --dry-run=client 
 Sortie attendue : poddisruptionbudget.policy/webapp-pdb created (dry run)

- Analyse statique : Utilisez des outils comme kubeval ou kubeconform pour valider la structure YAML par rapport aux schémas Kubernetes. Exécutez-les en CI.

- Appliquer au staging : Déployez le PDB dans le cluster de staging et exécutez des tests d'intégration qui simulent des perturbations.

- Vérifier le statut du PDB : Après l'application, exécutez un script qui vérifie :

kubectl get pdb webapp-pdb -o jsonpath='{.status.disruptionsAllowed}' 
 Assurez-vous qu'il renvoie un nombre non nul (si les perturbations doivent être autorisées).

- Approuver et appliquer en production : Utilisez une porte d'approbation manuelle ou une livraison progressive.

### Exemple de pipeline (GitHub Actions)

Voici un workflow condensé pour appliquer les modifications de PDB à un cluster Kubernetes à l'aide de GitHub Actions. Il utilise azure/k8s-set-context pour définir le contexte du cluster et kubectl pour appliquer les manifestes.

name: PDB Deployment
on:
 push:
 branches: [ main ]
jobs:
 deploy:
 runs-on: ubuntu-latest
 steps:
 - uses: actions/checkout@v3
 - uses: azure/k8s-set-context@v3
 with:
 kubeconfig: ${{ secrets.KUBE_CONFIG }}
 - name: Validate PDB manifest
 run: |
 kubectl apply -f deploy/webapp-pdb.yaml --dry-run=client
 - name: Apply PDB
 run: |
 kubectl apply -f deploy/webapp-pdb.yaml
 - name: Wait for PDB to be active
 run: |
 kubectl wait --for=condition=ready pdb/webapp-pdb --timeout=60s
 - name: Verify disruptions allowed
 run: |
 ALLOWED=$(kubectl get pdb webapp-pdb -o jsonpath='{.status.disruptionsAllowed}')
 if [ "$ALLOWED" -lt 1 ]; then echo "PDB not allowing disruptions"; exit 1; fi 

### Test en CI/CD

 Simulez une perturbation volontaire dans votre environnement de staging après avoir appliqué le PDB. Vous pouvez utiliser kubectl drain sur un nœud de staging (ou un minikube dédié) et vérifier que les pods restent disponibles. Automatisez cela dans un job de test séparé si possible. Par exemple, dans un cluster kind, vous pouvez exécuter :

kubectl drain kind-worker --ignore-daemonsets --delete-emptydir-data 
 Vérifiez ensuite la disponibilité de l'application à l'aide d'un simple curl ou d'une sonde.

## Liste de contrôle opérationnelle

Utilisez cette liste de contrôle avant et après tout changement de PDB pour garantir la sécurité opérationnelle.

<div class="my-stack-md overflow-x-auto">
<table class="min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Étape</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Commande/Action</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Résultat attendu</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Notes</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">1. Inventorier les PDB actuels</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl get pdb --all-namespaces</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Liste des PDB existants avec statut</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Capturer la référence</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">2. Vérifier la version du cluster</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl version --short</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Version du serveur &gt;= 1.21</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">PDB stable depuis 1.21</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">3. Vérifier les étiquettes des charges de travail</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl get pods -l app=webapp --show-labels</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Les pods ont les étiquettes attendues</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">S&#39;assurer que le sélecteur correspond</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">4. Créer/Mettre à jour le manifeste PDB</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Utiliser un fichier YAML avec minAvailable ou maxUnavailable</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Manifeste validé avec <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl apply --dry-run</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Stocker dans Git</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">5. Appliquer le PDB</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl apply -f webapp-pdb.yaml</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">PDB créé/mis à jour</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Utiliser CI/CD pour l&#39;automatisation</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">6. Vérifier le statut du PDB</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl describe pdb webapp-pdb</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">disruptionsAllowed</code> &gt; 0</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Si 0, enquêter</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">7. Tester la perturbation (staging)</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl drain &lt;node&gt;</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Pods évincés mais minAvailable reste</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Uniquement en environnement de test</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">8. Valider la santé de l&#39;application</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">kubectl rollout status deployment/webapp</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Déploiement réussi</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Utiliser port-forward pour test local</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">9. Documenter la récupération</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Stocker les commandes de restauration dans le runbook</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">S&#39;assurer que l&#39;équipe sait comment revenir en arrière</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Manifestes PDB dans Git</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">10. Surveiller</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Configurer des alertes sur le statut du PDB</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Alerter si <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">disruptionsAllowed</code> devient 0 de manière inattendue</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Utiliser les métriques Prometheus si disponibles</td></tr></tbody>
</table>
</div>
Gardez cette liste de contrôle accessible dans le runbook de votre équipe et mettez-la à jour à mesure que les procédures évoluent.

## Conclusion

Automatiser les budgets de perturbation des pods Kubernetes dans CI/CD ne consiste pas seulement à appliquer des fichiers YAML ; cela exige une approche disciplinée de l'observation, de la configuration sécurisée, de la vérification et de la récupération. En inventoriant votre environnement, en utilisant des manifestes sous contrôle de version, en intégrant la validation dans les pipelines et en vous préparant aux modes de défaillance, vous garantissez que vos applications maintiennent leur disponibilité pendant les perturbations volontaires sans intervention manuelle.

Commencez petit : implémentez un PDB pour une charge de travail critique, testez-le soigneusement en staging et intégrez-le à votre pipeline CI/CD. Au fur et à mesure que vous gagnez en confiance, étendez-le à d'autres services. N'oubliez pas de garder le rayon d'impact petit, d'utiliser le moindre privilège et d'avoir toujours un plan de restauration. La sécurité opérationnelle que vous gagnez dépasse de loin l'effort de mise en place.

Prochaines étapes : choisissez une charge de travail à faible risque, créez un PDB avec un minAvailable ou maxUnavailable approprié, appliquez-le via votre pipeline et simulez un drainage pour vérifier le comportement. Documentez vos conclusions et partagez-les avec votre équipe pour construire une culture de la fiabilité.