Trying ValidationAdmissionPolicy aka CEL Admission in K8s 1.26
Wed 14 December 2022CEL for admission control is a new 1.26 feature. With the feature, define ValidationAdmissionPolicy to express your desired policy and ValidationAdmissionPolicyBinding to assign the policy to e.g. a namespace.
This post has the following sections:
- Creating a 1.26 cluster with ValidationAdmissionPolicy / CEL Admission enabled
- Configure the policies
- Verifying the policy is working as expected
Creating a 1.26 cluster
We will be using kind to create a cluster with ValidatingAdmissionPolicy
feature
gate enabled and runtimeConfig set to admissionregistration.k8s.io/v1alpha1
.
Create a kind configuration file named cluster.yaml
with the following content:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
"ValidatingAdmissionPolicy": true
runtimeConfig:
"admissionregistration.k8s.io/v1alpha1": true
nodes:
- role: control-plane
image: kindest/node:v1.26.0@sha256:691e24bd2417609db7e589e1a479b902d2e209892a10ce375fab60a8407c7352
Create the kind cluster by running:
kind create cluster --config cluster.yaml
Verify the cluster is up and running:
kubectl get nodes
Configure the policies
For this example, we want a simple policy that prevents creating
a deployment that has the name samos
.
Create a file named cel-policy.yaml
with the following content:
apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicy
metadata:
name: "example-policy"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["deployments"]
validations:
- expression: "object.metadata.name != 'samos'"
Create the policy by running:
kubectl apply -f cel-policy.yaml
Create a file named cel-policy-binding.yaml
with the following content:
apiVersion: admissionregistration.k8s.io/v1alpha1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "example-policy-test"
spec:
policyName: "example-policy"
matchResources:
namespaceSelector:
matchLabels:
test: sam
The binding tells K8s to apply the ValidationAdmissionPolicy named example-policy
to any namespace that has the label test=sam
.
Let's add the label test=sam
to the default namespace by running:
kubectl label namespaces default test=sam
The policy should now be effective on the default namespace.
Verify everything works
Create a file named deployment.yaml
with the following content:
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: default
name: samos
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Try and create the deployment by running:
kubectl apply -f deployment.yaml
You should see an error like this:
The deployments "samos" is invalid: : ValidatingAdmissionPolicy 'example-policy' with binding 'example-policy-test' denied request: failed expression: object.metadata.name != 'samos'