Room 47
ADMISSION WEBHOOKS
The Gatekeeper’s Code
- Before any resource is persisted to etcd, it passes through admission controllers.
- Webhooks let you intercept and modify (mutate) or reject (validate) requests.
📜 Mission Briefing
- Understand the admission flow: Authentication → Authorization → Admission.
- Study
webhook-server.yaml- a simple validating webhook. - Learn about mutating vs validating admission webhooks.
- Deploy the webhook and test that it rejects pods without labels.
- The rejection message contains the password:
webhook9.
Key Commands
| Command | Purpose |
|---|---|
kubectl get validatingwebhookconfigurations |
List validating webhooks |
kubectl get mutatingwebhookconfigurations |
List mutating webhooks |
kubectl api-resources --api-group=admissionregistration.k8s.io |
Admission resources |
How Admission Webhooks Work
# Request Flow:
# API Request → Authentication → Authorization →
# Mutating Admission → Object Schema Validation →
# Validating Admission → Persisted to etcd
# Two types of webhooks:
# 1. MutatingAdmissionWebhook - Can modify the object (runs first)
# 2. ValidatingAdmissionWebhook - Can only approve/reject (runs second)
# ValidatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: pod-label-validator
webhooks:
- name: validate-labels.example.com
admissionReviewVersions: ["v1"]
sideEffects: None
clientConfig:
service:
name: webhook-server
namespace: webhook-system
path: /validate
caBundle: <base64-encoded-ca>
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
failurePolicy: Fail # Reject if webhook unavailable
matchPolicy: Equivalent
namespaceSelector:
matchExpressions:
- key: skip-validation
operator: DoesNotExist
# MutatingWebhookConfiguration
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: sidecar-injector
webhooks:
- name: inject-sidecar.example.com
admissionReviewVersions: ["v1"]
sideEffects: None
clientConfig:
service:
name: sidecar-injector
namespace: sidecar-system
path: /inject
rules:
- operations: ["CREATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
reinvocationPolicy: IfNeeded # Re-run if another webhook mutates
# Common use cases for admission webhooks:
# Mutating: inject sidecars, add labels/annotations, set defaults
# Validating: enforce naming conventions, require labels, deny privileged
# TLS is required for webhook servers
# The API server sends AdmissionReview objects to the webhook
# Webhook responds with AdmissionResponse (allowed: true/false)
Hints
Hint 2
Create a pod without the required label and check the error message:
Hint 3
The password is webhook9.