DevOps Peach

Docker & Kubernetes · Kubernetes Access Control – Authentication, RBAC, Admission · Lesson 4 of 4

Admission Controllers

Admission runs after authentication and authorization, before the object is stored; mutating controllers change objects, validating ones accept or reject.

Practice interactively →

An admission controller is code inside kube-apiserver that intercepts create/update/delete requests after authentication and authorization and before the object is stored in etcd. Read requests (get, list) skip admission.

flowchart LR
  R["Allowed request"] --> M["Mutating admission<br/>(may change the object)"]
  M --> S["Schema validation"]
  S --> V["Validating admission<br/>(accept / reject)"]
  V --> E[("etcd")]

Plugins are enabled with a kube-apiserver flag (comma-separated list; many plugins are on by default):

kube-apiserver --enable-admission-plugins=NamespaceLifecycle,LimitRanger ...
# kubeadm: edit /etc/kubernetes/manifests/kube-apiserver.yaml, the kubelet restarts the pod
Plugin What it does
NamespaceLifecycle Blocks new objects in a namespace that is terminating or does not exist
LimitRanger Applies CPU/memory defaults and limits from LimitRanges
DefaultStorageClass Fills in the default StorageClass for PVCs
Command Meaning
kubectl get validatingwebhookconfigurations Registered validating webhooks
kubectl get mutatingwebhookconfigurations Registered mutating webhooks

Pod Security Admission

The built-in PodSecurity plugin enforces three standard levels, chosen per namespace with labels:

Level Allows
privileged Everything, for system namespaces
baseline Blocks known privilege escalations: privileged containers, host namespaces, hostPath
restricted Also requires non-root, dropped capabilities, seccomp, no privilege escalation

Each namespace can set three modes: enforce (reject), audit (record in audit logs), and warn (show a warning to the user). Start with warn and audit on restricted, fix workloads, then switch to enforce.

Policy engines

Tool Policies written in Strengths
Kyverno Kubernetes-style YAML Validate, mutate, and generate resources; easy to read
OPA Gatekeeper Rego language Very flexible, shared with other OPA uses
ValidatingAdmissionPolicy CEL expressions, built into Kubernetes No webhook to run; good for simple rules

Typical rules: images must come from registry.example.com, every pod must have resource limits, the latest tag is forbidden, and every namespace needs an owner label.

A built-in CEL policy

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata: { name: require-replicas-limit }
spec:
  matchConstraints:
    resourceRules:
    - { apiGroups: ["apps"], apiVersions: ["v1"], operations: ["CREATE","UPDATE"], resources: ["deployments"] }
  validations:
  - expression: "object.spec.replicas <= 10"
    message: "replicas must be 10 or fewer"

A ValidatingAdmissionPolicyBinding then applies it to chosen namespaces.

Webhook risks

A webhook with failurePolicy: Fail blocks every matching request when the webhook service is down, which can stop deployments cluster-wide. Run webhooks with several replicas, exclude kube-system with a namespace selector, and keep timeouts short. kubectl apply --dry-run=server runs admission without saving, a safe way to test whether a manifest will be accepted.

Practice interactively →