
Kubespray déploie des clusters Kubernetes en utilisant Ansible. Ce guide construit un lab KVM reproductible servant de base à des déploiements plus robustes. Contrairement à kubeadm qui nécessite des commandes manuelles sur chaque nœud, Kubespray automatise tout depuis votre poste de travail.
Kubespray vs autres solutions
Section intitulée « Kubespray vs autres solutions »Kubespray n'est pas une distribution Kubernetes : c'est une collection de playbooks Ansible qui pilotent kubeadm sur chaque nœud. Il se compare donc mal aux distributions allégées comme k3s ou k0s, qui embarquent leur propre binaire et leurs propres choix. Le tableau ci-dessous sert à trancher sur trois critères : la méthode d'installation, la façon dont la haute disponibilité est obtenue, et le degré de liberté laissé sur le plugin réseau.
| Critère | Kubespray | kubeadm | k0s | k3s | RKE2 |
|---|---|---|---|---|---|
| Type | Playbooks Ansible | Bootstrap tool | Distribution | Distribution | Distribution |
| Orientation | Prod, multi-cloud | Standard upstream | Edge, prod, CI | Edge, IoT, dev | Enterprise, sécurité |
| Installation | Ansible | Commandes | k0sctl (YAML) | Script unique | Script |
| CNI défaut | Configurable | Aucun | kube-router | Flannel | Canal |
| HA native | ✅ Ansible | Manuel | ✅ Multi-controller | ✅ Multi-server | ✅ Intégrée |
| Profil CIS | Selon config | Manuel | Manuel | Manuel | ✅ Intégré |
| Cas d'usage | Prod automatisée | Bare metal, formation | Edge, CI/CD, prod | Edge, IoT, dev | Conformité, prod |
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »À la fin de ce guide, vous saurez :
- Provisionner des VMs KVM configurées via cloud-init pour un cluster Kubernetes
- Préparer l'environnement Kubespray avec les bonnes versions d'Ansible et dépendances
- Créer un inventaire personnalisé définissant la topologie du cluster
- Déployer un cluster complet avec Calico, containerd et CoreDNS en une seule commande
- Valider que tous les composants fonctionnent correctement
- Personnaliser les options (CNI, runtime, addons) selon vos besoins
Prérequis
Section intitulée « Prérequis »Vérifiez ces points avant de commencer : un manque à ce stade se manifeste bien plus tard, sous la forme d'une erreur qui ne le désigne pas.
Ressources matérielles
Section intitulée « Ressources matérielles »Kubespray déploie les mêmes composants que kubeadm mais automatise la configuration. Les besoins sont donc identiques :
| Rôle | CPU | RAM (min) | RAM (recommandé) | Disque | Quantité |
|---|---|---|---|---|---|
| Control plane | 2 vCPU | 2 Go | 2 Go | 20 Go | 1 (ou 3+ pour HA) |
| Worker | 2 vCPU | 1 Go | 2 Go | 20 Go | 2+ |
| Poste Ansible | 1 vCPU | 1 Go | 1 Go | 5 Go | Votre machine locale |
Le minimum Kubespray pour les workers est 1 Go, mais ce guide recommande 2 Go pour éviter les problèmes lors du téléchargement parallèle des images.
Logiciels requis
Section intitulée « Logiciels requis »Sur votre poste de travail (machine de contrôle Ansible) :
- Python 3.10+ avec pip
- Git pour cloner le repository Kubespray
- SSH avec une clé configurée (les VMs doivent être accessibles sans mot de passe)
Sur les VMs cibles :
- Ubuntu 24.04 ou Rocky Linux 9 (distribution supportée par Kubespray)
- Python 3 installé (requis par Ansible)
- Accès sudo sans mot de passe pour l'utilisateur SSH
- Accès Internet pour télécharger images et binaires (sauf configuration offline dédiée)
Versions validées dans ce guide
Section intitulée « Versions validées dans ce guide »Ce guide a été validé avec les versions suivantes :
| Composant | Version |
|---|---|
| Kubespray | v2.30.0 |
| Kubernetes | v1.34.3 |
| Ansible | core 2.17.x+ |
| CNI | Calico 3.30.6 (plugin par défaut) |
Création des machines virtuelles
Section intitulée « Création des machines virtuelles »Kubespray ne provisionne pas l'infrastructure : il prend en charge des machines déjà démarrées et joignables en SSH. Cette étape prépare donc trois VMs KVM avec cloud-init, le mécanisme d'initialisation au premier démarrage des images cloud, qui pose la clé SSH, le compte sudo sans mot de passe et désactive le swap. Les adresses IP sont fixées en statique parce qu'elles seront écrites en dur dans l'inventaire Ansible.
Architecture cible
Section intitulée « Architecture cible »Nous allons créer un cluster avec 1 control plane et 2 workers sur le réseau libvirt par défaut :
Préparer l'image cloud Ubuntu 24.04
Section intitulée « Préparer l'image cloud Ubuntu 24.04 »Téléchargez l'image cloud Ubuntu 24.04 si elle n'est pas déjà présente. Canonical publie à côté des images un fichier SHA256SUMS qui contient l'empreinte de chacune : téléchargez les deux, puis vérifiez l'empreinte avant d'installer l'image dans le pool libvirt. Une image altérée deviendrait le socle de tous vos nœuds.
# Vérifier si l'image existe déjàls -lh /var/lib/libvirt/images/ubuntu-24.04-cloud.img
# Télécharger l'image et le fichier de sommes officiel dans un dossier de travailcd /tmpcurl -LO https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.imgcurl -LO https://cloud-images.ubuntu.com/noble/current/SHA256SUMS
# Vérifier l'empreinte : la sortie doit afficher "OK"sha256sum --ignore-missing -c SHA256SUMS
# Installer l'image seulement si la vérification a réussisudo install -m 0644 noble-server-cloudimg-amd64.img \ /var/lib/libvirt/images/ubuntu-24.04-cloud.imgL'option --ignore-missing évite que sha256sum échoue sur les autres images listées dans le fichier de sommes et que vous n'avez pas téléchargées. Si la ligne affiche FAILED, ne poursuivez pas : retéléchargez l'image.
Configuration cloud-init
Section intitulée « Configuration cloud-init »Créez un fichier user-data pour configurer l'utilisateur SSH sur les VMs. Remplacez VOTRE_CLE_SSH_PUBLIQUE par le contenu de votre ~/.ssh/id_ed25519.pub :
#cloud-confighostname: ${HOSTNAME}manage_etc_hosts: trueusers: - name: kube sudo: ALL=(ALL) NOPASSWD:ALL groups: users, sudo shell: /bin/bash lock_passwd: true ssh_authorized_keys: - VOTRE_CLE_SSH_PUBLIQUE
packages: - qemu-guest-agent - python3
runcmd: - swapoff -a - sed -i '/swap/d' /etc/fstab - systemctl enable qemu-guest-agentConfigurer le réseau statique
Section intitulée « Configurer le réseau statique »Créez un fichier network-config pour chaque VM avec son IP statique :
version: 2ethernets: enp1s0: dhcp4: false addresses: - 192.168.122.50/24 routes: - to: default via: 192.168.122.1 nameservers: addresses: - 192.168.122.1 - 8.8.8.8Création des VMs
Section intitulée « Création des VMs »Quatre étapes, à répéter pour chacune des trois machines. Les disques sont créés en backing file : chaque VM ne stocke que ses différences par rapport à l'image de base, ce qui rend la création quasi instantanée et économise l'espace disque. Ne supprimez donc jamais l'image de base tant que les VMs existent.
-
Générer les ISOs cloud-init pour chaque VM :
Fenêtre de terminal # Pour ks-cp1cloud-localds ks-cp1-cloud-init.iso user-data-cp1 \--network-config network-config-cp1# Répéter pour ks-worker1 et ks-worker2 avec leurs fichiers respectifs -
Créer les disques avec backing file :
Fenêtre de terminal for vm in ks-cp1 ks-worker1 ks-worker2; dosudo qemu-img create -f qcow2 \-b /var/lib/libvirt/images/ubuntu-24.04-cloud.img \-F qcow2 \/var/lib/libvirt/images/${vm}.qcow2 20Gdone -
Créer les VMs avec virt-install :
Fenêtre de terminal for vm in ks-cp1 ks-worker1 ks-worker2; dosudo virt-install \--name ${vm} \--memory 2048 \--vcpus 2 \--disk /var/lib/libvirt/images/${vm}.qcow2 \--disk /var/lib/libvirt/images/${vm}-cloud-init.iso,device=cdrom \--os-variant ubuntu24.04 \--network network=default \--graphics none \--console pty,target_type=serial \--noautoconsole \--importdone -
Vérifier la connectivité SSH :
Fenêtre de terminal for ip in 192.168.122.50 192.168.122.51 192.168.122.52; dossh -o StrictHostKeyChecking=accept-new kube@${ip} hostnamedone
Si les trois hostnames s'affichent (ks-cp1, ks-worker1, ks-worker2), vos VMs sont prêtes.
Installation de Kubespray
Section intitulée « Installation de Kubespray »Kubespray s'installe sur votre poste, pas sur les nœuds : c'est un dépôt Git de playbooks accompagné d'un requirements.txt qui épingle les versions d'Ansible et de ses dépendances Python. Ces versions sont contraignantes, chaque release de Kubespray n'étant testée qu'avec la combinaison qu'elle déclare. Un environnement virtuel Python dédié évite tout conflit avec un Ansible déjà présent sur la machine.
Cloner le repository
Section intitulée « Cloner le repository »Utilisez toujours une version taggée pour la stabilité :
git clone https://github.com/kubernetes-sigs/kubespray.git \ --depth 1 --branch v2.30.0
cd kubesprayCréer l'environnement Python
Section intitulée « Créer l'environnement Python »Kubespray nécessite des versions spécifiques d'Ansible et de ses dépendances :
# Créer un environnement virtuel isolépython3 -m venv venvsource venv/bin/activate
# Installer les dépendancespip install -U pippip install -r requirements.txt
# Vérifier Ansibleansible --versionLa sortie doit indiquer ansible [core 2.17.x] ou supérieur pour Kubespray v2.30.0.
Configuration de l'inventaire
Section intitulée « Configuration de l'inventaire »L'inventaire est le seul endroit qui décrit la topologie du cluster : quelles machines existent, et quel rôle chacune tient. Kubespray ne déduit rien, il applique strictement les groupes Ansible que vous déclarez, kube_control_plane pour le plan de contrôle, kube_node pour les workers, etcd pour la base de données du cluster. Travaillez toujours sur une copie du template fourni : un git pull écraserait vos modifications faites dans inventory/sample.
Copier le template
Section intitulée « Copier le template »Kubespray fournit un inventory sample que vous personnalisez :
cp -r inventory/sample inventory/myclusterCréer le fichier hosts.yaml
Section intitulée « Créer le fichier hosts.yaml »Remplacez le contenu de inventory/mycluster/hosts.yaml par votre topologie :
all: hosts: ks-cp1: ansible_host: 192.168.122.50 ip: 192.168.122.50 access_ip: 192.168.122.50 ks-worker1: ansible_host: 192.168.122.51 ip: 192.168.122.51 access_ip: 192.168.122.51 ks-worker2: ansible_host: 192.168.122.52 ip: 192.168.122.52 access_ip: 192.168.122.52 children: kube_control_plane: hosts: ks-cp1: kube_node: hosts: ks-worker1: ks-worker2: etcd: hosts: ks-cp1: k8s_cluster: children: kube_control_plane: kube_node: calico_rr: hosts: {}Tester la connectivité Ansible
Section intitulée « Tester la connectivité Ansible »Avant le déploiement, vérifiez que Ansible peut se connecter à tous les nœuds :
ansible all -i inventory/mycluster/hosts.yaml -m ping -u kubeRésultat attendu :
ks-cp1 | SUCCESS => { "ping": "pong" }ks-worker1 | SUCCESS => { "ping": "pong" }ks-worker2 | SUCCESS => { "ping": "pong" }Personnalisation (optionnel)
Section intitulée « Personnalisation (optionnel) »Avant de déployer, vous pouvez ajuster les paramètres dans inventory/mycluster/group_vars/.
Ce que vous pouvez changer sans risque
Section intitulée « Ce que vous pouvez changer sans risque »Éditez inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml :
# Version Kubernetes (dans la plage supportée par votre release Kubespray)kube_version: v1.34.3
# Nom DNS du clustercluster_name: cluster.localCe qui mérite un guide dédié
Section intitulée « Ce qui mérite un guide dédié »Deux variables ressemblent à de simples choix dans une liste mais engagent en réalité toute l'architecture du cluster : le plugin réseau (kube_network_plugin) et le runtime de conteneurs (container_manager). Les modifier après un premier déploiement impose une réinstallation complète.
Options de référence
Section intitulée « Options de référence »Ces sept variables sont celles que l'on consulte le plus souvent. Les deux dernières méritent une attention particulière : les plages d'adresses des pods et des services doivent rester disjointes du réseau de vos VMs, faute de quoi le routage devient imprévisible. Les valeurs par défaut conviennent au réseau libvirt 192.168.122.0/24 utilisé ici.
| Variable | Fichier | Valeur par défaut | Description |
|---|---|---|---|
kube_version | k8s-cluster.yml | v1.34.3 | Version Kubernetes |
kube_network_plugin | k8s-cluster.yml | calico | CNI, garder par défaut en lab |
container_manager | k8s-cluster.yml | containerd | Runtime, containerd est le standard actuel |
kube_proxy_mode | k8s-cluster.yml | ipvs | Mode kube-proxy (iptables, ipvs) |
cluster_name | k8s-cluster.yml | cluster.local | Nom DNS du cluster |
kube_pods_subnet | k8s-cluster.yml | 10.233.64.0/18 | CIDR des pods |
kube_service_addresses | k8s-cluster.yml | 10.233.0.0/18 | CIDR des services |
Déploiement du cluster
Section intitulée « Déploiement du cluster »Le déploiement s'effectue avec le playbook cluster.yml. Comptez 10-20 minutes selon votre connexion Internet (téléchargement des images) :
ansible-playbook -i inventory/mycluster/hosts.yaml cluster.yml \ -u kube -b --become-user=rootProgression attendue
Section intitulée « Progression attendue »Le playbook exécute plusieurs phases :
- Préparation : configuration système, désactivation swap, modules kernel
- Téléchargement : binaires (kubectl, kubeadm, kubelet) et images conteneurs
- etcd : installation et configuration du cluster etcd
- Control plane : initialisation avec kubeadm, certificats
- Workers : jointure au cluster
- Réseau : déploiement de Calico (ou CNI choisi)
- Addons : CoreDNS, metrics-server (si activé)
Exemple de sortie finale
Section intitulée « Exemple de sortie finale »Ansible termine par un récapitulatif par hôte. Le compteur skipped élevé est normal : Kubespray couvre de nombreuses distributions et options, et saute toutes les tâches qui ne correspondent pas à votre configuration.
PLAY RECAP *********************************************************************ks-cp1 : ok=624 changed=135 unreachable=0 failed=0 skipped=1090ks-worker1 : ok=413 changed=82 unreachable=0 failed=0 skipped=640ks-worker2 : ok=413 changed=82 unreachable=0 failed=0 skipped=636failed=0 sur tous les nœuds indique un déploiement réussi.
Validation du cluster
Section intitulée « Validation du cluster »Un failed=0 signifie que les playbooks se sont exécutés, pas que le cluster fonctionne. La validation se fait en quatre temps, du plus structurel au plus applicatif : récupérer le kubeconfig, vérifier que les nœuds sont Ready, contrôler les pods système, puis déployer une application de test. Les nœuds ne passent Ready qu'une fois le plugin réseau opérationnel : c'est le signal que le CNI a bien démarré.
Récupérer le kubeconfig
Section intitulée « Récupérer le kubeconfig »Le fichier kubeconfig se trouve sur le control plane. Récupérez-le sur votre poste :
# Méthode simple avec scp (recommandée)ssh kube@192.168.122.50 "sudo cat /etc/kubernetes/admin.conf" > ~/.kube/kubespray-config
# Remplacer l'adresse localhost par l'IP du control planesed -i 's/127.0.0.1/192.168.122.50/g' ~/.kube/kubespray-config
# Configurer kubectlexport KUBECONFIG=~/.kube/kubespray-configVérifier les nœuds
Section intitulée « Vérifier les nœuds »L'option -o wide ajoute trois colonnes déterminantes : l'IP interne, qui doit correspondre à celle de l'inventaire, l'image système et le runtime effectivement utilisé. Un nœud en NotReady juste après le déploiement pointe presque toujours vers le plugin réseau.
kubectl get nodes -o wideSortie attendue :
NAME STATUS ROLES AGE VERSION INTERNAL-IP OS-IMAGE RUNTIMEks-cp1 Ready control-plane 19m v1.34.3 192.168.122.50 Ubuntu 24.04.3 LTS containerd://2.2.1ks-worker1 Ready <none> 19m v1.34.3 192.168.122.51 Ubuntu 24.04.3 LTS containerd://2.2.1ks-worker2 Ready <none> 19m v1.34.3 192.168.122.52 Ubuntu 24.04.3 LTS containerd://2.2.1Les trois nœuds doivent être Ready.
Vérifier les pods système
Section intitulée « Vérifier les pods système »Tous les composants d'infrastructure tournent dans le namespace kube-system. Le tableau qui suit liste ce que Kubespray installe avec les valeurs par défaut de ce guide, y compris deux ajouts qui lui sont propres : nodelocaldns, un cache DNS local sur chaque nœud, et nginx-proxy, qui relaie les appels à l'API server depuis les workers.
kubectl get pods -ATous les pods doivent être Running :
| Namespace | Pods attendus |
|---|---|
| kube-system | calico-node (3), calico-kube-controllers |
| kube-system | coredns (2), dns-autoscaler |
| kube-system | kube-apiserver, kube-controller-manager, kube-scheduler |
| kube-system | kube-proxy (3), nodelocaldns (3) |
| kube-system | nginx-proxy (workers uniquement) |
Test de déploiement applicatif
Section intitulée « Test de déploiement applicatif »Validez que vous pouvez déployer une application :
# Créer un déploiement nginxkubectl create deployment nginx --image=nginx:alpine
# Exposer en NodePortkubectl expose deployment nginx --port=80 --type=NodePort
# Attendre que le pod soit prêtkubectl wait --for=condition=Ready pod -l app=nginx --timeout=60s
# Vérifierkubectl get pods,svcRésultat attendu :
NAME READY STATUS RESTARTS AGEpod/nginx-6f564d4fd9-xxxxx 1/1 Running 0 30s
NAME TYPE CLUSTER-IP PORT(S) AGEservice/kubernetes ClusterIP 10.233.0.1 443/TCP 20mservice/nginx NodePort 10.233.33.101 80:30965/TCP 10sLe service nginx est accessible sur http://<IP_WORKER>:30965.
Nettoyez après le test :
kubectl delete deployment nginxkubectl delete svc nginxTest DNS et connectivité inter-pods
Section intitulée « Test DNS et connectivité inter-pods »Le test nginx valide peu de choses. Pour vérifier la résolution DNS et la connectivité inter-pods :
# Lancer un pod de testkubectl run dnstest --image=busybox:1.36 --rm -it --restart=Never -- \ nslookup kubernetes.default.svc.cluster.localRésultat attendu : une adresse IP dans le range 10.233.0.x (service ClusterIP).
Dépannage
Section intitulée « Dépannage »Les échecs de déploiement Kubespray se répartissent en deux familles distinctes. Ceux qui surviennent avant la première tâche relèvent d'Ansible et de l'accès SSH ; ceux qui surviennent en cours de route relèvent du cluster lui-même. Le message d'Ansible indique toujours la tâche exacte qui a échoué et sur quel hôte : c'est le point de départ du diagnostic.
Le déploiement échoue avec "UNREACHABLE"
Section intitulée « Le déploiement échoue avec "UNREACHABLE" »Ansible ne peut pas se connecter aux VMs :
# Vérifier la connectivité SSHssh -v kube@192.168.122.50
# Vérifier que la clé est autoriséessh kube@192.168.122.50 "cat ~/.ssh/authorized_keys"
# Vérifier que Python est installéansible all -i inventory/mycluster/hosts.yaml -m raw -a "which python3" -u kubeErreur "Unable to connect to the server"
Section intitulée « Erreur "Unable to connect to the server" »kubectl ne peut pas joindre l'API server :
# Vérifier que l'adresse est correcte dans kubeconfiggrep server ~/.kube/kubespray-config
# Tester la connectivité réseaunc -zv 192.168.122.50 6443
# Vérifier que l'API server tournessh kube@192.168.122.50 "sudo crictl ps | grep kube-apiserver"Pods bloqués en "Pending"
Section intitulée « Pods bloqués en "Pending" »Généralement un problème de ressources ou de taints :
# Décrire le pod pour voir les événementskubectl describe pod <pod-name>
# Vérifier les ressources disponibleskubectl describe nodes | grep -A5 "Allocated resources"
# Vérifier les taintskubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taintsRelancer un déploiement partiel
Section intitulée « Relancer un déploiement partiel »Si le déploiement a échoué à mi-chemin, relancez simplement la même commande. Ansible est idempotent et reprendra où il s'est arrêté :
ansible-playbook -i inventory/mycluster/hosts.yaml cluster.yml \ -u kube -b --become-user=rootOpérations courantes
Section intitulée « Opérations courantes »Une fois le cluster en place, Kubespray reste le point d'entrée pour le faire évoluer : chaque opération a son playbook dédié, et aucune ne doit être menée à la main sur les nœuds. La règle qui vaut pour les trois opérations ci-dessous : mettez toujours à jour hosts.yaml avant de lancer le playbook, l'inventaire étant la source de vérité de tout le reste.
Ajouter un worker
Section intitulée « Ajouter un worker »Le playbook scale.yml n'agit que sur les nœuds absents du cluster, ce qui le rend sûr à relancer. L'option --limit restreint l'exécution à la nouvelle machine et évite de retoucher aux nœuds existants.
- Provisionner la nouvelle VM avec cloud-init
- Ajouter l'entrée dans
hosts.yamlsouskube_node - Exécuter le playbook
scale.yml:
ansible-playbook -i inventory/mycluster/hosts.yaml scale.yml \ -u kube -b --become-user=root --limit=nouveau-workerSupprimer un nœud
Section intitulée « Supprimer un nœud »Kubespray fournit un playbook dédié pour la suppression propre :
# Méthode recommandée : playbook remove-nodeansible-playbook -i inventory/mycluster/hosts.yaml remove-node.yml \ -u kube -b --become-user=root \ -e "node=ks-worker2"Ce playbook effectue automatiquement le drain, la suppression des composants Kubernetes sur le nœud et le nettoyage. Après exécution, retirez manuellement le nœud de votre fichier hosts.yaml.
Mettre à jour Kubernetes
Section intitulée « Mettre à jour Kubernetes »upgrade-cluster.yml traite les nœuds un par un en les drainant au préalable, ce qui permet de garder le service disponible si vos applications ont plusieurs réplicas. Comptez nettement plus de temps que le déploiement initial, et lisez l'encadré ci-dessous avant de choisir la version cible : les sauts autorisés sont limités.
- Modifier
kube_versiondansgroup_vars/k8s_cluster/k8s-cluster.yml - Exécuter le playbook
upgrade-cluster.yml:
ansible-playbook -i inventory/mycluster/hosts.yaml upgrade-cluster.yml \ -u kube -b --become-user=rootNettoyage du cluster
Section intitulée « Nettoyage du cluster »Pour supprimer complètement Kubernetes des nœuds :
ansible-playbook -i inventory/mycluster/hosts.yaml reset.yml \ -u kube -b --become-user=rootCe playbook :
- Arrête et supprime tous les conteneurs
- Supprime les binaires Kubernetes
- Nettoie les règles iptables
- Supprime les fichiers de configuration
Pour supprimer aussi les VMs :
for vm in ks-cp1 ks-worker1 ks-worker2; do sudo virsh destroy ${vm} sudo virsh undefine ${vm} --remove-all-storagedoneÀ retenir
Section intitulée « À retenir »Kubespray industrialise le déploiement de clusters Kubernetes :
- Infrastructure as Code : votre cluster est défini dans des fichiers YAML versionnables
- Reproductibilité : le même inventory produit le même cluster à chaque exécution
- Automatisation : upgrades, scaling, suppression de nœuds via playbooks dédiés
- Base solide : ce lab constitue un socle pour des déploiements plus robustes
Ce guide vous a permis de déployer un lab reproductible. Pour passer en production, il faut encore :
- 3 control planes + load balancer devant l'API server
- Backup etcd externalisé et testé régulièrement
- Monitoring, alerting et logs centralisés
- Sécurité réseau (NetworkPolicies, firewall configuré)
- Plan de reprise d'activité (PRA) documenté