Introduction to Datree
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