Kubernetes policy management: III - Kyverno
Tags: kubernetes, policy, kyverno, series
Published: 2022-03-06 12:47:32

This is the third post of the series.

Other parts:
[I - Introduction](https://dev.to/ashokan/kubernetes-policy-management-through-admission-web-hooks-i-11i2)
[II - OPA Gatekeeper](https://dev.to/ashokan/kubernetes-policy-management-ii-opa-gatekeeper-465g)
[IV - jsPolicy](https://dev.to/ashokan/kubernetes-policy-management-iv-jspolicy-2o84)

---

##### Installation

```
❯ helm repo add kyverno https://kyverno.github.io/kyverno/
❯ helm install kyverno kyverno/kyverno --namespace kyverno --create-namespace
...
REVISION: 1
NOTES:
Thank you for installing kyverno v2.2.0 😀

Your release is named kyverno, app version v1.6.0
# Install the krew plugin
❯ kubectl krew install view-webhook
# Check the webhook details
❯ kubectl view-webhook

+------------+-----------------------------------------+------------------------------+-------------------------------------+----------------------+---------------+------------------------+
|    KIND    |                  NAME                   |           WEBHOOK            |               SERVICE               | RESOURCES&OPERATIONS | REMAINING DAY |       ACTIVE NS        |
+------------+-----------------------------------------+------------------------------+-------------------------------------+----------------------+---------------+------------------------+
| Mutating   | kyverno-policy-mutating-webhook-cfg     | mutate-policy.kyverno.svc    | └─┬kyverno-svc                      | ├──clusterpolicies/* | 52 weeks      | ✖ No Active Namespaces |
|            |                                         |                              |   ├──NS  : kyverno                  | └─┬policies/*        |               |                        |
|            |                                         |                              |   ├──Path: /policymutate            |   ├──+CREATE         |               |                        |
|            |                                         |                              |   └─┬IP  : 10.96.195.22 (ClusterIP) |   └──^UPDATE         |               |                        |
|            |                                         |                              |     └──443/TCP                      |                      |               |                        |
+            +-----------------------------------------+------------------------------+-------------------------------------+----------------------+               +                        +
|            | kyverno-resource-mutating-webhook-cfg   | mutate.kyverno.svc-ignore    | └─┬kyverno-svc                      |                      |               |                        |
|            |                                         |                              |   ├──NS  : kyverno                  |                      |               |                        |
|            |                                         |                              |   ├──Path: /mutate                  |                      |               |                        |
|            |                                         |                              |   └─┬IP  : 10.96.195.22 (ClusterIP) |                      |               |                        |
|            |                                         |                              |     └──443/TCP                      |                      |               |                        |
+            +                                         +------------------------------+                                     +----------------------+               +                        +
|            |                                         | mutate.kyverno.svc-fail      |                                     |                      |               |                        |
|            |                                         |                              |                                     |                      |               |                        |
|            |                                         |                              |                                     |                      |               |                        |
|            |                                         |                              |                                     |                      |               |                        |
|            |                                         |                              |                                     |                      |               |                        |
+            +-----------------------------------------+------------------------------+-------------------------------------+----------------------+               +                        +
|            | kyverno-verify-mutating-webhook-cfg     | monitor-webhooks.kyverno.svc | └─┬kyverno-svc                      | └─┬deployments/*     |               |                        |
|            |                                         |                              |   ├──NS  : kyverno                  |   └──^UPDATE         |               |                        |
|            |                                         |                              |   ├──Path: /verifymutate            |                      |               |                        |
|            |                                         |                              |   └─┬IP  : 10.96.195.22 (ClusterIP) |                      |               |                        |
|            |                                         |                              |     └──443/TCP                      |                      |               |                        |
+------------+-----------------------------------------+------------------------------+-------------------------------------+----------------------+               +                        +
| Validating | kyverno-policy-validating-webhook-cfg   | validate-policy.kyverno.svc  | └─┬kyverno-svc                      | ├──clusterpolicies/* |               |                        |
|            |                                         |                              |   ├──NS  : kyverno                  | └─┬policies/*        |               |                        |
|            |                                         |                              |   ├──Path: /policyvalidate          |   └──^UPDATE         |               |                        |
|            |                                         |                              |   └─┬IP  : 10.96.195.22 (ClusterIP) |                      |               |                        |
|            |                                         |                              |     └──443/TCP                      |                      |               |                        |
+            +-----------------------------------------+------------------------------+-------------------------------------+----------------------+               +                        +
|            | kyverno-resource-validating-webhook-cfg | validate.kyverno.svc-ignore  | └─┬kyverno-svc                      |                      |               |                        |
|            |                                         |                              |   ├──NS  : kyverno                  |                      |               |                        |
|            |                                         |                              |   ├──Path: /validate                |                      |               |                        |
|            |                                         |                              |   └─┬IP  : 10.96.195.22 (ClusterIP) |                      |               |                        |
|            |                                         |                              |     └──443/TCP                      |                      |               |                        |
+            +                                         +------------------------------+                                     +----------------------+               +                        +
|            |                                         | validate.kyverno.svc-fail    |                                     |                      |               |

```

##### Architecture
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7w0kz4zb9e1bkdtsf44h.png)

---
##### Creating and instantiating policies
Validating policy
```
# Mandate presence of label:app.kubernetes.io/name
❯ kubectl create -f- << EOF
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-labels
spec:
  validationFailureAction: enforce
  rules:
  - name: check-for-labels
    match:
      any:
      - resources:
          kinds:
          - Pod
    validate:
      message: "label 'app.kubernetes.io/name' is required"
      pattern:
        metadata:
          labels:
            app.kubernetes.io/name: "?*"
EOF
clusterpolicy.kyverno.io/require-labels created
# List the policy
❯ kubectl get cpol
NAME             BACKGROUND   ACTION    READY
require-labels   true         enforce   true
# Test the policy
❯ kubectl run pod test-pod --image=alpine --restart=Never
Error from server: admission webhook "validate.kyverno.svc-fail" denied the request:

resource Pod/default/pod was blocked due to the following policies

require-labels:
  check-for-labels: 'validation error: label ''app.kubernetes.io/name'' is required.
    Rule check-for-labels failed at path /metadata/labels/app.kubernetes.io/name/'
❯ echo $?
1
```

Mutating policy
```
# Policy to add some labels by default
❯  k create -f- << EOF
heredoc> apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-labels
  annotations:
    policies.kyverno.io/title: Add Labels
    policies.kyverno.io/category: Sample
    policies.kyverno.io/severity: medium
    policies.kyverno.io/subject: Label
    policies.kyverno.io/description: >-
      Labels are used as an important source of metadata describing objects in various ways
      or triggering other functionality. Labels are also a very basic concept and should be
      used throughout Kubernetes. This policy performs a simple mutation which adds a label
      `foo=bar` to Pods, Services, ConfigMaps, and Secrets.
spec:
  rules:
  - name: add-labels
    match:
      resources:
        kinds:
        - Pod
        - Service
        - ConfigMap
        - Secret
    mutate:
      patchStrategicMerge:
        metadata:
          labels:
            foo: bar
 
heredoc> EOF
clusterpolicy.kyverno.io/add-labels created
# Create a sample pod
❯ kubectl run test-pod --image=alpine --restart=Never
pod/test-pod created
# Test the application
❯ kubectl get pod test-pod --show-labels
NAME       READY   STATUS      RESTARTS   AGE   LABELS
test-pod   0/1     Completed   0          18s   foo=bar,run=test-pod
```
[All policies](https://kyverno.io/policies/)
[Adding a created-by label](https://neonmirrors.net/post/2020-12/exploring-kyverno-part2/)

---
[Kyverno CLI](https://kyverno.io/docs/kyverno-cli/)
From the documentation
> The Kyverno Command Line Interface (CLI) is designed to validate and test policy behavior to resources prior to adding them to a cluster. The CLI can be used in CI/CD pipelines to assist with the resource authoring process to ensure they conform to standards prior to them being deployed. It can be used as a kubectl plugin or as a standalone CLI

---
##### Testing for CI
You need the [kyverno cli](https://kyverno.io/docs/kyverno-cli/)
- To test yamls in a `given-folder/`
```
❯ kyverno test given-folder/
```
- To test yamls in a git repo
```
❯ kyverno test https://<repo-url>
```
- To test yamls in a given `branch` of a git-repo where yamls are in a given `folder/`
```
❯ kyverno test https://<repo-url>/<folder> --git-branch <BRANCH>
```
[test documentation](https://kyverno.io/docs/kyverno-cli/#test)

---
##### More info
[Documentation](https://kyverno.io/docs/introduction/)
[Excellent tutorial](https://neonmirrors.net/post/2020-12/exploring-kyverno-part1/)

---
I love the policy library that has a lot of specific examples