Belajar Kubernetes - Episode 13 - Pengenalan dan Penjelasan DaemonSet

Belajar Kubernetes - Episode 13 - Pengenalan dan Penjelasan DaemonSet

Di episode ini kita akan coba bahas important Kubernetes controller yaitu DaemonSet. Kita akan mempelajari bagaimana DaemonSet memastikan copy dari Pod berjalan di semua (atau beberapa) node di cluster.

Arman Dwi Pangestu
Arman Dwi PangestuMarch 16, 2026
0 views
8 min read

Pendahuluan

Catatan

Untuk kalian yang ingin membaca episode sebelumnya, bisa click thumbnail episode 12 di bawah ini

Episode 12Episode 12

Di episode sebelumnya kita sudah belajar tentang ReplicaSet, modern replacement untuk ReplicationController dengan enhanced selector capability. Selanjutnya di episode 13 kali ini, kita akan coba bahas tipe controller yang berbeda yaitu DaemonSet.

Catatan: Disini saya akan menggunakan Kubernetes Cluster yang di install melalui K3s.

Tidak seperti ReplicaSet yang maintain jumlah Pod replica yang spesifik, DaemonSet memastikan bahwa copy dari Pod berjalan di semua (atau beberapa) node di cluster kalian. Ini sangat berguna untuk menjalankan cluster-wide service seperti log collector, monitoring agent, atau network plugin.

Apa Itu DaemonSet?

DaemonSet memastikan bahwa semua (atau beberapa) node menjalankan copy dari Pod. Saat node ditambahkan ke cluster, Pod otomatis ditambahkan ke node tersebut. Saat node dihapus dari cluster, Pod tersebut di-garbage collected.

Bayangkan DaemonSet seperti system daemon di Linux - dia berjalan di setiap machine untuk menyediakan system-level service. Di Kubernetes, DaemonSet menjalankan Pod di setiap node untuk menyediakan node-level service.

Karakteristik kunci DaemonSet:

  • Satu Pod per node - Menjalankan tepat satu Pod di setiap node (by default)
  • Automatic scheduling - Node baru otomatis mendapat DaemonSet Pod
  • Automatic cleanup - Pod dihapus saat node dihapus
  • Node selection - Bisa target node spesifik menggunakan node selector atau affinity
  • System-level service - Perfect untuk cluster-wide infrastructure component

Kenapa Kita Butuh DaemonSet?

DaemonSet dirancang untuk workload yang perlu berjalan di setiap node di cluster:

  • Log collection - Menjalankan log collector seperti Fluentd atau Filebeat di setiap node
  • Monitoring - Menjalankan monitoring agent seperti Prometheus Node Exporter di setiap node
  • Network plugin - Menjalankan CNI plugin atau network proxy di setiap node
  • Storage daemon - Menjalankan storage plugin seperti Ceph atau GlusterFS di setiap node
  • Security agent - Menjalankan security scanning atau compliance tool di setiap node
  • Node maintenance - Menjalankan cleanup atau maintenance task di setiap node

Tanpa DaemonSet, kalian perlu:

  • Manually create Pod di setiap node
  • Track node mana yang punya Pod
  • Manually add Pod saat node baru join
  • Manually remove Pod saat node leave

DaemonSet vs ReplicaSet

Mari kita pahami perbedaan kunci nya:

AspekDaemonSetReplicaSet
Pod countSatu per nodeFixed number across cluster
SchedulingAutomatic per nodeScheduler decide placement
Use caseNode-level serviceApplication replica
ScalingScale dengan nodeManual scaling
Node additionAuto-create PodNo automatic action
Node removalAuto-remove PodNo automatic action

Contoh scenario:

  • DaemonSet: Kalian ingin menjalankan log collector di setiap node untuk collect log dari semua container
  • ReplicaSet: Kalian ingin menjalankan 3 replica dari web application kalian, distributed across available node

Membuat DaemonSet

Mari kita buat basic DaemonSet:

Contoh 1: Basic DaemonSet

Buat file bernama daemonset-basic.yml:

Kubernetesdaemonset-basic.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: nginx-daemonset
    labels:
        app: nginx-daemon
