E-NO
Kubernetes 7 min de lecture

Concepts avancés de Kubernetes expliqués avec des exemples pratiques

calendar_today Publié : 2026-08-10
update Dernière mise à jour : 2026-08-10
analytics Efficacité SEO : 100%
Illustration du guide technique pour « Concepts avancés de Kubernetes expliqués avec des exemples pratiques ».

Les opérateurs Kubernetes rencontrent fréquemment des scénarios où la gestion de base des pods et l'exposition des services ne suffisent plus. Les charges de travail de production exigent un contrôle d'ordonnancement granulaire, des patterns de stockage résilients, une segmentation réseau sécurisée et des domaines de défaillance observables. Cet article couvre cinq concepts avancés de Kubernetes — les contraintes de répartition topologique des pods, les classes de priorité avec préemption, les workflows de snapshot et restauration CSI, les contrôles d'égresse NetworkPolicy, et l'autoscaling par métriques personnalisées — avec des commandes versionnées, les patterns de sortie attendus et les étapes de vérification de récupération. Chaque section suit une approche « observer d'abord » : capturer l'état actuel, appliquer le plus petit changement justifié, vérifier le signal, et documenter le chemin de retour.

Contraintes de répartition topologique des pods pour le contrôle des domaines de défaillance

Les contraintes de répartition topologique (topology spread constraints) distribuent les pods à travers des domaines de défaillance tels que les zones, les nœuds ou des étiquettes personnalisées. Contrairement à l'anti-affinité des pods, qui peut laisser des pods non ordonnançables lorsque les contraintes entrent en conflit, la répartition topologique utilise un mécanisme de notation qui favorise un placement équilibré tout en restant ordonnançable.

Prérequis : Kubernetes 1.19+ (bêta), 1.24+ (stable). Les nœuds doivent porter l'étiquette topologique topology.kubernetes.io/zone ou une étiquette personnalisée telle que failure-domain.example.com/rack.

Observer l'état actuel :

kubectl get nodes --show-labels | grep -E 'zone|rack'
kubectl get pods -n production -l app=payment-api -o wide

Observation attendue : Pods regroupés sur deux des trois zones disponibles, laissant une zone vide.

Plus petit changement justifié : Ajouter une topologySpreadConstraint à la spec du Deployment avec maxSkew: 1, topologyKey: topology.kubernetes.io/zone, et whenUnsatisfiable: ScheduleAnyway.

spec:
  template:
    spec:
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: topology.kubernetes.io/zone
        whenUnsatisfiable: ScheduleAnyway
        labelSelector:
          matchLabels:
            app: payment-api

Vérifier le résultat : Après le déploiement, kubectl get pods -n production -l app=payment-api -o jsonpath='{.items[*].spec.nodeName}' | xargs -n1 kubectl get node --show-labels devrait montrer des pods répartis sur les trois zones avec une différence maximale d'un pod par zone.

Récupération : Revenir à la révision précédente du Deployment avec kubectl rollout undo deployment/payment-api -n production et confirmer que la distribution des pods revient à l'état antérieur.

Classes de priorité et préemption pour les charges de travail critiques

Les classes de priorité (PriorityClass) assignent une précédence d'ordonnancement aux pods. Lorsque les ressources du cluster sont épuisées, l'ordonnanceur préempte les pods de priorité inférieure pour admettre ceux de priorité supérieure. Ce mécanisme protège les composants du control plane et les services critiques pour le revenu pendant les contentions.

Prérequis : Kubernetes 1.14+ (bêta), 1.19+ (stable). Les ressources PriorityClass doivent exister avant que les pods ne les référencent.

Observer l'état actuel :

kubectl get priorityclasses
kubectl describe priorityclass system-cluster-critical
kubectl get pods -A -o custom-columns=NAME:.metadata.name,NAMESPACE:.metadata.namespace,PRIORITY:.spec.priorityClassName,NODE:.spec.nodeName

Observation attendue : Aucune PriorityClass personnalisée pour la charge de travail order-processing ; ses pods s'exécutent à la priorité par défaut (0) et sont évincés en premier lors de pression.

Plus petit changement justifié : Créer une PriorityClass nommée business-critical avec value: 1000000 et preemptionPolicy: PreemptLowerPriority, puis patcher le Deployment pour la référencer.

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: business-critical
value: 1000000
preemptionPolicy: PreemptLowerPriority
globalDefault: false
description: "Le traitement des commandes ne doit pas être préempté par les jobs batch"
kubectl patch deployment order-processor -n production -p '{"spec":{"template":{"spec":{"priorityClassName":"business-critical"}}}}'

