DaemonSet #

DaemonSet memastikan satu copy Pod berjalan di setiap node — atau di setiap node yang memenuhi kriteria tertentu. Ketika node baru bergabung ke cluster, DaemonSet otomatis membuat Pod di node tersebut. Ketika node dihapus, Pod-nya juga dihapus. Ini adalah resource yang tepat untuk semua kebutuhan di mana setiap node perlu menjalankan agen tertentu — log collector, monitoring agent, network plugin, atau storage driver.

Cara Kerja DaemonSet #

DaemonSet tidak menggunakan scheduler Kubernetes untuk menentukan di mana Pod berjalan. Scheduler biasa memilih node terbaik berdasarkan resource. DaemonSet lebih sederhana: satu Pod per node, titik.

Cluster dengan 4 worker node:

DaemonSet "node-exporter" (monitoring agent):
  worker-1 → Pod "node-exporter-a1b2"
  worker-2 → Pod "node-exporter-c3d4"
  worker-3 → Pod "node-exporter-e5f6"
  worker-4 → Pod "node-exporter-g7h8"

Worker node baru bergabung:
  worker-5 → Pod "node-exporter-i9j0" ← dibuat otomatis

Worker node dihapus:
  worker-3 dihapus → Pod "node-exporter-e5f6" juga hilang

Struktur Manifest DaemonSet #

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring
  labels:
    app: node-exporter
spec:
  selector:
    matchLabels:
      app: node-exporter
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1          # update satu node dalam satu waktu
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      # Akses ke filesystem dan informasi host
      hostPID: false
      hostNetwork: false         # true jika perlu akses network host langsung

      containers:
      - name: node-exporter
        image: prom/node-exporter:v1.7.0
        ports:
        - containerPort: 9100
          hostPort: 9100         # bind ke port host langsung
        args:
        - --path.rootfs=/host
        volumeMounts:
        - name: host-root
          mountPath: /host
          readOnly: true
        resources:
          requests:
            cpu: "50m"
            memory: "64Mi"
          limits:
            cpu: "200m"
            memory: "180Mi"

      volumes:
      - name: host-root
        hostPath:
          path: /                # akses ke root filesystem host

Use Case: Log Collection #

Log collector seperti Fluentd atau Promtail perlu berjalan di setiap node untuk mengumpulkan log dari semua container yang berjalan di node tersebut:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: logging
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    metadata:
      labels:
        app: fluentd
    spec:
      serviceAccountName: fluentd   # butuh permission untuk baca metadata Pod

      containers:
      - name: fluentd
        image: fluent/fluentd-kubernetes-daemonset:v1.16
        env:
        - name: FLUENT_ELASTICSEARCH_HOST
          value: "elasticsearch-service"
        volumeMounts:
        # Mount direktori log container dari host
        - 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

Use Case: Network Plugin (CNI) #

Plugin jaringan Kubernetes seperti Calico, Flannel, dan Cilium dijalankan sebagai DaemonSet. Mereka perlu berjalan di setiap node untuk mengelola network interface dan routing rules di level node.

# Contoh: Calico node agent sebagai DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: calico-node
  namespace: kube-system
spec:
  template:
    spec:
      hostNetwork: true          # perlu akses ke network namespace host
      containers:
      - name: calico-node
        image: calico/node:v3.26
        securityContext:
          privileged: true       # perlu akses tinggi untuk kelola network
        volumeMounts:
        - mountPath: /lib/modules
          name: lib-modules
          readOnly: true
        - mountPath: /run/xtables.lock
          name: xtables-lock
      volumes:
      - name: lib-modules
        hostPath:
          path: /lib/modules
      - name: xtables-lock
        hostPath:
          path: /run/xtables.lock

DaemonSet di Control Plane Node #

Secara default, DaemonSet tidak menjadwalkan Pod ke control plane node — control plane node biasanya punya taint node-role.kubernetes.io/control-plane:NoSchedule yang mencegah workload biasa berjalan di sana.

Untuk DaemonSet yang perlu berjalan di semua node termasuk control plane (misalnya network plugin atau monitoring):

      tolerations:
      # Tolerate taint di control plane node
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      # Untuk cluster lama yang masih pakai "master"
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      # Tolerate node yang sedang not-ready
      - key: node.kubernetes.io/not-ready
        operator: Exists
        effect: NoExecute
        tolerationSeconds: 300

DaemonSet di Subset Node #

DaemonSet tidak harus berjalan di semua node. Kamu bisa membatasi ke node tertentu menggunakan nodeSelector atau nodeAffinity:

      # Hanya node dengan GPU
      nodeSelector:
        hardware: gpu

      # Atau dengan nodeAffinity yang lebih ekspresif
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: node-type
                operator: In
                values:
                - high-memory
                - gpu-enabled

Contoh penggunaan: DaemonSet untuk GPU monitoring yang hanya perlu berjalan di node yang punya GPU, bukan semua node.


Update Strategy #

DaemonSet mendukung dua update strategy:

RollingUpdate (default) — update node satu per satu dengan jumlah yang dikontrol:

  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1        # default: 1
      # maxSurge: 0            # tersedia di Kubernetes 1.22+

OnDelete — Pod di-update hanya ketika dihapus manual; kamu yang kontrol kapan update terjadi per node:

  updateStrategy:
    type: OnDelete

OnDelete berguna ketika update perlu dilakukan dengan hati-hati, misalnya kernel module atau network plugin yang bisa mempengaruhi seluruh traffic di node tersebut.


Monitoring DaemonSet #

# Lihat status DaemonSet
kubectl get daemonset -n monitoring

# Output:
# NAME            DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR
# node-exporter   4         4         4       4            4           <none>

# DESIRED = jumlah node yang memenuhi syarat
# CURRENT = jumlah Pod yang sudah ada
# READY   = jumlah Pod yang siap menerima traffic

# Jika DESIRED != CURRENT atau CURRENT != READY, ada masalah
kubectl describe daemonset node-exporter -n monitoring

# Lihat Pod DaemonSet di semua node
kubectl get pods -n monitoring -o wide | grep node-exporter

Ringkasan #

  • Satu Pod per node, otomatis — DaemonSet tidak menggunakan scheduler biasa; Pod dibuat di setiap node yang memenuhi syarat saat node bergabung, dihapus saat node pergi.
  • Use case utama: node-level agent — log collector, monitoring agent, network plugin, storage driver; semua komponen yang perlu berjalan di setiap node untuk beroperasi.
  • hostPath dan hostNetwork untuk akses host — DaemonSet sering butuh akses ke filesystem dan network namespace host; perlu dipertimbangkan implikasi keamanannya.
  • Toleration untuk control plane — tambahkan toleration eksplisit jika DaemonSet perlu berjalan di control plane node.
  • nodeSelector untuk subset node — tidak semua DaemonSet harus di semua node; batasi ke node tertentu jika fungsionalitasnya spesifik (GPU node, high-memory node).
  • Resource limits tetap wajib — DaemonSet berjalan di setiap node, jadi resource yang dipakai aggregate sangat signifikan; tetapkan limits yang ketat untuk mencegah resource starvation di node.

← Sebelumnya: StatefulSet   Berikutnya: Job & CronJob →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact