DaemonSet adalah objek workload yang menjamin satu Pod berjalan di setiap Node yang cocok dengan seleksinya. Berbeda dari Deployment yang mengatur jumlah replika secara manual, jumlah Pod pada DaemonSet mengikuti jumlah Node di kluster. Topik ini membahas pola agen per Node, yaitu pengumpul logging ke arsip cadangan berkas dan agen pemantauan, pengaruh taint terhadap penempatan, serta perbandingan Deployment, DaemonSet, dan Job dalam satu tabel. Simulasi di bagian akhir menghitung penempatan Pod agen dari berkas manifest nyata.
Satu Pod per Node#
DaemonSet membuat satu Pod pada setiap Node yang labelnya cocok dengan nodeSelector atau Node affinity pada bagian spec.template, tanpa perantara ReplicaSet dan tanpa bidang replicas. Controller memantau daftar Node, sehingga setiap Node baru yang bergabung langsung menerima Pod agen, sedangkan Pod pada Node yang keluar ikut terhapus. Jumlah Pod yang diinginkan tidak ditulis di manifest, karena nilainya selalu sama dengan jumlah Node yang lolos seleksi.
Kedudukan Pod yang menempel pada Node tersebut penting bagi agen. Pod agen membaca sumber daya yang dimiliki Node secara langsung, misalnya berkas log pada /var/log atau statistik perangkat keras, sehingga pekerjaan itu tidak dapat dilakukan oleh Pod yang dijadwalkan bebas. Apabila satu Node bertambah, kapasitas agen bertambah satu Pod, dan apabila Node berkurang, Pod-nya hilang bersama Node itu.
Pembaruan image agen mengikuti bidang updateStrategy. Strategi bawaan RollingUpdate mengganti Pod per Node dengan batas maxUnavailable, sedangkan strategi OnDelete hanya mengganti agen apabila Pod di Node tersebut dihapus secara manual. Keduanya beroperasi per Node, bukan per replika seperti pada Deployment.
Pola agen per Node#
Dua pola mencakup sebagian besar penggunaan DaemonSet. Pola pertama adalah pengumpul logging, yaitu agen yang membaca log dari setiap Node dan menulis arsip cadangan berkas ke direktori Node masing-masing. Pola kedua adalah agen pemantauan yang melaporkan metrik perangkat keras dan container dari setiap Node. Keduanya harus hadir di semua Node, sehingga Deployment yang boleh menumpuk Pod di satu Node tidak memenuhi kebutuhan tersebut.
Akses langsung ke berkas Node memerlukan volume hostPath, yaitu volume yang memetakan direktori Node ke dalam Pod. Berkas log container dibaca dari /var/log dalam keadaan hanya-baca, sedangkan arsip ditulis ke direktori Node yang dibuat bila belum ada melalui type: DirectoryOrCreate. Karena setiap Pod menulis ke arsip Node-nya sendiri, tidak ada perselisihan penulisan antara agen.
Berkas daemonset.yaml berikut mendefinisikan DaemonSet bernama pengumpul-log yang mengemas arsip log setiap Node pekerja setiap satu jam:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: pengumpul-log
labels:
app: pengumpul-log
spec:
selector:
matchLabels:
app: pengumpul-log
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
app: pengumpul-log
spec:
nodeSelector:
peran: pekerja
tolerations:
- key: node.kubernetes.io/disk-pressure
operator: Exists
effect: NoSchedule
containers:
- name: pengumpul
image: busybox:1.36
command:
- sh
- -c
- >-
while true; do
tar -czf /arsip/log-$(date +%s).tar.gz /log-node;
sleep 3600;
done
volumeMounts:
- name: log
mountPath: /log-node
readOnly: true
- name: arsip
mountPath: /arsip
volumes:
- name: log
hostPath:
path: /var/log
type: Directory
- name: arsip
hostPath:
path: /var/arsip-log
type: DirectoryOrCreatePerintah berikut menerapkan manifest tersebut lalu menampilkan jumlah Pod agen per keadaan. Kolom DESIRED sama dengan jumlah Node yang lolos seleksi, dan tidak ada nilai yang diatur manual:
# tidak-dijalankan
# terapkan manifest DaemonSet ke kluster
kubectl apply -f daemonset.yaml
# tampilkan DaemonSet beserta jumlah pod per keadaannya
kubectl get daemonset pengumpul-logNAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
pengumpul-log 4 4 4 4 4 peran=pekerja 40sDaemonSet dan taint#
Taint adalah penanda pada Node yang menolak Pod tanpa toleration yang cocok, dan DaemonSet tidak dikecualikan dari aturan itu. Node control-plane membawa taint node-role.kubernetes.io/control-plane:NoSchedule, sehingga agen tidak berjalan di sana kecuali toleration yang cocok ditambahkan ke template. Taint kondisional seperti node.kubernetes.io/disk-pressure menahan Pod agen selama kondisi bermasalah, dan Pod baru dibuat kembali setelah kondisinya pulih.
Pemilihan Node dilakukan dengan dua lapis seleksi. nodeSelector menyaring Node berdasarkan label, sedangkan tolerations menentukan taint mana yang dapat ditembus. Dua lapis tersebut bekerja bersama, yaitu Node harus lolos seleksi label dan seluruh taint-nya harus ditoleransi, sehingga pengurangan cakupan agen dapat dilakukan dari salah satu lapis saja.
Agen pada Node control-plane sering memang diperlukan, misalnya untuk mengumpulkan log komponen control-plane. Apabila agen harus hadir di seluruh Node, toleration yang cocok ditambahkan ke template, sedangkan apabila Node control-plane sengaja dikeluarkan, seleksi yang ada sudah cukup. Keputusan ini menentukan cakupan agen sejak manifest ditulis.
Simulasi penempatan per Node#
Skrip berikut membaca daemonset.yaml, lalu menghitung penempatan Pod agen pada lima Node dengan aturan yang sama seperti scheduler, yaitu seleksi label terlebih dahulu, kemudian pemeriksaan taint terhadap tolerations. Kelima Node mewakili susunan kluster belajar yang umum, yaitu tiga Node pekerja sehat, satu Node pekerja bermasalah, dan satu Node control-plane. Scheduler asli juga menimbang sumber daya yang tersedia, sedangkan simulasi ini membatasi diri pada dua aturan seleksi agar hasilnya dapat dihitung ulang persis. Perhitungan kedua dijalankan dengan tolerations dihapus untuk memperlihatkan dampaknya secara langsung.
"""Perhitungan penempatan pod DaemonSet per node dengan nodeSelector dan taint."""
import yaml
with open("daemonset.yaml", encoding="utf-8") as berkas:
ds = yaml.safe_load(berkas)
pod_spec = ds["spec"]["template"]["spec"]
node_selector = pod_spec.get("nodeSelector", {})
tolerations = pod_spec.get("tolerations", [])
# daftar node beserta label dan taint yang terpasang
NODE = [
("node-1", {"peran": "pekerja"}, []),
("node-2", {"peran": "pekerja"}, []),
("node-3", {"peran": "pekerja"}, []),
("node-4", {"peran": "pekerja"}, [("node.kubernetes.io/disk-pressure", "NoSchedule")]),
("node-0", {}, [("node-role.kubernetes.io/control-plane", "NoSchedule")]),
]
def cocok_tolerasi(taint, daftar_tolerasi):
"""Benar bila seluruh taint ditoleransi oleh daftar tolerations."""
return all(
any(
(kunci_t == t["key"] or t["key"] == "")
and t["operator"] == "Exists"
and (t["effect"] == "" or t["effect"] == efek_t)
for t in daftar_tolerasi
)
for kunci_t, efek_t in taint
)
def status_node(label, taint, daftar_tolerasi):
cocok_label = all(label.get(k) == v for k, v in node_selector.items())
if not cocok_label:
return "dilewati (label tidak cocok)"
if taint and not cocok_tolerasi(taint, daftar_tolerasi):
return "dilewati (taint tidak ditoleransi)"
return "pod dibuat"
print(f"DaemonSet : {ds['metadata']['name']}")
print(f"nodeSelector : {node_selector}")
print()
print("Penempatan dengan tolerations pada manifest:")
for nama, label, taint in NODE:
print(f" {nama:<8} {status_node(label, taint, tolerations)}")
jumlah = sum(1 for _, label, taint in NODE if status_node(label, taint, tolerations) == "pod dibuat")
print(f"Total: {jumlah} dari {len(NODE)} node")
print()
print("Penempatan tanpa tolerations (tolerations dihapus):")
for nama, label, taint in NODE:
print(f" {nama:<8} {status_node(label, taint, [])}")
jumlah_tanpa = sum(1 for _, label, taint in NODE if status_node(label, taint, []) == "pod dibuat")
print(f"Total: {jumlah_tanpa} dari {len(NODE)} node")DaemonSet : pengumpul-log
nodeSelector : {'peran': 'pekerja'}
Penempatan dengan tolerations pada manifest:
node-1 pod dibuat
node-2 pod dibuat
node-3 pod dibuat
node-4 pod dibuat
node-0 dilewati (label tidak cocok)
Total: 4 dari 5 node
Penempatan tanpa tolerations (tolerations dihapus):
node-1 pod dibuat
node-2 pod dibuat
node-3 pod dibuat
node-4 dilewati (taint tidak ditoleransi)
node-0 dilewati (label tidak cocok)
Total: 3 dari 5 nodeKeluaran menunjukkan empat Node memperoleh agen dengan tolerations pada manifest, sedangkan Node control-plane tertahan karena tidak membawa label peran: pekerja. Tanpa tolerations, Node keempat ikut tertahan karena taint disk-pressure tidak lagi ditoleransi, sehingga jumlah agen turun menjadi tiga. Angka yang sama akan muncul pada kolom DESIRED apabila DaemonSet yang sama diterapkan pada kluster dengan lima Node tersebut. Seluruh keputusan bersifat per Node, dan tidak ada alokasi jumlah Pod yang diatur manual di mana pun.
Deployment, DaemonSet, dan Job dalam satu tabel#
Tiga objek tersebut berbagi mekanisme template Pod, tetapi menjawab pertanyaan penempatan yang berbeda. Deployment membagi replika ke Node mana pun yang memiliki sumber daya, DaemonSet menautkan satu Pod pada setiap Node yang lolos seleksi, sedangkan Job mengisi jumlah slot pekerjaan tanpa mengikat Pod ke Node tertentu. Ketiganya memuat spec.template yang sama, sehingga pemindahan definisi Pod antara objek hanya mengubah penempatan dan masa hidupnya.
| Aspek | Deployment | DaemonSet | Job |
|---|---|---|---|
| Jumlah Pod | Ditetapkan melalui replicas | Satu per Node yang lolos seleksi | Ditetapkan melalui completions |
| Penempatan | Bebas mengikuti sumber daya Node | Menempel pada Node tertentu | Bebas mengikuti sumber daya Node |
| Masa hidup Pod | Terus berjalan | Terus berjalan selama Node ada | Berhenti setelah sukses |
| Contoh kegunaan | Layanan web aplikasi catatan | Pengumpul log dan agen pemantauan | Pemrosesan statistik nilai ujian |
Tabel tersebut menegaskan batas masing-masing objek. Agen yang dijalankan sebagai Deployment dapat menumpuk di satu Node dan menyisakan Node lain tanpa agen, sedangkan agen yang dijalankan sebagai Job hanya berjalan sekali dan berhenti sebelum Node berikutnya bergabung. DaemonSet memenuhi syarat kehadiran yang berkelanjutan pada setiap Node, dan itulah satu-satunya alasan objek ini dipilih.
Ringkasan#
- DaemonSet membuat satu Pod pada setiap Node yang lolos seleksi, dan jumlah Pod mengikuti jumlah Node tanpa bidang
replicas. - Pola utamanya adalah agen per Node, seperti pengumpul log ke arsip cadangan berkas dan agen pemantauan, yang mengakses berkas Node melalui volume hostPath.
- Taint menahan Pod agen pada Node yang bermasalah, sedangkan nodeSelector dan tolerations menentukan cakupan agen.
- Pembaruan template berjalan per Node melalui RollingUpdate dengan
maxUnavailableatau menunggu penghapusan manual pada strategi OnDelete.
Referensi#
- DaemonSet — Kubernetes — Dokumentasi DaemonSet, termasuk pola penggunaan, updateStrategy, dan toleration bawaan controller.
- kubectl Cheat Sheet — Kubernetes — Daftar perintah kubectl untuk menerapkan manifest dan memeriksa objek yang digunakan pada contoh.