Vérifier le résultat : Simuler une pression de ressources en déployant un DaemonSet de faible priorité (value: 100) qui demande tout le CPU restant. L'ordonnanceur devrait préempter les pods du DaemonSet pour placer de nouveaux répliques order-processor. Confirmer avec kubectl get events --field-selector reason=Preempted -n production.

Récupération : Supprimer la PriorityClass (ce qui échoue si elle est référencée) après avoir retiré la référence du Deployment, puis restaurer le Deployment. Vérifier qu'aucun événement de préemption orphelin ne subsiste.

Snapshot et restauration CSI pour les charges de travail stateful

Les snapshots CSI (Container Storage Interface) fournissent des copies à un instant T des PersistentVolumes sans temps d'arrêt de l'application. Combinés avec VolumeSnapshotContent et VolumeSnapshotClass, ils permettent des workflows de sauvegarde, de clonage et de reprise après sinistre.

Prérequis : Kubernetes 1.20+ (bêta), 1.22+ (stable). Le driver CSI doit supporter la capacité VOLUME_SNAPSHOT (ex. : AWS EBS CSI driver v1.14+, GCE PD CSI driver v1.5+, Azure Disk CSI driver v1.5+). Une VolumeSnapshotClass doit exister dans le cluster.

Observer l'état actuel :

kubectl get volumesnapshotclass
kubectl get pvc -n data-platform -l app=postgres
kubectl describe pvc postgres-data-0 -n data-platform

Observation attendue : Un PVC unique postgres-data-0 lié à un PV provisionné par ebs.csi.aws.com, aucun snapshot existant.

Plus petit changement justifié : Créer un VolumeSnapshot référençant le PVC, puis restaurer vers un nouveau PVC pour un environnement de staging.

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: postgres-snap-2024-01-15
  namespace: data-platform
spec:
  volumeSnapshotClassName: csi-aws-ebs-snapclass
  source:
    persistentVolumeClaimName: postgres-data-0
kubectl apply -f postgres-snapshot.yaml
kubectl wait --for=condition=Ready volumesnapshot/postgres-snap-2024-01-15 -n data-platform --timeout=10m

Restauration :

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres-staging-restore
  namespace: data-platform
spec:
  storageClassName: gp3
  dataSource:
    name: postgres-snap-2024-01-15
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 100Gi

Vérifier le résultat : kubectl get pvc postgres-staging-restore -n data-platform affiche Bound. Déployer un pod PostgreSQL temporaire montant ce PVC et exécuter SELECT count(*) FROM orders; pour valider l'intégrité des données.

Récupération : Supprimer le PVC de staging et le VolumeSnapshot. Le PVC et le PV d'origine restent intacts. Documenter la politique de rétention des snapshots (ex. : snapshots quotidiens conservés 30 jours) dans le runbook.

Contrôles d'égresse NetworkPolicy pour une segmentation zero-trust

Les ressources NetworkPolicy restreignent le trafic pod-à-pod et pod-vers-externe. Les règles d'égresse (egress) sont souvent négligées mais sont essentielles pour prévenir l'exfiltration de données et limiter le rayon d'impact lorsqu'une charge de travail est compromise.

Prérequis : Kubernetes 1.8+ avec un plugin CNI qui applique les NetworkPolicy (Calico, Cilium, Weave Net, Antrea). kube-proxy ne doit pas être en mode IPVS strict-ARP sans support CNI.

Observer l'état actuel :

kubectl get networkpolicy -n finance
kubectl exec -n finance deploy/api-gateway -- curl -s -o /dev/null -w "%{http_code}" http://external-payment-provider.example.com

Observation attendue : Aucune NetworkPolicy n'existe dans l'espace de noms finance ; l'égresse vers toute destination réussit.

Plus petit changement justifié : Appliquer une politique de refus par défaut en égresse, puis autoriser uniquement les endpoints externes requis par CIDR ou DNS (via politique FQDN Cilium ou GlobalNetworkPolicy Calico avec sélecteur DNS).

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-gateway-egress
  namespace: finance
spec:
  podSelector:
    matchLabels:
      app: api-gateway
  policyTypes:
    - Egress
  egress:
    - to:
        - ipBlock:
            cidr: 203.0.113.0/24  # CIDR du fournisseur de paiement
      ports:
        - protocol: TCP
          port: 443
    - to:
        - namespaceSelector:
            matchLabels:
              name: monitoring
      ports:
        - protocol: TCP
          port: 9090

