Introduction
Les webhooks d'admission sont un point de contrôle critique dans les clusters Kubernetes. Ils interceptent les requêtes API pour des ressources telles que les Pods, les Deployments et les ressources personnalisées, et peuvent les modifier ou les valider avant qu'elles ne soient persistées. Lorsqu'un webhook échoue, il peut bloquer les déploiements, perturber la mise à l'échelle automatique ou affaiblir silencieusement la politique de sécurité. Une liste de contrôle opérationnelle structurée transforme le débogage ad hoc en procédures reproductibles et à faible risque.
Cet article s'adresse aux développeurs, aux consultants DevOps et aux équipes techniques de startups qui exécutent ou maintiennent des webhooks d'admission en production. Il couvre l'inventaire des versions et de l'environnement, les modifications de configuration en toute sécurité, la vérification et le diagnostic, les modes de défaillance et la récupération, ainsi qu'une liste de contrôle opérationnelle adaptable à votre cluster. Chaque étape associe une observation en lecture seule à une commande concrète, une sortie attendue et une décision de récupération.
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 le résultat et documenter comment récupérer si l'état attendu n'est pas atteint.
Inventaire des versions et de l'environnement
Avant de toucher à un webhook, vous devez savoir exactement ce qui est installé, quelle version d'API il utilise et comment il est déployé. Commencez par trouver toutes les configurations de webhooks d'admission dans le cluster. La commande en lecture seule est :
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations
Exemple de sortie (abrégé) :
NAME WEBHOOKS AGE
cert-manager-webhook 1 42d
kyverno-resource-validating-webhook-cfg 2 12d
pod-policy.example.com 1 3h
Pour chaque configuration de webhook, inspectez son YAML pour voir la configuration du client webhook, la politique d'échec, les règles de correspondance et la référence du service. Par exemple :
kubectl get validatingwebhookconfiguration pod-policy.example.com -o yaml
Recherchez ces champs clés :
failurePolicy:FailouIgnore. En production,Failest souvent préféré pour la sécurité, mais cela augmente le risque de panne si le webhook est indisponible.matchPolicy:ExactouEquivalent. Cela affecte si les règles s'appliquent aux groupes et versions d'API.timeoutSeconds: souvent 10 secondes par défaut. Si votre webhook est lent, les requêtes peuvent échouer.clientConfig.service: namespace, nom et port du service webhook. Vérifiez que le service existe et sélectionne les bons pods.
Vérifiez la version et l'image du serveur webhook déployé. Si votre webhook s'exécute comme un Deployment :
kubectl get deployment -n webhook-namespace pod-policy-webhook -o jsonpath='{.spec.template.spec.containers[*].image}'
Exemple de sortie :
registry.example.com/team/pod-policy-webhook:v1.4.2
Comparez cela avec la version documentée comme prise en charge pour votre cluster Kubernetes. Les webhooks d'admission reposent sur l'API admissionregistration.k8s.io, qui est stable en v1 depuis Kubernetes 1.16. La plupart des frameworks de webhooks nécessitent Kubernetes 1.19 ou plus pour des fonctionnalités comme matchConditions (introduit en 1.28 en bêta).
Consultez les journaux du serveur webhook pour voir s'il reçoit des requêtes et les traite sans erreur :
kubectl logs -n webhook-namespace deployment/pod-policy-webhook --tail=50
Faites attention à :
- Les erreurs TLS, surtout si le service webhook utilise un certificat auto-signé qui a expiré.
- Les traces de pile de panique ou les erreurs 500 répétées.
- Les latences de requête lentes, qui peuvent indiquer que le webhook fait trop de travail de manière synchrone.
Si le webhook utilise une ValidatingWebhookConfiguration ou une MutatingWebhookConfiguration qui référence un service, confirmez que les endpoints du service sont peuplés :
kubectl get endpoints -n webhook-namespace pod-policy-webhook
Exemple de sortie :
NAME ENDPOINTS AGE
pod-policy-webhook 10.244.2.15:8443 42d
Si ENDPOINTS est vide, le sélecteur de service ne correspond à aucun pod, ou les pods ne sont pas prêts.
Pour un inventaire complet de l'environnement, notez :
- La version du plan de contrôle Kubernetes (
kubectl version --short) - Les noms des configurations de webhooks et leurs politiques d'échec
- Les versions des images du serveur webhook
- Les dates d'expiration du certificat TLS servant le webhook
- Les ResourceQuotas ou LimitRanges pertinents qui pourraient affecter l'ordonnancement des pods du webhook
Liste de contrôle pratique pour l'inventaire des versions et de l'environnement :
- [ ] Lister toutes les configurations de webhooks mutateurs et validateurs avec leurs politiques d'échec.
- [ ] Enregistrer les versions du serveur et du client Kubernetes.
- [ ] Identifier l'image du serveur webhook et confirmer qu'elle est dans la plage de versions prise en charge.
- [ ] Vérifier que le service webhook existe et a des endpoints actifs.
- [ ] Vérifier les journaux du serveur webhook pour les erreurs TLS, les paniques ou les erreurs HTTP 500 répétées.
- [ ] Noter la date d'expiration du certificat TLS utilisé par le webhook.
- [ ] Documenter le namespace et la topologie de déploiement du serveur webhook.
Chemin de configuration sûr
Modifier une configuration de webhook peut avoir un impact immédiat sur l'ensemble du cluster. Suivez un chemin sûr : observez l'état actuel, préparez la modification dans un fichier local, validez-la, appliquez avec une simulation (dry-run), puis déployez progressivement.
Commencez par exporter la configuration actuelle dans un fichier. Cela sert de sauvegarde et de base de comparaison.
kubectl get validatingwebhookconfiguration pod-policy.example.com -o yaml > pod-policy-webhook-original.yaml
Faites une copie pour l'éditer :
cp pod-policy-webhook-original.yaml pod-policy-webhook-new.yaml
Modifiez pod-policy-webhook-new.yaml avec votre changement prévu. Par exemple, supposons que vous vouliez renforcer la politique d'échec de Ignore à Fail et augmenter le délai d'attente de 10 à 15 secondes. Ne modifiez que ces champs, et laissez tout le reste identique.
Avant d'appliquer, validez la syntaxe YAML et le schéma Kubernetes avec kubectl apply --dry-run=client :
kubectl apply -f pod-policy-webhook-new.yaml --dry-run=client
S'il y a une erreur de syntaxe, vous verrez un message comme :
error: error validating "pod-policy-webhook-new.yaml": error validating data: ValidationError(ValidatingWebhookConfiguration.webhooks[0].timeoutSeconds): invalid type for io.k8s.api.admissionregistration.v1.Webhook.timeoutSeconds: got "string", expected "integer"; if you choose to ignore these errors, turn validation off with --validate=false
Corrigez l'erreur et répétez la simulation jusqu'à ce qu'elle réussisse. Utilisez ensuite --dry-run=server pour simuler la validation du serveur d'API sans persister le changement :
kubectl apply -f pod-policy-webhook-new.yaml --dry-run=server
Si le serveur l'accepte, vous verrez :
validatingwebhookconfiguration.admissionregistration.k8s.io/pod-policy.example.com configured (server dry run)
Vous pouvez maintenant appliquer le changement. Mais pour réduire le risque, envisagez d'utiliser un namespace canari ou un sous-ensemble de ressources d'abord. Par exemple, si vous ajoutez une nouvelle règle de validation, vous pouvez la limiter à un namespace de test en ajoutant un namespaceSelector ou objectSelector. Dans le YAML du webhook, ajoutez sous le webhook :
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: test-namespace
Appliquez le changement :
kubectl apply -f pod-policy-webhook-new.yaml
Vérifiez immédiatement que la configuration du webhook a été mise à jour et que le serveur d'API peut toujours traiter les requêtes. Consultez les journaux du serveur webhook pour les nouvelles requêtes et les erreurs éventuelles :
kubectl logs -n webhook-namespace deployment/pod-policy-webhook --tail=20
Si vous devez revenir en arrière, restaurez la configuration d'origine :
kubectl apply -f pod-policy-webhook-original.yaml
Vérifiez ensuite que le retour en arrière est effectif en examinant à nouveau la configuration.
Gardez toujours une copie de la dernière configuration connue comme bonne dans le contrôle de version. Pour les webhooks en production, utilisez un flux GitOps où les modifications sont examinées et appliquées automatiquement, mais même les modifications manuelles doivent être traçables.
Liste de contrôle pratique pour le chemin de configuration sûr :
- [ ] Exporter la configuration actuelle du webhook dans un fichier de sauvegarde local.
- [ ] Apporter une seule modification bien définie dans une copie du fichier.
- [ ] Valider avec
kubectl apply --dry-run=clientet corriger les erreurs de syntaxe. - [ ] Valider avec
kubectl apply --dry-run=serverpour détecter les problèmes sémantiques. - [ ] Si possible, déployer sur un namespace de test ou un sous-ensemble en utilisant des sélecteurs.
- [ ] Appliquer le changement et surveiller immédiatement les journaux du serveur webhook pour les erreurs.
- [ ] Garder la configuration précédente disponible pour un retour en arrière rapide.
Vérification et diagnostic
Après avoir appliqué une modification de webhook (ou même avant, lors de l'investigation d'un problème suspecté), vous devez vérifier que le webhook fonctionne correctement et diagnostiquer tout écart.
Tout d'abord, vérifiez que le serveur webhook est en bonne santé. Si votre webhook expose un endpoint de santé, interrogez-le directement depuis l'intérieur du cluster ou via un transfert de port. Par exemple, si votre webhook utilise l'endpoint commun /healthz :
kubectl port-forward -n webhook-namespace service/pod-policy-webhook 8443:8443 &
curl -k https://localhost:8443/healthz
Sortie attendue si en bonne santé :
OK
Si la vérification de santé échoue ou si le service ne répond pas, le problème se situe probablement dans le serveur webhook lui-même, pas dans la configuration.
Ensuite, testez le comportement d'admission avec un objet contrôlé. Créez une spécification de Pod minimale que vous vous attendez à être acceptée ou rejetée selon la politique du webhook. Par exemple, si votre webhook exige une étiquette team sur chaque Pod, vous pouvez tester avec et sans l'étiquette.
Créez un fichier test-pod-no-label.yaml :
apiVersion: v1
kind: Pod
metadata:
name: test-no-label
spec:
containers:
- name: nginx
image: nginx:1.25
Tentez de le créer :
kubectl apply -f test-pod-no-label.yaml
Si le webhook fonctionne correctement avec failurePolicy: Fail et que la règle rejette les étiquettes manquantes, vous verrez une erreur comme :
Error from server: admission webhook "pod-policy.example.com" denied the request: Pod "test-no-label" is invalid: missing required label 'team'
Maintenant, testez avec l'étiquette :
apiVersion: v1
kind: Pod
metadata:
name: test-with-label
labels:
team: platform
spec:
containers:
- name: nginx
image: nginx:1.25
kubectl apply -f test-with-label.yaml
Sortie attendue :
pod/test-with-label created
Nettoyez les pods de test après la vérification :
kubectl delete pod test-no-label test-with-label
Pour diagnostiquer les délais d'attente ou les réponses lentes, vérifiez les métriques propres au webhook s'il les expose. De nombreux frameworks de webhooks exportent des métriques Prometheus. Par exemple, si votre webhook expose des métriques sur le port 8080 :
kubectl port-forward -n webhook-namespace deployment/pod-policy-webhook 8080:8080 &
curl http://localhost:8080/metrics | grep webhook_request_duration
Recherchez des percentiles élevés ou des erreurs. Vérifiez également les journaux d'audit du serveur d'API Kubernetes pour voir le minutage des appels webhook et les codes de statut. Si vous avez accès au plan de contrôle, recherchez les lignes contenant admission webhook ou webhook dans le journal d'audit.
Si le webhook utilise un certificat auto-signé, vérifiez que le bundle CA dans la configuration du webhook correspond au certificat de service. Le champ clientConfig.caBundle doit contenir le certificat CA encodé en PEM qui a signé le certificat de service du webhook. Si le certificat du serveur webhook est renouvelé, la configuration du webhook doit être mise à jour avec le nouveau bundle CA. Vous pouvez vérifier les détails du certificat avec openssl :
kubectl get validatingwebhookconfiguration pod-policy.example.com -o jsonpath='{.webhooks[0].clientConfig.caBundle}' | base64 -d | openssl x509 -noout -text | grep -E 'Subject:|Not After'
Exemple de sortie :
Subject: CN = pod-policy-webhook.webhook-namespace.svc
Not After : May 5 12:00:00 2025 GMT
Si le certificat est expiré ou si le bundle CA ne correspond pas, le serveur d'API Kubernetes refusera d'appeler le webhook et enregistrera des messages d'erreur comme x509: certificate signed by unknown authority ou certificate has expired.
Liste de contrôle pratique pour la vérification et le diagnostic :
- [ ] Confirmer que l'endpoint de santé du serveur webhook renvoie OK.
- [ ] Tester l'admission avec une ressource connue comme bonne et une connue comme mauvaise par rapport à la politique.
- [ ] Observer le message d'erreur exact du serveur d'API pour les requêtes refusées.
- [ ] Vérifier les métriques du serveur webhook pour une latence élevée ou des taux d'erreur.
- [ ] Examiner les journaux d'audit du serveur d'API Kubernetes pour les échecs d'appels webhook.
- [ ] Vérifier que le bundle CA dans la configuration du webhook correspond au certificat du serveur et n'est pas expiré.
Modes de défaillance et récupération
Les webhooks d'admission peuvent échouer de plusieurs manières, chacune avec ses propres symptômes et étapes de récupération. Comprendre ces modes de défaillance vous aide à concevoir un système résilient et à réagir rapidement.
1. Serveur webhook arrêté ou injoignable
Symptôme : Lors de la création ou de la mise à jour de ressources, le serveur d'API renvoie une erreur comme :
Error from server (InternalError): error when creating "pod.yaml": Internal error occurred: failed calling webhook "pod-policy.example.com": failed to call webhook: Post "https://pod-policy-webhook.webhook-namespace.svc:8443/validate?timeout=10s": dial tcp 10.96.0.15:8443: connect: connection refused
Récupération :
- Vérifiez si les pods du webhook sont en cours d'exécution et prêts :
kubectl get pods -n webhook-namespace -l app=pod-policy-webhook
Si aucun pod n'est prêt, examinez le Deployment, le StatefulSet ou le DaemonSet qui gère le webhook.
- Si la politique d'échec est
Fail, passer temporairement àIgnorepeut rétablir les opérations du cluster pendant que vous corrigez le webhook. Cependant, cela contourne la validation ou la mutation et ne doit être fait qu'en mesure d'urgence avec une approbation appropriée.
2. Délai d'attente du webhook
Symptôme : Les requêtes API échouent avec une erreur de délai d'attente, telle que :
Error from server: Timeout: request did not complete within requested timeout
Ou les journaux du serveur webhook montrent des requêtes prenant plus de temps que le timeoutSeconds configuré.
Récupération :
- Augmentez le
timeoutSecondsdans la configuration du webhook si le webhook a légitimement besoin de plus de temps, mais sachez que cela peut bloquer les requêtes API plus longtemps. - Optimisez le code du webhook pour réduire la latence. Par exemple, mettez en cache les données fréquemment utilisées ou déplacez les opérations coûteuses vers des contrôleurs asynchrones.
- Si le webhook est sous forte charge, augmentez le nombre de réplicas.
3. Échec du certificat TLS
Symptôme : Les journaux du serveur d'API montrent des erreurs TLS et les requêtes sont refusées. Le serveur webhook peut fonctionner correctement, mais le serveur d'API ne peut pas établir une connexion de confiance.
Récupération :
- Renouvelez le certificat de service du webhook et mettez à jour le
caBundledans la configuration du webhook avec le nouveau certificat CA. - Si vous utilisez cert-manager ou un outil similaire, assurez-vous que la ressource Certificate est valide et se renouvelle automatiquement.
- Réglez temporairement
failurePolicysurIgnoresi vous devez autoriser les requêtes pendant la correction du certificat, mais cela présente un risque de sécurité.
4. Le webhook renvoie une erreur ou refuse de manière inattendue
Symptôme : La création de ressources est refusée avec un message d'erreur spécifique au webhook. Le serveur d'API transmet l'erreur du webhook.
Récupération :
- Lisez les journaux du serveur webhook pour identifier la règle ou le chemin de code qui a renvoyé l'erreur.
- Si le rejet est dû à un bogue dans la politique du webhook, corrigez la politique et redéployez le webhook.
- Testez avec différentes ressources pour isoler si le problème est spécifique à certains types ou namespaces.
5. Mauvaise configuration du webhook
Symptôme : Le webhook correspond à des ressources qu'il ne devrait pas, ou ne correspond pas à des ressources qu'il devrait. Cela peut se produire en raison de rules, namespaceSelector ou objectSelector incorrects.
Récupération :
- Examinez la configuration du webhook par rapport à la portée prévue.
- Utilisez
kubectl describesur la configuration du webhook pour voir un résumé lisible par l'humain :
kubectl describe validatingwebhookconfiguration pod-policy.example.com
Exemple de sortie partielle :
Name: pod-policy.example.com
Namespace:
Labels: <none>
Annotations: <none>
API Version: admissionregistration.k8s.io/v1
Kind: ValidatingWebhookConfiguration
Webhooks:
Name: pod-policy.webhook.example.com
Client Config:
Ca Bundle: <base64-encoded>
Service:
Name: pod-policy-webhook
Namespace: webhook-namespace
Port: 8443
Rules:
API Groups: [""]
API Versions: ["v1"]
Operations: ["CREATE"]
Resources: ["pods"]
Scope: "Namespaced"
- Mettez à jour les règles ou les sélecteurs et réappliquez avec le chemin de configuration sûr décrit ci-dessus.
Les stratégies de récupération doivent être documentées dans vos runbooks. Incluez les commandes exactes pour annuler une modification de webhook, restaurer un certificat précédent ou désactiver un webhook en cas d'urgence. Par exemple, pour désactiver temporairement un webhook sans le supprimer, vous pouvez définir son failurePolicy sur Ignore et supprimer toutes ses règles, ou simplement supprimer la configuration du webhook (ce qui arrête tous les appels d'admission).
Extrait de récupération d'urgence :
kubectl delete validatingwebhookconfiguration pod-policy.example.com
Cela supprimera entièrement le webhook, permettant à toutes les requêtes de se poursuivre. Vous pourrez le recréer plus tard à partir de votre manifeste sous contrôle de version.
Liste de contrôle pratique pour les modes de défaillance et la récupération :
- [ ] Identifier le mode de défaillance à partir des erreurs du serveur d'API et des journaux du webhook.
- [ ] Si les pods du webhook sont arrêtés, redémarrez-les ou augmentez le nombre de réplicas.
- [ ] Si le délai d'attente est le problème, envisagez d'augmenter
timeoutSecondsou d'optimiser le webhook. - [ ] Si TLS échoue, renouvelez les certificats et mettez à jour le bundle CA.
- [ ] Si une mauvaise configuration est suspectée, examinez les règles et les sélecteurs.
- [ ] Avoir une procédure documentée de retour en arrière ou de désactivation d'urgence.
- [ ] Tester la procédure de récupération d'abord dans un cluster non productif.
Liste de contrôle opérationnelle
Utilisez cette liste de contrôle quotidienne ou hebdomadaire pour maintenir les webhooks d'admission en bonne santé. Adaptez les commandes à vos noms de webhooks et namespaces.
- Lister tous les webhooks et leurs statuts
- Commande :
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations - Attendu : tous les webhooks listés sans erreur ; notez tout webhook dont l'AGE est inhabituellement récent (peut indiquer un changement récent).
- Vérifier la santé du serveur webhook
- Commande :
kubectl get pods -n webhook-namespace -l app=pod-policy-webhook -o wide - Attendu : tous les pods en cours d'exécution et prêts (1/1 ou plus). Si un pod n'est pas prêt, examinez avec
kubectl describe podetkubectl logs.
- Vérifier les endpoints du service
- Commande :
kubectl get endpoints -n webhook-namespace pod-policy-webhook - Attendu : au moins un endpoint IP:port. Des endpoints vides signifient qu'aucun pod ne sert.
- Inspecter la configuration du webhook pour détecter les dérives
- Commande :
kubectl get validatingwebhookconfiguration pod-policy.example.com -o yaml | diff - pod-policy-webhook-original.yaml - Attendu : aucune différence à moins qu'un changement n'ait été autorisé. Si des différences existent, examinez et décidez d'accepter ou de revenir en arrière.
- Vérifier les journaux du webhook pour de nouvelles erreurs
- Commande :
kubectl logs -n webhook-namespace deployment/pod-policy-webhook --tail=100 | grep -i -E 'error|panic|timeout' - Attendu : aucune sortie ou seulement des erreurs bénignes connues. Examinez toute nouvelle ligne d'erreur.
- Vérifier l'expiration du certificat
- Commande :
kubectl get validatingwebhookconfiguration pod-policy.example.com -o jsonpath='{.webhooks[0].clientConfig.caBundle}' | base64 -d | openssl x509 -noout -enddate - Attendu : une date future, idéalement à plus de 30 jours. Si moins, planifiez le renouvellement du certificat.
- Tester l'admission avec une ressource d'exemple
- Commande : appliquez un Pod de test avec acceptation/rejet attendu, puis supprimez-le.
- Attendu : le webhook refuse lorsque la politique est violée et autorise lorsqu'elle est conforme.
- Examiner les métriques pour les anomalies
- Si des métriques sont exposées, interrogez le taux de requêtes, la latence et le taux d'erreur, et comparez avec la base de référence.
- Attendu : aucun pic soudain d'erreurs 5xx ou de latence.
- Vérifier l'utilisation des ressources des pods du webhook
- Commande :
kubectl top pods -n webhook-namespace -l app=pod-policy-webhook - Attendu : CPU et mémoire dans les limites. Une mémoire élevée peut indiquer une fuite de mémoire.
- Assurer que GitOps ou la gestion de configuration est synchronisée
- Comparez la configuration du webhook en direct avec la source de vérité dans votre dépôt.
- Attendu : aucun changement non commité en production.
Pour chaque élément, enregistrez l'horodatage, la personne effectuant la vérification et toute anomalie trouvée. Cela crée une piste d'audit et aide à repérer les tendances.
Conclusion
Les webhooks d'admission sont puissants mais risqués s'ils ne sont pas exploités avec soin. Cette liste de contrôle vous donne un moyen systématique d'inventorier, de modifier, de vérifier et de récupérer les configurations de webhooks en production. Chaque étape est limitée à la version, observable et réversible lorsque la technologie le permet.
Commencez par une vérification à faible risque : listez vos webhooks, vérifiez leur santé et testez une règle d'admission avec une ressource d'exemple. Enregistrez l'état actuel, exécutez les vérifications documentées, comparez les résultats avec les signaux attendus et passez en revue les dépendances telles que les endpoints de service, les certificats TLS et les permissions RBAC.
Un flux de travail technique fiable rend les défaillances visibles, protège les valeurs sensibles, limite les modifications à la ressource prévue et définit la vérification de récupération avant qu'un incident ne force la décision. En suivant ces pratiques, vous gardez vos webhooks d'admission stables, sécurisés et maintenables.