Exercise: a Gatekeeper policy that requires a label
Host: controlplane · Time: 15 min · Domain: Minimize Microservice Vulnerabilities
Task
- Every Pod created in
prodmust carry the labelowner. - 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 applyof an unlabelled Pod inprodfails 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