2023-03-16 10:52:38 +02:00
..
2023-01-14 09:14:40 +11:00
2023-01-14 09:14:40 +11:00
2023-01-14 09:14:40 +11:00
2022-06-24 09:40:32 +10:00
2023-03-16 10:52:38 +02:00
2023-02-07 12:19:01 +11:00

Introduction to Datree

Kubernetes Guide

Installation

Best place to start is the documentation

I like to start all my work inside a docker container.
Let's run a small Alpine linux container

docker run -it -v ${PWD}:/work -v ${HOME}/.kube/:/root/.kube/ -w /work --net host alpine sh 

Install some dependancies

Let's install curl and unzip because the installation script uses those.
We will also install sudo since we are running in a container as root and install scripts have sudo commands in them.

apk add curl unzip bash sudo

Automatic Installation

We can install the latest version of Datree with the command advertised:

curl https://get.datree.io | /bin/bash

Manual Installation

Or we can grab a specific version of datree on the GitHub releases page.
For example: 1.5.20 binary

curl -L https://github.com/datreeio/datree/releases/download/1.5.20/datree-cli_1.5.20_Linux_x86_64.zip -o /tmp/datree.zip

unzip /tmp/datree.zip -d /tmp && \
chmod +x /tmp/datree && \
mv /tmp/datree /usr/local/bin/datree

Now we can run the datree command:

datree
Datree is a static code analysis tool for kubernetes files. Full code can be found at https://github.com/datreeio/datree

Usage:
  datree [command]

Available Commands:
  completion       Generate completion script for bash,zsh,fish,powershell
  config           Configuration management
  help             Help about any command
  kustomize        Render resources defined in a kustomization.yaml file and run a policy check against them
  publish          Publish policies configuration for given <fileName>.
  test             Execute static analysis for given <pattern>
  version          Print the version number

Flags:
  -h, --help   help for datree

Use "datree [command] --help" for more information about a command.

Testing Kubernetes Manifests

We have a number of Kubernetes manifests in this repo.
Datree does a few things for us:

  • YAML validation ( Is this YAML well formatted ? )
  • Schema validation. ( Is this a Kubernetes YAML file ? For the right version ? )
  • Policy checks ( Checks YAML to ensure good practises are followed )

Let's test my example manifests under our datree folder kubernetes\datree\example

YAML validation

If we break the YAML file format, we can detect that with the YAML validation feature

datree test ./kubernetes/datree/example/deployment.yaml

Policy checks

When we fix our YAML file, notice if we run datree test again, we get some policy checks failing

datree test ./kubernetes/datree/example/deployment.yaml

Let's test some other types of Kubernetes objects

datree test ./kubernetes/services/service.yaml
datree test ./kubernetes/configmaps/configmap.yaml
datree test ./kubernetes/statefulsets/statefulset.yaml
datree test ./kubernetes/ingress/ingress.yaml

Schema validation

Datree can also check if our YAML matches the target Kubernetes version schema. For example, our Ingress YAML is a newer version of Kubernetes

datree test --schema-version 1.14.0 ./kubernetes/ingress/ingress-nginx-example.yaml
datree test --schema-version 1.19.0 ./kubernetes/ingress/ingress-nginx-example.yaml

We can also test a directory of YAML files and include * wildcard in your scans.
Let's test my latest Kubernetes tutorial that contains a Wordpress + MySQL + Ingress setup:

