Kubernetes policy management: II - OPA-Gatekeeper
Tags: kubernetes, policy, opa, series
Published: 2022-03-06 12:49:21

This is the second post of the series about Kubernetes policy management tools

Other parts:
[I - Introduction](https://dev.to/ashokan/kubernetes-policy-management-through-admission-web-hooks-i-11i2)
[III - Kyverno](https://dev.to/ashokan/kubernetes-policy-management-iii-kyverno-2gjj)
[IV - jsPolicy](https://dev.to/ashokan/kubernetes-policy-management-iv-jspolicy-2o84)

---
  **G**atekeeper 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.

**Architecture**
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5oop3n46csk0xxmgg8h0.png)

**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
```
- [conftest documentation](https://github.com/open-policy-agent/conftest)
- [A good tutorial](https://www.visualstudiogeeks.com/azure/kubernetes/devops/policy-enforcement-for-k8s)

##### 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**
- [Documentation](https://open-policy-agent.github.io/gatekeeper/website/docs/)
- [Policy examples #1](https://github.com/open-policy-agent/gatekeeper/tree/master/demo)
- [Policy examples #2](https://github.com/open-policy-agent/gatekeeper-library/tree/master/library)

---
OPA-Gatekeeper is very powerful, but hard to understand; hey it is in CKS syllabus - CNCF recommended!