spec:
    selector:
        matchLabels:
            app: nginx-daemon
    template:
        metadata:
            labels:
                app: nginx-daemon
        spec:
            containers:
                - name: nginx
                  image: nginx:1.25
                  ports:
                      - containerPort: 80

Apply konfigurasi:

Kubernetesbash
sudo kubectl apply -f daemonset-basic.yml

Verifikasi DaemonSet dibuat:

Kubernetesbash
sudo kubectl get daemonset

Atau gunakan shorthand:

Kubernetesbash
sudo kubectl get ds

Output:

Kubernetesbash
NAME               DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
nginx-daemonset    3         3         3       3            3           <none>          30s

DESIRED count match dengan jumlah node di cluster kalian.

Cek Pod:

Kubernetesbash
sudo kubectl get pods -o wide

Output:

Kubernetesbash
NAME                    READY   STATUS    RESTARTS   AGE   NODE
nginx-daemonset-abc12   1/1     Running   0          30s   node1
nginx-daemonset-def34   1/1     Running   0          30s   node2
nginx-daemonset-ghi56   1/1     Running   0          30s   node3

Perhatikan bahwa ada tepat satu Pod per node.

Melihat Detail DaemonSet

Untuk melihat informasi detail tentang DaemonSet:

Kubernetesbash
sudo kubectl describe ds nginx-daemonset

Output:

Kubernetesbash
Name:           nginx-daemonset
Selector:       app=nginx-daemon
Node-Selector:  <none>
Labels:         app=nginx-daemon
Annotations:    <none>
Desired Number of Nodes Scheduled: 3
Current Number of Nodes Scheduled: 3
Number of Nodes Scheduled with Up-to-date Pods: 3
Number of Nodes Scheduled with Available Pods: 3
Number of Nodes Misscheduled: 0
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=nginx-daemon
  Containers:
   nginx:
    Image:        nginx:1.25
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From                  Message
  ----    ------            ----  ----                  -------
  Normal  SuccessfulCreate  2m    daemonset-controller  Created pod: nginx-daemonset-abc12
  Normal  SuccessfulCreate  2m    daemonset-controller  Created pod: nginx-daemonset-def34
  Normal  SuccessfulCreate  2m    daemonset-controller  Created pod: nginx-daemonset-ghi56

Node Selection dengan DaemonSet

By default, DaemonSet berjalan di semua node. Kalian bisa kontrol node mana yang menjalankan DaemonSet Pod menggunakan:

Cara 1: Node Selector

Jalankan DaemonSet hanya di node dengan label spesifik:

Kubernetesdaemonset-node-selector.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: ssd-monitor
spec:
    selector:
        matchLabels:
            app: ssd-monitor
    template:
        metadata:
            labels:
                app: ssd-monitor
        spec:
            nodeSelector:
                disktype: ssd
            containers:
                - name: monitor
                  image: nginx:1.25

DaemonSet ini hanya berjalan di node yang dilabel dengan disktype: ssd.

Pertama, label node:

Kubernetesbash
sudo kubectl label nodes node1 disktype=ssd

Apply DaemonSet:

Kubernetesbash
sudo kubectl apply -f daemonset-node-selector.yml

Cek Pod:

Kubernetesbash
sudo kubectl get pods -o wide

Kalian akan melihat Pod hanya di node dengan label disktype: ssd.

Cara 2: Node Affinity

Node selection yang lebih flexible menggunakan affinity rule:

Kubernetesdaemonset-affinity.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: production-monitor
spec:
    selector:
        matchLabels:
            app: prod-monitor
    template:
        metadata:
            labels:
                app: prod-monitor
        spec:
            affinity:
                nodeAffinity:
                    requiredDuringSchedulingIgnoredDuringExecution:
                        nodeSelectorTerms:
                            - matchExpressions:
                                  - key: environment
                                    operator: In
                                    values:
                                        - production
                                        - staging
            containers:
                - name: monitor
                  image: nginx:1.25

DaemonSet ini berjalan di node dimana environment adalah production atau staging.

Cara 3: Taint dan Toleration

