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.
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.
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.
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.
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.