## Introduction

La sauvegarde et la restauration des déploiements Kubernetes ne sont pas une fonctionnalité que l’on attend d’avoir à utiliser. C’est un ensemble de procédures reproductibles qui protègent l’état de votre application, l’historique de vos versions et la capacité de votre équipe à récupérer lorsqu’un déploiement corrompt des données, supprime une étiquette critique ou qu’un espace de noms entier disparaît. Ce guide fournit aux développeurs, aux consultants DevOps et aux équipes techniques de startups des commandes concrètes, des exemples YAML et des chemins de décision pour sauvegarder et restaurer des déploiements dans un cluster réel.

Nous couvrirons :

- La capture des manifestes de déploiement, des ReplicaSets, des Pods et de la configuration associée sous forme de sauvegardes versionnées.
- La restauration à partir de sauvegardes après une suppression accidentelle, un mauvais déploiement ou une défaillance du cluster.
- L’utilisation de la fonctionnalité de retour en arrière de Kubernetes comme mécanisme de récupération rapide et intégré.
- La validation des restaurations pour vous assurer que l’application fonctionne, et pas seulement que les Pods sont en cours d’exécution.
- La construction d’un flux de travail de sauvegarde et de restauration simple mais fiable, sans outils externes.

L’objectif est la sécurité opérationnelle. Observez avant de modifier, limitez le rayon d’impact, utilisez des espaces réservés plutôt que des secrets dans vos fichiers de sauvegarde, vérifiez chaque restauration et documentez les étapes de récupération avant qu’un incident ne vous oblige à improviser.

Toutes les commandes supposent un cluster Kubernetes fonctionnel et kubectl configuré pour y accéder. Si vous utilisez un service géré comme EKS, GKE ou AKS, les mêmes commandes s’appliquent sauf indication contraire.

## Inventaire des versions et de l’environnement

Avant de sauvegarder quoi que ce soit, sachez à quoi vous avez affaire. L’inventaire des versions et de l’environnement évite l’erreur classique de restaurer un déploiement sur un cluster qui ne peut pas l’exécuter parce que la version de l’API a changé ou qu’une CRD requise est manquante.

Exécutez ces commandes en lecture seule pour capturer l’état actuel :

```bash
kubectl version --short
kubectl cluster-info
kubectl get nodes
kubectl get deployments --all-namespaces
kubectl get crds
```

Exemple de sortie d’un cluster sain :

```
Client Version: v1.27.3
Kustomize Version: v5.0.1
Server Version: v1.27.3

Kubernetes control plane is running at https://192.168.49.2:8443
CoreDNS is running at https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   13d   v1.27.3

NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   coredns                   1/1     1            1           13d
default       web-app                   3/3     3            3           2d
```

Vérifiez la version de l’API de vos déploiements. Exécutez :

```bash
kubectl get deployment web-app -o yaml | grep -E 'apiVersion|kind'
```

Sortie attendue :

```
apiVersion: apps/v1
kind: Deployment
```

Si vous voyez `extensions/v1beta1` quelque part, migrez avant de sauvegarder car cette version de l’API a été supprimée dans les versions modernes de Kubernetes. Pour plus de détails sur les dépréciations d’API, exécutez `kubectl api-versions` et comparez avec les notes de version de votre cluster.

Prérequis pour une sauvegarde et une restauration réussies :

- Version de kubectl dans une version mineure du serveur.
- Accès à l’espace de noms où le déploiement s’exécute.
- Espace disque suffisant sur votre cible de sauvegarde pour les fichiers YAML et, si nécessaire, les données etcd exportées.
- Pour la reprise après sinistre à l’échelle du cluster, accès administrateur au plan de contrôle ou à la fonctionnalité de capture instantanée de votre fournisseur géré.

Capturez une référence horodatée avant tout changement. Par exemple :

```bash
date -u +%Y%m%dT%H%M%SZ
```

Sortie :

```
20250315T140000Z
```

Utilisez ce horodatage dans les noms de fichiers de sauvegarde et les journaux de restauration.

## Chemin de configuration sécurisé