datree test kubernetes/tutorials/basics/yaml/*.y*ml

Policies

Now if we take a look at the CLI output of datree we notice a link in the Summary output.
The URL is in the form of https://app.datree.io/login?t=<token>

(Summary)

- Passing YAML validation: 4/4

- Passing Kubernetes (1.20.0) schema validation: 4/4

- Passing policy check: 2/4

+-----------------------------------+------------------------------------------------------+
| Enabled rules in policy "Default" | 21                                                   |
| Configs tested against policy     | 5                                                    |
| Total rules evaluated             | 84                                                   |
| Total rules skipped               | 0                                                    |
| Total rules failed                | 14                                                   |
| Total rules passed                | 70                                                   |
| See all rules in policy           | https://app.datree.io/login?t=xxxxxxxxxxxxxxxxxxxxxx |
+-----------------------------------+------------------------------------------------------+

We can use this URL to access the Datree UI to get a view of the policy management screens
Checkout the link to access the UI which helps us manage our policies.

Policy examples

One of the key features about policies is that we can apply rule sets for specific environments.
Perhaps you have a development environment where policies are a little loose and a staging server that has tighter restrictions to match production, or even a regulated environment that has very tight controls.

We can use the Datree UI to create policies with different sets of rules.
We can then tell datree about the policy we want it to test against:

datree test kubernetes/datree/example/deployment.yaml -p production

For a new policy, we notice that 0 rules are enabled, so now we have the flexibility to set up the rules we want to protect this environment.

Helm

What if I don't use kubectl and use helm instead ?
Let's install helm in our container

apk add tar git
curl -L https://get.helm.sh/helm-v3.5.4-linux-amd64.tar.gz -o /tmp/helm.tar.gz && \
tar -xzf /tmp/helm.tar.gz -C /tmp && \
chmod +x /tmp/linux-amd64/helm && \
mv /tmp/linux-amd64/helm /usr/local/bin/helm

Let's install the helm plugin for datree

helm plugin install https://github.com/datreeio/helm-datree 

Now we can test a helm chart we have in our repo from my helm tutorial


cd kubernetes/helm

helm datree test example-app \
-- --values ./example-app/example-app-01.values.yaml

Kustomize

What if I don't use helm and use kustomize instead ?
Datree has out the box built-in kustomize support
Let's test our kustomize template from a video I did on kustomize

datree kustomize test .\kubernetes\kustomize\application\

CI/CD examples

We can even run datree in GitHub Actions and various CI/CD integrations.

Admission Controller

So far, datree helps us detect misconfigurations on our local machine as well as at our CI level.
But what about the things that don't flow via our CI ?

When folks deploy stuff directly to our clusters via kubectl or helm.
Datree now allows us to not only detect but prevent misconfigurations being applied using a new admission controller feature.

The admission controller is available here

Create a Kubernetes cluster

Let's start by creating a local kind cluster

Note that we create a Kubernetes 1.23 cluster.
So we want to use datree to validate and ensure our manifests comply with that version of Kubernetes.

kind create cluster --name datree --image kindest/node:v1.23.6

Let's also grab kubectl:

curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.23.6/bin/linux/amd64/kubectl
chmod +x ./kubectl
mv ./kubectl /usr/local/bin/kubectl

We'll need a datree token so our admission controller can read our policies

export DATREE_TOKEN=[your-token]

Installation

I will need some dependencies since I am running in a lightweight alpine container.
OpenSSL is needed by the webhook install to generate certificates.

apk add openssl

Let's grab the datree manifests

curl -L https://get.datree.io/admission-webhook -o datree.sh
chmod +x datree.sh
bash datree.sh

With the admission controller now deployed, datree will validate things coming into the cluster.
For example, if we bypass our CI/CD, datree will catch our deployment and run our policy checks

I have a separate example deployment in our datree folder that we can play with:

kubectl apply -f kubernetes/datree/example/deployment.yaml

Output:

kubectl apply -f kubernetes/deployments/deployment.yaml
Error from server: error when creating "kubernetes/deployments/deployment.yaml": admission webhook "webhook-server.datree.svc" denied the request: 
---
webhook-example-deploy-Deployment.tmp.yaml

[V] YAML validation
[V] Kubernetes schema validation

[X] Policy check

❌  Ensure each container has a configured liveness probe  [1 occurrence]
    - metadata.name: example-deploy (kind: Deployment)
💡  Missing property object `livenessProbe` - add a properly configured livenessProbe to catch possible deadlocks

❌  Ensure each container has a configured readiness probe  [1 occurrence]
    - metadata.name: example-deploy (kind: Deployment)
💡  Missing property object `readinessProbe` - add a properly configured readinessProbe to notify kubelet your Pods are ready for traffic

❌  Prevent workload from using the default namespace  [1 occurrence]
    - metadata.name: example-deploy (kind: Deployment)
💡  Incorrect value for key `namespace` - use an explicit namespace instead of the default one (`default`)


(Summary)

- Passing YAML validation: 1/1

- Passing Kubernetes (v1.23.6) schema validation: 1/1

- Passing policy check: 0/1

+-----------------------------------+-----------------------+
| Enabled rules in policy "Default" | 21                    |
| Configs tested against policy     | 1                     |
| Total rules evaluated             | 21                    |
| Total rules skipped               | 0                     |
| Total rules failed                | 3                     |
| Total rules passed                | 18                    |
| See all rules in policy           | https://app.datree.io |
+-----------------------------------+-----------------------+

Now to get this deployment fixed up, let's go ahead and comply to some of the policies
Under the deployment.yaml I have included a livenessProbe as well as a readinessProbe
Let's add those in.
And finally we need to also add CPU and Memory requests and limit values.

The last one is simple. We should avoid using the default namespace. So I will create an example namespace where I will keep all example apps.

kubectl create ns examples

And finally we can deploy our resource, and specify a namespace:

kubectl apply -n examples -f kubernetes/datree/example/deployment.yaml
deployment.apps/example-deploy created

Kubectl

But what about resources already in your cluster ?
Datree covers this with their kubectl plugin.

We can grab the install script right off the GitHub Release page.
For this demo I'll grab the v0.11 version

Installation:

curl -L https://github.com/datreeio/kubectl-datree/releases/download/v0.1.1/manual_install.sh -o /tmp/kubectl-plugin.sh
chmod +x /tmp/kubectl-plugin.sh
bash /tmp/kubectl-plugin.sh

Now we have datree inside kubectl and can perform checks in our cluster.
We can check our entire namespace now, which should be pretty clean:

kubectl datree test -- --namespace examples
Fetching resources, this may take some time depending on the amount of resources in your cluster...

(Summary)

- Passing YAML validation: 1/1

- Passing Kubernetes (1.24.2) schema validation: 1/1

- Passing policy check: 1/1

+-----------------------------------+------------------------------------------------------+
| Enabled rules in policy "Default" | 21                                                   |
| Configs tested against policy     | 1                                                    |
| Total rules evaluated             | 21                                                   |
| Total rules skipped               | 0                                                    |
| Total rules failed                | 0                                                    |
| Total rules passed                | 21                                                   |
| See all rules in policy           | https://app.datree.io/login?t=xxxxxxxxxxxxxxxxxxxxxx |
+-----------------------------------+------------------------------------------------------+

The following cluster resources in namespace 'examples' were checked:

deployment.apps/example-deploy