KubernetesLXI · Admission ControlAdmission control
Admission best practices — the operational discipline
What you'll learn
- Layer admission controls: built-in, declarative, webhooks
- Choose the right failurePolicy for each webhook
- Observe admission decisions and alert on anomalies
- Migrate from webhooks to CEL where possible
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
A defensible admission programme layers controls: built-in controllers for the well-known policies (Pod Security, NodeRestriction), declarative policies (ValidatingAdmissionPolicy, Kyverno) for the workload-specific rules, and webhooks for the external lookups (signature verification, OPA Rego bundles, third-party integrations). This lesson covers the layered approach, the failurePolicy choices, the observability, and the production patterns.
The layered approach
Three layers, each with a different role:
flowchart LR
L1[Layer 1: Built-in controllers] --> L2[Layer 2: Declarative policies]
L2 --> L3[Layer 3: Webhooks for external lookups]
L1 --> A[Admission chain]
L2 --> A
L3 --> A
Layer 1 — Built-in controllers. The API server’s built-in controllers enforce the well-known policies without external dependencies:
PodSecurityfor PSS enforcement.NodeRestrictionfor kubelet permissions.LimitRangerfor default limits.ResourceQuotafor namespace quotas.ServiceAccountfor SA defaulting.
These run in the API server itself; they are fast,
reliable, and don’t need a separate deployment. The
CIS Benchmark requires PodSecurity and
NodeRestriction.
Layer 2 — Declarative policies. For
workload-specific rules (image registry, label
requirements, resource limits), use
ValidatingAdmissionPolicy (CEL) or Kyverno. These
are evaluated in the API server or in a small
controller; they don’t depend on external services.
Layer 3 — Webhooks for external lookups. For policies that require external data (signature verification against Cosign, OPA bundles from an external server, third-party integrations), use a webhook. The webhook is a separate service with its own HA, observability, and SLO.
The failurePolicy choice
For each webhook, choose Fail or Ignore:
Failfor security webhooks: image signature, privilege restriction, PSS enforcement. The webhook outage means the policy cannot be enforced; the request is rejected.Ignorefor advisory webhooks: linting, naming conventions, optional best practices. The webhook outage means the policy is skipped; the request is allowed.
The CIS Benchmark requires Fail for security
webhooks. A webhook with Ignore is a bypass that
an attacker can exploit.
flowchart LR
A[Webhook] -->|reachable| B[Decision]
A -->|unreachable| F{failurePolicy}
F -->|Fail| G[Reject]
F -->|Ignore| H[Allow]
Observability
Every admission decision should be observable:
- Audit log. Enable audit logging at
RequestResponselevel for the admission phase. The audit log records every decision with the UserInfo, the policy name, the resource, and the decision. - Webhook metrics. Every webhook exposes Prometheus metrics: request rate, latency, success rate, error rate. SIEM rules alert on anomalies.
- Admission events. Rejected requests produce
Kubernetes events.
kubectl get eventsshows the policy violations. - Policy audit logs.
ValidatingAdmissionPolicydecisions are logged with the policy name and the reason.
A cluster without admission observability has a gatekeeper that is silent; a cluster with observability has a gatekeeper that is auditable.
Migration from webhooks to CEL
For policies that can be expressed in CEL, the migration from webhooks to CEL improves reliability:
- Identify the policy. Find a webhook whose handler logic is purely declarative (no external lookups).
- Express in CEL. Translate the logic into CEL expressions.
- Deploy the CEL policy. Create the
ValidatingAdmissionPolicyand binding. - Run in
Warnmode. SetvalidationActions: [Warn]. - Verify. Check that the warning events match the expected rejections.
- Switch to
Deny. SetvalidationActions: [Deny]. - Disable the webhook. Delete the
ValidatingAdmissionWebhookConfiguration.
A migration reduces the cluster’s dependence on external services for policy enforcement.
Production failure modes
- All webhooks, no CEL. The cluster’s admission chain depends on webhooks for everything; an outage blocks the cluster. The fix is to migrate declarative policies to CEL.
Ignoreon a security webhook. The webhook is a bypass. The fix isFail.- Single webhook replica. The webhook is a single point of failure. The fix is HA replicas.
- No observability. Admission decisions are invisible. The fix is audit logging + Prometheus metrics + SIEM alerts.
- Built-in controllers disabled. The
PodSecuritycontroller is off; PSS is not enforced. The fix is to enable the controller.
Cross-course references
- The Observability course covers the audit log and SIEM integration.
- The Linux course covers the TLS and CA management for webhook client config.
Quiz
Knowledge check · 4 questions
Q1. What are the three layers of a defensible admission programme?
Q2. For purely declarative policies (no external lookups), CEL-based `ValidatingAdmissionPolicy` is more reliable than webhook-based policy because it is evaluated in the API server and does not depend on an external service.
Q3. Your cluster runs a webhook for image registry whitelist enforcement. The webhook has had three outages this quarter, each blocking all Pod creations. The policy is purely declarative (no external lookups). Walk the migration to CEL.
The webhook rejects any image not starting with `registry.example.com/`. The webhook service has 1 replica (no HA). The policy is expressible in CEL: `object.spec.containers.all(c, c.image.startsWith('registry.example.com/'))`. The team wants a more reliable enforcement.
Q4. Explain when to use `failurePolicy: Fail` vs `failurePolicy: Ignore` for an admission webhook.
Passing score: 75%. Answers are checked in this browser.
Production discipline
A defensible admission programme layers controls:
built-in for the well-known policies, declarative for
the workload-specific rules, webhooks for the external
lookups. Every webhook has the right failurePolicy
(Fail for security, Ignore for advisory), HA
replicas, observability, and a documented disable
procedure. The audit log is the proof: every decision
is recorded. A cluster whose admission chain is
layered, observed, and documented is a cluster whose
gatekeeper is auditable; a cluster whose admission
chain is webhooks-only and silent is not.