Prevent Kubernetes misconfigurations from reaching production with Datree
The problem
What are some of the challenges that Kubernetes admins might face? Let's say you have a few developers that made changes to K8s configurations files, to deploy their objects, and they are working with CI/CD and they push their configuration file on git repo. Let's say it caused a failure in production. Wouldn't it be cool to figure out these misconfigurations before the production? Here’s where Datree enters the picture.
About Datree
Datree is a CLI tool that supports Kubernetes owners in their roles and it helps by preventing developers from making errors in their Kubernetes configuration files before they reach production and causes failure. It does so by providing a policy enforcement solution to run automatic checks for rule violations. It can be used on the command line to run policies against Kubernetes manifests YAML files or Helm charts. You can include Datree's policy check as part of your CI/CD pipeline or run it locally before every commit.
How to sign up
You'll have to sign up in order to access the dashboard containing your policy checks. Head over to the sign up page and you can choose to either continue to GitHub or Google account.
Follow these steps to get started:
1) Download and install Datree in just one command!
$ curl https://get.datree.io | /bin/bash
2) Scan a Kubernetes file or helm chart directory
$ datree test [k8s-file-path] / helm datree test [chart-dir]
3) You can now click on the link provided in the Summary of the CLI output that says, “See all rules in the policy to access your dashboard”. Here you can also find the cliId
in the URL itself. This token is what connects the policy checks to your centralized policy to know which policies and rules to run. You can also find your token by going to your profile settings in the dashboard.
You can also find it via Datree's config via, such as:
$ nano ~/.datree/config.yaml
More information about account tokens can be found here.
How to run
By default, Datree offers a demo Kubernetes configuration file for you to test out the tool. You can find it at ~/.datree/k8s-demo.yaml
and use it to test the tool out quickly. Let's modify it a little bit.
➜ ~ cat ~/.datree/k8s-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: rss-site
namespace: test
labels:
owner: --
environment: prod
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
namespace: test
labels:
app: we
spec:
containers:
- name: front-end
image: nginx:latest
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: "64Mi"
cpu: "64m"
limits:
cpu: "500m"
ports:
- containerPort: 80
- name: rss-reader
image: datree/nginx@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
- name: Custom-Header
value: Awesome
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
cpu: "64m"
memory: "128Mi"
limits:
memory: "128Mi"
ports:
- containerPort: 88
You can run the following command in order to test Datree against the pre-compiled demo file:
$ datree test ~/.datree/k8s-demo.yaml
As you can see, it consists of 5 rules failing in the policy checks. You can also find the history of this in your Datree dashboard.
Out of the box, Datree offers 34 such rules for you to test. These rules are spread across categories such as:
- Containers
- Workload
- CronJob
- Security
- Networking
- Deprecation
- and more
You can find these rules in the default policy on your dashboard.
Here, you can either change the error message of various rules, turn some of those on/off, and then see the changes in your command line instantly!
Since it's not connected to a cluster, you can also run it offline without needing to setup something like Minikube, Kubeadm, etc.
Schema validation
Datree also performs schema validation checks for your files before running the policy checks. For example, if I make an error in the structure of my YAML file and run a Datree check on it, it's going to give me the following error:
Here, you can see the order in which these checks are performed. YAML validation -> Kubernetes schema validation -> policy checks
Key features
Datree also allows you to create your own policies. This can be useful for different stages of deployment. You can add policies with different rules configured, giving each policy its own use cases. In order to do so, head over to your Datree dashboard and click on + Create Policy
. Here you can give it a name, and once the policy is created, you can apply rules to it. You can select any or all of the 34 rules for your own policy.
I am also going to edit the error message to something customized. This is something that is also a huge advantage as compared to using checks provided by kubectl
.
For this example, I'm going to a Kubernetes configuration file that consists of a Deployment, and a Service that consists of a database and an API.
➜ ~ cat go-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-demo-2-db
spec:
selector:
matchLabels:
type: db
service: go-demo-2
strategy:
type: Recreate
template:
metadata:
labels:
type: db
service: go-demo-2
vendor: MongoLabs
spec:
containers:
- name: db
image: mongo:3.3
ports:
- containerPort: 28017
---
apiVersion: v1
kind: Service
metadata:
name: go-demo-2-db
spec:
ports:
- port: 27017
selector:
type: db
service: go-demo-2
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-demo-2-api
spec:
replicas: 5
selector:
matchLabels:
type: api
service: go-demo-2
template:
metadata:
labels:
type: api
service: go-demo-2
language: go
spec:
containers:
- name: api
image: vfarcic/go-demo-2:3.0
env:
- name: DB
value: go-demo-2-db
readinessProbe:
httpGet:
path: /demo/hello
port: 8080
periodSeconds: 1
livenessProbe:
httpGet:
path: /demo/hello
port: 8080
---
apiVersion: v1
kind: Service
metadata:
name: go-demo-2-api
spec:
type: NodePort
ports:
- port: 8080
selector:
type: api
service: go-demo-2
Now, in order to select this policy instead of the default one when running checks, you can use the -p
flag:
$ datree test go-demo.yaml -p My_Policy
As you can see, this only failed on one of the rules that I added, as compared to 5 rules failing in the default one. You can also notice the custom error message that I have added.
Policy as code
But what if you want to collaborate with other people and share your policies with someone else? This includes following development best practices such as version controlling, automation, collaboration and more. For this, Datree offers something called policy as code. This is a declarative method to represent your policies. When this mode is enabled, the only way to change the policies in your account is by publishing a YAML configuration file. This file is going to contain all your defined policies.
In order to use this feature, you can turn it on from your profile settings and download the policies.yaml
file.
The file is going to look something like this, with the inactive rules commented out:
apiVersion: v1
customRules: null
policies:
- name: My_Policy
rules:
# - identifier: CONTAINERS_MISSING_IMAGE_VALUE_VERSION
# messageOnFailure: Incorrect value for key `image` - specify an image version to avoid unpleasant "version surprises" in the future
# - identifier: CONTAINERS_MISSING_MEMORY_REQUEST_KEY
# messageOnFailure: Missing property object `requests.memory` - value should be within the accepted boundaries recommended by the organization
- identifier: CONTAINERS_MISSING_CPU_REQUEST_KEY
messageOnFailure: Missing property object `requests.cpu` - value should be within the accepted boundaries recommended by the organization
# - identifier: CONTAINERS_MISSING_MEMORY_LIMIT_KEY
# messageOnFailure: Missing property object `limits.memory` - value should be within the accepted boundaries recommended by the organization
# - identifier: CONTAINERS_MISSING_CPU_LIMIT_KEY
# messageOnFailure: Missing property object `limits.cpu` - value should be within the accepted boundaries recommended by the organization
# - identifier: INGRESS_INCORRECT_HOST_VALUE_PERMISSIVE
# messageOnFailure: Incorrect value for key `host` - specify host instead of using a wildcard character ("*")
# - identifier: SERVICE_INCORRECT_TYPE_VALUE_NODEPORT
# messageOnFailure: Incorrect value for key `type` - `NodePort` will open a port on all nodes where it can be reached by the network external to the cluster
# - identifier: CRONJOB_INVALID_SCHEDULE_VALUE
# messageOnFailure: 'Incorrect value for key `schedule` - the (cron) schedule expressions is not valid and, therefore, will not work as expected'
# - identifier: WORKLOAD_INVALID_LABELS_VALUE
# messageOnFailure: Incorrect value for key(s) under `labels` - the vales syntax is not valid so the Kubernetes engine will not accept it
# - identifier: WORKLOAD_INCORRECT_RESTARTPOLICY_VALUE_ALWAYS
# messageOnFailure: Incorrect value for key `restartPolicy` - any other value than `Always` is not supported by this resource
# - identifier: HPA_MISSING_MINREPLICAS_KEY
# messageOnFailure: Missing property object `minReplicas` - the value should be within the accepted boundaries recommended by the organization
# - identifier: HPA_MISSING_MAXREPLICAS_KEY
# messageOnFailure: Missing property object `maxReplicas` - the value should be within the accepted boundaries recommended by the organization
Working with your CI
You can use Datree's policy check in your CI process. This way, every time the CI is triggered, it will also run datree test
to verify the Kubernetes configuration files are always configured according to your needs. In order to use Datree, you'll need your account's token as mentioned above.
Datree supports integrations with:
- Helm plugin
- Git hooks
- CircleCi
- Travis CI
- GitHub Actions
- GitLab CI/CD
- Jenkins
You can find examples for these in the public repository.