Admission Webhooks
Admission webhooks intercept requests to the Kubernetes API server before resources are persisted. They enable custom validation and mutation logic without modifying the API server itself.
Two Types of Webhooks
Validating webhooks accept or reject requests based on custom logic. They cannot modify the resource:
# List validating webhook configurations
kubectl get validatingwebhookconfigurations
# Inspect a webhook
kubectl describe validatingwebhookconfiguration my-validator
Mutating webhooks can modify requests before they are validated. Common uses include injecting sidecars, setting defaults, and adding labels:
# List mutating webhook configurations
kubectl get mutatingwebhookconfigurations
# Inspect a mutating webhook
kubectl describe mutatingwebhookconfiguration my-mutator
Webhook Configuration
Register a webhook by creating a configuration resource:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: pod-policy
webhooks:
- name: pod-policy.example.com
admissionReviewVersions: ["v1"]
sideEffects: None
clientConfig:
service:
name: webhook-service
namespace: webhook-system
path: /validate
caBundle: LS0tLS1CRUd...
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
failurePolicy: Fail
matchPolicy: Equivalent
Implementing the Webhook Server
The webhook server handles AdmissionReview requests:
func handleValidate(w http.ResponseWriter, r *http.Request) {
var review admissionv1.AdmissionReview
json.NewDecoder(r.Body).Decode(&review)
// Inspect the resource
pod := corev1.Pod{}
json.Unmarshal(review.Request.Object.Raw, &pod)
// Validate: reject pods without resource limits
allowed := pod.Spec.Containers[0].Resources.Limits != nil
review.Response = &admissionv1.AdmissionResponse{
Allowed: allowed,
UID: review.Request.UID,
}
json.NewEncoder(w).Encode(review)
}
Debugging Webhooks
# Check webhook service is reachable
kubectl get svc webhook-service -n webhook-system
# View webhook pod logs for errors
kubectl logs -n webhook-system -l app=webhook
# Test by creating a resource and checking for rejection
kubectl apply -f test-pod.yaml
# Temporarily disable a webhook for emergency access
kubectl delete validatingwebhookconfiguration pod-policy
Set failurePolicy: Ignore during development to prevent a broken webhook from blocking all API operations.