open-policy-agent / gatekeeper

🐊 Gatekeeper - Policy Controller for Kubernetes
https://open-policy-agent.github.io/gatekeeper/
Apache License 2.0
3.72k stars 764 forks source link

Option to apply mutations (Assign and AssignMetadata) only on create #3571

Open sathieu opened 1 month ago

sathieu commented 1 month ago

Describe the solution you'd like

We have a few mutations changing immutable fields, this is particularly the case for Pods.

For example: mutation-mustRunAsNonRoot.yaml

This is preventing Pod deletions if the Pod was created before the admission.

Suggestion:

Add a spec.operations (defaulting to ['*']) to Assign and AssignMetadata. Example:

apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
  name: k8spsprunasnonroot
spec:
  applyTo:
  - groups: [""]
    kinds: ["Pod"]
    versions: ["v1"]
  match:
    excludedNamespaces:
    - kube-system
  location: "spec.containers[name:*].securityContext.runAsNonRoot"
  parameters:
    pathTests:
      - subPath: "spec.containers[name:*].securityContext.runAsNonRoot"
        condition: MustNotExist
    assign:
      value: true
  operations:
  - CREATE

Anything else you would like to add:

We workaround this with label selector, and we apply the labels to any pod stuck in Terminating state.

See: https://gitlab.com/kubitus-project/kubitus-installer/-/blob/d7aeb334a6d6404f5a006b09ac928f21123a896d/roles/gatekeeper/files/helm/templates/library/mutation/pod-security-policy/users-mustRunAsNonRoot.yaml.yaml#L29-34

Environment:

JaydipGabani commented 1 month ago

@sathieu can you provide exact steps to replicate your issue? I tested the assign mutator you provided with deleting a pod that existed before the mutator was applied and I didn't face the same issue.

sathieu commented 1 month ago

@JaydipGabani This is reproduced with foreground deletion (and for other method using finalizers, like pods with PVCs).

How to test (with kind):

Setup:

$ kind create cluster -n gk-3571
$ helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
$ helm repo update
$ helm install -n gatekeeper-system gatekeeper gatekeeper/gatekeeper --create-namespace

Test:

$ # create a pod
$ kubectl run --image nginx my-pod
$ # apply mutation above
$ kubectl apply -f mutation.yaml
$ # delete pod
$ kubectl delete po my-pod  --cascade=foreground
pod "my-pod" deleted
# [blocked]

Deleting the mutation will unblock the deletion (with a delay)