La sauvegarde d’un déploiement commence par l’exportation de son manifeste et de tous les objets dépendants. La commande native `kubectl get -o yaml` est votre premier outil. Mais une exportation brute inclut des champs en direct comme `status`, `creationTimestamp` et `resourceVersion` qui ne devraient pas faire partie d’une sauvegarde propre. Utilisez un outil comme `kubectl neat` ou nettoyez manuellement le YAML pour ne conserver que l’état souhaité.

Voici un flux de travail complet pour sauvegarder un déploiement nommé `web-app` dans l’espace de noms `default` :

```bash
mkdir -p backups/20250315T140000Z
cd backups/20250315T140000Z

# Exporter le déploiement, le ReplicaSet et le Pod (le cas échéant, géré directement)
kubectl get deployment web-app -o yaml > deployment-web-app.yaml
kubectl get rs -l app=web-app -o yaml > replicasets-web-app.yaml

# Exporter le service et les ConfigMaps/Secrets (attention aux secrets !)
kubectl get svc -l app=web-app -o yaml > service-web-app.yaml
kubectl get configmap -l app=web-app -o yaml > configmap-web-app.yaml
# Évitez d’exporter directement les Secrets ; utilisez plutôt un outil de gestion des secrets ou encodez des références.
```

Après l’exportation, nettoyez les manifestes. Pour la démonstration, supprimez manuellement la section `status` et les champs de métadonnées non nécessaires à la recréation. Un YAML de déploiement nettoyé devrait ressembler à :

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  namespace: default
  labels:
    app: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
      - name: nginx
        image: nginx:1.25.0
        ports:
        - containerPort: 80
        env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
