## Introduction

La planification Kubernetes est flexible, mais garantir une haute disponibilité entre les domaines de défaillance nécessite un placement minutieux des pods. Les contraintes de répartition topologique permettent de contrôler la répartition des pods à travers la topologie du cluster, comme les nœuds, les zones ou les régions. Ce guide propose une approche pratique, étape par étape, pour mettre en place un environnement de laboratoire local sûr afin de tester et d'apprendre les contraintes de répartition topologique. En expérimentant localement, vous pouvez comprendre le comportement, résoudre les problèmes et gagner en confiance avant de déployer en production.

Un laboratoire local bien conçu réduit les retouches en vous permettant de tester les politiques de planification de manière isolée. Le premier pilote utile doit être étroit, mesurable et facile à inspecter localement avant le déploiement. Cet article explique comment créer un cluster multi-nœuds avec kind (Kubernetes in Docker), étiqueter les nœuds pour simuler des zones, déployer une charge de travail avec des contraintes de répartition topologique et vérifier la distribution.

Dans cet article, vous allez :

- Configurer un cluster Kubernetes multi-nœuds avec kind qui simule plusieurs zones.
- Étiqueter les nœuds avec des clés de topologie telles que `topology.kubernetes.io/zone`.
- Déployer une application d'exemple avec des contraintes de répartition topologique.
- Vérifier la distribution des pods et diagnostiquer les problèmes courants.
- Découvrir les modes de défaillance et les procédures de récupération.

Toutes les commandes et les exemples sont conçus pour fonctionner sur un poste de travail de développeur typique avec Docker installé.

## Inventaire des versions et de l'environnement

Avant de plonger dans les contraintes de répartition topologique, assurez-vous que votre environnement est correctement configuré. Cette section couvre les prérequis et les versions spécifiques utilisées dans ce guide.

### Prérequis

Vous devez installer les outils suivants sur votre machine locale :

- **Docker** : requis pour `kind`. Installez Docker Desktop (Windows/Mac) ou Docker Engine (Linux).
- **kubectl** : outil en ligne de commande Kubernetes. Assurez-vous qu'il correspond à la version du cluster à une version mineure près.
- **kind** : Kubernetes in Docker. Installez-le depuis les versions officielles.

### Matrice des versions

Les commandes de ce guide sont testées avec les versions suivantes, mais les concepts s'appliquent largement :

| Composant | Version testée | Notes |
|---|---|---|
| kind | v0.20.0 | Prend en charge les clusters multi-nœuds |
| Kubernetes | v1.27.1 | Contraintes de répartition topologique en disponibilité générale |
| kubectl | v1.27.1 | Correspond à la version du serveur |
| Docker | 24.0.2 | Pour les conteneurs locaux |

Si vos versions diffèrent, ajustez en conséquence. L'essentiel est que Kubernetes prenne en charge `topologySpreadConstraints` dans les spécifications de pod (introduit en v1.19, stable en v1.25).

### Conception de la topologie du cluster

Pour des tests significatifs, nous avons besoin de plusieurs nœuds avec des étiquettes de topologie différentes. Nous allons créer un cluster kind avec trois nœuds de travail, chacun simulant une zone différente :

- `worker1` dans la zone `zone-a`
- `worker2` dans la zone `zone-b`
- `worker3` dans la zone `zone-c`

Chaque nœud aura également une étiquette `node-role.kubernetes.io/worker` pour la planification des pods réguliers (facultatif). Le cluster aura un nœud de plan de contrôle.

### Configuration du cluster avec kind

Créez un fichier de configuration `kind-config.yaml` :

```yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
  labels:
    topology.kubernetes.io/zone: zone-a
- role: worker
  labels:
    topology.kubernetes.io/zone: zone-b
- role: worker
  labels:
    topology.kubernetes.io/zone: zone-c
```

Ensuite, créez le cluster :

```bash
kind create cluster --name topo-lab --config kind-config.yaml
```

Sortie attendue :

```
Creating cluster "topo-lab" ...
 ✓ Ensuring node image (kindest/node: v1.27.1) 🖼
 ✓ Preparing nodes 📦 📦 📦 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
 ✓ Joining worker nodes 🚜
Set kubectl context to "kind-topo-lab"
You can now use your cluster with:

kubectl cluster-info --context kind-topo-lab
```

