What is Kubernetes DaemonSet and How to Use It?

July 16, 2020

Introduction

Kubernetes allows you to automate software deployment, manage containerized applications, and scale your clusters with ease. A wide array of Kubernetes objects, including DaemonSets, provide an additional level of control.

Use Kubernetes DaemonSets to deploy specific Pods to every single node in your cluster.

This article explains what a DaemonSet is, when to use it, and how to create it.

Use Kubernetes DaemonSet to deploy specific Pods cluster-wide.

What is a Kubernetes DaemonSet?

Kubernetes makes sure that an application has ample resources, runs reliably, and maintains high availability throughout its lifecycle. The location of the app within the cluster is not a priority.

A DaemonSet allows you to overcome Kubernetes’ scheduling limitations and makes sure that a specific app gets deployed on all the nodes within the cluster.m  The deployed Pods usually contain background processes that need to be disseminated throughout the entire cluster.

A DaemonSet is typically described using a YAML file. The fields in the YAML file give you added control of the Pod deployment process. A good example is utilizing labels to start specific Pods on a limited subset of nodes.

How do DaemonSets Work?

A DaemonSet is an active Kubernetes object managed by a controller. You can declare your desired state, indicating that a specific Pod needs to be present on every node. The reconciliation control loop is going to compare the desired state with the current observed state. If an observed node does not have a matching Pod, the DaemonSet controller is going to create one automatically.

This automated process includes existing nodes and all newly created nodes. The Pods created by DaemonSet controllers are ignored by the Kubernetes scheduler and exist as long as the node itself.

A DaemonSet creates a Pod on every node by default. If necessary, you can limit the number of acceptable nodes by using a node selector. The DaemonSet controller is going to create Pods only on nodes that match the predefined nodeSelector field in the YAML file.

Why Use a DaemonSet?

DaemonSets can improve cluster performance by deploying Pods that perform maintenance tasks and support services to every node. Specific background processes, Kubernetes monitoring apps, and other agents must be present throughout the cluster to provide relevant and timely services.

DaemonSets are exceptionally well suited for long-running services which can include:

  • Logs collection
  • Node resource monitoring (frameworks such as Prometheus)
  • Cluster storage
  • Infrastructure-related Pods (system operations)

It is common for one DaemonSet to deploy one daemon type across all nodes. However, multiple DaemonSets can also control one daemon type by using different labels. Kubernetes labels specify deployment rules based on the characteristics of individual nodes.

Note: To ensure high performance of your clusters, learn how to optimize containers for Kubernetes.

How to Create a DaemonSet?

You can describe a DaemonSet in a YAML file and apply the file to the cluster using the kubectl commands.

For example, the daemonset-node-exporter.yaml file below deploys a Prometheus node-exporter, within the monitoring namespace, to monitor hardware usage metrics on every node in the cluster.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring
  labels:
    name: node-exporter
spec:
  selector:
    matchLabels:
      name: node-exporter
  template:
    metadata:
      labels:
        name: node-exporter
      annotations:
         prometheus.io/scrape: "true"
         prometheus.io/port: "9100"
    spec:
      hostPID: true
      hostIPC: true
      hostNetwork: true
      containers:
        - ports:
            - containerPort: 9100
              protocol: TCP
          resources:
            requests:
              cpu: 0.15
          securityContext:
            privileged: true
          image: prom/node-exporter:v0.15.2
          args:
            - --path.procfs
            - /host/proc
            - --path.sysfs
            - /host/sys
            - --collector.filesystem.ignored-mount-points
            - '"^/(sys|proc|dev|host|etc)($|/)"'
          name: node-exporter
          volumeMounts:
            - name: dev
              mountPath: /host/dev
            - name: proc
              mountPath: /host/proc
            - name: sys
              mountPath: /host/sys
            - name: rootfs
              mountPath: /rootfs
      volumes:
        - name: proc
          hostPath:
            path: /proc
        - name: dev
          hostPath:
            path: /dev
        - name: sys
          hostPath:
            path: /sys
        - name: rootfs
          hostPath:
            path: /

Access your Kubernetes command-line interface and apply the newly created YAML file:

kubectl apply -f daemonset-node-exporter.yaml

The system confirms that the DaemonSet has been created.

Confirmation that the daemon based on the yaml file has been successfully created.

Once you submit the daemonset-node-exporter DaemonSet, confirm its current state with the describe command:

kubectl describe daemonset node-exporter -n monitoring

The output offers basic DaemonSet information and indicates that the pod has been deployed on all the available nodes.

Using the describe command to list details of the daemonset deployment.

You can additionally confirm this by listing all running pods with the following command:

kubectl get pod -o wide -n monitoring

The DaemonSet is now going to continually deploy the node-exporter Pod to all newly created nodes.

How to Limit DaemonSet to Specific Nodes

DaemonSets create Pods on every node in the cluster by default, unless node selectors constrain them. Initially, it is necessary to add the desired set of labels to a subset of nodes.

Achieve this by using the kubectl label command. Add the ssd=true label to the node01 node with the following command:

kubectl label nodes node01 ssd=true

Node selectors are part of the nodeSelector field within the DaemonSet YAML file. In the following example, a DaemonSet is going to deploy Nginx only on nodes labeled as ssd=true.

apiVersion: apps/v1 
kind: "DaemonSet" 
metadata: 
  labels: 
    app: nginx 
    ssd: "true" 
  name: nginx-ssd-storage 
spec:
  selector:
    matchLabels:
      ssd: "true" 
  template: 
    metadata: 
      labels: 
        app: nginx 
        ssd: "true" 
    spec: 
      nodeSelector: 
        ssd: "true" 
      containers: 
        - name: nginx 
          image: nginx:latest

Adding the ssd=true label to a new node is going to deploy the nginx-ssd-storage Pod to that node. If a label is removed from a node, the DaemonSet controller removes the Pod as well.

How to Update a DaemonSet?

The OnDelete update strategy was the only way to update Pods managed by a DaemonSet in early Kubernetes versions (prior to version 1.6). An OnDelete approach requires you to delete each Pod manually. Only then is the DaemonSet able to create a new Pod using the new configuration.

Recent Kubernetes versions use rolling updates by default. The update strategy is defined using the spec.updateStrategy.type field. The default value is set to RollingUpdate.

The rolling update strategy removes old Pods and creates new ones instead. The process is automatic and controlled. Deleting and creating all the Pods at the same time can lead to unavailability and prolonged downtime.

Two parameters allow you to control the update process:

  • minReadySeconds defines the period between Pod upgrades. The value is defined in seconds, and setting a reasonable time-frame secures Pod health before the system proceeds to update the next Pod.
  • updateStrategy.rollingUpdate.maxUnavailable allows you to define the number of Pods that can be upgraded at the same time. The value of this parameter is highly dependent on the type of application being deployed. It is necessary to balance speed and safety to ensure high availability.

Use the kubectl rollout command to check the status of a DaemonSet rolling upgrade:

kubectl rollout status ds/daemonset-node-exporter -n monitoring

The system observes DaemonSet updates and informs you of the current roll-out status of the node-exporter DaemonSet.

System observing DaemonSet updates.

How to Delete a DaemonSet?

Remove a DaemonSet using the kubectl delete command. Be sure to correctly specify the name of the DaemonSet you want to delete:

kubectl delete -f daemonset-node-exporter.yaml -n monitoring

This command should be used with care. Deleting a DaemonSet also cleans up all the Pods the DaemonSet in question deployed.

Conclusion

You now have a thorough understanding of Kubernetes DaemonSets.

You can try out the basic commands outlined in this article to deploy pods across nodes. Use DaemonSets to assert your control over processes in the cluster and make sure that you are always on top of things.

Was this article helpful?
YesNo
Vladimir Kaplarevic
Vladimir is a resident Tech Writer at phoenixNAP. He has more than 7 years of experience in implementing e-commerce and online payment solutions with various global IT services providers. His articles aim to instill a passion for innovative technologies in others by providing practical advice and using an engaging writing style.
Next you should read
How to Containerize Legacy Applications
February 27, 2020

This article focuses on the benefits of migrating to a new distributed architecture. Containers have taken...
Read more
kubectl port-forward: Kubernetes Port Forwarding Guide
February 25, 2020

This article shows you how to port forward from your localhost and interact with Kubernetes cluster...
Read more
6 Kubernetes Security Best Practices: Secure Your Workloads
January 23, 2020

This article presents basic security principles such as defense-in-depth and restricted privilege. Learn how...
Read more
What are Microservices? Introduction to Microservices Architecture
December 26, 2019

Microservices are a system used to develop an application, built on a selection of individual services...
Read more