DaemonSet #
Di dalam kluster Kubernetes yang terus berkembang, ada kebutuhan infrastruktur tertentu di mana setiap Worker Node harus menjalankan satu kontainer pendukung yang sama. Misalnya, kita ingin mengumpulkan log dari seluruh kontainer di setiap node, memantau utilisasi CPU dan RAM fisik di tingkat mesin host, atau menjalankan agen routing jaringan (CNI plugin). Jika kita mendeploy agen-agen ini menggunakan Deployment biasa, tidak ada jaminan bahwa setiap node akan mendapatkan tepat satu Pod. Beberapa node mungkin akan memiliki dua Pod, sementara node lain kosong. Untuk menjamin distribusi agen secara presisi satu Pod per node, Kubernetes menyediakan objek khusus bernama DaemonSet.
DaemonSet bertugas memastikan bahwa satu replika Pod yang kita spesifikasikan selalu berjalan secara konsisten di setiap node kluster (atau di setiap node yang memenuhi kriteria seleksi tertentu). Memahami cara kerja DaemonSet, penggunaan akses tingkat sistem (host access), serta aturan toleransi (Tolerations) Control Plane sangat penting bagi administrator kluster untuk mengelola sistem pemantauan dan agen jaringan secara aman dan efisien.
Mengapa DaemonSet Dibutuhkan? (Node-Level Agents) #
Secara konseptual, DaemonSet bekerja dengan prinsip yang sangat sederhana:
Satu Node = Satu Pod DaemonSet
Ketika kita mendeploy DaemonSet:
- Deteksi Otomatis Node Baru: Jika kluster kita melakukan autoscaling dan ada 3 Worker Node baru bergabung, DaemonSet Controller akan langsung mendeteksi hal tersebut dan secara otomatis menjadwalkan Pod DaemonSet baru ke 3 node baru tersebut tanpa campur tangan manual.
- Pembersihan Node Hancur: Sebaliknya, jika ada node yang dihapus dari kluster, DaemonSet Controller akan menghapus Pod yang terikat pada node tersebut dan membiarkan Garbage Collector membuang sisa-sisa datanya.
Berbeda dengan Deployment biasa yang diserahkan penuh kepada algoritma Scheduler untuk diletakkan di node mana saja yang paling kosong, DaemonSet secara tradisional melewati sebagian besar kalkulasi scheduler normal. Ia langsung menetapkan Pod ke node target menggunakan field spec.nodeName di dalam manifest internal Pod.
Interaksi DaemonSet dengan Node Cordon, Drain, dan Taints #
Salah satu karakteristik unik dari DaemonSet adalah perilakunya yang sangat persisten terhadap perubahan status node host:
1. Perilaku Saat Node di-Cordon #
Ketika seorang administrator menjalankan perintah kubectl cordon <node-name>, node tersebut akan ditandai sebagai Unschedulable. Scheduler Kubernetes dijamin tidak akan pernah menempatkan Pod baru dari objek Deployment ke node tersebut. Namun, DaemonSet Controller mengabaikan batasan cordon ini.
- Jika ada DaemonSet baru dideploy atau ada pod DaemonSet yang terhapus secara tidak sengaja di node yang di-cordon, DaemonSet Controller tetap akan menjadwalkan ulang Pod DaemonSet ke sana.
- Hal ini dilakukan karena kita tetap membutuhkan layanan infrastruktur dasar (seperti CNI network agent atau log shipper) untuk tetap menyala mengawasi node meskipun node tersebut tidak lagi menerima Pod aplikasi baru.
2. Perilaku Saat Node di-Drain #
Saat kita menjalankan kubectl drain <node-name>, seluruh Pod aplikasi akan diusir (evicted) secara paksa dari node tersebut agar node dapat dipelihara dengan aman.
- Secara default, perintah
kubectl drainakan menolak berjalan dan mengembalikan error jika mendeteksi adanya Pod DaemonSet di node tersebut. - Untuk melanjutkan proses drain tanpa menghapus DaemonSet (karena DaemonSet memang didesain untuk tetap bertahan di node), kita harus menyertakan flag khusus:
kubectl drain <node-name> --ignore-daemonsets=true
Tabel Komparasi: DaemonSet vs Static Pods #
Kubernetes memiliki mekanisme lain untuk menjalankan Pod langsung di tingkat node, yaitu Static Pods. Berikut perbandingan mendasar untuk membantu kita memilih pendekatan yang tepat:
| Dimensi Perbandingan | DaemonSet | Static Pods |
|---|---|---|
| Otoritas Pengelola | Controller Manager (API Server kluster) | Kubelet Lokal (melalui direktori manifest host) |
| Visibilitas Objek | Terdaftar penuh sebagai objek API Server | Hanya dibuat sebagai “Mirror Pod” bayangan di API Server |
| Metode Deployment | Sentralisasi via manifest YAML kluster | Desentralisasi (harus menulis berkas ke /etc/kubernetes/manifests) |
| Update Strategi | Otomatis via RollingUpdate atau OnDelete |
Manual dengan mengganti file konfigurasi di disk fisik host |
| Use Case Utama | Log shipper, Exporter metrik, CNI | Komponen inti Control Plane (API Server, Scheduler, etcd) |
Struktur Manifes DaemonSet Secara Mendalam #
Karena DaemonSet sering kali bertindak sebagai agen pemantau sistem (system monitoring) atau pengelola jaringan, ia membutuhkan hak akses yang jauh lebih tinggi dibanding aplikasi biasa.
Berikut adalah contoh manifest DaemonSet tingkat produksi untuk memantau metrik fisik hardware (Node Exporter):
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: prometheus-node-exporter
namespace: monitoring
labels:
app.kubernetes.io/name: node-exporter
spec:
selector:
matchLabels:
app: node-exporter
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # Lakukan update satu node secara berurutan
template:
metadata:
labels:
app: node-exporter
spec:
hostNetwork: true # Menggunakan network namespace host secara langsung
hostPID: true # Menggunakan PID namespace host untuk melihat proses OS
containers:
- name: node-exporter
image: prom/node-exporter:v1.7.0
securityContext:
readOnlyRootFilesystem: true
ports:
- containerPort: 9100
hostPort: 9100 # Mengikat port 9100 langsung ke IP fisik node
resources:
requests:
cpu: "50m"
memory: "64Mi"
limits:
cpu: "150m"
memory: "128Mi"
volumeMounts:
- name: proc
mountPath: /host/proc
readOnly: true
- name: sys
mountPath: /host/sys
readOnly: true
volumes:
- name: proc
hostPath:
path: /proc # Mount filesystem proc milik host
- name: sys
hostPath:
path: /sys # Mount filesystem sys milik host
Peringatan Keamanan Hak Akses Host (hostPath & hostNetwork)
#
hostNetwork: true: Memungkinkan kontainer menggunakan jaringan IP fisik Worker Node langsung. Ini sangat cepat karena menghindari overhead translasi jaringan (NAT), namun berbahaya jika port kontainer bentrok dengan aplikasi lain di sistem operasi host.hostPath: Me-mount file atau direktori langsung dari harddisk Worker Node host ke dalam kontainer. Ini wajib digunakan oleh log collector untuk membaca file/var/log/pods.
[!CAUTION] Membiarkan kontainer menggunakan
hostPath: /(akses root filesystem host) dengan parametersecurityContext.privileged: truememberikan akses kontrol penuh ke sistem operasi node. Jika kontainer ini berhasil dieksploitasi oleh hacker, mereka dapat dengan mudah mengambil alih seluruh server fisik. Selalu terapkan akses baca saja (readOnly: true) pada volume hostPath di produksi.
Use Case 1: Pengumpul Log Tingkat Node (Log Collectors) #
Di Kubernetes, log keluaran kontainer (stdout/stderr) ditulis oleh Kubelet ke dalam folder lokal /var/log/pods di server host Worker Node. Untuk mengumpulkan log-log ini secara realtime, kita menempatkan agen log collector (seperti Fluent Bit atau Promtail) sebagai DaemonSet yang me-mount folder tersebut.
flowchart TD
subgraph HostNode ["Worker Node Host OS"]
LogDir["/var/log/pods/\n(Penyimpanan Log Kontainer)"]
end
subgraph DaemonSetPod ["DaemonSet Pod (Fluent Bit)"]
direction TB
HostMount["Volume Mount: /var/log"]
Shipper["Fluent Bit Engine"]
end
subgraph CentralLogging ["Central Infrastructure"]
Loki["Grafana Loki / Elasticsearch"]
end
LogDir -->|1. Akses Fisik hostPath| HostMount
HostMount -->|2. Baca Log| Shipper
Shipper -->|3. Kirim Log asinkron| Loki
style DaemonSetPod stroke:#9b59b6,stroke-width:2px
Dengan model ini, berapa pun jumlah Pod aplikasi baru yang dibuat di node tersebut, log-nya akan otomatis terbaca oleh satu instansi Fluent Bit DaemonSet yang sama, menghemat RAM dibanding memasang sidecar log shipper di setiap Pod aplikasi.
Use Case 2: Plugin Jaringan (CNI - Container Network Interface) #
Plugin jaringan kluster (seperti Cilium, Calico, atau Flannel) wajib berjalan di setiap node. Tugas mereka adalah memanipulasi aturan tabel jaringan kernel Linux, menyusun rute paket data, serta mengelola enkripsi traffic jaringan antarnode.
- CNI selalu dideploy sebagai DaemonSet dengan konfigurasi
hostNetwork: truedanprivileged: trueagar dapat langsung membuat virtual interface jaringan di tingkat sistem operasi kernel Linux Worker Node. - Calico CNI misalnya, membutuhkan mount filesystem
/run/cni,/etc/cni/net.d, dan/lib/modulesagar dapat menyuntikkan file konfigurasi konfigurasi routing langsung ke folder konfigurasi jaringan host.
Menjadwalkan DaemonSet di Master/Control Plane Node #
Secara default, master node (Control Plane) kluster memiliki tanda penolak (Taint) bawaan dari Kubernetes untuk mencegah aplikasi biasa berjalan di sana agar master node tidak kehabisan CPU:
node-role.kubernetes.io/control-plane:NoSchedule
Namun, agen pemantau metrik (Node Exporter) atau plugin jaringan (CNI) wajib berjalan di control plane node juga agar master node dapat diawasi kesehatannya dan terhubung ke jaringan kluster. Untuk melewati pembatasan ini, kita harus menambahkan spesifikasi Tolerations di dalam manifes DaemonSet:
spec:
template:
spec:
tolerations:
# Mengizinkan penempatan Pod di master node Kubernetes lama
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
# Mengizinkan penempatan Pod di control-plane node Kubernetes modern
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
# Mengizinkan penempatan Pod saat status node sedang tidak siap (maintenance)
- key: node.kubernetes.io/not-ready
operator: Exists
effect: NoExecute
Penjadwalan di Sebagian Wilayah Node (Subset of Nodes) #
DaemonSet tidak selalu harus berjalan di 100% total node kluster. Kita dapat membatasi penempatannya hanya pada kelompok node yang memiliki karakteristik perangkat keras (hardware) tertentu menggunakan selektor label nodeSelector atau nodeAffinity.
Contoh use case: Kita ingin mendeploy DaemonSet pemantau temperatur GPU (seperti NVIDIA Device Plugin) yang hanya boleh berjalan di node yang memiliki kartu grafis GPU fisik:
spec:
template:
spec:
nodeSelector:
accelerator: nvidia-gpu # Hanya jalankan Pod di node yang memiliki label ini
Strategi Update: RollingUpdate vs OnDelete #
Sama seperti Deployment, DaemonSet mendukung dua strategi pembaruan versi kontainer:
- RollingUpdate (Default): Begitu kita menerapkan update image pada manifest DaemonSet, Controller akan menghapus Pod DaemonSet lama di satu node, menunggu hingga Pod baru di node tersebut menyala sehat (Ready), barulah melangkah menghapus Pod di node berikutnya secara berurutan. Kapasitas update dikendalikan oleh properti
maxUnavailable(biasanya diatur bernilai1). - OnDelete: Ketika kita mengupdate manifest DaemonSet, Kubernetes tidak akan melakukan restart pada Pod yang sedang berjalan. Update baru akan diterapkan pada suatu node hanya jika kita secara manual menghapus Pod di node tersebut.
[!TIP] Strategi
OnDeletesangat direkomendasikan saat memperbarui plugin jaringan (CNI) atau modul kernel kritis di kluster produksi berskala besar. Kita ingin mengontrol secara manual dan bertahap kapan setiap node mengalami gangguan koneksi sementara selama transisi update jaringan guna menghindari putusnya koneksi kluster secara massal.
Anti-Pattern dalam Manajemen DaemonSet #
Berikut adalah dua kesalahan fatal yang sering kali menyebabkan pemborosan resource kluster secara tidak sadar:
Anti-Pattern 1: Menggunakan DaemonSet untuk Aplikasi Web Stateless Biasa #
Mendeploy aplikasi bisnis di bawah kendali DaemonSet demi kepraktisan routing.
ANTI-PATTERN: Mendeploy payment-gateway API sebagai DaemonSet di Kluster 100 Node
// KITA MELAKUKAN:
- Menulis manifest DaemonSet untuk aplikasi payment-api agar ia berjalan di setiap node kluster.
- Kluster kita saat ini memiliki 100 Worker Node.
// KONSEKUENSI DI PRODUKSI:
- Pemborosan CPU & RAM Ekstrem: Kubernetes akan memaksa menjalankan 100 replika aplikasi payment-api.
- Jika traffic transaksi sebenarnya sangat sepi dan cukup dilayani oleh 3 replika saja,
kita telah menyia-nyiakan alokasi biaya 97 kontainer kosong yang memakan CPU/RAM secara pasif.
- Kita kehilangan manfaat utama autoscaling dinamis.
✓ SOLUSI YANG BENAR:
- Gunakan objek `Deployment` digabung dengan `Horizontal Pod Autoscaler` (HPA) untuk aplikasi stateless.
- Biarkan Kubernetes menyesuaikan jumlah replika secara dinamis (misal scale down ke 2 saat sepi, scale up ke 20 saat ramai).
Anti-Pattern 2: Mengabaikan Limit Resource Komputasi (Resource Starvation) #
Tidak membatasi alokasi RAM dan CPU untuk agen DaemonSet yang berjalan di seluruh node.
ANTI-PATTERN: Menyuntikkan Log Collector DaemonSet Tanpa limits.memory
// KITA MELAKUKAN:
- Mendeploy Fluent Bit DaemonSet tanpa menuliskan batas limits.memory di manifest.
- Terjadi kebocoran memori (memory leak) di dalam biner log shipper akibat memproses log corrupt.
// KONSEKUENSI DI PRODUKSI:
- Kebocoran Memori Host: Memori Fluent Bit akan terus membengkak hingga memakan seluruh RAM fisik Worker Node.
- Karena DaemonSet adalah proses sistem utama, kernel Linux akan mendeteksi kehabisan RAM fisik
dan mulai membunuh aplikasi bisnis penting kita (yang berada di kelas QoS lebih rendah) untuk menyelamatkan node.
- Node menjadi tidak stabil, memicu kegagalan startup berantai.
✓ SOLUSI YANG BENAR:
- Selalu batasi secara ketat memori limits pada DaemonSet (misalnya limit memory 128Mi atau 256Mi).
- Karena DaemonSet berjalan di setiap node, overhead resource yang tidak dibatasi akan terakumulasi
secara masif lintas kluster.
Ringkasan #
- Agen Tingkat Node Otomatis — DaemonSet bertugas memastikan satu replika Pod pendukung selalu berjalan secara konsisten di setiap node kluster yang memenuhi syarat.
- Penyelaras Skala Kluster — Begitu ada node baru bergabung via autoscaling, DaemonSet secara otomatis akan menempatkan Pod baru di sana tanpa campur tangan operator.
- Abaikan Batasan Cordon — DaemonSet Controller secara khusus mengabaikan status cordon (
Unschedulable) pada node agar agen infrastruktur dasar tetap menyala mendeteksi kesehatan node.- Gunakan hostPath & hostNetwork Cermat — Batasi penggunaan hak akses fisik hostPath dan jaringan hostNetwork guna meminimalkan celah keamanan kontainer.
- Tolerasi untuk Control Plane — Tuliskan blok
tolerationssecara eksplisit pada spesifikasi manifest jika DaemonSet harus berjalan di control plane master node.- Batasi dengan Selektor Node — Manfaatkan selektor
nodeSelectorataunodeAffinityjika DaemonSet hanya perlu berjalan di node dengan hardware khusus (seperti node GPU).- OnDelete untuk Jaringan Kritis — Pilih strategi update
OnDeletesaat memperbarui komponen jaringan (CNI) guna menghindari gangguan koneksi kluster secara serentak.- Resource Limits Wajib — Terapkan batas limits CPU/RAM yang ketat pada DaemonSet untuk menghindari terjadinya kehabisan memori host fisik node (Resource Starvation).