Day 29: Strengthening Kubernetes Security with Open Policy Agent (OPA) and Gatekeeper

π Software Engineer by day, SRE magician by night! β¨ Tech enthusiast with an insatiable curiosity for data. π Harvard CS50 Undergrad igniting my passion for code. Currently delving into the MERN stack β because who doesn't love crafting seamless experiences from front to back? Join me on this exhilarating journey of embracing technology, penning insightful tech chronicles, and unraveling the mysteries of data! ππ§ Let's build, let's write, let's explore β all aboard the tech express! ππ #CodeAndCuriosity
Welcome back to Day 29 of my 90-day DevOps journey! Today, we're diving into Kubernetes security by exploring how to use Open Policy Agent (OPA) and Gatekeeper to enforce policies within your cluster.
This guide is designed for beginners and will walk you through setting up OPA with Gatekeeper, creating custom policies, and handling common issues you might encounter along the way.
Table of Contents
Introduction to OPA and Gatekeeper
Open Policy Agent (OPA) is like a rulebook for your software. It lets you define rules (policies) that can be applied to different parts of your system. In Kubernetes, OPA helps you enforce rules on resources before they're created or changed.
Gatekeeper is a special tool that works with OPA and Kubernetes. It allows you to create and apply policies using Kubernetes' own language (Custom Resource Definitions or CRDs).
By combining OPA and Gatekeeper, you can make sure everything in your Kubernetes cluster follows your security and compliance rules.
Project Prerequisites
A running Kubernetes cluster: You can use Minikube, Docker Desktop, or any managed Kubernetes service.
kubectlinstalled and configured: This is the command-line tool to interact with your Kubernetes cluster.Basic understanding of Kubernetes resources: You should know about pods, deployments, services, etc.
Folder Structure
Let's organize our project files for better readability:
90days-devops/
βββ day29/
βββ manifests/
β βββ gatekeeper.yaml
βββ policies/
β βββ deny-privileged-pods.yaml
β βββ require-labels.yaml
β βββ sample-app.yaml
βββ README.md
manifests/: Contains YAML files for deploying Gatekeeper.
policies/: Holds custom policy definitions and sample applications to test the policies.
README.md: Documentation and steps followed during the project.
Step-by-Step Guide
Step 1: Setting Up the Kubernetes Cluster
If you haven't set up a Kubernetes cluster yet, you can use Minikube:
minikube start
kubectl config use-context minikube
Verify the cluster is running:
kubectl get nodes
Step 2: Installing Gatekeeper
Apply the Gatekeeper manifest to install it on your cluster:
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml --validate=false
Note: You might encounter an error related to OpenAPI validation. Adding --validate=false bypasses this issue.
Step 3: Verifying the Installation
Check if the Gatekeeper pods are running:
kubectl get pods -n gatekeeper-system
You should see something like:
NAME READY STATUS RESTARTS AGE
gatekeeper-controller-manager-xxxxxxxxxx-xxxxx 1/1 Running 0 xxm
Step 4: Creating Custom Policies
Policy 1: Deny Privileged Pods
Create a policy to prevent the deployment of privileged pods.
File: policies/deny-privileged-pods.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDenyPrivilegedContainer
metadata:
name: deny-privileged-pods
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
Apply the constraint template and the constraint:
kubectl apply -f policies/deny-privileged-pods.yaml
Policy 2: Require Labels on Resources
Create a policy that enforces the presence of specific labels on all resources.
File: policies/require-labels.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: require-app-label
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod", "Deployment", "Service"]
parameters:
labels: ["app"]
Apply the policy:
kubectl apply -f policies/require-labels.yaml
Step 5: Testing the Policies
Testing Deny Privileged Pods Policy
Try deploying a privileged pod.
File: policies/sample-app.yaml
apiVersion: v1
kind: Pod
metadata:
name: privileged-pod
spec:
containers:
- name: nginx
image: nginx
securityContext:
privileged: true
Apply the sample app:
kubectl apply -f policies/sample-app.yaml
Expected Outcome:
Error from server ([denied by deny-privileged-pods] Privileged containers are not allowed): error when creating "policies/sample-app.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by deny-privileged-pods] Privileged containers are not allowed
Testing Require Labels Policy
Important: The require-labels.yaml policy is set up to target Pods, Deployments, and Services. Make sure to test the policy with each of these resource types.
1. Testing with a Pod:
File:
policies/sample-app.yaml(already defined as a Pod)Remove the
applabel:apiVersion: v1 kind: Pod metadata: name: sample-app spec: containers: - name: nginx image: nginxApply the Pod:
kubectl apply -f policies/sample-app.yamlExpected Outcome:
Error from server ([denied by require-app-label] Missing required labels: app): error when creating "policies/sample-app.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by require-app-label] Missing required labels: app
2. Testing with a Deployment:
File:
policies/sample-app.yamlChange the
kindtoDeployment:apiVersion: apps/v1 kind: Deployment metadata: name: sample-app spec: replicas: 1 selector: matchLabels: app: sample-app template: metadata: labels: app: sample-app spec: containers: - name: nginx image: nginxRemove the
applabel from thetemplate.metadata.labelssection:apiVersion: apps/v1 kind: Deployment metadata: name: sample-app spec: replicas: 1 selector: matchLabels: app: sample-app template: metadata: # labels: # Remove this line and its content # app: sample-app spec: containers: - name: nginx image: nginxApply the Deployment:
kubectl apply -f policies/sample-app.yamlExpected Outcome:
Error from server ([denied by require-app-label] Missing required labels: app): error when creating "policies/sample-app.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by require-app-label] Missing required labels: app
3. Testing with a Service:
Create a new file:
policies/sample-service.yamlDefine the Service:
apiVersion: v1 kind: Service metadata: name: sample-service spec: selector: app: sample-app ports: - protocol: TCP port: 80 targetPort: 80Remove the
applabel from theselectorsection:apiVersion: v1 kind: Service metadata: name: sample-service spec: # selector: # app: sample-app ports: - protocol: TCP port: 80 targetPort: 80Apply the Service:
kubectl apply -f policies/sample-service.yamlExpected Outcome:
Error from server ([denied by require-app-label] Missing required labels: app): error when creating "policies/sample-service.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by require-app-label] Missing required labels: app
Common Issues and Troubleshooting
Error: OpenAPI Validation Failed
Problem:
error validating "https://.../gatekeeper.yaml": error validating data: failed to download openapi...
Solution:
Add the --validate=false flag when applying the manifest:
kubectl apply -f https://.../gatekeeper.yaml --validate=false
Gatekeeper Pods Not Running
Problem:
Gatekeeper pods are not in the Running state.
Solution:
Check the pod logs for errors:
kubectl logs -n gatekeeper-system <pod-name>
Ensure your Kubernetes cluster meets the minimum requirements.
Policies Not Enforced
Problem:
Resources violating policies are still being created.
Solution:
Ensure that the constraint templates and constraints are properly applied.
Verify that the
matchsection in your constraint YAML files correctly targets the resources.
Conclusion
By integrating OPA and Gatekeeper into your Kubernetes cluster, you've taken a significant step toward enhancing your deployment's security and compliance. Policies help prevent misconfigurations and enforce best practices automatically, reducing the risk of human error.
Feel free to leave comments or questions below. Happy DevOps-ing , See you on day 30 !