```

Remarquez que la référence au secret (`db-secret`) est préservée, mais que les données réelles du secret ne figurent pas dans le fichier de sauvegarde. Vous devez sauvegarder vos Secrets séparément à l’aide d’une méthode sécurisée comme Sealed Secrets, External Secrets ou le gestionnaire de secrets de votre fournisseur cloud.

Au lieu de nettoyer manuellement à chaque fois, utilisez `kubectl neat` si disponible :

```bash
kubectl neat get deployment web-app > deployment-web-app-clean.yaml
```

`kubectl neat` supprime automatiquement le statut, les champs gérés et autres éléments superflus.

Pour le contrôle de version, validez ces fichiers YAML dans un dépôt Git. Cela vous donne un historique, une comparaison et une piste d’audit.

## Vérification et diagnostic

Une sauvegarde n’est utile que si vous pouvez la restaurer. La vérification commence avant tout incident. Planifiez des exercices de restauration réguliers dans un espace de noms de test. Cette section montre comment restaurer et vérifier un déploiement de manière contrôlée.

### Restauration dans le même espace de noms

Si le déploiement d’origine existe toujours mais que vous devez revenir à une sauvegarde (par exemple, quelqu’un l’a modifié de manière incorrecte), vous pouvez appliquer directement le manifeste de sauvegarde, mais attention : écraser un déploiement en direct peut perturber le trafic. Une méthode plus sûre consiste à utiliser la fonctionnalité de retour en arrière de Kubernetes, décrite plus loin. Pour l’instant, supposons que le déploiement a été supprimé accidentellement et que vous devez le restaurer.

```bash
kubectl apply -f deployment-web-app-clean.yaml
kubectl apply -f service-web-app.yaml
kubectl apply -f configmap-web-app.yaml
```

Après l’application, vérifiez l’état du déploiement :

```bash
kubectl rollout status deployment/web-app
```

Sortie attendue en cas de succès :

```
Waiting for deployment "web-app" rollout to finish: 2 of 3 updated replicas are available...
deployment "web-app" successfully rolled out
```

Ensuite, vérifiez les Pods :

```bash
kubectl get pods -l app=web-app -o wide
```

La sortie montre tous les Pods en cours d’exécution avec des IP uniques :

```
NAME                       READY   STATUS    RESTARTS   AGE   IP           NODE
web-app-7c9b8f6d5b-2x4pz   1/1     Running   0          5m    10.244.1.5   minikube
web-app-7c9b8f6d5b-7qz9k   1/1     Running   0          5m    10.244.1.6   minikube
web-app-7c9b8f6d5b-9s2lt   1/1     Running   0          5m    10.244.1.7   minikube
```

Consultez les journaux pour détecter les erreurs de démarrage :

```bash
kubectl logs deployment/web-app --tail=20
```

Si vous avez besoin des journaux d’un conteneur précédent qui a planté, utilisez `--previous`.

### Restauration dans un autre espace de noms

Pour les exercices ou la migration, restaurez dans un espace de noms de test :

```bash
kubectl create namespace restore-test
# Modifiez l’espace de noms dans le YAML ou utilisez sed
sed 's/namespace: default/namespace: restore-test/' deployment-web-app-clean.yaml > deployment-web-app-test.yaml
kubectl apply -f deployment-web-app-test.yaml
```

Vérifiez le trafic localement :

```bash
kubectl port-forward -n restore-test deployment/web-app 8080:80
```

Dans un autre terminal :

```bash
curl http://localhost:8080
```

Sortie attendue : page d’accueil nginx par défaut. Cela confirme que l’application répond aux requêtes, pas seulement qu’elle fonctionne.

Pour arrêter le transfert de port, appuyez sur Ctrl+C.

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

Même avec des sauvegardes, les choses tournent mal. Connaître les modes de défaillance courants accélère la récupération.

### Échec de déploiement : CrashLoopBackOff

Une défaillance courante après restauration est un Pod qui reste en CrashLoopBackOff parce que l’étiquette de l’image du conteneur est manquante ou que la configuration est incorrecte.

Diagnostiquez avec :

```bash
kubectl describe pod <nom-du-pod>
```

Regardez la section Événements pour des indices comme :

```
Warning  BackOff    2m (x20 over 4m)  kubelet  Back-off restarting failed container
```

Ensuite, obtenez les journaux :

```bash
kubectl logs <nom-du-pod> --previous
```

Si les journaux affichent une erreur comme « no such file or directory » pour un fichier monté, votre ConfigMap ou votre volume est manquant. Corrigez en restaurant la ConfigMap manquante ou en corrigeant le chemin de montage, puis réappliquez.

### Mauvaise version d’image

Si une restauration pointe accidentellement vers une étiquette d’image obsolète (par exemple, `nginx:1.24.0` alors que vous vouliez `1.25.0`), vous pouvez la corriger avec `kubectl set image` :

```bash
kubectl set image deployment/web-app nginx=nginx:1.25.0
kubectl rollout status deployment/web-app
```

### Suppression accidentelle du déploiement

Si un déploiement est supprimé, mais que ses ReplicaSets existent toujours (possible si vous avez utilisé certaines options de suppression), vous pouvez récupérer en créant un nouveau déploiement à partir du modèle de pod du ReplicaSet. Cependant, si les ReplicaSets ont également disparu, vous devez restaurer à partir de votre YAML de sauvegarde comme indiqué précédemment.

### Cluster multi-tenant : la restauration échoue en raison d’un quota de ressources

Dans un cluster partagé, une restauration peut échouer avec un message comme `exceeded quota: namespace quota exceeded`. Vérifiez les quotas :

```bash
kubectl describe resourcequota -n <espace-de-noms>
```

Si nécessaire, demandez une augmentation temporaire du quota ou restaurez dans un autre espace de noms.

### Retour en arrière d’une mauvaise mise à jour avec kubectl rollout undo

Kubernetes conserve un historique de déploiement pour les déploiements. Si une mise à jour récente cause des problèmes, vous pouvez rapidement revenir à une version précédente sans utiliser votre sauvegarde externe. C’est la récupération la plus rapide pour un mauvais code d’application ou des changements de configuration.

Affichez l’historique :

```bash
kubectl rollout history deployment/web-app
```

Exemple de sortie :

```
deployment.apps/web-app
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
```

Pour voir les détails d’une révision :

```bash
kubectl rollout history deployment/web-app --revision=1
```

Annulez le dernier déploiement :

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

Ou revenez à une révision spécifique :

```bash
kubectl rollout undo deployment/web-app --to-revision=1
```

Après le retour en arrière, vérifiez à nouveau les Pods et la santé.

Important : l’historique de déploiement est conservé pour le déploiement, mais seulement pour les révisions récentes (par défaut 10). Pour les sauvegardes à long terme, votre exportation YAML est toujours nécessaire.

## Liste de contrôle opérationnelle

Faites de la sauvegarde et de la restauration une routine, pas une panique. Voici une liste de contrôle que vous pouvez adapter au calendrier de votre équipe. Remplacez les valeurs d’exemple par vos vrais noms et métriques.

### Vérification quotidienne de préparation (5 minutes)

```bash
# Vérifiez s’il y a des Pods en échec
kubectl get pods --all-namespaces | grep -v Running
# Vérifiez l’état de déploiement des déploiements critiques
kubectl get deployments --all-namespaces
# Assurez-vous que le job de sauvegarde etcd s’est exécuté (si autogéré)
kubectl logs -n kube-system etcd-backup-job-<horodatage>
```

### Exercice de sauvegarde hebdomadaire (30 minutes)

1. Créez un répertoire de sauvegarde horodaté comme indiqué précédemment.
2. Exportez les déploiements, les services et les ConfigMaps depuis l’espace de noms de production.
3. Nettoyez les manifestes et validez-les dans Git.
4. Restaurez dans un espace de noms de test.
5. Exécutez les tests de fumée de votre application contre le déploiement restauré.
6. Documentez tout problème et faux positif.

### Test de restauration complète mensuel (1 heure)

1. Choisissez au hasard une sauvegarde de déploiement du mois précédent.
2. Restaurez-la dans un environnement isolé.
3. Validez l’intégrité des données si une base de données est impliquée (voir ci-dessous).
4. Chronométrez la restauration et enregistrez-la pour la planification future de l’objectif de délai de récupération (RTO).

### Sauvegardez les secrets en toute sécurité

Si votre déploiement utilise des secrets, ne les stockez pas en texte brut dans des dépôts Git. Options :

- Utilisez Sealed Secrets et validez des fichiers chiffrés.
- Utilisez un KMS cloud et référencez-le via External Secrets.
- Faites régulièrement tourner les secrets et entraînez-vous à les restaurer.

### Vérifiez l’intégrité des données pour les applications avec état

Pour les déploiements gérant des charges de travail avec état (par exemple, un déploiement qui sert de frontal à une base de données), les sauvegardes du déploiement seul sont insuffisantes. Vous devez également sauvegarder les volumes persistants ou les dumps de base de données. Utilisez des outils comme `velero` ou les instantanés cloud. Testez toujours la restauration à la fois de l’application et des données.

## Conclusion

La sauvegarde et la restauration des déploiements Kubernetes sont une discipline, pas un script ponctuel. Les techniques décrites ici vous donnent une base : exporter les manifestes, les nettoyer, les stocker dans un contrôle de version, pratiquer les restaurations et utiliser le retour en arrière pour des corrections rapides. Mais la vraie valeur vient de l’intégration de ces procédures dans votre rythme opérationnel.

Commencez petit. Choisissez un déploiement à faible risque, effectuez une sauvegarde et une restauration manuelles dans un espace de noms de test, et documentez les commandes et les résultats exacts. Ensuite, automatisez les étapes avec un script ou un outil comme Velero pour les sauvegardes à l’échelle du cluster. Impliquez vos coéquipiers dans un exercice pour partager les connaissances.

N’oubliez pas de vérifier au-delà du statut des Pods : testez la fonctionnalité réelle de l’application, consultez les journaux et simulez le trafic utilisateur. Suivez votre temps de restauration pour améliorer vos objectifs de récupération.

Un flux de travail de sauvegarde et de restauration fiable protège la configuration de votre application et l’état des versions, mais il protège également la confiance de votre équipe. Lorsque le prochain incident surviendra, vous aurez un chemin de récupération que vous avez déjà parcouru.

Pour aller plus loin, explorez la documentation Kubernetes sur les déploiements, les ReplicaSets et la commande `kubectl rollout`. Envisagez l’intégration avec CI/CD pour tester automatiquement les sauvegardes après chaque fusion.