Datree - Clear out your misconfigurations

Datree - Clear out your misconfigurations

Don't wait for your misconfigs. to show up at the prod. stage

·

10 min read

Headstart

To manage and ensure the integrity of Kubernetes configurations within organizations, Datree was developed to handle the difficulties and complexities involved. As Kubernetes grew in popularity, it became clear that it might be very difficult to manage and enforce best practices, security standards, and governance across numerous teams and deployments.

Let's say some developers build an app, and edit their kubernetes config file for the proper working of their apps. and deploy them. And suddenly the app crashes at the production stage. Now what if we could fix this issue like knowing what went wrong in the kubernetes manifests files that might contain unwanted misconfigurations before we can encounter it at the production stage?

Datree helps us do that!

What is Datree?

Datree is a tool for policy enforcement created especially for Kubernetes. By automatically validating Kubernetes configurations against predefined policies, it aids organizations in ensuring best practices, compliance, and security.

Datree provides us with a CLI tool that helps developers to catch their k8s misconfigurations "red-handed" in the development phase before they slip out and go for production.

Using a straightforward and understandable syntax, we can also define policies along with predefined ones, as code with Datree. These guidelines cover a wide range of topics, including deployment tactics, naming conventions, resource limitations, and security settings. For Kubernetes, Datree offers a comprehensive policy library with ready-made policies that address industry-standard best practices and security criteria.

In order to automatically analyze and check Kubernetes misconfigurations after policies have been developed, Datree interfaces with the development workflow, including Git and CI/CD pipelines. To look for policy violations, it examines YAML files, Helm charts, and other configuration artifacts. If any violations are discovered, Datree gives developers useful feedback, outlining the particular problems and making recommendations for solutions.

Additionally, Datree provides a web-based dashboard that shows policy compliance across all of your Kubernetes deployments. You can manage and keep an eye on the condition of your Kubernetes infrastructure, thanks to the thorough reports it gives, which include policy breaches, configuration trends, and compliance metrics.

Installation

Here is the website to get started with it and make sure you sign up with an account and log in. Once you are logged in, you will be redirected to this page.

There are multiple ways to install the datree CLI tool like Helm, fluxCD, argo CLI, etc. Go ahead and venture out these tools but let's see how we can do it using Helm.

Helm is a Kubernetes package manager tool.

This is the website for Helm that instructs on how we can install it on various operating systems. After you've got helm, there shouldn't be any problem downloading datree as it gives a list of commands to execute one by one. Make sure to add your token provided on the bottom of the page mentioning "copy it here" to the field "--set datree.token=<paste-your-token-here>"

The reason why there is a token up there is that it will synchronize your CLI tool with the GUI dashboard of datree in your browser. So any changes that you make in either of them will be reflected in the latter.

Once you are done, check the version of datree to make sure it is installed.

datree version

Now, let's get started!

Interact with datree CLI

Datree provides us with a sample yaml file to start making policy checks on it. What you can do is, you can copy the code below and create a file with a ".yaml" extension. I am going to name it "datree_demo.yaml" but you can name it whatever you can think of.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rss-site
  namespace: test
  labels:
    owner: --
    environment: prod
    app: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      namespace: test
      labels:
        app: web
    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"
              cpu: "500m"
          ports:
            - containerPort: 88

So what do we have over here?

We got a Kubernetes object of kind "deployment" that will work on a production environment. We got two containers, "front-end" and "rss-reader" that listens on port 80 and the latter one on 88. We also got a bunch of other requirements like CPU, memory, TCP port, and so on for the respective containers.

We are going to scan this object against some policies provided by datree and see whether it passes those tests.

How do we do it? Here's the command.

datree test datree_demo.yaml

Make sure you are in the correct directory where you have stored the yaml file.

This is what you would normally see when first executing the command.

Datree does a series of checks...

  1. YAML validation - To guarantee that the YAML file's structure and syntax are proper, Datree runs YAML validation. It looks for problems including improper key-value pairings, missing or excess commas, indentation flaws, and other YAML-specific syntax mistakes. The YAML file must pass this validation process in order for Kubernetes to be able to parse it correctly.

  2. Kubernetes schema validation - Datree does Kubernetes schema validation after the YAML validation. In order to make sure that the resource definitions adhere to the anticipated structure and field types, it verifies the contents of the YAML file against the Kubernetes API schemas. The YAML file's compliance with the Kubernetes resource standards, including the right API version, kind, and needed fields, is checked during this validation stage.

  3. Policy checks - By letting you create personalized policies or make use of pre-configured policy packs, Datree facilitates policy enforcement. To ensure compliance with best practices, security rules, and organizational standards, policy checks compare the content and configuration of the YAML file to set policies. These guidelines may include naming conventions for resources, label specifications, security configurations, resource caps, network regulations, and more.

Running policy checks

What can we observe from the output we got just after testing our yaml file?

We see that YAML and Kubernetes schema validation checks have been passed but not the policy ones. The first check that we are failing is..

X Ensure each container image has a pinned (tag) version

..which is pretty self-explanatory. An image is missing in each container. Gotta fix that! You see none of these solutions work...

spec:
  containers:
    - name: front-end
      image: nginx
spec:
  containers:
    - name: front-end
      image: nginx:latest

So what you can do is add a version to the image like this

