Skip to main content
In this lesson you’ll learn how to enforce custom Kubernetes admission policies using OPA Gatekeeper. Built-in admission controllers (for example, LimitRanger and ResourceQuota) handle resource governance, but they don’t cover arbitrary policy requirements such as:
  • requiring specific labels on every Pod,
  • restricting images to approved registries,
  • disallowing the :latest image tag.
Gatekeeper extends the admission pipeline with policy-as-code using two primary resources:
  • ConstraintTemplate — defines a policy (registers a new CRD and contains Rego logic).
  • Constraint — an instance of that policy (sets parameters, scope, and enforcement).
This guide walks through a complete example that enforces the presence of team and environment labels on Pods. Important references: Check Gatekeeper components are running
Example output:

ConstraintTemplate — define the policy and CRD

Create a ConstraintTemplate that registers a new CRD RequiredLabels and embeds the Rego logic to detect missing labels. Save this as required-labels-template.yaml:
What this template does
  • spec.crd.spec.names.kind creates the CRD Kind RequiredLabels.
  • openAPIV3Schema validates the constraint parameters (labels must be an array of strings).
  • targets.rego contains the Rego policy executed during admission; it compares required labels with provided labels and generates violations when labels are missing.
Apply the template:
Expected response:
Verify the CRD exists:
Example output:

Constraint — instantiate the policy

Instantiate the policy by creating a Constraint of kind RequiredLabels. This configures parameters, scope, and the enforcement action. Save as required-labels-constraint.yaml:
Key fields
  • enforcementAction: deny, dryrun, or warn. Use deny to block violating requests.
  • match.kinds: scopes the constraint to core Pods.
  • parameters.labels: the required label keys validated by the template schema.
Apply the constraint:
Example response:
Quick reference: Gatekeeper resources

Test: pod without required labels (expected to be denied)

Create test-pod-no-labels.yaml:
Attempt to apply it:
Expected admission error:

Test: pod with required labels (expected to be admitted)

Create test-pod-with-labels.yaml:
Apply it:
Example response:

Dry-run mode: audit without breaking workloads

Before enforcing a blocking policy, use dryrun to discover existing violations safely. Patch the constraint to dryrun:
Expected response:
Now reapply the previously rejected unlabeled pod — Gatekeeper will allow creation but will record violations:
Example response:
List pods in namespace policy-test:
Example output:
Describe the constraint to inspect recorded violations:
Example excerpt:
Enforcement action options
Start in dryrun to discover existing violations, remediate resources where needed, and then switch to deny to fully enforce the policy. This staged rollout pattern reduces disruption.

Summary

  • ConstraintTemplate defines a policy: it registers a CRD and contains Rego logic.
  • Constraint is a policy instance: it configures parameters, scope, and enforcement mode.
  • Use dryrun to audit and identify violations before enabling deny.
  • Gatekeeper is an effective policy-as-code solution for Kubernetes: use it to enforce labels, image registries, tag policies, and other organizational rules.

Watch Video

Practice Lab