Introduction
Les Secrets Kubernetes contiennent des identifiants, clés API, jetons, matériel TLS et autres valeurs critiques. Les sauvegarder et les restaurer en toute sécurité est un prérequis indispensable pour la reprise d'activité, mais cela reste souvent implicite jusqu'à ce qu'une panne force l'action. Ce guide pratique montre comment :
- Inventorier et délimiter un projet pilote sûr pour la sauvegarde des Secrets
- Exporter les Secrets avec des manifests minimaux et réutilisables
- Chiffrer et stocker les sauvegardes
- Restaurer les Secrets proprement vers un namespace ou un nouveau cluster
- Vérifier la correction avec des contrôles concrets et observables
- Identifier les modes de défaillance et récupérer de façon prévisible
- Exécuter avec une liste de contrôle opérationnelle répétable
Les exemples supposent un shell de type Unix et l'accès kubectl. Tous les exemples sont construits et utilisent des noms et valeurs hypothétiques pour la clarté.
Inventaire des versions et de l'environnement
Avant toute manipulation, consignez votre environnement. Cela aide à choisir les bonnes commandes, éviter les surprises et garder une trace reproductible.
Prérequis :
- Kubernetes : v1.19+ recommandé (supporte les Secrets immuables). Toute version maintenue fonctionne.
kubectl: correspondez à la version mineure de votre cluster quand c'est possible.- Accès : vous avez besoin au minimum de get/list/watch/create/patch/delete sur les Secrets dans les namespaces cibles. Pour une sauvegarde cluster-wide, il faut lister les Secrets à l'échelle du cluster.
- Outils optionnels pour simplifier l'export et la conversion :
jq,yq,openssl,sops/age(pour le chiffrement au repos des sauvegardes). - Un périmètre pilote étroit : un namespace et 1 à 3 Secrets critiques. Restez mesurable et inspectable localement.
Commandes d'inventaire rapides (lecture seule) :
kubectl version --short
kubectl config get-contexts
kubectl auth can-i list secrets -A
kubectl get ns
Consignez le ou les namespaces cibles et les Secrets pour le pilote. Par exemple : namespace demo, secrets ai-api, app-tls.
Chemin de configuration sécurisé
Cette section décrit un chemin délimité et répétable que vous pouvez adopter dès aujourd'hui. Elle se concentre sur l'export basé sur kubectl avec métadonnées minimales, chiffrement au repos optionnel, et restaurations simples. Vous pourrez l'étendre plus tard avec votre gestion de clés ou automatisation préférée.
Décider quoi sauvegarder et quoi exclure
Tous les Secrets n'ont pas leur place dans votre jeu de sauvegarde. Commencez par les éléments à haute valeur et faible taux de changement.
| Type ou usage du Secret | Inclure dans la sauvegarde ? | Notes |
|---|---|---|
| Opaque (clés API, identifiants DB) | Oui | Identifiants critiques d'application. |
| kubernetes.io/tls | Oui | Certificats et clés ; vérifier l'expiration à la restauration. |
| kubernetes.io/dockerconfigjson | Oui | Requis pour les tirages d'images depuis registres privés. |
| Jetons de compte de service (hérités) | Généralement non | Éphémères dans les clusters modernes (1.24+). Recréer via comptes de service si nécessaire. |
| Jetons générés ou courts | Généralement non | Préférer les procédures de régénération à la sauvegarde. |
Identifier les Secrets cibles (pilote)
Exemples de commandes construits pour un pilote dans le namespace demo :
# Lister les Secrets et leurs types
kubectl get secrets -n demo -o custom-columns=NAME:.metadata.name,TYPE:.type
# Filtrer les Secrets probablement gérés par l'utilisateur (exclure les jetons de compte de service hérités)
kubectl get secrets -n demo -o json | jq -r '.items[] | select(.type!="kubernetes.io/service-account-token\)) | [.metadata.name,.type] | @tsv'
Choisissez 1 à 3 Secrets pour le pilote, par exemple :
ai-api(Opaque) avec une clé APIapp-tls(kubernetes.io/tls) pour le HTTPS entrant
Exporter un Secret unique avec métadonnées minimales
kubectl renvoie des données encodées en base64 plus de nombreux champs de métadonnées que vous ne voulez pas dans une sauvegarde réutilisable. Supprimez les champs volatils pour que le manifest puisse être appliqué proprement ailleurs.
Exemple construit : exporter le Secret ai-api depuis demo en YAML minimal :
- Exporter en JSON et retirer les métadonnées volatiles :
kubectl get secret ai-api -n demo -o json \
| jq 'del(.metadata.uid, .metadata.resourceVersion, .metadata.creationTimestamp, .metadata.managedFields, .metadata.annotations["kubectl.kubernetes.io/last-applied-configuration"], .metadata.generation)' \
> ai-api.json
- Optionnellement convertir le JSON en YAML pour la lisibilité :
yq -P e ai-api.json > ai-api.yaml
Le fichier ai-api.yaml résultant doit ressembler à cet exemple construit (valeurs hypothétiques) :
apiVersion: v1
kind: Secret
metadata:
name: ai-api
namespace: demo
type: Opaque
data:
OPENAI_API_KEY: c2stdGVzdC1BQUFCQ0QxMjM0NTY=
Attention : les valeurs data sont encodées en base64, pas chiffrées. Traitez ces fichiers comme sensibles et restreignez l'accès.
Exporter les Secrets TLS
Pour TLS, le type doit être kubernetes.io/tls avec deux clés : tls.crt et tls.key.
kubectl get secret app-tls -n demo -o json \
| jq 'del(.metadata.uid, .metadata.resourceVersion, .metadata.creationTimestamp, .metadata.managedFields, .metadata.annotations["kubectl.kubernetes.io/last-applied-configuration"], .metadata.generation)' \
> app-tls.json
yq -P e app-tls.json > app-tls.yaml
Export en masse pour un namespace
Pour une structure simple par fichier Secret (diffing et restauration plus faciles) :
NS=demo
TS=$(date +%Y%m%d-%H%M%S)
mkdir -p backups/$NS-$TS
for s in $(kubectl get secrets -n $NS -o jsonpath='{.items[*].metadata.name}'); do
kubectl get secret "$s" -n $NS -o json \
| jq 'select(.type != "kubernetes.io/service-account-token\)) | del(.metadata.uid, .metadata.resourceVersion, .metadata.creationTimestamp, .metadata.managedFields, .metadata.annotations["kubectl.kubernetes.io/last-applied-configuration"], .metadata.generation)' \
> backups/$NS-$TS/$s.json
yq -P e backups/$NS-$TS/$s.json > backups/$NS-$TS/$s.yaml
rm backups/$NS-$TS/$s.json
done
Ajustez les filtres selon votre environnement. Conservez JSON et YAML si vous préférez ; le YAML est montré pour la lisibilité.
Optionnel : Chiffrer les sauvegardes au repos
Si vous stockez les sauvegardes hors d'un coffre dédié, utilisez le chiffrement au niveau fichier. Comme option, chiffrez avec sops et age (exemple construit) :
# Générer une paire de clés age (une fois)
age-keygen -o ~/.age/key.txt
# Chiffrer un fichier YAML pour votre destinataire public
sops --encrypt --age YOUR_AGE_PUBLIC_KEY backups/demo-20260101-000000/ai-api.yaml \
> backups/demo-20260101-000000/ai-api.enc.yaml
# Déchiffrer lors de la restauration
sops --decrypt backups/demo-20260101-000000/ai-api.enc.yaml > /tmp/ai-api.yaml
Restreignez les permissions du système de fichiers pour les clés et sauvegardes (par exemple, chmod 600 sur les fichiers et répertoires sensibles).
Restaurer un Secret unique (même cluster ou nouveau cluster)
- Assurez-vous que le namespace cible existe :
kubectl get ns demo || kubectl create ns demo
- Appliquez le manifest du Secret :
kubectl apply -f ai-api.yaml
- Si un Secret était marqué
immutable: trueet que des valeurs changées sont requises, supprimez puis recréez :
# Vérifier si immuable
kubectl get secret ai-api -n demo -o jsonpath='{.immutable}' 2>/dev/null || true
# Si immutable est true, faire delete-then-apply :
kubectl delete secret ai-api -n demo
kubectl apply -f ai-api.yaml
- Pour TLS, appliquez de façon similaire :
kubectl apply -f app-tls.yaml
- Redémarrez les charges de travail qui consomment des variables d'environnement depuis les Secrets (les pods ne rechargent pas automatiquement les variables d'env). Pour les déploiements :
kubectl rollout restart deploy/myapp -n demo
Les montages en volume reflètent les mises à jour des Secrets peu après modification ; les variables d'env nécessitent un redémarrage du pod.
Restaurer plusieurs Secrets
Si vous avez exporté des fichiers YAML par Secret dans un répertoire :
kubectl apply -f backups/demo-20260101-000000/
Si les fichiers incluent des Secrets immuables et que les valeurs ont réellement changé, pré-supprimez au besoin (ou retirez immutable: true du fichier, supprimez, puis appliquez).
Vérification et diagnostics
Il vous faut des contrôles clairs et observables prouvant que les artefacts de sauvegarde et les objets restaurés sont corrects.
Vérifier les fichiers de sauvegarde localement
# Inspecter métadonnées et type
yq e '.kind, .metadata.name, .metadata.namespace, .type' ai-api.yaml
# Vérifier l'existence des clés attendues (exemple construit attend OPENAI_API_KEY)
yq e '.data | keys' ai-api.yaml
# Optionnellement décoder et comparer les valeurs hors ligne (stocker les sorties en sécurité)
yq -r '.data.OPENAI_API_KEY' ai-api.yaml | base64 -d | sha256sum
Consignez les hachages pour comparaison après restauration.
Vérifier le Secret restauré dans le cluster
# Confirmer présence et type du Secret
kubectl get secret ai-api -n demo -o jsonpath='{.type}{"\n"}'
# Comparer jeu de clés et hachages à la sauvegarde
kubectl get secret ai-api -n demo -o json \
| jq -r '.data | to_entries[] | "\(.key) \(.value)"}' \
| while read k v; do echo -n "$k " ; echo -n "$v" | base64 -d | sha256sum; done
# Pour TLS, décoder et vérifier CN et expiration (exemple construit)
kubectl get secret app-tls -n demo -o jsonpath='{.data.tls\.crt}' \
| base64 -d > /tmp/tls.crt
openssl x509 -in /tmp/tls.crt -noout -subject -dates -fingerprint -sha256
Résultats attendus :
- Les types correspondent (Opaque vs kubernetes.io/tls)
- Les jeux de clés correspondent
- Les hachages correspondent aux valeurs précédentes (si inchangées)
- Le certificat TLS a le sujet attendu et des dates valides
Vérifier que les charges de travail consomment les Secrets
# Pods montant les Secrets en volumes : vérifier que les fichiers existent et ont le contenu et permissions attendus
kubectl exec -n demo deploy/myapp -- sh -c 'ls -l /etc/secrets && head -c 16 /etc/secrets/some-key | wc -c'
# Pods utilisant des variables d'env depuis les Secrets : confirmer la présence de la valeur (éviter d'afficher les secrets). Utiliser des contrôles indirects ou endpoints de santé de l'application.
# Le statut du rollout est sain après les redémarrages
kubectl rollout status deploy/myapp -n demo --timeout=120s
Diagnostics pour problèmes courants
# Problème de permission
kubectl auth can-i create secrets -n demo
# Incohérence de namespace
kubectl get secret ai-api -A | grep ai-api
# Mauvais contexte
kubectl config current-context
# Événements référençant les Secrets
kubectl get events -n demo --sort-by=.lastTimestamp | grep -i secret || true
Modes de défaillance et récupération
Anticipez les façons dont les sauvegardes et restaurations de Secrets peuvent échouer, pour récupérer sans précipitation.
| Mode de défaillance | Symptôme | Récupération |
|---|---|---|
| Namespace manquant | kubectl apply échoue : namespace introuvable | Créer le namespace, réappliquer. |
| Secret immuable modifié | L'application échoue ; le champ immuable empêche la mise à jour | Supprimer le Secret, puis appliquer le nouveau manifest. |
| Incohérence de type à la restauration | L'application peut réussir, mais les charges de travail attendent un type spécifique | S'assurer que .type correspond à l'original ; supprimer-et-recréer si nécessaire. |
| Données corrompues ou non-base64 | kubectl apply ou montage pod échoue | Recréer le fichier depuis une sauvegarde saine connue ; vérifier base64 et clés. |
| Export incomplet (métadonnées seulement) | Le Secret existe mais manque de clés | Réexporter en assurant la présence des clés .data ; vérifier avant restauration. |
| Mauvais cluster/contexte | Secrets restaurés sur cluster non intentionnel | Vérifier le contexte kubectl avant apply ; étiqueter les sauvegardes avec l'ID du cluster. |
| Charges de travail ne rechargeant pas les variables d'env | L'application voit encore les anciennes valeurs | Rollout restart des déploiements/statefulsets utilisant le Secret. |
Risques supplémentaires et atténuations :
- Fuite de stockage : Les sauvegardes contiennent des données sensibles. Utilisez le chiffrement au repos et des permissions de fichier strictes.
- Sauvegardes trop larges : Commencez par un namespace pilote pour réduire le rayon d'impact, puis étendez progressivement.
- Dérive d'expiration TLS : À la restauration, confirmez la fenêtre de validité du certificat pour éviter des pannes immédiates.
Scénarios de reprise d'activité
- Restaurer sur un nouveau cluster après perte
- Recréer les namespaces.
- Appliquer les manifests de Secrets (commencer par les dépendances critiques : Secrets de tirage d'images, identifiants d'app, certificats TLS).
- Restaurer les ConfigMaps et charges de travail.
- Déclencher les rollouts et vérifier la santé de bout en bout.
- Revenir à une version antérieure connue saine d'un Secret
- Identifier le fichier de sauvegarde horodaté.
- Si immuable : supprimer le Secret courant.
- Appliquer le manifest plus ancien.
- Redémarrer les charges de travail concernées (consommateurs de variables d'env) et vérifier.
Identifier les Secrets manquants en comparant l'inventaire des manifests au cluster vivant :
- Perte partielle d'un namespace
comm -23 <(ls backups/demo-20260101-000000 | sed 's/.yaml$//' | sort) <(kubectl get secrets -n demo -o jsonpath='{.items[*].metadata.name}' | tr ' ' '\n' | sort)
- Appliquer uniquement les Secrets manquants.
Liste de contrôle opérationnelle
Utilisez ceci comme runbook répétable pour le pilote et la production.
Quotidien ou par changement (selon contexte) :
- Confirmer le contexte
kubectlet le(s) namespace(s) cible(s). - Exporter les Secrets modifiés avec métadonnées minimales.
- Chiffrer et stocker les sauvegardes avec permissions restreintes.
Hebdomadaire :
- Effectuer une restauration test dans un namespace non-production.
- Vérifier les hachages et, pour TLS, la validité des certificats.
- Confirmer que les charges de travail rechargent comme attendu (sémantiques volume vs variable d'env).
Mensuel ou trimestriel :
- Auditer le RBAC pour qui peut lire et sauvegarder les Secrets.
- Rotater les clés de chiffrement pour la sauvegarde au repos si la politique l'exige.
- Réviser l'inventaire et ajouter/retirer des Secrets du périmètre de sauvegarde.
Avant restauration en production :
- Valider que le namespace cible existe et est correct.
- Confirmer que le manifest correspond au
.typeet aux clés intentionnels. - Pour les Secrets immuables, planifier la fenêtre delete-then-apply et le redémarrage des charges de travail.
Après restauration :
- Vérifier présence, type et hachages de données du Secret.
- Redémarrer les consommateurs de variables d'env et confirmer le succès du rollout.
- Contrôler les endpoints de santé et logs de l'application pour erreurs d'identifiants ou TLS.
- Documenter ce qui a été restauré, quand, et par qui.
Exemples pratiques
Exemple construit 1 : Sauvegarder et restaurer un Secret de clé API
- Créer et sauvegarder :
- Nom du Secret :
ai-api, namespace :demo, type :Opaque - Exporter le YAML minimal comme montré plus tôt vers
ai-api.yaml - Chiffrer vers
ai-api.enc.yaml(optionnel)
- Restaurer :
- Déchiffrer si nécessaire :
sops --decrypt ai-api.enc.yaml > /tmp/ai-api.yaml kubectl apply -f /tmp/ai-api.yaml- Vérifier que le hachage correspond à la sauvegarde
- Redémarrer le déploiement l'utilisant :
kubectl rollout restart deploy/myapp -n demo
Exemple construit 2 : Sauvegarder et restaurer un Secret TLS
- Sauvegarder
app-tls:
- Exporter le YAML minimal vers
app-tls.yaml - Optionnellement stocker le
tls.crtdécodé séparément pour vérificationsopensslrapides (stocker en sécurité)
- Restaurer :
kubectl apply -f app-tls.yaml- Vérifier avec
openssl x509 -noout -subject -dates -fingerprint -sha256 - Confirmer que l'ingress ou le service reprend des handshakes TLS sains
Conclusion
Une procédure fiable de sauvegarde et restauration des Secrets Kubernetes est compacte, testable et observable. Commencez par un pilote étroit dans un namespace, exportez des manifests minimaux, chiffrez-les au repos, et entraînez-vous aux restaurations avec des étapes de vérification explicites. À mesure que vous dépassez le pilote, codifiez la liste de contrôle, étiquetez et versionnez vos sauvegardes, et répétez les scénarios de sinistre. Quand la restauration devient une opération claire et distincte avec vérification prévisible, vous réduisez le retravail et raccourcissez les temps de récupération. Votre prochaine étape : choisissez un namespace, sélectionnez deux Secrets, et lancez dès aujourd'hui un exercice complet sauvegarde-vérification-restauration de bout en bout.