Lab 31 - Admission policies
Lab 31 - Admission policies
Goal: enforce your own rules with a built-in ValidatingAdmissionPolicy - no extra software. Chapter: Admission policies
Rule 1: no latest
# 1 -
cd ~
cat > vap-latest.yaml <<'YAML'
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: no-latest-tag
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["deployments"]
validations:
- expression: >-
object.spec.template.spec.containers.all(c,
c.image.contains(':') && !c.image.endsWith(':latest'))
message: "images must have an explicit tag other than latest"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: no-latest-tag
spec:
policyName: no-latest-tag
validationActions: ["Warn"]
matchResources:
namespaceSelector:
matchLabels:
policy: enforced
YAML
kubectl apply -f vap-latest.yaml
kubectl create ns policy-demo
kubectl label ns policy-demo policy=enforced
# 2 - Warn mode
kubectl create deploy a -n policy-demo --image nginx
kubectl create deploy b -n policy-demo --image nginx:1.27
a is created with a warning; b without. Warn first - see who would be
hit.
# 3 - Deny mode
kubectl patch validatingadmissionpolicybinding no-latest-tag --type=merge \
-p '{"spec":{"validationActions":["Deny"]}}'
kubectl create deploy c -n policy-demo --image nginx:latest # denied
kubectl create deploy c -n default --image nginx:latest # allowed - no label on default
kubectl delete deploy c -n default
The binding decides where (namespace selector) and how strictly.
Rule 2: every Deployment needs a team label
# 4 - write it yourself: copy vap-latest.yaml to vap-team.yaml and change
# name, message and the expression
# 5 - test
kubectl apply -f vap-team.yaml
kubectl create deploy d -n policy-demo --image nginx:1.27 # denied
kubectl create deploy d -n policy-demo --image nginx:1.27 --dry-run=client -o yaml \
| kubectl label -f - --local team=shop -o yaml | kubectl apply -f - # allowed
Discovery
InfodiscoverTask A. Allow images only from registry.k8s.io and docker.io/library
(written as plain nginx:...). Tip: c.image.startsWith(...), ||.
Task B (optional). Install Kyverno and see the same rule as a report on existing objects.
Clean up
kubectl delete ns policy-demo
kubectl delete -f vap-latest.yaml -f vap-team.yaml --ignore-not-found
helm uninstall kyverno -n kyverno 2>/dev/null; kubectl delete ns kyverno --ignore-not-found