Introduction
Les contrôleurs d'admission Kubernetes se situent directement sur le chemin des requêtes de l'API. Ils interceptent les opérations de création, de mise à jour et de suppression, et peuvent rejeter une requête avant qu'elle ne soit persistée. Cela en fait une couche de politiques et de sécurité puissante, mais aussi fragile. Un webhook d'admission mal configuré peut bloquer tous les déploiements, casser des namespaces ou empêcher le cluster de planifier des charges de travail.
La sauvegarde, la restauration et la reprise après sinistre des contrôleurs d'admission ne sont pas des réflexions après coup. Ce sont des prérequis opérationnels. Un cluster sans chemin de récupération testé pour son pipeline d'admission est à un seul mauvais manifeste d'une panne.
Cet article s'adresse aux développeurs, consultants DevOps et équipes techniques de startups qui exploitent de vrais clusters. Il couvre :
- L'inventaire des versions et de l'environnement pour les contrôleurs d'admission
- Les chemins de configuration sûrs, y compris les manifestes de webhooks et la gestion des certificats
- La vérification et le diagnostic avec des commandes concrètes et des sorties attendues
- Les modes de défaillance et les flux de récupération
- Une liste de contrôle opérationnelle que vous pouvez réellement exécuter
Chaque section inclut des commandes pratiques, des extraits de manifestes et des signaux de défaillance. L'objectif est la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, utiliser des espaces réservés au lieu de secrets, vérifier les résultats et documenter la récupération avant d'en avoir besoin.
Inventaire des versions et de l'environnement
Avant de toucher à un contrôleur d'admission, sachez exactement ce qui tourne. Les contrôleurs d'admission se répartissent en deux grandes catégories :
- Contrôleurs d'admission intégrés compilés dans le serveur d'API Kubernetes, activés avec
--enable-admission-plugins. - Contrôleurs d'admission dynamiques (webhooks) enregistrés via
ValidatingWebhookConfigurationetMutatingWebhookConfiguration.
Quoi inventorier
Capturez :
- La version du cluster Kubernetes (
kubectl version --short) - Les drapeaux du serveur d'API sur les nœuds du plan de contrôle
- Toutes les configurations de webhooks
- Les services, déploiements et pods derrière chaque webhook
- Les certificats des webhooks et leur expiration
- Toutes les politiques, ressources personnalisées et namespaces impliqués
Observation en lecture seule d'abord
Exécutez ces commandes avant de faire tout changement :
kubectl version --short
kubectl get validatingwebhookconfigurations
kubectl get mutatingwebhookconfigurations
kubectl get apiservices | grep -E 'v1beta1.admission|v1.admission'
Exemple de sortie attendue (tronquée) :
NAME WEBHOOKS AGE
opa-validating-webhook 1 12d
image-policy-mutating-webhook 1 8d
Pour chaque webhook, inspectez ses règles, son sélecteur de namespace et sa configuration client :
kubectl describe validatingwebhookconfiguration opa-validating-webhook
Recherchez :
rules: quelles ressources et opérations déclenchent le webhooknamespaceSelector: quels namespaces sont affectésclientConfig.service: le nom du service, le namespace, le chemin et le bundle CA optionnelfailurePolicy:FailouIgnore. SiFail, le serveur d'API rejette les requêtes lorsque le webhook est indisponible.
Vérifier la santé du backend du webhook
Les backends des webhooks sont simplement des pods. Utilisez la séquence de dépannage Kubernetes standard :
kubectl get pods -n webhook-system -o wide
kubectl describe pod <pod-name> -n webhook-system
kubectl logs <pod-name> -n webhook-system --previous
kubectl rollout status deployment/<webhook-deployment> -n webhook-system
Exemple d'un déploiement de webhook sain :
$ kubectl rollout status deployment/opa-webhook -n webhook-system
deployment "opa-webhook" successfully rolled out
Si le déploiement est bloqué, inspectez les événements et les journaux avant de changer quoi que ce soit.
Les certificats font partie de l'inventaire
Les webhooks d'admission dynamiques nécessitent TLS. Le bundle CA dans la configuration du webhook doit correspondre au certificat présenté par le serveur du webhook. Vérifiez l'expiration du certificat :
kubectl get validatingwebhookconfiguration opa-validating-webhook -o jsonpath='{.webhooks[0].clientConfig.caBundle}' | base64 -d | openssl x509 -noout -dates
Sortie attendue :
notBefore=Mar 1 12:00:00 2024 GMT
notAfter=Mar 1 12:00:00 2025 GMT
Si le certificat est proche de l'expiration, planifiez une rotation avant qu'il ne tombe en panne.
Enregistrer l'état avant le changement
Créez un fichier instantané :
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations -o yaml > admission-webhooks-snapshot-$(date +%F).yaml
Cet instantané est votre chemin de retour rapide. Stockez-le dans le contrôle de version avec vos configurations de cluster.
Chemin de configuration sûr
Modifier les contrôleurs d'admission est à haut risque car une erreur peut bloquer la création de charges de travail à l'échelle du cluster. Suivez un chemin contrôlé.
Étape 1 : Définir le changement et le rayon d'impact
Avant de modifier, documentez :
- Quel webhook ou drapeau change ?
- Quelles ressources et namespaces sont affectés ?
- Quelle est la
failurePolicy? - Comment allez-vous vérifier le succès ?
- Quelle est la commande de retour en arrière ?
Étape 2 : Utiliser une copie, pas l'objet en direct
Travaillez toujours à partir d'une copie de la configuration :
kubectl get validatingwebhookconfiguration opa-validating-webhook -o yaml > opa-webhook-backup.yaml
cp opa-webhook-backup.yaml opa-webhook-new.yaml
Modifiez opa-webhook-new.yaml avec vos changements.
Étape 3 : Validation avant vol
Utilisez kubectl apply --dry-run=client ou --dry-run=server pour valider la syntaxe et l'admission côté serveur :
kubectl apply -f opa-webhook-new.yaml --dry-run=client
Pour une validation plus approfondie, testez avec une requête d'admission minimale en utilisant kubectl create en mode dry-run sur une ressource factice qui déclenche le webhook.
Étape 4 : Appliquer et vérifier immédiatement
Appliquez le changement :
kubectl apply -f opa-webhook-new.yaml
Vérifiez ensuite que le webhook fonctionne toujours :
kubectl get validatingwebhookconfiguration opa-validating-webhook -o yaml
kubectl get pods -n webhook-system
kubectl logs <webhook-pod> -n webhook-system --tail=20
Créez une ressource de test qui devrait être admise et une qui devrait être rejetée (si votre politique a une liste de refus). Par exemple, utilisez un dry-run pour éviter les effets de bord :
kubectl create deployment test-admission --image=nginx --dry-run=client -o yaml | kubectl apply --dry-run=server -f -
Si la requête est rejetée de manière inattendue, vérifiez les journaux et les métriques du webhook.
Étape 5 : Garder les tests locaux minimaux
Pour le développement de nouveaux webhooks, utilisez un cluster local ou un namespace dédié avec un namespaceSelector limitant le webhook à ce namespace. Exemple de sélecteur de namespace dans la configuration du webhook :
namespaceSelector:
matchLabels:
admission-webhook: enabled
Étiquetez ensuite uniquement le namespace de test :
kubectl label namespace test-ns admission-webhook=enabled
Vérifiez le trafic localement avec kubectl port-forward vers le service du webhook avant de l'exposer via un équilibreur de charge ou une entrée.
Vérification et diagnostic
La vérification ne consiste pas à dire « ça s'est appliqué sans erreur ». Vous devez confirmer que le contrôleur d'admission intercepte réellement les requêtes et prend les bonnes décisions.
1. Vérifier que la configuration du webhook est active
kubectl get validatingwebhookconfigurations opa-validating-webhook -o jsonpath='{.metadata.name} {.webhooks[0].failurePolicy} {.webhooks[0].rules}'
La sortie attendue montre les règles et la failurePolicy.
2. Tester les décisions d'admission avec dry-run
Créez un manifeste qui devrait passer et un qui devrait échouer. Utilisez kubectl apply --dry-run=server pour éviter de persister la ressource.
Exemple de passage :
cat <<EOF | kubectl apply --dry-run=server -f -
apiVersion: v1
kind: Pod
metadata:
name: test-pass
spec:
containers:
- name: nginx
image: nginx:1.21
EOF
Exemple d'échec (en supposant que la politique exige une étiquette spécifique) :
cat <<EOF | kubectl apply --dry-run=server -f -
apiVersion: v1
kind: Pod
metadata:
name: test-fail
spec:
containers:
- name: nginx
image: nginx:latest
EOF
Message d'échec attendu :
Error from server (Forbidden): error when creating "STDIN": admission webhook "opa-validating-webhook.example.com" denied the request: image tag 'latest' not allowed
Si l'échec n'est pas celui attendu, le webhook ne fonctionne pas correctement.
3. Inspecter les journaux et les métriques du webhook
La plupart des webhooks enregistrent les requêtes d'examen d'admission. Activez une journalisation verbeuse si nécessaire.
kubectl logs -n webhook-system deploy/opa-webhook --tail=50
Recherchez les décisions et les horodatages. Pour OPA, utilisez opa eval ou consultez le journal de décision.
De nombreux frameworks de webhooks exposent des métriques Prometheus. Interrogez des métriques comme apiserver_admission_webhook_request_total depuis le serveur d'API pour voir les appels des webhooks :
kubectl get --raw /metrics | grep apiserver_admission_webhook_request_total
Cela montre les compteurs par webhook et par résultat.
4. Tester les drapeaux du serveur d'API pour les contrôleurs d'admission intégrés
Si vous avez modifié --enable-admission-plugins, vérifiez les journaux du serveur d'API et les drapeaux actuels :
kubectl -n kube-system logs kube-apiserver-control-plane | grep admission
Ou consultez le manifeste du pod statique sur le nœud du plan de contrôle.
5. Valider la chaîne de certificats
Si le TLS du webhook est mal configuré, les journaux du serveur d'API affichent des erreurs. Vérifiez :
kubectl -n kube-system logs kube-apiserver-control-plane | grep "x509"
Vérifiez que le bundle CA correspond au certificat du serveur du webhook en utilisant openssl.
Modes de défaillance et récupération
Les défaillances des contrôleurs d'admission peuvent être silencieuses ou bruyantes. Connaissez les modes de défaillance courants et comment récupérer.
Mode de défaillance 1 : Service du webhook indisponible
Symptôme : toutes les requêtes API qui correspondent aux règles du webhook échouent avec un délai d'attente ou une connexion refusée, mais seulement si failurePolicy: Fail. Si failurePolicy: Ignore, les requêtes sont autorisées silencieusement.
Exemple d'erreur :
Error from server (InternalError): error when creating "deployment.yaml": Internal error occurred: failed calling webhook "opa-validating-webhook.example.com": Post "https://opa-webhook.webhook-system.svc:443/validate?timeout=10s": dial tcp 10.96.0.42:443: connect: connection refused
Récupération :
- Vérifiez si le déploiement du webhook tourne :
kubectl get pods -n webhook-system
- Sinon, augmentez le nombre de répliques ou redémarrez :
kubectl scale deployment opa-webhook --replicas=1 -n webhook-system
- Si le sélecteur de service est incorrect, corrigez-le.
- Comme échappatoire d'urgence, définissez temporairement
failurePolicy: Ignoreou supprimez la configuration du webhook :
kubectl delete validatingwebhookconfiguration opa-validating-webhook
Avertissement : supprimer le webhook retire l'application de la politique. Restaurez à partir de la sauvegarde dès que possible.
Mode de défaillance 2 : Expiration ou non-concordance du certificat
Symptôme : les journaux du serveur d'API affichent x509: certificate signed by unknown authority ou certificate has expired. Toutes les requêtes correspondantes échouent.
Récupération :
- Générez une nouvelle paire cert/clé pour le serveur du webhook.
- Mettez à jour le secret TLS du déploiement du webhook.
- Mettez à jour le
caBundledans la configuration du webhook avec la nouvelle CA. - Appliquez la configuration mise à jour.
Exemple pour mettre à jour le bundle CA à partir d'un fichier :
CA_BUNDLE=$(cat ca.crt | base64 | tr -d '\n')
kubectl patch validatingwebhookconfiguration opa-validating-webhook --type='json' -p="[{'op': 'replace', 'path': '/webhooks/0/clientConfig/caBundle', 'value':'${CA_BUNDLE}'}]"
Vérifiez ensuite avec un test d'admission en mode dry-run.
Mode de défaillance 3 : Règles de webhook trop larges bloquent toutes les ressources
Symptôme : après l'application d'un nouveau webhook, tout échoue, y compris les composants système.
Récupération :
- Supprimez immédiatement la configuration du webhook :
kubectl delete validatingwebhookconfiguration <name>
- Restaurez la version précédente à partir de votre instantané :
kubectl apply -f admission-webhooks-snapshot-YYYY-MM-DD.yaml
- Enquêtez sur les règles et le
namespaceSelectorpour réduire la portée. - Réappliquez une version corrigée.
Mode de défaillance 4 : Le webhook mutateur corrompt les ressources
Un webhook mutateur peut injecter des correctifs invalides, cassant les applications. Si vous remarquez que des pods échouent après une mutation, vérifiez :
kubectl get pods <name> -o yaml | grep -A5 'annotations'
Recherchez les mutations qui ont modifié des champs requis.
Récupération :
- Désactivez le webhook mutateur.
- Redéployez les charges de travail affectées.
- Corrigez la logique de mutation et réactivez-la dans un namespace de test.
Flux de retour en arrière
Gardez toujours un instantané connu bon. Appliquez le retour en arrière avec :
kubectl apply -f admission-webhooks-known-good.yaml
Surveillez ensuite les journaux du serveur d'API et les métriques d'admission pour confirmer que la base est restaurée.
Liste de contrôle opérationnelle
Utilisez cette liste avant et après tout changement sur les contrôleurs d'admission.
Avant le changement
- [ ] Version du cluster et liste des webhooks capturées dans un document
- [ ] Configurations actuelles des webhooks exportées en YAML et stockées dans git
- [ ] Dates d'expiration des certificats notées
- [ ] Santé du déploiement et du service du backend du webhook vérifiée (
kubectl get pods,kubectl describe) - [ ] Namespace de test étiqueté pour un déploiement limité si possible
- [ ] Dry-run de la nouvelle configuration terminé sans erreurs
- [ ] Instantané de retour en arrière accessible
- [ ] Notification d'astreinte ou fenêtre de maintenance arrangée
Pendant le changement
- [ ] Appliquer un changement de webhook à la fois
- [ ] Surveiller les journaux du serveur d'API pour les erreurs
- [ ] Exécuter des tests d'admission en mode dry-run pour les cas d'autorisation et de refus
- [ ] Surveiller la métrique
apiserver_admission_webhook_request_total
Après le changement
- [ ] Vérifier que les webhooks sont toujours enregistrés
- [ ] Exécuter la suite complète de tests d'admission
- [ ] Vérifier la création d'applications dans les namespaces affectés
- [ ] Consigner le changement dans le runbook avec horodatage et résultat
- [ ] S'assurer que le document de retour en arrière est mis à jour si nécessaire
Référence rapide pour les réponses d'urgence
| Situation | Action immédiate |
|---|---|
| Toutes les ressources sont rejetées | Supprimer la configuration du webhook ou définir failurePolicy=Ignore |
| Backend du webhook en panne | Augmenter le nombre de répliques ou redémarrer le déploiement |
| Certificat expiré | Faire tourner les certificats et mettre à jour le caBundle |
| Corruption par le webhook mutateur | Désactiver le webhook mutateur, redéployer les charges de travail |
Conclusion
Les contrôleurs d'admission Kubernetes sont puissants, mais ils exigent une discipline opérationnelle. La sauvegarde et la restauration ne concernent pas seulement les fichiers de configuration — elles incluent les certificats, les déploiements du backend du webhook et les procédures de test.
Ce guide fournit un flux de travail pratique :
- Inventorier vos contrôleurs d'admission et leur état
- Apporter des changements via un chemin sûr et limité avec des dry-runs et des sauvegardes
- Vérifier le comportement avec des tests et des métriques concrets
- Se préparer aux défaillances courantes avec des étapes de récupération explicites
- Utiliser une liste de contrôle opérationnelle pour prévenir les erreurs
Commencez par une vérification à faible risque dans un namespace de test. Enregistrez l'état actuel, exécutez la vérification, comparez le résultat et examinez les dépendances. Un flux de travail fiable rend la défaillance visible, protège les valeurs sensibles, limite les changements et définit la récupération avant qu'un incident ne force la décision.
Prochaines étapes : choisissez un webhook que vous exécutez déjà, exportez sa configuration, examinez sa failurePolicy et ses sélecteurs de namespace, et testez un retour en arrière avec votre instantané. Cet exercice vous montrera exactement à quel point vous êtes préparé.