CKSKubernetes 1.35

Exercises

Exercise: a Gatekeeper policy that requires a label

updated 2026-10-22 by seed

Host: controlplane · Time: 15 min · Domain: Minimize Microservice Vulnerabilities

Task

  • Every Pod created in prod must carry the label owner.
  • Use OPA Gatekeeper (install it if it is not there).
  • A Pod without the label must be rejected; one with it must be accepted.

Acceptance criteria

  • kubectl apply of an unlabelled Pod in prod fails with a message naming the constraint.
  • A labelled Pod is created.
  • Pods in other namespaces are unaffected.

Solution

kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.15/deploy/gatekeeper.yaml
kubectl -n gatekeeper-system get pods
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata: {name: k8srequiredlabels}
spec:
  crd:
    spec:
      names: {kind: K8sRequiredLabels}
      validation:
        openAPIV3Schema:
          type: object
          properties: {labels: {type: array, items: {type: string}}}
  targets:
  - target: admission.k8s.gatekeeper.sh
    rego: |
      package k8srequiredlabels

      violation[{"msg": msg, "details": {"missing_labels": missing}}] {
        provided := {label | input.review.object.metadata.labels[label]}
        required := {label | label := input.parameters.labels[_]}
        missing := required - provided
        count(missing) > 0
        msg := sprintf("you must provide labels: %v", [missing])
      }
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata: {name: pods-must-have-owner}
spec:
  match:
    kinds: [{apiGroups: [""], kinds: ["Pod"]}]
    namespaces: ["prod"]
  parameters:
    labels: ["owner"]
kubectl apply -f template.yaml && sleep 10 && kubectl apply -f constraint.yaml
kubectl run no-owner --image=nginx -n prod                 # rejected
kubectl run with-owner --image=nginx -n prod --labels=owner=me