This is the second post of the series about Kubernetes policy management tools
Other parts:
I - Introduction
III - Kyverno
IV - jsPolicy
Gatekeeper is a customizable admission webhook for Kubernetes that dynamically enforces policies executed by the OPA. Gatekeeper uses CustomResourceDefinitions internally and allows us to define ConstraintTemplates and Constraints to enforce policies on Kubernetes resources such as Pods, Deployments, Jobs.
OPA/Gatekeeper uses its own declarative language called Rego, a query language. You define rules in Rego which, if invalid or returned a false expression, will trigger a constraint violation and blocks the ongoing process of creating/updating/deleting the resource.
Installation
❯ helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
❯ helm upgrade --install gatekeeper-app gatekeeper/gatekeeper --namespace gatekeeper-system --create-namespace
❯ kubectl get all -n gatekeeper-system
NAME NAMESPACE AGE
configmap/kube-root-ca.crt gatekeeper-system 7d10h
endpoints/gatekeeper-webhook-service gatekeeper-system 7d10h
...
role.rbac.authorization.k8s.io/gatekeeper-manager-role gatekeeper-system 7d10h
Creating and instantiating policies
The templates themselves involve creating rego based rules and are complex; look at the More info section for predefined libraries containing templates and constraints
Create gatekeeper templates
# Create or copy (and customize) the templates
# In my case all templates are under templates/ directory
# Note: Template names themself follow a Capital-case and need to start with k8s (not sure why for the second part)
❯ kubectl create -f templates/
constrainttemplate.templates.gatekeeper.sh/k8sallowedrepos created
constrainttemplate.templates.gatekeeper.sh/k8scontainerlimits created
...
❯ kubectl get constrainttemplates.templates.gatekeeper.sh | grep -c k8s
9
Create the constraints based on the above defined templates
# In my case constraints are in constraints directory
❯ kubectl apply -f constraints/
❯ kubectl get constraints | grep -c k8s
7
Configuration
The key section to configure is in the <constraint>.yaml
spec:
enforcementAction: dryrun # or warn or deny (default)
match:
namespaces: ["dev-*", "stage-*", "prod-*"] # to include
excludedNamespaces: [kube-*]
kinds:
- apiGroups: [""]
kinds: ["Namespace"] # or pod
parameters:
labels: ["label-a", "label-b"] # or could be other parameters
minLimit: 3
maxLimit: 10
...
Testing
# For a policy that restricts replica counts to be between 3 to 50
# ref: https://github.com/open-policy-agent/gatekeeper-library/tree/master/library/general/replicalimits
❯ kubectl create deployment opa-test-dep --image=alpine --namespace=test-ns --replicas=1
error: failed to create deployment: admission webhook "validation.gatekeeper.sh" denied the request: [replica-limits] The provided number of replicas is not allowed for deployment: opa-test-dep. Allowed ranges: {"ranges": [{"max_replicas": 50, "min_replicas": 3}]}
❯ echo $?
1
Related tools
conftest for CI
Conftest helps you write tests against structured configuration data. Using Conftest you can write tests for your Kubernetes configuration, Tekton pipeline definitions, Terraform code, Serverless configs or any other config files.
Getting started is easy
❯ brew install conftest
Assuming we have yaml configurations in a given directory along with the policies to check for in a folder called policy/
underneath
❯ tree .
.
├── pod.yaml
└── policy
└── labels.rego
❯ conftest test .
FAIL - deployment.yaml - main - Must include Kubernetes recommended labels: https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/#labels
FAIL - deployment.yaml - main - image 'nginx:1.14.2' comes from untrusted registry
2 tests, 0 passed, 0 warnings, 2 failures, 0 exceptions
❯ echo $?
1
UI based tool
https://github.com/sighupio/gatekeeper-policy-manager
OPA violations in grafana dashboard
https://github.com/developer-guy/monitor-opa-gatekeeper
More info
OPA-Gatekeeper is very powerful, but hard to understand; hey it is in CKS syllabus - CNCF recommended!
Top comments (0)