DaemonSet

What is DaemonSet in Kubernetes?

A DaemonSet makes sure that the pods getting created in all the Kubernetes nodes in the cluster.

For example, I have three nodes server1, server2, server3. When I create nginx pods in my kubernetes cluster as DaemonSet as Kind, then the pods will be created in all three nodes server1, server2, and server3.

kubectl get nodes
NAME        STATUS   ROLES           AGE    VERSION 
iam7hills   Ready    control-plane   106m   v1.28.2
server1     Ready    <none>          93m    v1.28.2                  #NODE 1
server2     Ready    <none>          93m    v1.28.2                  #NODE 2
server3     Ready    <none>          93m    v1.28.2                  #NODE 3

daemonset.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemondemo
spec:
  selector:
    matchLabels:
      name: nginxdemo
  template:
    metadata:
      labels:
        name: nginxdemo
    spec:
      containers:
      - name: testpods
        image: iam7hills/learnkubernetes:podsdemo-1.0

If I run the above yaml, the scheduler will take care of scheduling to run pods in all three nodes in the cluster.

kubectl get pods -o wide
NAME               READY   STATUS    RESTARTS   AGE   IP                NODE   
daemondemo-cls4r   1/1     Running   0          6s    192.168.116.134   server1  
daemondemo-rbjs6   1/1     Running   0          6s    192.168.141.195   server3 
daemondemo-rfzbx   1/1     Running   0          6s    192.168.179.73    server2 

How it works?
    It uses the spec.selector label identifier to find the matching pods running inside the cluster. In our above example, DaemonSet finds all the matching Labels with the name "nginxdemo" having the labels as nginxdemo in the pod spec.template.

How to restrict daemonSet to run in specific nodes?

We can do this in two different methods
    1. nodeName
    2. nodeSelector

1. nodeName
    If you want to create a pod on a specific node and ignore all other nodes, then you can specify nodeName: <node-name> under the template.spec like below.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemondemo
spec:
  selector:
    matchLabels:
      name: nginxdemo
  template:
    metadata:
      labels:
        name: nginxdemo
    spec:
      nodeName: server2   # This pod will run only in the node server2
      containers:
      - name: testpods
        image: iam7hills/learnkubernetes:podsdemo-1.0

kubectl apply -f daemonset.yaml
daemonset.apps/daemondemo configured

kubectl get pods -o wide
NAME               READY   STATUS    RESTARTS   AGE   IP NODE    Node
daemondemo-q8bg8   1/1     Running   0          31s   192.168.179.74   server2

2. nodeSelector

Requirements: My requirements is to create pods for specific nodes, where the node label name is "nginxlabel". In this example, I am going to create a label called nginxlabel and assign it to node server1.

currently no label is applied to any nodes as below
kubectl get nodes --show-labels
NAME        STATUS   ROLES           AGE    VERSION   LABELS
iam7hills   Ready    control-plane   3h9m   v1.28.2  
server1     Ready    <none>          177m   v1.28.2   
server2     Ready    <none>          177m   v1.28.2   
server3     Ready    <none>          177m   v1.28.2  

To apply label to the server1
kubectl label nodes server1 nodelabelname=nginxlabel
node/server1 labeled

kubectl get nodes --show-labels
NAME        STATUS   ROLES           AGE     VERSION   LABELS
iam7hills   Ready    control-plane   3h13m   v1.28.2   
server1     Ready    <none>          3h1m    v1.28.2   nodelabelname=nginxlabel
server2     Ready    <none>          3h1m    v1.28.2
server3     Ready    <none>          3h1m    v1.28.2

cat daemonset.yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemondemo
spec:
  selector:
    matchLabels:
      name: nginxdemo
  template:
    metadata:
      labels:
        name: nginxdemo
    spec:
      containers:
      - name: testpods
        image: iam7hills/learnkubernetes:podsdemo-1.0
      nodeSelector:
        nodelabelname: nginxlabel

kubectl create -f daemonset.yaml
daemonset.apps/daemondemo created

kubectl get pods -o wide
NAME               READY   STATUS    RESTARTS   AGE   IP                NODE 
daemondemo-mf5ld   1/1     Running   0          11s   192.168.116.135   server1