Jalankan DaemonSet di node dengan taint spesifik:

Kubernetesdaemonset-tolerations.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: special-daemon
spec:
    selector:
        matchLabels:
            app: special-daemon
    template:
        metadata:
            labels:
                app: special-daemon
        spec:
            tolerations:
                - key: node-role.kubernetes.io/control-plane
                  operator: Exists
                  effect: NoSchedule
            containers:
                - name: daemon
                  image: nginx:1.25

DaemonSet ini bisa berjalan di control plane node (yang normally punya taint preventing regular Pod).

Contoh Praktis

Contoh 1: Log Collector DaemonSet

Contoh realistic menjalankan Fluentd log collector di setiap node:

Kubernetesfluentd-daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: fluentd
    namespace: kube-system
    labels:
        app: fluentd
spec:
    selector:
        matchLabels:
            app: fluentd
    template:
        metadata:
            labels:
                app: fluentd
        spec:
            tolerations:
                - key: node-role.kubernetes.io/control-plane
                  effect: NoSchedule
            containers:
                - name: fluentd
                  image: fluent/fluentd:v1.16
                  resources:
                      limits:
                          memory: 200Mi
                      requests:
                          cpu: 100m
                          memory: 200Mi
                  volumeMounts:
                      - name: varlog
                        mountPath: /var/log
                      - name: varlibdockercontainers
                        mountPath: /var/lib/docker/containers
                        readOnly: true
            volumes:
                - name: varlog
                  hostPath:
                      path: /var/log
                - name: varlibdockercontainers
                  hostPath:
                      path: /var/lib/docker/containers

DaemonSet ini:

  • Berjalan di kube-system namespace
  • Tolerate control plane taint
  • Mount host directory untuk access log
  • Set resource limit

Contoh 2: Monitoring Agent DaemonSet

Menjalankan Prometheus Node Exporter di setiap node:

Kubernetesnode-exporter-daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: node-exporter
    namespace: monitoring
    labels:
        app: node-exporter
spec:
    selector:
        matchLabels:
            app: node-exporter
    template:
        metadata:
            labels:
                app: node-exporter
        spec:
            hostNetwork: true
            hostPID: true
            containers:
                - name: node-exporter
                  image: prom/node-exporter:latest
                  args:
                      - --path.procfs=/host/proc
                      - --path.sysfs=/host/sys
                      - --collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($|/)
                  ports:
                      - containerPort: 9100
                        hostPort: 9100
                        name: metrics
                  resources:
                      limits:
                          memory: 180Mi
                      requests:
                          cpu: 100m
                          memory: 180Mi
                  volumeMounts:
                      - name: proc
                        mountPath: /host/proc
                        readOnly: true
                      - name: sys
                        mountPath: /host/sys
                        readOnly: true
            volumes:
                - name: proc
                  hostPath:
                      path: /proc
                - name: sys
                  hostPath:
                      path: /sys

DaemonSet ini:

  • Gunakan host network dan PID namespace
  • Expose metric di port 9100
  • Mount host /proc dan /sys untuk system metric

Contoh 3: Network Plugin DaemonSet

Menjalankan network plugin di setiap node:

Kubernetesnetwork-plugin-daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: kube-proxy
    namespace: kube-system
    labels:
        k8s-app: kube-proxy
spec:
    selector:
        matchLabels:
            k8s-app: kube-proxy
    updateStrategy:
        type: RollingUpdate
        rollingUpdate:
            maxUnavailable: 1
    template:
        metadata:
            labels:
                k8s-app: kube-proxy
        spec:
            priorityClassName: system-node-critical
            hostNetwork: true
            tolerations:
                - operator: Exists
                  effect: NoSchedule
            containers:
                - name: kube-proxy
                  image: registry.k8s.io/kube-proxy:v1.28.0
                  command:
                      - /usr/local/bin/kube-proxy
                      - --config=/var/lib/kube-proxy/config.conf
                  securityContext:
                      privileged: true
                  volumeMounts:
                      - name: kube-proxy
                        mountPath: /var/lib/kube-proxy
            volumes:
                - name: kube-proxy
                  configMap:
                      name: kube-proxy