spec:
  containers:
    - name: front-end
      image: nginx:1.23.0

The image ID or image SHA also works...

spec:
  containers:
    - name: front-end
      image: nginx@sha256:0a564e80a3156f2cc825d1720f303d59bd521da19bcbd01316870e1313ecbd23

The next check that we are failing is...

X Ensure each container has a configured liveness probe.

Kubernetes can decide when to replace a pod using liveness probes. They are essential when setting up a robust cluster design.

We can use either of these two ways to define our liveness probe..

spec:
  containers:
    - name: front-end
      image: nginx:1.23.0
      livenessProbe:
        httpGet:
          path: /frontend
          port: 8888
          httpHeaders:
            - name: Custom-frontend
              value: Great
spec:
  containers:
    - name: front-end
      image: nginx:1.23.0
      livenessProbe:
        tcpSocket:
          port: 8080

The next check that we are failing is...

X Ensure each container has a configured memory limit.

As simple as it is, we need to add a memory for each container.

spec:
  containers:
    - name: front-end
      image: nginx:1.23.0
      resources:
        limits:
          memory: "128Mi"

Looks like we have covered all the checks. Now we can test our yaml file again to see if there is anything left to correct.

datree test datree_demo.yaml

Yoohoo! We have 0 rules failing which means our kubernetes yaml configuration file is ready to be deployed to the production stage.

Now, let's head to our datree dashboard which is opened up once we had logged in earlier. If we look at the activity log, we can see that there is a list of all the policy checks that were failing until the time we passed all of them.

Now if we switch to the policies section, we'll find a long list of them. There are more than 100 policy rules we can work around with. There's a toggle attached to each rule. If we want our manifest files to be tested against these policies, we can turn on the toggle for the respective ones.

This gives us the flexibility to work with our manifest files. You see, we didn't have to necessarily pass those policy checks which we did just now. We could have easily headed to our dashboard policies section and switched off those policy checks for which we were failing. But it was good practice to learn something new!

Tweaking YAML validation

Previously, we saw that our datree_demo.yaml was passing the yaml check. Let's see what could be the possible ways we can fail over here.

There can be an indentation problem like, say we add some extra spaces before "kind" and "name" and test our code.

apiVersion: apps/v1
     kind: Deployment
metadata:
        name: rss-site
  namespace: test
datree test datree_demo.yaml

And there we go, successfully failing the YAML validation check. We'll also get errors if we add some unwanted characters like '{', ',' , '?', and so on.

Tweaking Kubernetes schema validation

Let's say we make a typo error like instead of metadata, we write metADATA.

apiVersion: apps/v1
kind: Deployment
metADATA:
  name: rss-site
  namespace: test

Well, the test crashed because we misconfigured our Kubernetes schema.

Creating our own policies

Datree not only provides its pre-defined policies but also gives us the freedom to define our own. Isn't it cool?

There can be times when you want your Kubernetes manifests to strongly adhere to a particular policy in regard to the organization's immediate needs that may not be available in the datree policy database. Hence we got the flexibility to create one.

How can we do that? It's pretty simple. Head over to the policies section dashboard where you'll see a "+ Create policy" option. Let's say we create a policy with the name "test_policy". You'll see that under this policy, there are 0 policies.

Let's turn on some rules...

  1. Ensure each container has a configured CPU limit.

  2. Ensure each container has a configured liveness probe.

  3. Ensure each container has a configured memory limit.

  4. Ensure each container has a configured readiness probe.

  5. Ensure each container probe has an initial delay configured.

  6. Ensure each container image has a pinned (tag) version.

We can edit these policy messages too!

On hovering over each policy, we can click on the "Learn and customize" button to which a right panel pops up. Let's say we do it for the "Ensure each container probe has an initial delay configured" policy rule.

Under "Message on rule failure", let's add a "Hey there!" and save it.

Now let's test out datree_demo.yaml against the "test_policy".

datree test datree_demo.yaml -p test_policy

As we can see, the changes in the error message have been reflected over here too. Awesome!

Policy as code

Datree policies can be used to collaborate within the organizations and with peers too. How can we do that?

Datree provides us with something called "Policy as code". It helps us to define our policies in a declarative way in a yaml file and export it. There is an option called policy as code. Once it is enabled, you can download a policies.yaml file. We won't be able to make any changes to the policies on the user interface but you are free to do so by editing the yaml file.

Head over to the settings -> enable policy as code -> download the yaml file.

This is a rough view of "policies.yaml" file. You can view it in the local editor of your preference.

Let's comment out the first two rules under "test_policy". And then we'll publish our policies.yaml file so that it syncs with the user interface dashboard and for us to see the changes being reflected in real-time.

datree publish policies.yaml

As you can see out of 6 policies we have only 4 of them on our dashboard!

New device authorization

We can configure our datree account to our CLI terminal if we want to use it on a new device or say we want some other person's datree configurations to be aligned with a local system. A token helps us to do that.

The token for each specific user can be found in the settings section if you are searching for it. And now that we have our token we can configure our settings in our terminal. This won't make any difference because we had already configured ourselves during the time of installation of datree.

datree config set token <your-token-here>

References..

  1. Prevent Kubernetes Misconfigurations from Reaching Production with Datree

  2. Datree docs

Let's connect on Twitter ->Alve___