/talk-kcd-italy-2021-opa-gatekeeper

Repository for the talk "Tu non puoi passare! Policy compliance con OPA Gatekeeper" presented at KCD Italy 2021

Primary LanguageMakefileGNU General Public License v3.0GPL-3.0

KCD Italy Banner

KCD Italy 2021 Demo ๐Ÿ• โ˜ธ๏ธ๐Ÿ‡ฎ๐Ÿ‡น

Repository for the talk "Tu non puoi passare! Policy compliance con OPA Gatekeeper" presented at KCD Italy 2021 ๐Ÿ‡ฎ๐Ÿ‡น.

Slides are available under ./slides/

โ˜ธ๏ธ Setup Minikube Cluster

  1. Create minikube cluster
make minikube

๐Ÿ”จ Deploy OPA Gatekeeper and Gatekeeper Policy Manager

  1. Deploy OPA Gatekeeper 3.5:
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/release-3.5/deploy/gatekeeper.yaml
# Local version available at ./manifests/gatekeeper.yaml
  1. Deploy Gatekeeper Policy Manager v0.5.0:
kubectl apply -k https://github.com/sighupio/gatekeeper-policy-manager/
# Local version available at ./manifests/gatekeeper-policy-manager.yaml
  1. Port forward Gatekeeper Policy Manager UI on localhost:8080:
kubectl port-forward svc/gatekeeper-policy-manager -n gatekeeper-system 8080:80 2>&1 >/dev/null &

๐Ÿš” Deploy OPA Policies

โ›” Policy #1 - Mandatory label in namespaces

  1. Create our first ContraintTemplate:
kubectl apply -f manifests/rules/0-ns-require-labels/template.yaml

A ConstraintTemplate describes both the Rego that enforces the constraint and the schema of the constraint.

  1. Check the creation of the related resources:
kubectl get constrainttemplates.templates.gatekeeper.sh

Expected Output:

NAME                     AGE
namespacerequirelabels   6m48s
  1. Check the new CRD that gets created:
kubectl get crd | grep constraints

Expected Output:

namespacerequirelabels.constraints.gatekeeper.sh     2021-11-15T13:52:53Z
  1. Instantiate the template with a Constraint:
kubectl apply -f manifests/rules/0-ns-require-labels/require-kcd-italy-label/constraint.yaml

Constraints are used to actually enforce a ConstraintTemplate

  1. Inspect new resources:
kubectl get constraints

Expected output:

NAME                           AGE
ns-must-have-kcd-italy-label   9s
  1. Test creation of a namespace bad without the kcd-italy label:
kubectl create ns bad
# kubectl apply -f manifests/rules/0-ns-require-labels/require-kcd-italy-label/example_disallowed.yaml                                  

Expected output:

Error from server ([ns-must-have-kcd-italy-label] you must provide labels: {"kcd-italy"}): admission webhook "validation.gatekeeper.sh" denied the request: [ns-must-have-kcd-italy-label] you must provide labels: {"kcd-italy"}
  1. Test creation of a namespace good with the kcd-italy label:
kubectl apply -f manifests/rules/0-ns-require-labels/require-kcd-italy-label/example_allowed.yaml

Expected output:

namespace/good created

โ›” Policy #2 - Pod from trusted registries

  1. Create the ContraintTemplate and the Constraint:
kubectl apply -f manifests/rules/1-pod-from-trusted-registry/template.yaml
kubectl apply -f manifests/rules/1-pod-from-trusted-registry/trust-sighup-registry/constraint.yaml
  1. Check the creation of the related resources:
kubectl get constrainttemplates.templates.gatekeeper.sh,constraints

Expected Output:

NAME                                                              AGE
constrainttemplate.templates.gatekeeper.sh/trustedimageregistry   18s
# ... hiding other constrainttemplates for brevity

NAME                                                                           AGE
trustedimageregistry.constraints.gatekeeper.sh/all-pods-from-sighup-registry   9s

# ... hiding other constraints for brevity
  1. Test that the Constraint allows a registry.sighup.io/workshop/nginx image:
kubectl apply -f manifests/rules/1-pod-from-trusted-registry/trust-sighup-registry/example_allowed.yaml

Expected Output:

pod/good-pod created
  1. Test that the Constraint does not allow a nginx image:
kubectl apply -f manifests/rules/1-pod-from-trusted-registry/trust-sighup-registry/example_disallowed.yaml

Expected Output:

Error from server ([all-pods-from-sighup-registry] image 'nginx' comes from untrusted registry): error when creating "manifests/rules/1-pod-from-trusted-registry/trust-sighup-registry/example_disallowed.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [all-pods-from-sighup-registry] image 'nginx' comes from untrusted registry
  1. Try to create a deployment with an untrusted registry. What happens?
kubectl create deployment nginx-deploy --image nginx --replicas 10

Expected Output:

deployment.apps/nginx-deploy created

Are the pods running?

kubectl get deployments.apps nginx-deploy  

Expected Output:

NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   0/10    0            0           6s

Try to inspect the related ReplicaSet:

kubectl describe rs $(kubectl get rs -o jsonpath='{.items[*].metadata.name}' | grep nginx-deploy)

โ›” Policy #3 - Unique ingress names

  1. Create the ContraintTemplate and the Constraint:
kubectl apply -f manifests/rules/2-unique-ingress-host/template.yaml
kubectl apply -f manifests/rules/2-unique-ingress-host/unique-ingress/constraint.yaml
  1. Check the creation of the related resources:
kubectl get constrainttemplates.templates.gatekeeper.sh,constraints

Expected Output:

NAME                                                              AGE
constrainttemplate.templates.gatekeeper.sh/k8suniqueingresshost   6m3s
# ... hiding other constrainttemplates for brevity

NAME                                                                 AGE
k8suniqueingresshost.constraints.gatekeeper.sh/unique-ingress-host   5m13s

# ... hiding other constraints for brevity
  1. Test the Constraint:
kubectl apply -f manifests/rules/2-unique-ingress-host/unique-ingress/example_disallowed.yaml

Expected Output:

ingress.networking.k8s.io/ingress-host-1 created
ingress.networking.k8s.io/ingress-host-2 created

The Constraint is correct, but it's not working as we have not replicated any data to Gatekeeper.

  1. Deploy necessary config:
kubectl apply -f manifests/rules/2-unique-ingress-host/config.yaml
  1. Test the Constraint again:
kubectl delete -f manifests/rules/2-unique-ingress-host/unique-ingress/example_disallowed.yaml
kubectl apply -f manifests/rules/2-unique-ingress-host/unique-ingress/example_disallowed.yaml 

Expected Output:

ingress.networking.k8s.io/ingress-host-1 created

Error from server ([unique-ingress-host] Ingress host conflicts with an existing Ingress <example-host.example.com>
[unique-ingress-host] Ingress host conflicts with an existing Ingress <example-host.example.com>): error when creating "manifests/rules/2-unique-ingress-host/unique-ingress/example_disallowed.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [unique-ingress-host] Ingress host conflicts with an existing Ingress <example-host.example.com>
[unique-ingress-host] Ingress host conflicts with an existing Ingress <example-host.example.com>

๐Ÿงน Cleanup

  1. Delete minikube cluster:
make delete

๐Ÿ“– Additional Resources