Vérifiez les nœuds et leurs étiquettes :

```bash
kubectl get nodes --show-labels
```

Sortie attendue (abrégée) :

```
NAME                 STATUS   ROLES           AGE   VERSION   LABELS
kind-control-plane   Ready    control-plane   1m    v1.27.1   ...
kind-worker          Ready    <none>          1m    v1.27.1   topology.kubernetes.io/zone=zone-a,...
kind-worker2         Ready    <none>          1m    v1.27.1   topology.kubernetes.io/zone=zone-b,...
kind-worker3         Ready    <none>          1m    v1.27.1   topology.kubernetes.io/zone=zone-c,...
```

Remarque : kind nomme les workers par défaut `kind-worker`, `kind-worker2` et `kind-worker3`. Nous les avons correctement étiquetés.

## Comprendre les contraintes de répartition topologique

Une contrainte de répartition topologique spécifie comment les pods doivent être répartis dans un domaine topologique. Les champs clés dans une spécification de pod sont :

- `topologyKey` : la clé d'étiquette des nœuds qui définit un domaine (par exemple, `topology.kubernetes.io/zone`).
- `maxSkew` : la différence maximale autorisée du nombre de pods correspondants entre deux domaines topologiques.
- `whenUnsatisfiable` : `DoNotSchedule` (contrainte stricte) ou `ScheduleAnyway` (contrainte souple).
- `labelSelector` : sélectionne les pods à compter pour le calcul du déséquilibre (généralement des pods avec les mêmes étiquettes que le pod lui-même).

Un mécanisme similaire, les contraintes de répartition topologique des pods, a évolué à partir des règles `podAntiAffinity` mais offre un contrôle plus fin sur la distribution des pods. Le planificateur tente de respecter la contrainte tout en considérant d'autres exigences de planification comme les ressources des nœuds, les teintures et les affinités.

### Sélection d'un scénario pilote

Nous allons déployer un simple déploiement avec trois répliques, chacune avec une contrainte de répartition topologique pour répartir sur les trois zones avec `maxSkew: 1`. C'est une configuration courante de haute disponibilité.

Créez un fichier `app.yaml` :

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: DoNotSchedule
        labelSelector:
          matchLabels:
            app: web
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
```

Appliquez le déploiement :

```bash
kubectl apply -f app.yaml
```

Sortie attendue :

```
deployment.apps/web created
```

Vérifiez la distribution des pods :

```bash
kubectl get pods -o wide
```

Sortie attendue (similaire) :

```
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE          NOMINATED NODE   READINESS GATES
web-5c8b6f7c9d-abcde   1/1     Running   0          10s   10.244.1.2   kind-worker   <none>           <none>
web-5c8b6f7c9d-fghij   1/1     Running   0          10s   10.244.2.2   kind-worker2  <none>           <none>
web-5c8b6f7c9d-klmno   1/1     Running   0          10s   10.244.3.2   kind-worker3  <none>           <none>
```

Nous observons un pod par zone, satisfaisant la contrainte.

### Combinaison de plusieurs contraintes

En production, vous pourriez vouloir répartir les pods à la fois entre les zones et entre les nœuds au sein de chaque zone. Vous pouvez définir plusieurs contraintes de répartition topologique. Cependant, soyez prudent : augmenter le nombre de contraintes peut rendre la planification impossible si le cluster manque de diversité suffisante. Par exemple, si vous exigez maxSkew=1 à la fois sur la zone et le nom d'hôte avec seulement trois nœuds au total, certaines contraintes entreront en conflit. Utilisez `ScheduleAnyway` si vous voulez une distribution au mieux.

## Vérification et diagnostic

Après le déploiement, la vérification est cruciale. Cette section fournit des commandes et des sorties attendues pour confirmer que les contraintes de répartition topologique fonctionnent comme prévu.

### Vérification de la distribution des pods

La vérification principale est l'emplacement des pods. Utilisez `kubectl get pods -o wide` pour voir l'affectation aux nœuds. Pour compter les pods par zone, vous pouvez utiliser `kubectl` avec des colonnes personnalisées ou `jq`.

Exemple avec `kubectl` et `awk` :

```bash
kubectl get pods -l app=web -o wide | awk 'NR>1 {print $7}' | sort | uniq -c
```

Sortie attendue :

```
      1 kind-worker
      1 kind-worker2
      1 kind-worker3