DaemonSet ini:

  • Berjalan dengan system-node-critical priority
  • Gunakan host network
  • Tolerate semua taint
  • Berjalan di privileged mode

Update DaemonSet

DaemonSet support dua update strategy:

OnDelete Strategy

Pod hanya di-update saat manually deleted:

Kubernetesyml
spec:
    updateStrategy:
        type: OnDelete

Dengan strategy ini:

  1. Update DaemonSet
  2. Manually delete Pod
  3. Pod baru dibuat dengan updated template

RollingUpdate Strategy (Default)

Pod otomatis di-update secara rolling fashion:

Kubernetesyml
spec:
    updateStrategy:
        type: RollingUpdate
        rollingUpdate:
            maxUnavailable: 1

Dengan strategy ini:

  1. Update DaemonSet
  2. Kubernetes otomatis update Pod satu per satu
  3. Respect maxUnavailable setting

Contoh update DaemonSet:

Kubernetesbash
# Edit DaemonSet
sudo kubectl edit ds nginx-daemonset
 
# Atau update file YAML dan apply
sudo kubectl apply -f daemonset-basic.yml

Watch rolling update:

Kubernetesbash
sudo kubectl rollout status ds nginx-daemonset

Menghapus DaemonSet

Cara 1: Hapus DaemonSet dan Pod

Kubernetesbash
sudo kubectl delete ds nginx-daemonset

Ini menghapus DaemonSet dan semua Pod nya.

Cara 2: Hapus DaemonSet tapi Jaga Pod

Kubernetesbash
sudo kubectl delete ds nginx-daemonset --cascade=orphan

Ini hanya menghapus DaemonSet, membiarkan Pod berjalan sebagai orphan.

Use Case Umum

Use Case 1: Cluster Monitoring

Deploy monitoring agent untuk collect metric dari setiap node:

Kubernetesmonitoring-daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: monitoring-agent
spec:
    selector:
        matchLabels:
            app: monitoring
    template:
        metadata:
            labels:
                app: monitoring
        spec:
            containers:
                - name: agent
                  image: monitoring-agent:latest
                  resources:
                      limits:
                          memory: 200Mi
                      requests:
                          cpu: 100m
                          memory: 100Mi

Use Case 2: Log Aggregation

Collect log dari semua node:

Kuberneteslog-collector-daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: log-collector
spec:
    selector:
        matchLabels:
            app: logs
    template:
        metadata:
            labels:
                app: logs
        spec:
            containers:
                - name: collector
                  image: log-collector:latest
                  volumeMounts:
                      - name: logs
                        mountPath: /var/log
            volumes:
                - name: logs
                  hostPath:
                      path: /var/log

Use Case 3: Security Scanning

Jalankan security agent di setiap node:

Kubernetessecurity-scanner-daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
    name: security-scanner
spec:
    selector:
        matchLabels:
            app: security
    template:
        metadata:
            labels:
                app: security
        spec:
            containers:
                - name: scanner
                  image: security-scanner:latest
                  securityContext:
                      privileged: true

Kesalahan Umum dan Pitfall

Kesalahan 1: Tidak Set Resource Limit

DaemonSet Pod berjalan di setiap node, jadi resource usage multiply:

Problem: Tanpa limit, DaemonSet Pod bisa consume semua node resource.

Solusi: Selalu set resource request dan limit:

Kubernetesyml
resources:
    requests:
        cpu: 100m
        memory: 128Mi
    limits:
        cpu: 200m
        memory: 256Mi

Kesalahan 2: Menggunakan DaemonSet untuk Application Workload

Problem: Menggunakan DaemonSet untuk regular application yang tidak perlu berjalan di setiap node.

Solusi: Gunakan Deployment atau ReplicaSet untuk application workload. Gunakan DaemonSet hanya untuk node-level service.

Kesalahan 3: Tidak Pertimbangkan Node Taint

Problem: DaemonSet Pod tidak schedule di tainted node.

Solusi: Tambahkan appropriate toleration:

Kubernetesyml
tolerations:
    - key: node-role.kubernetes.io/control-plane
      effect: NoSchedule

