{"id":508,"date":"2025-08-18T10:56:00","date_gmt":"2025-08-18T10:56:00","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=508"},"modified":"2025-08-18T10:56:00","modified_gmt":"2025-08-18T10:56:00","slug":"kubernetes-daemonset","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=508","title":{"rendered":"Kubernetes Daemonset: A Comprehensive Guide"},"content":{"rendered":"<p>If you&#8217;re new to Kubernetes Daemonsets and want to learn more, this complete beginner&#8217;s guide is for you.<\/p>\n<p>You&#8217;ll learn about<\/p>\n<ol>\n<li>How Daemonset works<\/li>\n<li>Deploying and managing Daemonsets<\/li>\n<li>Daemonset use cases<\/li>\n<li>Daemonset best practices.<\/li>\n<\/ol>\n<p>So if you want to learn and implement Daemonset practically, you\u2019ll love this guide.<\/p>\n<p>Let\u2019s get started.<\/p>\n<h2 id=\"what-is-a-daemonset-in-kubernetes\">What is a DaemonSet In Kubernetes?<\/h2>\n<p><a href=\"https:\/\/kubernetes.io\/?ref=devopscube.com\" rel=\"noreferrer noopener\">Kubernetes<\/a> is a distributed system, and there should be some functionality for kubernetes platform administrators to run platform-specific applications on all the nodes. For example, running a logging agent on all the Kubernetes nodes.<\/p>\n<p>Here is where Daemonset comes into the picture.<\/p>\n<p>Daemonset is a native<a href=\"https:\/\/devopscube.com\/kubernetes-objects-resources\/\"> Kubernetes object<\/a>. As the name suggests, it is designed to run system daemons.<\/p>\n<p>The DaemonSet object is designed to ensure that a <strong>single pod runs on each worker node<\/strong>. This means you cannot scale daemonset pods in a node. And for some reason, if the daemonset pod gets deleted from the node, the daemonset controller creates it again.<\/p>\n<p>Let&#8217;s look at an example. <\/p>\n<p>If there are 500 worker nodes and you deploy a daemonset, the daemonset controller will run one pod per worker node by default. That is a total of 500 pods. However, using <strong>nodeSelector, nodeAffinity, Taints, and Tolerations<\/strong>, you can restrict the daemonset to run on specific nodes.<\/p>\n<p>For example, in a cluster of 100 worker nodes, one might have 20 worker nodes labeled GPU enabled to run batch workloads. And you should run a pod on those 20 worker nodes. In this case, you can deploy the pod as a Daemonset using a node selector. We will look at it practically later in this guide.<\/p>\n<p>Another example is that you have a specific number of worker nodes dedicated to platform tools (ingress, monitoring, logging, etc.) and want to run Daemonset related to platform tools only on the nodes labeled as platform tools. <\/p>\n<p>In this case, you can use the <strong>nodeSelector<\/strong> to run the daemonset pods only on the worker nodes dedicated to platform tooling.<\/p>\n<figure class=\"kg-card kg-image-card kg-card-hascaption\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-4-44.png\" class=\"kg-image\" alt=\"Kubernetes DaemonSet\" loading=\"lazy\" width=\"2000\" height=\"1339\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-4-44.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/image-4-44.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/03\/image-4-44.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-4-44.png 2213w\" sizes=\"auto, (min-width: 720px) 720px\"><figcaption><span style=\"white-space: pre-wrap;\">Click to view in HD<\/span><\/figcaption><\/figure>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">By default, <b><strong style=\"white-space: pre-wrap;\">DeamonSets<\/strong><\/b> run only on worker nodes and if need to run on Controlplane, we need to add tolerations.<\/div>\n<\/div>\n<h2 id=\"kubernetes-daemonset-use-cases\">Kubernetes DaemonSet Use Cases<\/h2>\n<p>The very basic use case of DaemonSet is in the cluster itself. If you look at the <a href=\"https:\/\/devopscube.com\/kubernetes-architecture-explained\/\" rel=\"noreferrer noopener\">Kubernetes architecture<\/a>, the kube-proxy component runs a daemonset.<\/p>\n<p>The following are the real-world use cases of Daemonset.<\/p>\n<ol>\n<li><strong>Cluster Log Collection:<\/strong> Running a log collector on every node to centralize <a href=\"https:\/\/devopscube.com\/kubernetes-logging-tutorial\/\">Kubernetes logging<\/a> data. Eg:\u200a \u200a<a href=\"https:\/\/devopscube.com\/setup-efk-stack-on-kubernetes\/\">fluentd<\/a>\u200a,\u200alogstash, fluentbit<\/li>\n<li><strong>Cluster Monitoring:<\/strong> Deploy monitoring agents, such as <a href=\"https:\/\/devopscube.com\/node-exporter-kubernetes\/\">Prometheus Node Exporter<\/a>, on every node in the cluster to collect and expose node-level metrics. This way <a href=\"https:\/\/devopscube.com\/setup-prometheus-monitoring-on-kubernetes\/\">prometheus<\/a> gets all the required worker node metrics.<\/li>\n<li><strong>Security and Compliance:<\/strong> Running CIS Benchmarks on every node using tools like <a href=\"https:\/\/devopscube.com\/kube-bench-guide\/\" rel=\"noreferrer noopener\">kube-bench<\/a>. Also deploy security agents, such as intrusion detection systems or vulnerability scanners, on specific nodes that require additional security measures. For example,  nodes that handle PCI, and PII-compliant data.<\/li>\n<li><strong>Storage Provisioning: <\/strong>Running a storage plugin on every node to provide a shared storage system to the entire cluster.<\/li>\n<li><strong>Network Management:<\/strong> Running a network plugin or firewall on every node to ensure consistent network policy enforcement. For example, the <a href=\"https:\/\/docs.tigera.io\/calico\/latest\/about\/?ref=devopscube.com\" rel=\"noreferrer noopener\">Calico CNI plugin <\/a>runs as a Daemonset on all the nodes.<\/li>\n<\/ol>\n<p>According to the requirements, we can deploy multiple <code>DaemonSet<\/code> for one kind of daemon, using a variety of flags or memory and CPU requests for various hardware types<\/p>\n<h2 id=\"daemonset-example\">DaemonSet Example<\/h2>\n<p>Like other Kubernetes objects, <code>DaemonSet<\/code> also gets configured by using YAML files. We need to create a manifest file that will contain all of the necessary configuration information for our <code>DaemonSet<\/code>.<\/p>\n<p>Let&#8217;s assume we want to deploy a Fluentd logging agent as a DaemonSet on all the cluster worker nodes.<\/p>\n<p>Below is a sample <code>daemonset.yaml<\/code> file that gets deployed in the logging namespace.<\/p>\n<p>You can also get the daemonset YAML examples from the <a href=\"https:\/\/github.com\/techiescamp\/kubernetes-course\/tree\/main\/daemonset?ref=devopscube.com\" rel=\"noreferrer noopener\">Kubernetes Course Github Repo<\/a><\/p>\n<pre><code class=\"language-yaml\">apiVersion: apps\/v1\nkind: DaemonSet\nmetadata:\n  name: fluentd\n  namespace: logging\n  labels:\n    app: fluentd-logging\nspec:\n  selector:\n    matchLabels:\n      name: fluentd\n  template:\n    metadata:\n      labels:\n        name: fluentd\n    spec:\n      containers:\n      - name: fluentd-elasticsearch\n        image: quay.io\/fluentd_elasticsearch\/fluentd:v2.5.2\n        resources:\n          limits:\n            memory: 200Mi\n          requests:\n            cpu: 100m\n            memory: 200Mi\n        volumeMounts:\n        - name: varlog\n          mountPath: \/var\/log\n      terminationGracePeriodSeconds: 30\n      volumes:\n      - name: varlog\n        hostPath:\n          path: \/var\/log<\/code><\/pre>\n<p>Let&#8217;s understand the manifest file.<\/p>\n<ol>\n<li><code><strong>apiVersion:<\/strong><\/code> <code>apps\/v1<\/code> for <code>DaemonSet<\/code><\/li>\n<li><code><strong>kind:<\/strong><\/code> <code>DaemonSet<\/code> such as Pod, <a href=\"https:\/\/devopscube.com\/kubernetes-deployment-tutorial\/\">Deployment<\/a>, and Service<\/li>\n<li><code><strong>metadata:<\/strong><\/code> Put the name of the <code>DaemonSet<\/code>, mention namespace, annotations, and labels. In our case <code>DaemonSet's<\/code> name is fluentd.<\/li>\n<li><code><strong>spec.selector:<\/strong><\/code> The selector for the pods is managed by the <code>DaemonSet<\/code>. This value must be a label specified in the pod template. This value is immutable.<\/li>\n<li><code><strong>spec.template:<\/strong><\/code> This is a required field that specifies a pod template for the <code>DaemonSet<\/code> to use. Along with all the required fields for containers. It has everything of pod schema except <code>apiVersion<\/code> and <code>kind<\/code>.<\/li>\n<\/ol>\n<p><code>template.metadata<\/code> will have the details about the pod and <code>template.spec<\/code> will have the schema of the pod.<\/p>\n<p>Here in the pod template, we are using <code>quay.io\/fluentd_elasticsearch\/fluentd:v2.5.2<\/code> image that will run on every node in a <a href=\"https:\/\/devopscube.com\/setup-kubernetes-cluster-kubeadm\/\">Kubernetes cluster<\/a>. Each pod would then collect logs and send the data to ElasticSearch. Added resource limit and request for the pod, also volume and volumeMount accordingly.<\/p>\n<p>We don&#8217;t provide any replica counts. It is because the replica count of DaemonSet is dynamic in nature, as it depends on the node count of the cluster.<\/p>\n<p>Let&#8217;s deploy this manifest by using the below commands. First, we will have to create a namespace and deploy the Daemonset in that namespace.<\/p>\n<pre><code class=\"language-bash\">kubectl create ns logging\n\nkubectl apply -f daemonset.yaml<\/code><\/pre>\n<p>Check the <code>DaemonSet<\/code> status and pods&#8217; status.<\/p>\n<pre><code class=\"language-bash\">kubectl get daemonset -n logging<\/code><\/pre>\n<pre><code class=\"language-bash\">kubectl get pods -n logging -o wide<\/code><\/pre>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-1-51.png\" class=\"kg-image\" alt=\"Listing Kubernetes daemonset pods\" loading=\"lazy\" width=\"540\" height=\"185\"><\/figure>\n<p>You can see Fluentd pods are running on the two available worker nodes.<\/p>\n<p>Here are some other useful commands to describe, edit, and get the <code>DaemonSet<\/code>.<\/p>\n<pre><code class=\"language-bash\">kubectl describe daemonset -n logging<\/code><\/pre>\n<pre><code class=\"language-bash\">kubectl edit daemonset -n logging<\/code><\/pre>\n<pre><code class=\"language-bash\">#shortcut for daemonset is ds\n\nkubectl get ds<\/code><\/pre>\n<h2 id=\"apply-taint-and-tolerations-for-daemonset\">Apply Taint and Tolerations For Daemonset<\/h2>\n<p><code>Taints<\/code> and <code>Tolerations<\/code> are the Kubernetes feature that allows you to ensure that pods are not placed on inappropriate nodes.  We taint the nodes and add tolerations in the pod schema.<\/p>\n<pre><code class=\"language-bash\">kubectl taint nodes node1 key1=value1:&lt;Effect&gt;<\/code><\/pre>\n<p>There are 3 effects:<\/p>\n<ol>\n<li><strong><code>NoSchedule<\/code><\/strong>: Kubernetes scheduler will only allow scheduling pods that have tolerations for the tainted nodes.<\/li>\n<li><strong><code>PreferNoSchedule:<\/code><\/strong> Kubernetes scheduler will try to avoid scheduling pods that don\u2019t have tolerations for the tainted nodes.<\/li>\n<li><strong><code>NoExecute:<\/code><\/strong> Kubernetes will evict the running pods from the nodes if the pods don\u2019t have tolerations for the tainted nodes.<\/li>\n<\/ol>\n<p>Below, I&#8217;m tainting one of the nodes with key app and value monitoring and the effect is <code>NoExecute<\/code>. We don&#8217;t want <code>DaemonSet<\/code> to run the pod on this particular node.<\/p>\n<pre><code class=\"language-bash\">kubectl taint node k8s-worker-2 app=fluentd-logging:NoExecute<\/code><\/pre>\n<p>Now adding toleration like this in our <code>daemonset.yaml<\/code><\/p>\n<pre><code class=\"language-yaml\">spec:\n  tolerations:\n  - key: app\n    value: fluentd-logging\n    operator: Equal\n    effect: NoExecute\n  containers:\n  -----\n  -----<\/code><\/pre>\n<p>As you will update the <code>DaemonSet<\/code>, you will see that one pod got deleted which was running on the node <code>k8s-worker-2<\/code>. <code>DaemonSet<\/code> now won&#8217;t schedule any pod on this node.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-2-48.png\" class=\"kg-image\" alt=\"daemonset taint and toleration\" loading=\"lazy\" width=\"612\" height=\"233\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-2-48.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-2-48.png 612w\"><\/figure>\n<h2 id=\"using-nodeselector-for-daemonset-pods\">Using Nodeselector For Daemonset Pods<\/h2>\n<p>We can use <code>nodeSelector<\/code> to run the pods on some specific nodes. <code>DaemonSet<\/code> controller will create Pods on nodes that match the node selector&#8217;s key and value<\/p>\n<p>First, you need to add a label to the node.<\/p>\n<pre><code class=\"language-bash\">kubectl label node &lt;node-name&gt; key=value<\/code><\/pre>\n<p>For example, let&#8217;s say you want to label a node as <code>type=platform-tools<\/code>, you can use the following command.<\/p>\n<pre><code class=\"language-bash\">kubectl label node k8s-worker-1 type=platform-tools<\/code><\/pre>\n<p>Now, to apply a nodeSelector to a Daemonset, under the spec section, add the <strong>nodeSelector<\/strong> with the key and value as shown below.<\/p>\n<pre><code class=\"language-yaml\">spec:\n  nodeSelector:\n    &lt;key&gt;: &lt;value&gt;<\/code><\/pre>\n<p>The following image shows the Daemonset YAML with the <strong>nodeSelector<\/strong> spec highlighter in yellow.<\/p>\n<figure class=\"kg-card kg-image-card kg-card-hascaption\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-3-53.png\" class=\"kg-image\" alt=\"Daemonset nodeselector Example\" loading=\"lazy\" width=\"596\" height=\"705\"><figcaption><span style=\"white-space: pre-wrap;\">Click to view in HD<\/span><\/figcaption><\/figure>\n<h2 id=\"daemonset-node-affinity\">Daemonset Node Affinity<\/h2>\n<p>We can also achieve more fine-grained control over how nodes are selected using <code>Node affinity<\/code>. <code>DaemonSet<\/code> controller will create Pods on nodes that match <code>Node affinity<\/code>.<\/p>\n<p><code>Node affinity<\/code> is conceptually similar to <code>nodeSelector<\/code>, allowing you to constrain which nodes your pod can be scheduled on based on node labels. There are two types of node affinity:<\/p>\n<ol>\n<li><code>requiredDuringSchedulingIgnoredDuringExecution<\/code>: The scheduler can&#8217;t schedule the Pod unless the rule is met. This functions like <code>nodeSelector<\/code>, but with a more expressive syntax.<\/li>\n<li><code>preferredDuringSchedulingIgnoredDuringExecution<\/code>: The scheduler tries to find a node that meets the rule. If a matching node is not available, the scheduler still schedules the Pod.<\/li>\n<\/ol>\n<p>We can add an affinity like this to our manifest<\/p>\n<pre><code class=\"language-yaml\">spec:\n  affinity:\n    nodeAffinity:\n      requiredDuringSchedulingIgnoredDuringExecution:\n        nodeSelectorTerms:\n        - matchFields:\n          - key: key-name\n            operator: In\n            values:\n            - value-name<\/code><\/pre>\n<p>The Pods are only allowed to run on nodes that have the key and values mentioned in the <code>matchFields<\/code> section.<\/p>\n<p>The following Daemonset YAML uses both Affinity rules highlighted in bold. Required rules for node label and a preferred rule to select a node with instance label instance type <strong>t2.large<\/strong><\/p>\n<pre><code class=\"language-yaml\">apiVersion: apps\/v1\nkind: DaemonSet\nmetadata:\n  name: fluentd\n  namespace: logging\n  labels:\n    app: fluentd-logging\nspec:\n  selector:\n    matchLabels:\n      name: fluentd\n  template:\n    metadata:\n      labels:\n        name: fluentd\n    spec:\n      affinity:\n        nodeAffinity:\n          requiredDuringSchedulingIgnoredDuringExecution:\n            nodeSelectorTerms:\n            - matchExpressions:\n              - key: type\n                operator: In\n                values:\n                - platform-tools\n          preferredDuringSchedulingIgnoredDuringExecution:\n          - weight: 1\n            preference:\n              matchExpressions:\n              - key: instance-type\n                operator: In\n                values:\n                - t2.large\n      containers:\n      - name: fluentd-elasticsearch\n        image: quay.io\/fluentd_elasticsearch\/fluentd:v2.5.2\n        resources:\n          limits:\n            memory: 200Mi\n          requests:\n            cpu: 100m\n            memory: 200Mi\n        volumeMounts:\n        - name: varlog\n          mountPath: \/var\/log\n      terminationGracePeriodSeconds: 30\n      volumes:\n      - name: varlog\n        hostPath:\n          path: \/var\/log<\/code><\/pre>\n<h2 id=\"daemonset-privileged-access\">Daemonset Privileged Access<\/h2>\n<p>There are use cases where you need privileged access to the host from the Deamonset pod. For example, the <strong>calico CNI daemoset requires<\/strong> host-level access for its networking requirements because it needs to modify IPtables.<\/p>\n<p>Another example is the Kube-proxy daemonset. It also requires privileged access.<\/p>\n<p>You can use <strong>securityContext<\/strong> in the Pod Spec to allow or deny Privileged access. A security context defines privilege and access control settings for a Pod or Container. To specify security settings for a pod, you need to include the <code>securityContext<\/code> field in the pod manifest.<\/p>\n<pre><code class=\"language-yaml\">spec:\n  securityContext:\n    runAsNonRoot: true\n  containers:\n  - name: fluentd-elasticsearch\n    image: quay.io\/fluentd_elasticsearch\/fluentd:v2.5.2\n    securityContext:\n      allowPrivilegeEscalation: false\n    -------<\/code><\/pre>\n<p>The first is a pod-level security context defined by the object, and the second is a SecurityContext defined by the individual container.<\/p>\n<ol>\n<li><strong><code>allowPrivilegeEscalation<\/code><\/strong>: AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process.<\/li>\n<li><strong><code>privileged<\/code><\/strong>: Run the container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host.<\/li>\n<li><strong><code>runAsNonRoot<\/code><\/strong>: Indicates that the container must run as a non-root user.<\/li>\n<li><strong><code>runAsUser<\/code><\/strong>: The UID to run the entry point of the container process.<\/li>\n<li><strong><code>runAsGroup<\/code><\/strong>: The GID to run the entry point of the container process.<\/li>\n<\/ol>\n<h2 id=\"rolling-update-rollback-and-deleting-daemonset\">Rolling Update, Rollback, and Deleting Daemonset<\/h2>\n<p>Let&#8217;s look at the concepts for updating, deleting, and rolling back Daemonset deployments.<\/p>\n<h3 id=\"rolling-update\">Rolling Update<\/h3>\n<p><code>DaemonSet<\/code> has two update strategy types:<\/p>\n<ol>\n<li><code><strong>OnDelete<\/strong><\/code>: Using the <code>OnDelete<\/code> strategy, the <code>DaemonSet<\/code> pod will only be created when we manually delete any pod.<\/li>\n<li><code><strong>RollingUpdate<\/strong><\/code>:  This is the default update strategy. Using the <code>RollingUpdate<\/code> strategy, whenever you update a <code>DaemonSet<\/code> template, old pods will be killed, and new pods will be created automatically. At most one pod of the <code>DaemonSet<\/code> will be running.<\/li>\n<\/ol>\n<pre><code class=\"language-yaml\">spec:\n  updateStrategy:\n    type: RollingUpdate\n    rollingUpdate:\n      maxUnavailable: 1<\/code><\/pre>\n<h3 id=\"rollback\">Rollback<\/h3>\n<p>We can rollback the <code>DaemonSet<\/code> by using the below command:<\/p>\n<pre><code class=\"language-bash\">kubectl rollout undo daemonset &lt;daemonset-name&gt;<\/code><\/pre>\n<p>To check all the revisions of the <code>DaemonSet<\/code>:<\/p>\n<pre><code class=\"language-bash\">kubectl rollout history daemonset &lt;daemonset-name&gt;<\/code><\/pre>\n<p>If you want to rollback to the specific revision, then use:<\/p>\n<pre><code>kubectl rollout undo daemonset &lt;daemonset-name&gt; --to-revision=&lt;revision&gt;<\/code><\/pre>\n<h3 id=\"deletion\">Deletion<\/h3>\n<pre><code class=\"language-bash\">kubectl delete daemonset &lt;daemonset-name&gt;<\/code><\/pre>\n<p>Use <code>--cascade=false<\/code> if you want the pods to be running on the node.<\/p>\n<h2 id=\"daemonset-pod-priority\">DaemonSet Pod Priority<\/h2>\n<p><a href=\"https:\/\/devopscube.com\/pod-priorityclass-preemption\/\" rel=\"noreferrer noopener\">Kubernetes Pod Priority<\/a> determines the importance of a pod over another pod.<\/p>\n<p>We can set a higher pod <code>PriorityClass<\/code> to the <code>DaemonSet<\/code> in case you are running critical system components as a Deamonset. This ensures that the daemonset pods are not preempted by lower-priority or less critical pods.<\/p>\n<p><code>PriorityClass<\/code> is used to define the priority of the pod. <code>PriorityClass<\/code> objects can have any 32-bit integer value smaller than or equal to 1 billion<strong><em>.<\/em><\/strong> The higher the value, the higher will be the priority.<\/p>\n<p>Create a priority class and that to DaemonSet pod spec<\/p>\n<pre><code class=\"language-yaml\">apiVersion: scheduling.k8s.io\/v1\nkind: PriorityClass\nmetadata:\n  name: high-priority\nvalue: 100000\nglobalDefault: false\ndescription: \"daemonset priority class\"<\/code><\/pre>\n<p>Check by running this command<\/p>\n<pre><code class=\"language-bash\">kubectl get priorityClass<\/code><\/pre>\n<p>We need to add the <code>priorityClass<\/code> in our <code>daemonset.yaml<\/code><\/p>\n<pre><code class=\"language-yaml\">spec:\n  priorityClassName: high-priority\n  containers:\n  ------\n  ------\n  terminationGracePeriodSeconds: 30\n  volumes:\n  ------<\/code><\/pre>\n<p>If you look at Kube-Proxy &amp; Cluser CNI (Calico) Daemonsets, it has the <a href=\"https:\/\/devopscube.com\/pod-priorityclass-preemption\/\" rel=\"noreferrer\">priority class<\/a> set to <strong>system-node-critical which<\/strong> has the highest priority. It is a built-in <code>PriorityClass<\/code> in Kubernetes that is applied to pods that should not be evicted in any circumstances.<\/p>\n<h2 id=\"daemonset-troubleshooting\">Daemonset Troubleshooting<\/h2>\n<p>A <code>DaemonSet<\/code> is called unhealthy when any pod is not running on the node. The generic reason for that is pod status is <code>crashloopbackoff<\/code>, the pod is in the <code>pending<\/code> state or in an <code>error<\/code> state. <\/p>\n<p>In such cases, the initial step to check the logs of the Pods using the following command.<\/p>\n<pre><code class=\"language-bash\">kubecttl -n &lt;NAMESPACE&gt; logs &lt;POD NAME&gt; -f<\/code><\/pre>\n<p>From the output, we can fix this by:<\/p>\n<ol>\n<li>Pod might be running out of resources. We can lower the requested CPU and memory of the <code>DaemonSet<\/code>.<\/li>\n<li>We can move some pods off of the affected nodes to free up resources. Use taints and tolerations to prevent the pods from running on certain nodes.<\/li>\n<li>We can scale up the nodes as well.<\/li>\n<\/ol>\n<p>You can perform normal <a href=\"https:\/\/devopscube.com\/troubleshoot-kubernetes-pods\/\">pod troubleshooting<\/a> steps to figure out the issues.<\/p>\n<h2 id=\"daemonset-best-practices\">DaemonSet Best Practices<\/h2>\n<p>Below are some practices that we must follow:<\/p>\n<ol>\n<li><code>DaemonSet<\/code> pods must have Restart Policy set to <code>Always<\/code> or <code>unspecified<\/code><\/li>\n<li>Separate each <code>DaemonSet<\/code> into its own namespace to ensure clear isolation and easier resource management.<\/li>\n<li>It is better to use <code>preferredDuringSchedulingIgnoredDuringExecution<\/code> instead of <code>requiredDuringSchedulingIgnoredDuringExecution<\/code> because it is impossible to start new Pods if the number of nodes required for the new Pods is larger than the number of nodes available.<\/li>\n<li><code>DaemonSet<\/code> priority should be 10000. It is not advised for <code>DaemonSet<\/code> Pods to be evicted from cluster nodes<\/li>\n<li>We must specify a pod selector that matches the labels of the <code>.spec.template.<\/code><\/li>\n<li>We can use <code>minReadySeconds<\/code> in pod schema. It tells Kubernetes how long it should wait until it creates the next pod. This property ensures that all application pods are in the ready state during the update.<\/li>\n<li>Use proper labels and selectors to deploy the DaemonSets on specific nodes.<\/li>\n<li>DaemonSet resource request\/limit should be kept as minimal as possible, because they run on each node.<\/li>\n<li>Use the <code>PodDisruptionBudgets<\/code> to ensure the controlled eviction of Daemonset pods.<\/li>\n<\/ol>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>In this <a href=\"https:\/\/devopscube.com\/kubernetes-tutorials-beginners\/\">kubernetes tutorial<\/a>, we learned about Kubernetes <code>DaemonSets<\/code>. <code>DaemonSet<\/code> is a great way to manage and deploy applications in a clustered environment.<\/p>\n<p>We have seen how can we create the <code>DaemonSet<\/code> along with its use case. We can configure them to create pods on certain nodes using tolerations and node selectors and perform rolling updates on them in a controlled manner.<\/p>\n<p>Further, we have talked about unhealthy <code>DaemonSet<\/code> and their best practices. Also, If you are preparing for <a href=\"https:\/\/devopscube.com\/cka-exam-study-guide\/\">CKA certification<\/a>, Daemonset is an important concept to prepare for the exam.<\/p>\n<p>If you are learning Kubernetes check out the <a href=\"https:\/\/devopscube.com\/learn-kubernetes-complete-roadmap\/\">Kubernetes learning roadmap<\/a> to deepen your Kubernetes knowledge.<\/p>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/kubernetes-daemonset\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes Daemonset: A Comprehensive Guide \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/kubernetes-daemonset\/<\/p>\n","protected":false},"author":1,"featured_media":509,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-508","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/508","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=508"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/508\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/509"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=508"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=508"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=508"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}