```

Cela montre un pod sur chaque nœud (et donc chaque zone).

### Description du déploiement pour les événements

Vérifiez les événements du déploiement pour les décisions de planification :

```bash
kubectl describe deployment web
```

Regardez la section `Events`. S'il y a eu des échecs, ils y apparaîtraient. Pour une planification réussie, vous ne verrez peut-être aucun événement pertinent.

### Inspection des annotations des pods

Lorsqu'un pod est planifié, le planificateur enregistre les contraintes de répartition topologique dans les annotations du pod (depuis Kubernetes 1.20). Vous pouvez inspecter :

```bash
kubectl get pod <pod-name> -o jsonpath='{.metadata.annotations}'
```

La sortie attendue inclut une annotation comme :

```json
{"kubernetes.io/topology-spread-constraints":"[{\"maxSkew\":1,\"topologyKey\":\"topology.kubernetes.io/zone\",\"whenUnsatisfiable\":\"DoNotSchedule\",\"labelSelector\":{\"matchLabels\":{\"app\":\"web\"}}}]"}
```

Cela confirme que la contrainte a été appliquée.

### Test du déséquilibre par mise à l'échelle

Pour vérifier l'application du déséquilibre, mettez à l'échelle le déploiement à 4 répliques :

```bash
kubectl scale deployment web --replicas=4
```

Vérifiez ensuite la distribution des pods. Avec `maxSkew: 1` et trois zones, le planificateur essaie d'équilibrer les pods, mais avec 4 pods, une zone aura 2 pods, les autres 1 chacune. C'est acceptable car le déséquilibre est au plus de 1. Cependant, si vous mettez à l'échelle à 5, le planificateur peut ne pas pouvoir placer tous les pods car la contrainte ne peut pas être satisfaite (si `whenUnsatisfiable: DoNotSchedule`). Le pod supplémentaire restera `Pending`.

Vérifiez les pods en attente :

```bash
kubectl get pods -l app=web --field-selector=status.phase=Pending
```

La sortie attendue montre un pod en attente. Décrivez-le pour plus de détails :

```bash
kubectl describe pod <pending-pod-name>
```

Dans les événements, vous verrez un message comme :

```
0/4 nodes are available: 1 node(s) didn't match pod topology spread constraints, 3 node(s) had no free ports.
```

Cela indique que la contrainte est appliquée, même si le message peut mentionner des ports en raison des calculs de ressources des nœuds.

## Pièges courants et comment les éviter

Comprendre ce qui peut mal tourner est la moitié de la bataille. Voici des pièges courants avec les contraintes de répartition topologique et comment les éviter.

### Piège 1 : Étiquettes de nœuds manquantes ou incorrectes

**Pourquoi cela arrive** : les contraintes de répartition topologique reposent sur les étiquettes de nœuds pour définir les domaines. Si les nœuds n'ont pas l'étiquette requise (par exemple, `topology.kubernetes.io/zone`), le planificateur peut ne pas les considérer, ou il peut les traiter comme un seul domaine, conduisant à une distribution déséquilibrée.

**Comment éviter** : vérifiez toujours les étiquettes de nœuds avant de déployer. Utilisez `kubectl get nodes --show-labels` et assurez-vous que tous les nœuds prévus ont les bonnes étiquettes. En production, utilisez l'automatisation des pools de nœuds pour garantir l'étiquetage.

**Récupération** : ajoutez ou corrigez les étiquettes avec :

```bash
kubectl label node <node-name> topology.kubernetes.io/zone=zone-a --overwrite
```

Supprimez ensuite les pods pour forcer une replanification si nécessaire.

### Piège 2 : maxSkew trop faible pour la taille du cluster

**Pourquoi cela arrive** : si `maxSkew` est plus petit que l'inégalité que vous devez tolérer, le planificateur ne peut pas satisfaire la contrainte. Par exemple, avec 5 répliques et 3 zones, vous ne pouvez pas avoir une distribution égale (5/3 = 1,67). Avec `maxSkew: 1`, le mieux que vous puissiez faire est 2,2,1 ou 2,1,2, ce qui est autorisé car la différence entre le maximum et le minimum est de 1. Mais si vous essayez d'obtenir une égalité parfaite (impossible avec 5), le planificateur laisserait des pods en attente.

**Comment éviter** : calculez le minimum et le maximum théoriques par domaine en fonction des répliques et du nombre de domaines. Assurez-vous que `maxSkew` est au moins ceil(replicas/domains) - floor(replicas/domains). Pour 5 répliques sur 3 zones, c'est ceil(5/3)=2 et floor(5/3)=1, différence 1, donc `maxSkew: 1` fonctionne. Mais si vous essayez de répartir sur 2 zones avec 3 répliques et `maxSkew: 1`, c'est ceil(3/2)=2 et floor(3/2)=1, différence 1, cela fonctionne aussi. En général, testez avant d'appliquer des contraintes strictes.

**Récupération** : si des pods sont en attente, assouplissez la contrainte en augmentant `maxSkew` ou en passant `whenUnsatisfiable` à `ScheduleAnyway`, ou ajoutez plus de nœuds/domaines.

### Piège 3 : Contraintes conflictuelles

**Pourquoi cela arrive** : combiner plusieurs contraintes de répartition topologique (par exemple, zone et nom d'hôte) peut rendre la planification impossible si le cluster est trop petit. Par exemple, exiger maxSkew=1 sur la zone et maxSkew=1 sur le nom d'hôte dans un cluster de 3 nœuds et 3 zones signifie que chaque pod doit être sur un nœud unique et dans une zone unique, ce qui est bien pour 3 pods, mais passer à 4 pods devient impossible car ajouter un pod à n'importe quel nœud violerait soit le déséquilibre de zone, soit celui du nom d'hôte.

**Comment éviter** : examinez les contraintes de manière holistique. Utilisez `minDomains` (Kubernetes 1.25+) pour spécifier un nombre minimum de domaines pour une contrainte, ce qui peut influencer les décisions de planification. Simulez ou testez d'abord en laboratoire.

**Récupération** : supprimez ou assouplissez l'une des contraintes, ou ajoutez des nœuds.

### Piège 4 : Inadéquation du sélecteur d'étiquettes

**Pourquoi cela arrive** : le `labelSelector` dans la contrainte doit correspondre aux étiquettes du pod lui-même. Si vous définissez un sélecteur qui ne correspond pas au pod, la contrainte peut compter zéro pod ou des pods non prévus, conduisant à une planification inattendue.

**Comment éviter** : définissez toujours `labelSelector.matchLabels` avec les mêmes étiquettes que celles utilisées dans le modèle de pod (par exemple, `app: web`).

**Récupération** : corrigez le sélecteur et mettez à jour le déploiement :

```bash
kubectl patch deployment web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/topologySpreadConstraints/0/labelSelector/matchLabels/app", "value": "web"}]'
```

### Piège 5 : Interférence avec les affinités de nœuds et les teintures

**Pourquoi cela arrive** : les sélecteurs de nœuds, les affinités ou les teintures peuvent restreindre les nœuds éligibles, réduisant le nombre de domaines et rendant la contrainte de répartition insatisfaisable.

**Comment éviter** : assurez-vous que les pods peuvent être planifiés sur tous les nœuds des domaines prévus. Par exemple, si vous utilisez des teintures, ajoutez des tolérances.

**Récupération** : ajustez les affinités/teintures ou assouplissez la contrainte.

## Chemin d'expérimentation sûr

Maintenant que le cluster est prêt, nous pouvons explorer les contraintes de répartition topologique en toute sécurité. L'objectif est d'avoir une expérience contrôlée étroite et mesurable.

Commencez avec un simple déploiement comme montré ci-dessus. Expérimentez ensuite avec ces variations :

- Changez `whenUnsatisfiable` en `ScheduleAnyway` pour voir comment les pods se répartissent lorsque les contraintes ne peuvent pas être entièrement satisfaites.
- Ajoutez une deuxième contrainte sur `kubernetes.io/hostname` pour répartir entre les nœuds au sein des zones.
- Utilisez `minDomains` pour imposer un nombre minimum de zones même si toutes n'ont pas de pods initialement.
- Combinez avec une affinité de nœuds pour restreindre le placement à certaines zones.

Pour chaque expérience, enregistrez la distribution des pods et comprenez les décisions du planificateur.

### Exemple : contrainte souple avec ScheduleAnyway

Modifiez le déploiement pour utiliser `ScheduleAnyway` :

```yaml
topologySpreadConstraints:
- maxSkew: 1
  topologyKey: topology.kubernetes.io/zone
  whenUnsatisfiable: ScheduleAnyway
  labelSelector:
    matchLabels:
      app: web