Kesalahan 4: Lupa Host Path Permission

Problem: DaemonSet tidak bisa access host directory karena permission.

Solusi: Gunakan appropriate security context dan volume mount:

Kubernetesyml
securityContext:
    privileged: true
volumeMounts:
    - name: host-path
      mountPath: /host
      readOnly: true

Kesalahan 5: Tidak Gunakan Update Strategy

Problem: Manual Pod deletion required untuk update.

Solusi: Gunakan RollingUpdate strategy:

Kubernetesyml
updateStrategy:
    type: RollingUpdate
    rollingUpdate:
        maxUnavailable: 1

Best Practice

Set Appropriate Resource Limit

Karena DaemonSet berjalan di setiap node, resource usage di-multiply:

Kubernetesyml
resources:
    requests:
        cpu: 100m
        memory: 128Mi
    limits:
        cpu: 200m
        memory: 256Mi

Gunakan RollingUpdate Strategy

Enable automatic update:

Kubernetesyml
updateStrategy:
    type: RollingUpdate
    rollingUpdate:
        maxUnavailable: 1

Tambahkan Toleration untuk System Node

Allow DaemonSet berjalan di semua node including control plane:

Kubernetesyml
tolerations:
    - operator: Exists
      effect: NoSchedule

Gunakan Priority Class

Set appropriate priority untuk system DaemonSet:

Kubernetesyml
priorityClassName: system-node-critical

Implementasikan Health Check

Tambahkan Probe untuk ensure DaemonSet Pod healthy:

Kubernetesyml
livenessProbe:
    httpGet:
        path: /health
        port: 8080
    initialDelaySeconds: 30
    periodSeconds: 10
readinessProbe:
    httpGet:
        path: /ready
        port: 8080
    initialDelaySeconds: 5
    periodSeconds: 5

Gunakan Namespace Appropriately

System DaemonSet harus berjalan di system namespace:

Kubernetesyml
metadata:
    namespace: kube-system

Monitoring DaemonSet

Cek Status DaemonSet

Kubernetesbash
sudo kubectl get ds

Lihat Detail DaemonSet

Kubernetesbash
sudo kubectl describe ds nginx-daemonset

Cek DaemonSet Pod

Kubernetesbash
sudo kubectl get pods -l app=nginx-daemon -o wide

Watch DaemonSet Rollout

Kubernetesbash
sudo kubectl rollout status ds nginx-daemonset

Cek DaemonSet Event

Kubernetesbash
sudo kubectl get events --sort-by='.lastTimestamp' | grep DaemonSet

Penutup

Pada episode 13 ini, kita telah membahas DaemonSet di Kubernetes secara mendalam. Kita sudah belajar apa itu DaemonSet, bagaimana dia berbeda dari ReplicaSet, dan kapan menggunakannya untuk node-level service.

Key takeaway:

  • DaemonSet memastikan satu Pod berjalan di setiap node
  • Otomatis schedule Pod di node baru
  • Otomatis remove Pod dari deleted node
  • Perfect untuk cluster-wide service (logging, monitoring, networking)
  • Support node selection via selector, affinity, dan toleration
  • Dua update strategy: OnDelete dan RollingUpdate
  • Berbeda dari ReplicaSet yang maintain fixed replica count
  • Selalu set resource limit untuk prevent resource exhaustion
  • Gunakan toleration untuk berjalan di tainted node

DaemonSet essential untuk menjalankan infrastructure component yang perlu present di setiap node di cluster kalian. Dengan memahami DaemonSet, kalian bisa effectively deploy dan manage cluster-wide service seperti log collector, monitoring agent, dan network plugin.

Bagaimana, makin jelas kan tentang DaemonSet di Kubernetes? Di episode 14 berikutnya, kita akan membahas Job, controller yang dirancang untuk menjalankan task sampai selesai daripada keep Pod running continuously. Jadi, pastikan tetap semangat belajar dan nantikan episode selanjutnya!

Catatan

Untuk kalian yang ingin lanjut ke episode berikutnya, bisa click thumbnail episode 14 di bawah ini

Episode 14Episode 14

Related Posts