Job adalah objek Kubernetes yang menjalankan Pod hingga pekerjaannya tuntas, sedangkan CronJob membuat Job baru mengikuti jadwal yang ditetapkan. Keduanya melayani kerja batch, yaitu pemrosesan data dalam jumlah besar yang berhenti setelah selesai, berbeda dari layanan yang harus terus berjalan. Topik ini membahas bidang completions, parallelism, backoffLimit, dan activeDeadlineSeconds, kebijakan restartPolicy, pola jadwal CronJob, serta perbandingannya dengan Deployment. Simulasi di tengah topik menghitung ulangan Job dan merangkum pembacaan jadwal cron.
Job untuk kerja sekali jalan#
Deployment menuntut Pod agar terus berjalan, sedangkan Job justru menunggu Pod berhenti dengan sukses. Job menganggap satu slot pekerjaan selesai apabila Pod yang menjalankannya keluar dengan kode sukses, dan pekerjaan keseluruhan selesai apabila jumlah Pod yang sukses mencapai completions. Keberhasilan tercatat pada bidang .status.succeeded, sedangkan kegagalan terakumulasi pada .status.failed. Angka keberhasilan itulah yang dibandingkan dengan completions, sedangkan sisa pekerjaan terus dihitung ulang oleh controller.
Berkas job.yaml berikut mendefinisikan Job bernama hitung-statistik yang menjalankan empat slot pekerjaan dengan dua Pod paralel untuk menghitung statistik nilai ujian. Untuk contoh sederhana, setiap Pod menjalankan perintah yang sama, sedangkan pembagian pekerjaan nyata biasanya dilakukan dengan membedakan input per Pod atau melalui antrean bersama:
apiVersion: batch/v1
kind: Job
metadata:
name: hitung-statistik
labels:
app: aplikasi-catatan
spec:
completions: 4
parallelism: 2
backoffLimit: 6
activeDeadlineSeconds: 600
template:
metadata:
labels:
app: aplikasi-catatan
spec:
restartPolicy: Never
containers:
- name: hitung
image: python:3.12-slim
command:
- python
- -c
- |
import statistics
nilai = [72, 85, 90, 68, 77, 88]
print(f"n={len(nilai)} rata-rata={statistics.mean(nilai):.1f} median={statistics.median(nilai)}")Perintah berikut menerapkan Job lalu menampilkan statusnya setelah selesai. Kolom COMPLETIONS menunjukkan empat slot yang seluruhnya sukses, dan keempat Pod mencapai keadaan Completed:
# tidak-dijalankan
# terapkan manifest Job ke kluster
kubectl apply -f job.yaml
# tampilkan status Job beserta pod yang dihasilkannya
kubectl get jobs,pods -l app=aplikasi-catatanjob.batch/hitung-statistik created
NAME STATUS COMPLETIONS DURATION AGE
hitung-statistik Complete 4/4 2m21s 2m21s
NAME READY STATUS RESTARTS AGE
hitung-statistik-w9kfc 0/1 Completed 0 2m21s
hitung-statistik-b4n8m 0/1 Completed 0 2m21s
hitung-statistik-6tpdx 0/1 Completed 0 1m19s
hitung-statistik-z2vqh 0/1 Completed 0 1m19sKebijakan ulang dan batas waktu#
Kegagalan merupakan keadaan yang diantisipasi pada kerja batch, sehingga Job menyediakan lapisan ulangan yang diatur tiga bidang. backoffLimit menyatakan banyaknya kegagalan yang ditoleransi sebelum Job dinyatakan gagal, dan jumlahnya dihitung dari seluruh Pod yang gagal, bukan per slot pekerjaan. restartPolicy: Never membuat kegagalan berujung pada Pod baru, sedangkan restartPolicy: OnFailure memulai ulang container pada Pod yang sama. Perbedaannya memengaruhi kecepatan ulangan, karena Pod baru membawa biaya penjadwalan, sedangkan mulai ulang container tetap di dalam Pod yang sama. Pencacahan keberhasilan dan kegagalan terbaca pada bidang .status Job, sehingga keputusan ulangan selalu dapat diikuti tanpa membaca log satu per satu.
activeDeadlineSeconds menetapkan batas waktu untuk keseluruhan Job, dihitung sejak Job mulai berjalan. Apabila batas terlampaui, seluruh Pod yang masih berjalan dihentikan dan Job dinyatakan gagal dengan alasan DeadlineExceeded, bahkan apabila backoffLimit belum tercapai. Kombinasi keduanya membatasi kerugian, karena backoffLimit menghentikan ulangan yang percuma, sedangkan activeDeadlineSeconds menghentikan pekerjaan yang menggantung terlalu lama. Batas waktu berlaku tanpa memandang keberhasilan parsial, sehingga slot yang sudah sukses tetap tercatat meskipun Job keseluruhan dinyatakan gagal.
Simulasi completions, parallelism, dan backoffLimit#
Skrip berikut membaca job.yaml, lalu mensimulasikan pengisian slot pekerjaan dengan pola kegagalan yang tetap, sehingga banyaknya percobaan dapat dihitung ulang persis. Setiap slot mewakili satu unit pekerjaan yang sukses setelah salah satu Pod-nya keluar dengan sukses. Pod yang gagal mengembalikan slotnya ke antrean, dan kegagalannya dihitung terhadap backoffLimit. Bagian akhir skrip membaca cronjob.yaml dan meringkas lima field jadwal cron beserta interpretasi tiga pola yang umum.
"""Simulasi completions, parallelism, dan backoffLimit Job serta pola jadwal CronJob."""
import yaml
with open("job.yaml", encoding="utf-8") as berkas:
job = yaml.safe_load(berkas)
spec = job["spec"]
completions = spec["completions"]
parallelism = spec["parallelism"]
backoff_limit = spec["backoffLimit"]
restart = spec["template"]["spec"]["restartPolicy"]
# pola kegagalan deterministik: banyaknya percobaan gagal sebelum sukses per slot
kegagalan_slot = [2, 0, 1, 1]
assert len(kegagalan_slot) == completions
print(f"completions={completions} parallelism={parallelism} backoffLimit={backoff_limit} restartPolicy={restart}")
print()
antre = list(range(completions)) # slot pekerjaan yang belum sukses
percobaan = {s: 0 for s in range(completions)}
urutan_pod = 0
total_gagal = 0
berjalan = []
while antre or berjalan:
# isi kapasitas paralel dengan slot yang belum sukses
while antre and len(berjalan) < parallelism:
s = antre.pop(0)
percobaan[s] += 1
urutan_pod += 1
gagal = percobaan[s] <= kegagalan_slot[s]
berjalan.append((s, gagal))
status = "gagal" if gagal else "sukses"
print(f" pod {urutan_pod} slot {s} percobaan {percobaan[s]} -> {status}")
# percobaan selesai: slot yang gagal dikembalikan ke antrean
for s, gagal in berjalan:
if gagal:
total_gagal += 1
antre.append(s)
berjalan = []
if total_gagal > backoff_limit:
print()
print(f"Job gagal: {total_gagal} kegagalan melebihi backoffLimit {backoff_limit}")
else:
print()
print(f"Job selesai: {completions} slot sukses, {urutan_pod} pod dibuat, {total_gagal} kegagalan (batas {backoff_limit})")
FIELD_CRON = [
("menit", "0-59"),
("jam", "0-23"),
("tanggal dalam bulan", "1-31"),
("bulan", "1-12"),
("hari dalam minggu", "0-6, dengan 0 untuk Minggu"),
]
ARTI = {
"30 2 * * *": "pukul 02:30 setiap hari",
"0 * * * *": "pukul 00:00 setiap awal jam",
"0 9 * * 1-5": "pukul 09:00 hari Senin sampai Jumat",
}
with open("cronjob.yaml", encoding="utf-8") as berkas:
cronjob = yaml.safe_load(berkas)
schedule = cronjob["spec"]["schedule"]
policy = cronjob["spec"]["concurrencyPolicy"]
print()
print(f"CronJob {cronjob['metadata']['name']} menjadwalkan Job dengan schedule \"{schedule}\" dan concurrencyPolicy {policy}")
print()
print("Lima field jadwal cron, berurutan dari kiri ke kanan:")
for nama_field, rentang in FIELD_CRON:
print(f" {nama_field:<22} {rentang}")
print()
print("Interpretasi pola jadwal umum:")
for pola, arti in ARTI.items():
print(f" {pola:<12} -> {arti}")completions=4 parallelism=2 backoffLimit=6 restartPolicy=Never
pod 1 slot 0 percobaan 1 -> gagal
pod 2 slot 1 percobaan 1 -> sukses
pod 3 slot 2 percobaan 1 -> gagal
pod 4 slot 3 percobaan 1 -> gagal
pod 5 slot 0 percobaan 2 -> gagal
pod 6 slot 2 percobaan 2 -> sukses
pod 7 slot 3 percobaan 2 -> sukses
pod 8 slot 0 percobaan 3 -> sukses
Job selesai: 4 slot sukses, 8 pod dibuat, 4 kegagalan (batas 6)
CronJob statistik-harian menjadwalkan Job dengan schedule "30 2 * * *" dan concurrencyPolicy Forbid
Lima field jadwal cron, berurutan dari kiri ke kanan:
menit 0-59
jam 0-23
tanggal dalam bulan 1-31
bulan 1-12
hari dalam minggu 0-6, dengan 0 untuk Minggu
Interpretasi pola jadwal umum:
30 2 * * * -> pukul 02:30 setiap hari
0 * * * * -> pukul 00:00 setiap awal jam
0 9 * * 1-5 -> pukul 09:00 hari Senin sampai JumatDelapan Pod dibuat untuk empat slot karena empat kegagalan menyebar pada slot 0, slot 2, dan slot 3. Total kegagalan berjumlah empat dan masih berada di bawah backoffLimit 6, sehingga Job dinyatakan selesai. Apabila pola kegagalan menambah satu kegagalan lagi, totalnya menjadi lima dan tetap lolos, sedangkan tujuh kegagalan melampaui batas dan menghentikan Job dengan keadaan Failed.
Bagian cron menampilkan lima field jadwal dalam urutan menit, jam, tanggal dalam bulan, bulan, dan hari dalam minggu. Tanda bintang berarti pemenuhan setiap nilai, sedangkan tanda hubung menyusun rentang, sehingga 30 2 * * * dibaca sebagai pukul 02:30 setiap hari tanpa memandang tanggal maupun hari. Interpretasi semacam ini bersifat statis dan tidak menyentuh waktu berjalan pada kluster mana pun.
Pola schedule CronJob#
CronJob membuat objek Job baru setiap kali jadwal tercapai, sehingga kebijakan ulang pada Job tetap berlaku untuk setiap pelaksanaannya. Bidang schedule menuliskan lima field jadwal cron, sedangkan jobTemplate berisi spec Job yang akan dibuat. Bidang concurrencyPolicy mengatur perilaku saat pelaksanaan sebelumnya belum selesai, yaitu Allow membiarkan tumpang tindih, Forbid menunda pelaksanaan baru, dan Replace menghentikan pelaksanaan lama untuk digantikan. Apabila bidang timeZone tidak diisi, jadwal ditafsirkan mengikuti zona waktu komponen control plane.
Berkas cronjob.yaml berikut menjadwalkan statistik nilai ujian setiap pukul 02:30 dengan kebijakan Forbid, sehingga dua pelaksanaan tidak pernah berjalan bersamaan. Riwayat pelaksanaan dibatasi melalui successfulJobsHistoryLimit dan failedJobsHistoryLimit, yang menyimpan objek Job lama agar dapat diperiksa. Batas ini berlaku secara bawaan, sehingga daftar Job lama tidak menumpuk tanpa kendali:
apiVersion: batch/v1
kind: CronJob
metadata:
name: statistik-harian
labels:
app: aplikasi-catatan
spec:
schedule: "30 2 * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
backoffLimit: 2
activeDeadlineSeconds: 1800
template:
spec:
restartPolicy: OnFailure
containers:
- name: hitung
image: python:3.12-slim
command:
- python
- -c
- |
import statistics
nilai = [72, 85, 90, 68, 77, 88]
print(f"n={len(nilai)} rata-rata={statistics.mean(nilai):.1f}")Perintah berikut menerapkan CronJob lalu menampilkan jadwal dan keadaan pelaksanaannya:
# tidak-dijalankan
# terapkan manifest CronJob ke kluster
kubectl apply -f cronjob.yaml
# tampilkan CronJob beserta jadwal dan pelaksanaan aktifnya
kubectl get cronjob statistik-harianNAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE
statistik-harian 30 2 * * * <none> False 0 8h 3d2hPerbandingan dengan Deployment#
Deployment, Job, dan CronJob melayani masa hidup Pod yang berbeda. Deployment menjaga sejumlah replika agar selalu berjalan dan mengganti Pod yang mati secara otomatis, sedangkan Job menghitung keberhasilan dan berhenti setelah target completions tercapai. CronJob berada satu lapis di atas Job karena tidak menjalankan Pod secara langsung, melainkan membuat Job mengikuti jadwal.
| Aspek | Deployment | Job | CronJob |
|---|---|---|---|
| Masa hidup Pod | Terus berjalan | Berhenti setelah sukses | Berhenti setelah sukses, diulang sesuai jadwal |
| Jumlah Pod | replicas | completions | Satu Job per pelaksanaan jadwal |
| Reaksi terhadap kegagalan | Pod dibuat ulang tanpa batas | Dihitung terhadap backoffLimit | Dihitung terhadap backoffLimit per Job |
| Pembaruan template | RollingUpdate bertahap | Tanpa rollout, Pod baru mengikuti template terbaru | Tanpa rollout, diwarisi jobTemplate |
| Contoh kegunaan | Layanan web aplikasi catatan | Pemrosesan statistik nilai ujian | Statistik harian terjadwal |
Pemilihan objek mengikuti pertanyaan sederhana tentang masa hidup Pod. Apabila layanan harus selalu tersedia, Deployment menjadi pilihan bawaan. Apabila pekerjaan berakhir setelah satu kali berjalan, Job menghindari Pod yang tidak pernah berhenti, dan hasilnya terbaca pada jumlah keberhasilan. Apabila pekerjaan yang sama perlu berulang pada waktu tertentu, CronJob menetapkan jadwalnya tanpa alat penjadwal tambahan di luar kluster.
Ringkasan#
- Job menjalankan Pod hingga sukses dan dinyatakan selesai setelah jumlah Pod yang berhasil mencapai
completions, dengan kecepatan yang diaturparallelism. backoffLimitmembatasi total kegagalan, sedangkanactiveDeadlineSecondsmembatasi durasi keseluruhan Job dan menghentikannya dengan alasanDeadlineExceeded.- restartPolicy pada template Job wajib Never atau OnFailure, karena Pod yang selalu dimulai ulang tidak pernah memberi tanda keberhasilan.
- CronJob membuat Job mengikuti jadwal lima field cron dan mengatur tumpang tindih pelaksanaan melalui
concurrencyPolicy.
Referensi#
- Jobs — Kubernetes — Dokumentasi Job, termasuk completions, parallelism, backoffLimit, dan activeDeadlineSeconds.
- CronJob — Kubernetes — Dokumentasi CronJob, termasuk schedule, concurrencyPolicy, dan batas riwayat pelaksanaan.