Kubernetes – DaemonSets

Kubernetes – DaemonSets

August 13, 2019 1 By Eric Shanks

DaemonSets can be a really useful tool for managing the health and operation of the pods within a Kubernetes cluster. In this post we’ll explore a use case for a DaemonSet, why we need them, and an example in the lab.

DaemonSets – The Theory

DaemonSets are actually pretty easy to explain. A DaemonSet is a Kubernetes construct that ensures a pod is running on every node (where eligible) in a cluster. This means that if we were to create a DaemonSet on our six node cluster (3 master, 3 workers), the DaemonSet would schedule the defined pods on each of the nodes for a total of six pods. Now, this assumes there are either no taints on the nodes, or there are tolerations on the DaemonSets.

In reality, DaemonSets behave very similarly to a Kubernetes deployment, with the exception that they will be automatically distributed to ensure the pods are deployed on each node in the cluster. Also, if a new node is deployed to your cluster after the DaemonSet has been deployed, the new node will also get the DaemonSet deployed by the scheduler, after the join occurs.

So why would we use a DaemonSet? Well, a common use for DaemonSets would be for logging. Perhaps we need to ensure that our log collection service is deployed on each node in our cluster to collect the logs from that particular node. This might be a good use case for a DaemonSet. Think of this another way; we could run and install services on each of our Kubernetes nodes by installing the app on the OS. But now that we’ve got a container orchestrator available to use, lets take advantage of that and build those tools into a container and automatically schedule them on all nodes within the cluster, in one fell swoop.

DaemonSets – In Practice

For this example, we’ll deploy a simple container as a DaemonSet to show that they are distributed on each node. While this example, is just deploying a basic container, it could be deploying critical services like a log collector. The manifest below contains the simple Daemonset manifest.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-example
  labels:
    app: daemonset-example
spec:
  selector:
    matchLabels:
      app: daemonset-example
  template:
    metadata:
      labels:
        app: daemonset-example
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: busybox
        image: busybox
        args:
        - sleep
        - "10000"Code language: JavaScript (javascript)

Note that the DaemonSet has a toleration so that we can deploy this container on our master nodes as well, which are tainted.

We apply the manifest with the:

kubectl apply -f [file name].yamlCode language: CSS (css)

After we apply it, lets take a look at the results by running:

kubectl get pods --selector=app=daemonset-example -o wideCode language: JavaScript (javascript)

You can see from the screenshot above, there are six pods deployed. Three on master nodes and three more on worker nodes. Great, so we didn’t have to use any affinity rules to do this, the DaemonSet made sure we had one pod per node as we had hoped.

What happens if we add another worker nodes to the cluster? Well, let’s try it.

I’ve used kubeadm to join another node to my cluster. Shortly after the join completed, I noticed the DaemonSets started deploying another pod without my intervention.

And, as you’d hoped, a minute later the container was up and running on my new node “k8s-worker-3”.

Summary

DaemonSets can make pretty short work of deploying resources throughout your k8s nodes. You’ll see many applications use DaemonSets to ensure that each node of your cluster is being properly managed.