This lab is crafted to inspire the integration of validating admission policies in your environments, promoting the adoption of best practices. Embrace these strategies to fortify the security and reliability of your systems, and stay vigilant for upcoming vulnerabilities and misconfigurations with the assistance of Zora & Marvin! Happy Kuberneting!
Step by step (oh baby!)
For this lab we'll use an GKE alpha cluster 1.27.7 .
gcloud container clusters create kubilab --zone us-central1-a --num-nodes=3 --cluster-version "1.27.7-gke.1121000" --release-channel "regular" --machine-type n2-standard-2 --enable-kubernetes-alpha --no-enable-autoupgrade --no-enable-autorepair
This can be done with KinD too, Matheus Faria wrote an awesome post about it here.
#Google - Demo Store
git clone https://github.com/GoogleCloudPlatform/microservices-demo
cd microservices-demo/
kubectl apply -f ./release/kubernetes-manifests.yaml
#Buoyant - Emojivoto
kubectl apply -k github.com/BuoyantIO/emojivoto/kustomize/deployment
#PodInfo
helm repo add podinfo https://stefanprodan.github.io/podinfo
kubectl create ns test
helm upgrade --install --wait frontend --namespace test --set replicaCount=2 --set backend=https://backend-podinfo:9898/echo podinfo/podinfo
helm test frontend --namespace test
helm upgrade --install --wait backend --namespace test --set redis.enabled=true podinfo/podinfo
3. Deploy Zora with Marvin to have visibility of your cluster
helm repo add undistro https://charts.undistro.io --force-update
helm repo update undistro
helm upgrade --install zora undistro/zora \
-n zora-system \
--create-namespace \
--wait \
--set clusterName=kubilab \
--set saas.workspaceID='WoRkSpAcE_ID'
#What is Validating Admission Policy? >>> https://kubernetes.io/docs/reference/access-authn-authz/validating-admission-policy/#getting-started-with-validating-admission-policy
#Example 01 - Maximum replicas
- Create Namespace (
kubectl apply -f namespace_replicas.yml
) - Create Policy (
kubectl apply -f policy_replicas.yml
) - Binding Policy (
kubectl apply -f policy_replicas_binding.yml
) - Test Deployment (
kubectl apply -f nginx_deploy_replicas.yml
)
Comments: This is the documentation example, and the deploy will fail because it's configured to have 6 replicas. Update line 9 in the nginx_deploy_replicas.yml
and apply it again to see it working.
#Example 02 - Prevent containers with images outside defined registry
- Create Namespace (
kubectl apply -f namespace_registry.yml
) - Create Policy (
kubectl apply -f policy_registry.yml
) - Binding Policy (
kubectl apply -f policy_registry_binding.yml
) - Test Deployment (
kubectl apply -f nginx_deploy_registry.yml
)
Comments: The registry is defined in the line 14 of the policy_registry.yml
, here we are using the aws ecr to get the nginx image, if you want to see it failing just update the line 18 in the nginx_deploy_registry.yml
to another registry, or none to use dockerhub.
#Example 03 - Warning containers with latest
image tag
- Create Namespace (
kubectl apply -f namespace_latest.yml
) - Create Policy (
kubectl apply -f policy_latest.yml
) - Binding Policy (
kubectl apply -f policy_latest_binding.yml
) - Test Deployment (
kubectl apply -f nginx_deploy_latest.yml
)
Comments: This example allows the deployment to proceed, but issues a warning message to inform the user that this practice will be prevented in the near future. Engage in discussions with your team, evangelize them, and highlight the benefits of adhering to best practices :D.
#Example 04 - Prevent containers with privileged security context
- Create Namespace (
kubectl apply -f namespace_root.yml
) - Create Policy (
kubectl apply -f policy_root.yml
) - Binding Policy (
kubectl apply -f policy_root_binding.yml
) - Test Deployment (
kubectl apply -f nginx_deploy_root.yml
)
Comments: In the line 18 of the policy_root.yml
file, we check for the privileged
attribute in the securityContext to be set to false. This is considered a secure configuration. If it's set to true
, the operation will fail.
#Example 05 - Prevent deployments without required labels
- Create Namespace (
kubectl apply -f namespace_labels.yml
) - Create Policy (
kubectl apply -f policy_labels.yml
) - Binding Policy (
kubectl apply -f policy_labels_binding.yml
) - Create ConfigMap (
kubectl apply -f configmap_labels.yml
) - Test Deployment (
kubectl apply -f nginx_deploy_labels.yml
)
Comments: This policy utilizes a configMap with a list of required labels. The initial deployment will fail; therefore, uncomment lines 6-8 in the nginx_deploy_labels.yml
file and reapply it for a successful deployment.
#Example 06 - Prevent deployments without probes defined
- Create Namespace (
kubectl apply -f namespace_probes.yml
) - Create Policy (
kubectl apply -f policy_probes.yml
) - Binding Policy (
kubectl apply -f policy_probes_binding.yml
) - Test Deployment (
kubectl apply -f nginx_deploy_probes.yml
)
Comments: Probes are a best practice to inform Kubernetes about when your app is ready to receive connections or needs to be restarted. While it's not a required field in deployment, creating this VAP allows you to enforce liveness, readiness, and startup probes. Uncomment lines 28-51 in the nginx_deploy_probes.yml
to successfully deploy it.
#Example 07 - Prevent deployments without resources defined
- Create Namespace (
kubectl apply -f namespace_resources.yml
) - Create Policy (
kubectl apply -f policy_resources.yml
) - Binding Policy (
kubectl apply -f policy_resources_binding.yml
) - Test Deployment (
kubectl apply -f nginx_deploy_resources.yml
)
Comments: It's considered a best practice to define resources in your deployment, as described here. There's an ongoing discussion about whether to set CPU limits or not, so choose wisely :D (article 1 & article 2). Uncomment lines 21-27 in the file nginx_deploy_resources.yml
to make it work.
This was presented during a workshop in Portuguese (Brazil) and is available online on YouTube.
Other useful links can be found here.