```

Appliquez et mettez à l'échelle à 5 répliques. Observez que les 5 pods sont en cours d'exécution, mais que la distribution est inégale, par exemple 2 pods dans zone-a, 2 dans zone-b, 1 dans zone-c. Le planificateur a essayé de minimiser le déséquilibre mais n'a pas bloqué la planification.

### Exemple : ajout d'une contrainte de nom d'hôte

Ajoutez une deuxième contrainte :

```yaml
topologySpreadConstraints:
- maxSkew: 1
  topologyKey: topology.kubernetes.io/zone
  whenUnsatisfiable: DoNotSchedule
  labelSelector:
    matchLabels:
      app: web
- maxSkew: 1
  topologyKey: kubernetes.io/hostname
  whenUnsatisfiable: DoNotSchedule
  labelSelector:
    matchLabels:
      app: web
```

Avec 3 répliques, cela placera un pod sur chaque nœud (et zone). Avec 4 répliques, un pod sera en attente car aucun nœud ne peut héberger un deuxième pod sans violer le déséquilibre du nom d'hôte.

Cela démontre comment les contraintes interagissent.

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

Comprendre ce qui peut mal tourner et comment récupérer est essentiel. Cette section couvre les modes de défaillance courants et la récupération étape par étape.

### Pods bloqués en attente

Comme vu précédemment, si la contrainte de répartition topologique ne peut pas être satisfaite, les pods restent non planifiés. Cela peut arriver en raison de nœuds insuffisants, d'étiquettes mal configurées ou de conflits.

**Étapes de récupération** :

1. Identifiez le pod en attente :

```bash
kubectl get pods --field-selector=status.phase=Pending
```

2. Décrivez le pod pour voir la raison :

```bash
kubectl describe pod <pending-pod>
```

Recherchez des événements comme « 0/4 nodes are available... »

3. Décidez d'une correction :
   - Réduire : `kubectl scale deployment web --replicas=3`
   - Assouplir la contrainte : changez `maxSkew` pour une valeur plus élevée ou `whenUnsatisfiable` en `ScheduleAnyway`.
   - Ajoutez plus de nœuds avec des étiquettes appropriées.
   - Supprimez les contraintes conflictuelles.

Exemple de correctif pour assouplir :

```bash
kubectl patch deployment web -p '{"spec":{"template":{"spec":{"topologySpreadConstraints":[{"maxSkew":2,"topologyKey":"topology.kubernetes.io/zone","whenUnsatisfiable":"ScheduleAnyway","labelSelector":{"matchLabels":{"app":"web"}}}]}}}}'
```

Supprimez ensuite les pods en attente pour permettre la recréation :

```bash
kubectl delete pod -l app=web --field-selector=status.phase=Pending
```

### Inadéquations des étiquettes de nœuds

Si un nœud n'a pas l'étiquette attendue, ajoutez-la :

```bash
kubectl label node <node-name> topology.kubernetes.io/zone=zone-a
```

Pour les nœuds mal étiquetés, corrigez l'étiquette :

```bash
kubectl label node <node-name> topology.kubernetes.io/zone=zone-b --overwrite
```

Après le réétiquetage, vous devrez peut-être supprimer les pods pour déclencher une replanification.

### Retour en arrière

Pour revenir à un état connu d'un déploiement, vous pouvez utiliser `kubectl rollout undo` si vous avez une révision précédente :

```bash
kubectl rollout undo deployment/web
```

Ou appliquez un fichier YAML précédemment enregistré.

### Recréation du cluster

Si le laboratoire devient instable, supprimez et recréez le cluster :

```bash
kind delete cluster --name topo-lab
kind create cluster --name topo-lab --config kind-config.yaml
```

Cela réinitialise tout.

## Liste de contrôle opérationnelle

Utilisez cette liste de contrôle pour des opérations reproductibles lorsque vous travaillez avec des contraintes de répartition topologique en laboratoire.

### Liste de contrôle pré-déploiement

- [ ] Vérifiez que le cluster est en cours d'exécution : `kubectl cluster-info`
- [ ] Vérifiez que les nœuds ont les bonnes étiquettes : `kubectl get nodes --show-labels`
- [ ] Assurez-vous que les clés de topologie requises sont présentes sur tous les nœuds prévus.
- [ ] Testez la planification avec un pod simple (par exemple, `nginx`) sans contraintes pour confirmer que la planification de base fonctionne.
- [ ] Décidez de `whenUnsatisfiable` en fonction des exigences (strict ou souple).
- [ ] Calculez le déséquilibre attendu en fonction des répliques et du nombre de domaines.
- [ ] Attribuez un propriétaire pour l'examen de la configuration du déploiement (par exemple, Priya Shah, responsable de l'ingénierie), qui doit approuver toute modification des contraintes.

### Liste de contrôle du déploiement

- [ ] Appliquez le déploiement avec des contraintes de répartition topologique : `kubectl apply -f app.yaml`
- [ ] Vérifiez que les pods sont planifiés comme prévu : `kubectl get pods -o wide`
- [ ] Comptez les pods par domaine topologique en utilisant la commande awk.
- [ ] Vérifiez les pods en attente : `kubectl get pods --field-selector=status.phase=Pending`
- [ ] Examinez les événements en cas de problème : `kubectl describe deployment web`
- [ ] Confirmez que l'annotation de contrainte est présente sur un pod : `kubectl get pod <pod-name> -o jsonpath='{.metadata.annotations}'`

### Liste de contrôle post-déploiement

- [ ] Surveillez la distribution des pods après des événements de mise à l'échelle (par exemple, passez à 4 et 5 répliques).
- [ ] Testez les scénarios de défaillance : isolez un nœud (`kubectl cordon kind-worker`) et voyez comment les pods se replanifient ; supprimez l'isolement après le test.
- [ ] Validez que le déséquilibre reste dans les limites.
- [ ] Documentez tout comportement inattendu dans un carnet de laboratoire pour référence future.
- [ ] Examinez le déploiement chaque semaine avec l'équipe pour vous assurer que les contraintes correspondent toujours aux objectifs de disponibilité.

### Liste de contrôle du retour en arrière

- [ ] Conservez les manifestes YAML précédents dans le contrôle de version.
- [ ] Utilisez `kubectl rollout undo` si le déploiement est géré via des mises à jour progressives.
- [ ] Si nécessaire, réduisez ou supprimez le déploiement.
- [ ] Recréez le cluster si nécessaire.

Exemples de commandes opérationnelles :

```bash
# Vérifiez le déséquilibre en comptant les pods par nœud
kubectl get pods -l app=web -o wide | awk 'NR>1 {print $7}' | sort | uniq -c

