The work here is heavily based on the resources exposed by Karen Bruner in these blog posts:
- Better Kubernetes Security with Open Policy Agent (OPA) - Part 1
- Better Kubernetes Security with Open Policy Agent (OPA) - Part 2
This work tries to answer the questions exposed in this card.
- OpenShift Cluster (We tested with 4.9.12)
- OpenPolicyAgent Gatekeeper deployed on the cluster (We tested with CSV gatekeeper-operator-product.v0.2.1)
Inside the assets/no-master-toleration/ folder we have the rego
policy and the tests files. You can run the tests as follows:
NOTE: You can download the opa cli from https://github.com/open-policy-agent/opa/releases.
opa test --explain fails src.rego src_test.rego
data.restrictedtainttoleration.test_input_no_global_violation: PASS (544.483µs)
data.restrictedtainttoleration.test_input_ok_global_allow: PASS (363.567µs)
data.restrictedtainttoleration.test_input_no_global_equal_match_violation: PASS (401.24µs)
data.restrictedtainttoleration.test_input_ok_global_equal_match_allow: PASS (357.066µs)
data.restrictedtainttoleration.test_input_equal_match_violation: PASS (625.204µs)
data.restrictedtainttoleration.test_input_equal_no_effect_match_violation: PASS (565.071µs)
data.restrictedtainttoleration.test_input_equal_no_operator_match_violation: PASS (576.912µs)
data.restrictedtainttoleration.test_input_equal_no_effect_no_operator_match_violation: PASS (594.109µs)
data.restrictedtainttoleration.test_input_equal_different_value_match_allow: PASS (1.448449ms)
data.restrictedtainttoleration.test_input_no_toleration_field_allow: PASS (396.695µs)
--------------------------------------------------------------------------------
PASS: 10/10
There is a gatekeeper policies library where there are existing policies written by the community, you can also use the rego playground to tests your policies, links below:
Inside the assets/no-master-toleration/k8s/ folder we have the ConstraintTemplate
file and the Constraint
file.
-
First, we need to load the
ConstraintTemplate
:oc create -f assets/no-master-toleration/k8s/constraint_template.yaml
-
Second, we can create a
Constraint
out of theConstraintTemplate
we just created:oc create -f assets/no-master-toleration/k8s/constraint.yaml
-
If we look inside the
Constraint
file we will see a list of namespaces where these constraints will not be enforced, as of the time of this writing (01/25/2022) theexcludedNamespaces
clause does not support prefix matching, you can see the enhancement request here.
At this point we already have the Constraint
loaded, so we can use the pod files in the assets/no-master-toleration/k8s/ to see if the policy is working as expected.
-
The first pod defines a toleration for the master node taints:
tolerations: - key: "node-role.kubernetes.io/master" effect: "NoSchedule"
-
The second pod defines a toleration for all taints in the node (where master taint may very well be one of them):
NOTE: In our
Constraint
we can define if we allow (or not) this kind of toleration by setting theConstraint
parameterallowGlobalToleration
to eithertrue
(allow) orfalse
(not allow).tolerations: - operator: "Exists"
-
If we try to create the first pod in our test namespace this is what we get:
oc create -f assets/no-master-toleration/k8s/test-pod-master-toleration.yaml Error from server ([master-node-or-global-toleration] Toleration is not allowed for taint {"effect": "NoSchedule", "key": "node-role.kubernetes.io/master", "value": ""}): error when creating "test-pod-master-toleration.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [master-node-or-global-toleration] Toleration is not allowed for taint {"effect": "NoSchedule", "key": "node-role.kubernetes.io/master", "value": ""}
-
If we try to create the second pod this is what we get:
NOTE: We have the
allowGlobalToleration
parameter set tofalse
.oc create -f assets/no-master-toleration/k8s/test-pod-all-tolerations.yaml Error from server ([master-node-or-global-toleration] Global tolerations not allowed for taint {"effect": "NoSchedule", "key": "node-role.kubernetes.io/master", "value": ""}): error when creating "test-pod-all-tolerations.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [master-node-or-global-toleration] Global tolerations not allowed for taint {"effect": "NoSchedule", "key": "node-role.kubernetes.io/master", "value": ""}
-
If we try to create these pods in a namespace where we are not enforcing this policy (like
kube-system
), the pods will be created without issues:oc -n kube-system create -f assets/no-master-toleration/k8s/test-pod-master-toleration.yaml -f assets/no-master-toleration/k8s/test-pod-all-tolerations.yaml pod/test-pod-master-toleration created pod/test-pod-all-tolerations created
Explore if the policy can be updated, so users from a given group can define master taints toleration in any namespace.