Introduction
Les événements Kubernetes sont souvent négligés jusqu'à ce qu'un incident critique nécessite une chronologie de ce qui s'est passé. Les événements enregistrent des transitions comme la planification des pods, les échecs de vérification de santé et les problèmes de nœuds, mais ils sont éphémères : par défaut, le serveur d'API ne les conserve qu'environ une heure. Perdre cet historique peut compliquer le dépannage, les audits et les post-mortems. Ce guide fournit une approche pratique pour sauvegarder et restaurer les événements Kubernetes, avec des commandes concrètes, des validations et des procédures de récupération. À la fin, vous disposerez d'un processus reproductible qui s'intègre à vos opérations existantes.
Inventaire des versions et de l'environnement
Avant de mettre en œuvre une solution de sauvegarde, documentez votre environnement de cluster et les versions des outils. Cet inventaire garantit la cohérence et aide à éviter les problèmes de compatibilité. Vérifiez les éléments suivants :
- Version de Kubernetes : exécutez
kubectl version --short(oukubectl versiondans les versions plus récentes). Exemple de sortie :Client Version: v1.29.2,Server Version: v1.29.1. - Version de l'API Events : exécutez
kubectl api-resources | grep events. Confirmez quel groupe d'API est disponible :events.k8s.io/v1ouevents.k8s.io/v1beta1(obsolète depuis la v1.19). Exemple de sortie :
events events.k8s.io/v1 true Event
events v1 true Event
Cela montre à la fois les événements core v1 et le groupe plus récent events.k8s.io/v1.
- TTL des événements du serveur d'API : vérifiez le drapeau
--event-ttlsur lekube-apiserver. La valeur par défaut est 1 heure. Cela définit la durée de conservation des événements sans sauvegarde. Vous pouvez inspecter la spécification du pod du serveur d'API ou le fichier de configuration. Par exemple, dans un cluster kubeadm, consultez/etc/kubernetes/manifests/kube-apiserver.yamlet recherchez--event-ttl. S'il n'est pas défini, la valeur par défaut est1h0m0s. - Topologie du cluster : identifiez les espaces de noms et les charges de travail qui génèrent des événements critiques. Pour un projet pilote, concentrez-vous sur un espace de noms d'application, par exemple
defaultou un espace de noms personnalisé commepayments. - Permissions d'accès : vous avez besoin d'un accès en lecture aux événements dans l'espace de noms cible. Exécutez
kubectl auth can-i get events -n votre-espace-de-noms. Si la réponse estyes, vous pouvez continuer. Si c'estno, vous devrez peut-être accorder des autorisations via RBAC. Exemple de sortie lorsque c'est autorisé :yes. - Emplacement de stockage de la sauvegarde : décidez où stocker les événements exportés (par exemple, système de fichiers local, stockage d'objets). Pour ce guide, nous utilisons des fichiers JSON locaux.
Exemple de commande pour vérifier le support des événements :
kubectl get --raw /apis/events.k8s.io/v1 | jq .
La sortie attendue montre la version du groupe d'API :
{
"kind": "APIResourceList",
"apiVersion": "v1",
"groupVersion": "events.k8s.io/v1",
"resources": [
{
"name": "events",
"singularName": "event",
"namespaced": true,
"kind": "Event",
"verbs": ["create", "delete", "get", "list", "patch", "update", "watch"]
}
]
}
Si l'API events.k8s.io n'est pas disponible, utilisez l'API des événements core v1 (/api/v1/namespaces/{namespace}/events), qui a une structure similaire mais des champs différents.
Chemin de configuration sûr
Un processus de sauvegarde sûr doit être limité, idempotent et éviter d'altérer le cluster. Nous utiliserons des commandes kubectl natives pour exporter les événements en JSON, qui peuvent être restaurés plus tard en recréant les événements via l'API. Pour la production, vous pouvez automatiser cela avec un CronJob, mais les étapes manuelles sont essentielles pour la validation.
Sauvegarde limitée
Sauvegardez d'abord les événements d'un seul espace de noms :
kubectl get events -n votre-espace-de-noms -o json > events-backup-$(date +%Y%m%d-%H%M%S).json
Sortie attendue : un fichier JSON avec la liste des événements. Exemple d'extrait :
{
"apiVersion": "v1",
"items": [
{
"metadata": {
"name": "my-pod.16a1b2c3d4e5f6g7",
"namespace": "votre-espace-de-noms",
"uid": "12345678-1234-1234-1234-123456789abc",
"resourceVersion": "12345",
"creationTimestamp": "2023-05-01T10:00:00Z"
},
"involvedObject": {
"kind": "Pod",
"namespace": "votre-espace-de-noms",
"name": "my-pod",
"uid": "abcdef12-3456-7890-abcd-ef1234567890"
},
"reason": "Scheduled",
"message": "Successfully assigned votre-espace-de-noms/my-pod to node-1",
"type": "Normal",
"count": 1,
"firstTimestamp": "2023-05-01T10:00:00Z",
"lastTimestamp": "2023-05-01T10:00:00Z"
}
],
"kind": "List",
"metadata": {
"resourceVersion": ""
}
}
Filtrage pour la pertinence
Vous pouvez vouloir sauvegarder uniquement les événements d'avertissement ou les événements d'une ressource spécifique :
kubectl events -n votre-espace-de-noms --types=Warning -o json > warnings-backup.json
Cette commande exporte uniquement les événements avec type: Warning. Le fichier de sortie contient des événements comme FailedScheduling, BackOff, etc. Vous pouvez également filtrer par objet impliqué, par exemple :
kubectl events -n votre-espace-de-noms --for pod/my-pod -o json > my-pod-events.json
Pour un filtrage plus complexe, utilisez jq sur le fichier exporté pour sélectionner des événements en fonction des champs.
Automatisation avec CronJob
Pour des sauvegardes continues, créez un CronJob qui exécute un script en utilisant un compte de service avec un accès en lecture aux événements. Exemple de manifeste CronJob (exemple construit) :
apiVersion: batch/v1
kind: CronJob
metadata:
name: event-backup
namespace: backup-tools
spec:
schedule: "0 * * * *"
jobTemplate:
spec:
template:
spec:
serviceAccountName: event-backup-sa
restartPolicy: OnFailure
containers:
- name: backup
image: bitnami/kubectl:latest
command:
- /bin/sh
- -c
- |
kubectl get events --all-namespaces -o json > /backups/events-$(date +%Y%m%d-%H%M%S).json
volumeMounts:
- name: backup-volume
mountPath: /backups
volumes:
- name: backup-volume
persistentVolumeClaim:
claimName: event-backup-pvc
Remarque : cela nécessite un PersistentVolumeClaim et des RBAC appropriés. Pour un projet pilote, une sauvegarde manuelle est suffisante.
Pour configurer les RBAC pour le compte de service du CronJob, créez un Role et un RoleBinding. Exemple :
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: event-reader
namespace: backup-tools
rules:
- apiGroups: [""]
resources: ["events"]
verbs: ["get", "list", "watch"]
- apiGroups: ["events.k8s.io"]
resources: ["events"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: event-backup-binding
namespace: backup-tools
subjects:
- kind: ServiceAccount
name: event-backup-sa
namespace: backup-tools
roleRef:
kind: Role
name: event-reader
apiGroup: rbac.authorization.k8s.io
Appliquez-les avec kubectl apply -f rbac.yaml.
Pour le PersistentVolumeClaim, vous pouvez utiliser un provisionneur dynamique ou un simple hostPath pour les tests. Exemple de PVC :
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: event-backup-pvc
namespace: backup-tools
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
Vérification et diagnostics
Après la sauvegarde, vérifiez que le fichier de sauvegarde est valide et complet. Utilisez jq pour inspecter et compter les événements :
jq '.items | length' events-backup-*.json
Sortie attendue : un nombre (par exemple, 42).
Vérifiez que le fichier contient les champs attendus :
jq '.items[0] | {reason, message, type, involvedObject}' events-backup-*.json
Exemple de sortie :
{
"reason": "Scheduled",
"message": "Successfully assigned votre-espace-de-noms/my-pod to node-1",
"type": "Normal",
"involvedObject": {
"kind": "Pod",
"name": "my-pod",
"namespace": "votre-espace-de-noms"
}
}
Comparez avec le nombre d'événements en direct pour détecter les événements manqués :
LIVE_COUNT=$(kubectl get events -n votre-espace-de-noms --no-headers | wc -l)
BACKUP_COUNT=$(jq '.items | length' events-backup-*.json)
echo "Live: $LIVE_COUNT, Backup: $BACKUP_COUNT"
Sortie attendue : Live: 50, Backup: 50 (les nombres peuvent différer légèrement en raison de la création d'événements entre les commandes). Si le nombre de sauvegardes est nettement inférieur, cela peut indiquer que certains événements ont expiré avant la sauvegarde ou que la sauvegarde était incomplète.
Pour les sauvegardes automatisées, vérifiez le statut du CronJob :
kubectl get cronjob event-backup -n backup-tools
La sortie attendue montre LAST SCHEDULE et SUSPEND comme False :
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
event-backup 0 * * * * False 0 3m20s 1d
Vérifiez les exécutions des jobs :
kubectl get jobs -n backup-tools
Exemple :
NAME COMPLETIONS DURATION AGE
event-backup-1651234567 1/1 5s 3m20s
Si un job échoue, inspectez les journaux :
kubectl logs job/event-backup-1651234567 -n backup-tools
Modes de défaillance et récupération
Plusieurs modes de défaillance peuvent affecter la sauvegarde et la restauration des événements. Les comprendre vous aide à planifier la récupération.
Modes de défaillance courants
| Mode de défaillance | Symptôme | Atténuation |
|---|---|---|
| Fichier de sauvegarde manquant ou vide | jq renvoie une erreur ou le compte est zéro | Ajouter une étape de vérification ; vérifier la disponibilité du stockage |
| La restauration échoue en raison de doublons | Le serveur d'API rejette les événements avec le même nom | Utiliser kubectl replace ou supprimer les événements existants avant la restauration |
| Permissions RBAC incorrectes | kubectl get events renvoie Forbidden | Mettre à jour les rôles du compte de service |
| Expiration du TTL des événements avant la sauvegarde | Certains événements manquent dans la sauvegarde | Réduire l'intervalle de sauvegarde ou augmenter --event-ttl |
| Incompatibilité de version d'API | Les événements ne sont pas reconnus lors de la restauration | Convertir entre core v1 et events.k8s.io/v1 si nécessaire |
Retour en arrière et récupération
Si une tentative de restauration cause des problèmes (par exemple, des événements indésirables inondent le cluster), vous pouvez supprimer tous les événements restaurés dans un espace de noms :
kubectl delete events --all -n votre-espace-de-noms
Avertissement : cela supprime tous les événements, y compris les événements en direct. Pour être plus sélectif, étiquetez les événements restaurés avant de les appliquer, puis supprimez-les par étiquette.
Exemple de retour en arrière sélectif :
- Lors de la restauration, ajoutez une étiquette personnalisée en modifiant le fichier de sauvegarde avant de l'appliquer. Vous pouvez utiliser
jqpour ajouter une étiquette à tous les événements de la sauvegarde :
jq '.items[].metadata.labels.restored = "true"' events-backup.json > events-backup-with-label.json
kubectl apply -f events-backup-with-label.json
- Pour revenir en arrière, supprimez les événements avec cette étiquette :
kubectl delete events -n votre-espace-de-noms -l restored=true
Procédure de restauration
Pour restaurer des événements à partir d'un fichier de sauvegarde, vous devez recréer chaque objet événement. Comme les événements sont immuables dans certains champs (par exemple, eventTime pour events.k8s.io), vous devrez peut-être supprimer certains champs comme metadata.resourceVersion, metadata.uid et eventTime avant de les appliquer. Utilisez un script pour nettoyer et appliquer :
jq 'del(.items[].metadata.resourceVersion, .items[].metadata.uid, .items[].eventTime)' events-backup.json | kubectl apply -f -
Sortie attendue : event/event-name created pour chaque événement (ou configured s'il existe).
Important : l'API des événements core v1 ne prend pas en charge apply ; vous devrez peut-être utiliser kubectl create après le nettoyage. Pour events.k8s.io, apply fonctionne si vous omettez les champs immuables.
Pour les événements core v1, utilisez une boucle pour créer chaque événement individuellement après le nettoyage :
while read -r event; do
echo "$event" | kubectl create -f -
done < <(jq -c '.items[]' cleaned-events.json)
Alternativement, utilisez kubectl replace si l'événement existe déjà et que vous voulez le mettre à jour (bien que les événements soient largement immuables, certains champs peuvent être mis à jour).
Liste de contrôle des opérations
Utilisez la liste de contrôle suivante pour les opérations de sauvegarde d'événements en continu :
- [ ] Inventorier les versions de Kubernetes et de l'API Events ; les enregistrer dans le runbook. Exemple : Kubernetes v1.29, API Events events.k8s.io/v1.
- [ ] Confirmer les permissions RBAC pour le compte de service de sauvegarde (le cas échéant). Vérifier avec
kubectl auth can-i get events --as=system:serviceaccount:backup-tools:event-backup-sa -n votre-espace-de-noms. - [ ] Sélectionner l'espace de noms pilote et documenter le volume d'événements. Exemple :
kubectl get events -n default --no-headers | wc -lrenvoie 120 événements dans la dernière heure. - [ ] Exécuter la sauvegarde manuelle avec
kubectl get events -n <ns> -o json > backup.json. - [ ] Valider la sauvegarde : compter les événements, vérifier que le fichier n'est pas vide, inspecter un événement d'exemple.
- [ ] Tester la restauration dans un espace de noms hors production d'abord. Utiliser un espace de noms séparé comme
test-restoreet nettoyer après. - [ ] Configurer l'automatisation (CronJob) seulement après que la validation manuelle réussit.
- [ ] Configurer des alertes de surveillance pour les échecs de job de sauvegarde (par exemple, vérifier le statut du CronJob ou définir une alerte Prometheus sur
kube_job_status_failed). - [ ] Planifier des exercices de restauration périodiques (par exemple, trimestriels) pour s'assurer que les sauvegardes sont utilisables.
- [ ] Réviser et mettre à jour la politique de rétention des sauvegardes ; supprimer les anciennes sauvegardes du stockage. Exemple : conserver les 30 dernières sauvegardes quotidiennes, supprimer automatiquement les plus anciennes.
Exemple de commande de surveillance pour les échecs de CronJob :
kubectl get jobs -n backup-tools -l job-name=event-backup-<suffix> --field-selector status.successful=0
Si un job n'a pas réussi, examinez les journaux avec kubectl logs job/event-backup-<suffix> -n backup-tools.
Pour une alerte plus robuste, vous pouvez configurer une règle d'alerte Prometheus comme :
groups:
- name: kubernetes-events
rules:
- alert: EventBackupJobFailed
expr: kube_job_status_failed{job_name=~"event-backup-.*", namespace="backup-tools"} > 0
for: 5m
labels:
severity: warning
annotations:
summary: "Échec du job de sauvegarde d'événements"
description: "Le CronJob event-backup a échoué. Consultez les journaux pour plus de détails."
Conclusion
La sauvegarde des événements Kubernetes est une pratique à faible effort et à forte valeur pour le dépannage et la conformité. Commencez par un projet pilote étroit : sauvegardez manuellement les événements d'un espace de noms, vérifiez le fichier et testez la restauration. Ensuite, automatisez avec un CronJob si nécessaire. Utilisez la liste de contrôle des opérations pour maintenir un processus fiable. En suivant les exemples de ce guide, vous pouvez préserver l'historique des événements du cluster et le récupérer en cas de besoin, réduisant les temps d'arrêt et améliorant la réponse aux incidents.