# Obtenez les événements d'un déploiement
kubectl describe deployment web | tail -20

# Vérifiez les pods en attente
kubectl get pods --field-selector=status.phase=Pending
```

## Conclusion

Dans ce guide, vous avez mis en place un laboratoire Kubernetes local pour tester en toute sécurité les contraintes de répartition topologique. Vous avez appris à :

- Créer un cluster multi-zones avec kind.
- Étiqueter les nœuds avec des clés de topologie.
- Déployer des applications avec des contraintes de répartition topologique.
- Vérifier la distribution des pods et diagnostiquer les échecs.
- Récupérer des problèmes courants.

En suivant l'approche de pilote étroit, vous pouvez explorer systématiquement le comportement de planification Kubernetes sans risquer les environnements de production. Les points clés à retenir sont :

- Commencez avec un scénario clair et testable.
- Utilisez `whenUnsatisfiable: ScheduleAnyway` lors de l'exploration initiale.
- Vérifiez toujours avec `kubectl get pods -o wide` et `describe`.
- Ayez un plan de retour en arrière.

Prochaines étapes :

- Expérimentez avec plusieurs contraintes et affinités de nœuds.
- Testez les contraintes souples et observez le déséquilibre sous charge.
- Explorez le paramètre `minDomains` (Kubernetes 1.25+) pour encore plus de contrôle.
- Intégrez les contraintes de répartition topologique dans vos tests CI/CD.

Avec ce laboratoire, vous pouvez acquérir la confiance et l'expertise nécessaires pour appliquer efficacement les contraintes de répartition topologique en production.