Vérifier le résultat : La commande curl de l'étape d'observation retourne maintenant 000 (connexion refusée/timeout). Les destinations autorisées retournent 200. Vérifier les logs Cilium/Calico pour les verdicts DENY sur les tentatives d'égresse inattendues.

Récupération : Supprimer la NetworkPolicy avec kubectl delete networkpolicy api-gateway-egress -n finance. Confirmer que l'égresse est restaurée immédiatement. Si vous utilisez Cilium, vérifier que cilium policy get n'affiche aucun trou d'application.

Autoscaling par métriques personnalisées avec Prometheus Adapter

L'Horizontal Pod Autoscaler (HPA) supporte les métriques personnalisées via l'API Custom Metrics. Le Prometheus Adapter expose les requêtes Prometheus comme métriques scalables, permettant l'autoscaling sur des signaux métier (profondeur de file d'attente, latence de requête, taux d'erreur) plutôt que sur le CPU seul.

Prérequis : Kubernetes 1.16+ (API Custom Metrics stable). Prometheus Operator v0.50+ avec prometheus-adapter déployé. Les métriques doivent être étiquetées avec namespace et pod pour le scaling au niveau pod.

Observer l'état actuel :

kubectl get apiservice v1beta1.custom.metrics.k8s.io
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/shopping/pods/*/http_requests_per_second" | jq .

Observation attendue : Service API disponible. La métrique retourne {"items":[]} car aucun pod n'expose l'ensemble d'étiquettes requis.

Plus petit changement justifié : S'assurer que l'application émet un compteur Prometheus http_requests_total avec les étiquettes namespace, pod, service. Configurer la règle Prometheus Adapter pour dériver un taux par seconde.

# Extrait de config map prometheus-adapter
rules:
  - seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
    resources:
      overrides:
        namespace: {resource: "namespace"}
        pod: {resource: "pod"}
    name:
      matches: "^(.*)_total$"
      as: "${1}_per_second"
    metricsQuery: 'sum(rate(<<.Series>>{<<.LabelMatchers>>}[2m])) by (<<.GroupBy>>)'
kubectl rollout restart deployment/prometheus-adapter -n monitoring

Créer le HPA :

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: checkout-service-hpa
  namespace: shopping
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: checkout-service
  minReplicas: 3
  maxReplicas: 50
  metrics:
    - type: Pods
      pods:
        metric:
          name: http_requests_per_second
        target:
          type: AverageValue
          averageValue: "100"

Vérifier le résultat : Générer de la charge avec hey -z 5m -c 50 https://checkout.example.com. Surveiller kubectl get hpa checkout-service-hpa -n shopping -w — les répliques devraient passer de 3 vers 50 alors que la métrique dépasse 100 req/s par pod. Quand la charge cesse, le scale-down survient après la fenêtre de stabilisation (5 minutes par défaut).

Récupération : Supprimer le HPA. Revenir à la config Prometheus Adapter et redémarrer. Confirmer que l'API custom metrics ne sert plus la métrique.

Conclusion

Les opérations avancées sur Kubernetes exigent de sortir des configurations par défaut pour adopter des patterns versionnés, observables et réversibles. Les contraintes de répartition topologique éliminent les défaillances silencieuses de zone unique. Les classes de priorité avec préemption protègent les chemins critiques pour le revenu pendant les contentions. Les snapshots CSI transforment le stockage en un actif récupérable plutôt qu'en une responsabilité. Les règles d'égresse NetworkPolicy imposent des frontières zero-trust qui survivent au compromis d'une charge de travail. L'autoscaling par métriques personnalisées aligne le coût d'infrastructure sur les signaux de demande métier. Chaque technique suit la même discipline : observer l'état actuel avec des commandes concrètes, appliquer le plus petit changement justifié, vérifier le signal attendu, et documenter la procédure de retour avant que l'incident ne survienne. Commencez par implémenter un pattern dans un cluster de staging, mesurez les signaux de vérification, et promouvez seulement quand la procédure de récupération est testée et documentée.

Recherches connexes

Score de qualité de l’article

Utilité pour le lecteur 100%
  • check_circle Guide prêt à lire
  • check_circle Exemples pratiques inclus
  • check_circle URL d’article optimisée pour le SEO