Edit This Page

Job - Dijalankan Hingga Selesai

Sebuah Job membuat satu atau beberapa Pod dan menjamin bahwa jumlah Pod yang telah dispesifikasikan sebelumnya berhasil dijalankan. Pada saat Pod telah dihentikan, Job akan menandainya sebagai Job yang sudah berhasil dijalankan. Ketika jumlah sukses yang dispesifikasikan sebelumnya sudah terpenuhi, maka Job tersebut dianggap selesai. Menghapus sebuah Job akan menghapus semua Pod yang dibuat oleh Job tersebut.

Sebuah kasus sederhana yang dapat diberikan adalah membuat sebuah objek Job untuk menjamin sebuah Pod dijalankan hingga selesai. Objek Job ini akan membuat sebuah Pod baru apabila Pod pertama gagal atau dihapus (salah satu contohnya adalah akibat adanya kegagalan pada perangkat keras atau terjadinya reboot pada Node).

Kamu juga dapat menggunakan Job untuk menjalankan beberapa Pod secara paralel.

Menjalankan Contoh Job

Berikut merupakan contoh konfigurasi Job. Job ini melakukan komputasi π hingga digit ke 2000 kemudian memberikan hasilnya sebagai keluaran. Job tersebut memerlukan waktu 10 detik untuk dapat diselesaikan.

controllers/job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

Kamu dapat menjalankan contoh tersebut dengan menjalankan perintah berikut:

kubectl apply -f https://k8s.io/examples/controllers/job.yaml
job "pi" created

Perhatikan status dari Job yang baru dibuat dengan menggunakan perintahkubectl:

kubectl describe jobs/pi
Name:             pi
Namespace:        default
Selector:         controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495
Labels:           controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495
                  job-name=pi
Annotations:      <none>
Parallelism:      1
Completions:      1
Start Time:       Tue, 07 Jun 2016 10:56:16 +0200
Pods Statuses:    0 Running / 1 Succeeded / 0 Failed
Pod Template:
  Labels:       controller-uid=b1db589a-2c8d-11e6-b324-0209dc45a495
                job-name=pi
  Containers:
   pi:
    Image:      perl
    Port:
    Command:
      perl
      -Mbignum=bpi
      -wle
      print bpi(2000)
    Environment:        <none>
    Mounts:             <none>
  Volumes:              <none>
Events:
  FirstSeen    LastSeen    Count    From            SubobjectPath    Type        Reason            Message
  ---------    --------    -----    ----            -------------    --------    ------            -------
  1m           1m          1        {job-controller }                Normal      SuccessfulCreate  Created pod: pi-dtn4q

Untuk melihat Pod yang sudah selesai dari sebuah Job, kamu dapat menggunakan perintah kubectl get pods.

Untuk menampilkan semua Pod yang merupakan bagian dari suatu Job di mesin kamu dalam bentuk yang mudah dipahami, kamu dapat menggunakan perintah berikut ini:

pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath='{.items[*].metadata.name}')
echo $pods
pi-aiw0a

Disini, selektor yang ada merupakan selektor yang sama dengan yang ada pada Job. Opsi --output=jsonpath menspesifikasikan bahwa ekspresi yang hanya menampilkan nama dari setiap Pod pada list yang dikembalikan.

Untuk melihat keluaran standar dari salah satu pod:

kubectl logs $pods

Keluaran yang dihasilkan akan sama dengan:

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901

Sama halnya dengan konfigurasi Kubernetes lainnya, sebuah Job memerlukan field apiVersion, kind, dan metadata.

Sebuah Job juga membutuhkan sebuah bagian .spec.

Templat Pod

Field .spec.template merupakan satu-satunya field wajib pada .spec.

Field .spec.template merupakan sebuah templat Pod. Field ini memiliki skema yang sama dengan yang ada pada Pod, kecuali field ini bersifat nested dan tidak memiliki field apiVersion atau field kind.

Sebagai tambahan dari field wajib pada sebuah Job, sebuah tempat pod pada Job haruslah menspesifikasikan label yang sesuai (perhatikan selektor pod) dan sebuah mekanisme restart yang sesuai.

Hanya sebuah RestartPolicy yang sesuai dengan Never atau OnFailure yang bersifat valid.

Selektor Pod

Field .spec.selector bersifat opsional. Dan dalam sebagian besar kasus, kamu tidak perlu memberikan spesifikasi untuk hal ini. Perhatikan bagian menspesifikasikan selektor Pod kamu sendiri.

Job Paralel

Terdapat tiga jenis utama dari task yang sesuai untuk dijalankan sebagai sebuah Job:

  1. Job non-paralel
  • secara umum, hanya sebuah Pod yang dimulai, kecuali jika Pod tersebut gagal.
  • Job akan dianggap sudah selesai dikerjakan apabila Pod dari Job tersebut sudah selesai dijalankan dan mengalami terminasi dengan status sukses.
  1. Job paralel dengan jumlah nilai penyelesaian tetap:
  • berikan spesifikasi pada .spec.completions dengan nilai non-negatif.
  • Job yang ada merupakan representasi dari task yang dikerjakan, dan akan dianggap selesai apabila terdapat lebih dari satu Pod yang sukses untuk setiap nilai yang ada dalam jangkauan 1 hingga .spec.completions.
  • belum diimplementasikan saat ini: Setiap Pod diberikan nilai indeks yang berbeda di dalam jangkauan 1 hingga .spec.completions.
  1. Job paralel dengan sebuah work queue:
  • jangan berikan spesifikasi pada .spec.completions, nilai default-nya merupakan .spec.parallelism.
  • Pod yang ada haruslah dapat berkoordinasi satu sama lain atau dengan Service eksternal lain untuk menentukan apa yang setiap Pod tadi perlu lakukan. Sebagai contohnya, sebuah Pod bisa saja melakukan fetch job batch hingga N kali pada work queue
  • setiap Pod secara independen mampu menentukan apakah Pod lainnya telah menyelesaikan tugasnya dengan baik atau belum, dengan kata lain suatu Job telah dikatakan selesai
  • ketika Pod mana pun dari sebuah Job berhenti dalam keadaan sukses, maka tidak ada Pod lain yang akan dibuat untuk Job tersebut.
  • apabila salah satu Pod sudah dihentikan sekali dalam keadaan sukses, maka Job akan ditandai sebagai sukses.
  • apabila sebuah Pod sudah dihentikan dalam keadaan sukses, tidak boleh ada Pod lain yang mengerjakan task tersebut. Dengan kata lain, semua Pod tersebut haruslah dalam keadaan akan dihentikan.

Untuk sebuah Job yang non-paralel, kamu tidak perlu menspesifikasikan field .spec.completions dan .spec.parallelism. Ketika kedua field tersebut dalam keadaan tidak dispesifikasikan, maka nilai defult-nya akan diubah menjadi 1.

Untuk sebuah Job dengan jumlah nilai penyelesaian tetap, kamu harus memberikan spesifikasi nilai dari .spec.completions dengan nilai yang diinginkan. Kamu dapat menspesifikasikan .spec.parallelism, atau jika kamu tidak melakukannya nilai dari field ini akan memiliki nilai default 1.

Untuk sebuah Job work queue, kamu harus meninggalkan spesifikasi field .spec.completions menjadi kosong, serta memberikan nilai pada .spec.parallelism menjadi sebuah bilangan bulat non negatif.

Untuk informasi lebih lanjut mengenai bagaimana menggunakan Job dengan jenis yang berbeda, kamu dapat melihat bagian pola job.

Mengendalikan Paralelisme

Paralelisme yang diminta (.spec.parallelism) dapat diaktifkan dengan cara memberikan nilai bilangan bulat non-negatif. Jika tidak dispesifikasikan maka nilainya akan secara default yaitu 1. Jika dispesifikasikan sebagai 0, maka Job akan secara otomatis dihentikan sementara hingga nilainya dinaikkan.

Paralelisme yang sebenarnya (jumlah Pod yang dijalankan pada satu waktu tertentu) bisa saja lebih atau kurang dari nilai yang diharapkan karena adanya alasan berikut:

  • Untuk Job fixed completion count, nilai sebenarnya dari jumlah Pod yang dijalankan secara paralel tidak akan melebihi jumlah
    completion yang tersisa. Nilai yang lebih tinggi dari .spec.parallelism secara efektif, akan diabaikan.
  • Untuk Job work queue, tidak akan ada Pod yang dimulai setelah ada Pod yang berhasil -- meskipun begitu, sisa Pod yang ada akan diizinkan untuk menyelesaikan tugasnya.
  • Jika sebuah ControllerKontrol tertutup yang mengawasi kondisi bersama dari klaster melalui apiserver dan membuat perubahan yang mencoba untuk membawa kondisi saat ini ke kondisi yang diinginkan. Job tidak memiliki waktu untuk memberikan reaksi.
  • Jika sebuah controller Job gagal membuat Pod dengan alasan apa pun (kurangnya ResourceQuota, kurangnya permission, dkk.), maka bisa saja terdapat lebih sedikit Pod dari yang diminta.
  • Jika controller Job melakukan throttle pembuatan Pod karena terdapat gagalnya pembuatan Pod yang berlebihan sebelumnya pada Job yang sama.
  • Ketika sebuah Pod dihentikan secara graceful, maka Pod tersebut akan membutuhkan waktu untuk berhenti.

Mengatasi Kegagalan Pod dan Container

Sebuah Container pada sebuah Pod bisa saja mengalami kegagalan karena berbagai alasan yang berbeda, misalnya saja karena proses yang ada di dalamnya berakhir dengan exit code yang tidak sama dengan nol, atau Container yang ada di-kill karena menyalahi batasan memori, dkk. Jika hal ini terjadi, dan .spec.template.spec.restartPolicy = "OnFailure", maka Pod akan tetap ada di dalam node, tetapi Container tersebut akan dijalankan kembali. Dengan demikian, program kamu harus dapat mengatasi kasus dimana program tersebut di-restart secara lokal, atau jika tidak maka spesifikasikan .spec.template.spec.restartPolicy = "Never". Perhatikan lifecycle pod untuk informasi lebih lanjut mengenai restartPolicy.

Sebuah Pod juga dapat gagal secara menyeluruh, untuk beberapa alasan yang mungkin, misalnya saja, ketika Pod tersebut dipindahkan dari Node (ketika Node diperbarui, di-restart, dihapus, dsb.), atau jika sebuah Container dalam Pod gagal dan .spec.template.spec.restartPolicy = "Never". Ketika sebuah Pod gagal, maka controller Job akan membuat sebuah Pod baru. Ini berarti aplikasi kamu haruslah bisa mengatasi kasus dimana aplikasimu dimulai pada Pod yang baru. Secara khusus apabila aplikasi kamu berurusan dengan berkas temporer, locks, keluaran yang tak lengkap dan hal-hal terkait dengan program yang dijalankan sebelumnya.

Perhatikan bahwa bahakan apabila kamu menspesifikasikan .spec.parallelism = 1 dan .spec.completions = 1 dan .spec.template.spec.restartPolicy = "Never", program yang sama bisa saja tetap dijalankan lebih dari sekali.

Jika kamu menspesifikasikan .spec.parallelism dan .spec.completions dengan nilai yang lebih besar dari 1, maka bisa saja terdapat keadaan dimana terdapat beberapa Pod yang dijalankan pada waktu yang sama. Dengan demikian, Pod kamu haruslah fleksibel terhadap adanya konkurensi.

Mekanisme Kebijakan Backoff apabila Terjadi Kegagalan

Terdapat situasi dimana kamu ingin membuat suatu Job gagal setelah dijalankan mekanisme retry beberapa kali akibat adanya kesalahan pada konfigurasi dsb. Untuk melakukan hal tersebut, spesifikasikan .spec.backoffLimit dengan nilai retry yang diinginkan sebelum menerjemahkan Job dalam keadaan gagal. Secara default, nilai dari field tersebut adalah 6. Pod yang gagal dijalankan dan terkait dengan suatu Job tertentu akan dibuat kembali oleh controller Job dengan delay back-off eksponensial (10 detik, 20 detik, 40 detik ...) yang dibatasi pada 6 menit. Penghitungan back-off akan diulang jika tidak terdapat Pod baru yang gagal sebelum siklus pengecekan status Job selanjutnya.

Catatan: Isu #54870 masih ada untuk versi Kubernetes sebelum 1.12.
Catatan: Jika Job yang kamu miliki memiliki restartPolicy = "OnFailure", perhatikan bahwa Container kamu yang menjalankan Job tersebut akan dihentikan ketika limit back-off telah dicapai. Hal ini akan membuat proses debugging semakin sulit. Dengan demikian, kami memberikan saran untuk menspesifikasikan restartPolicy = "Never" ketika melakukan proses debugging atau menggunakan mekanisme logging untuk menjamin keluaran dari Job yang gagal agar tidak terus menerus hilang.

Terminasi dan Clean Up Job

Ketika sebuah Job selesai dijalankan, tidak akan ada lagi Pod yang dibuat, meskipun begitu Pod yang ada juga tidak akan dihapus. Dengan demikian kamu masih bisa mengakses log yang ada dari Pod yang sudah dalam status complete untuk mengecek apabila terjadi eror, warning, atau hal-hal yang dapat digunakan untuk proses pelaporan dan identifikasi. Objek Job itu sendiri akan tetap ada, sehingga kamu tetap bisa melihat statusnya. Penghapusan objek akan diserahkan sepenuhnya pada pengguna apabila Job tidak lagi digunakan. Penghapusan Job dengan perintah kubectl (misalnya, kubectl delete jobs/pi atau kubectl delete -f ./job.yaml). Ketika kamu menghapus Job menggunakan perintah kubectl, semua Pod yang terkait dengan Job tersebut akan ikut dihapus.

Secara default, sebuah Job akan dijalankan tanpa adanya interupsi kecuali terdapat Pod yang gagal, (restartPolicy=Never) atau terdapat Container yang dihentikan dalam kondisi error (restartPolicy=OnFailure), suatu keadaan dimana Job akan dijalankan dengan mekanisme yang dijelaskan di atas berdasarkan pada .spec.backoffLimit. Apabila .spec.backoffLimit telah mencapai limit, maka Job akan ditandai sebagai gagal dan Pod yang saat ini sedang dijalankan juga akan dihentikan.

Cara lain untuk menghentikan sebuah Job adalah dengan mengatur deadline aktif. Untuk melakukannya kamu dapat menspesifikasikan field .spec.activeDeadlineSeconds dari sebuah Job dengan suatu angka dalam satuan detik. Field activeDeadlineSeconds diterapkan pada durasi dari sebuah Job, tidak peduli seberapa banyak Pod yang dibuat. Setelah sebuah Job mencapai limit activeDeadlineSeconds, semua Pod yang dijalankan akan dihentikan dan status dari Job tersebut akan berubah menjadi type: Failed dengan reason: DeadlineExceeded.

Perhatikan bahwa field .spec.activeDeadlineSeconds pada Job memiliki tingkat presedensi di atas .spec.backoffLimit. Dengan demikian, sebuah Job yang sedang mencoba melakukan restart pada suatu Pod-nya tidak akan melakukan pembuatan Pod yang baru apabila Job tersebut telah mencapai limit yang didefinisikan pada activeDeadlineSeconds, bahkan apabila nilai dari backoffLimit belum tercapai.

Contoh:

apiVersion: batch/v1
kind: Job
metadata:
  name: pi-with-timeout
spec:
  backoffLimit: 5
  activeDeadlineSeconds: 100
  template:
    spec:
      Containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

Perhatikan bahwa baik spek Job dan spek templat Pod di dalam Job memiliki field activeDeadlineSeconds. Pastikan kamu telah menspesifikasikan nilai tersebut pada level yang dibutuhkan.

Mekanisme Clean Up Otomatis pada Job yang Sudah Selesai

Job yang sudah selesai biasanya tidak lagi dibutuhkan di dalam sistem. Tetap menjaga keberadaan objek-objek tersebut di dalam sistem akan memberikan tekanan tambahan pada API server. Jika sebuah Job yang diatur secara langsung oleh controller dengan level yang lebih tinggi, seperti CronJob, maka Job ini dapat di-clean up oleh CronJob berdasarkan policy berbasis kapasitas yang dispesifikasikan.

Mekanisme TTL untuk Job yang Telah Selesai Dijalankan

FEATURE STATE: Kubernetes v1.12 [alpha]

Salah satu cara untuk melakukan clean up Job yang telah selesai dijalankan (baik dengan status Complete atau Failed) secara otomatis adalah dengan menerapkan mekanisme TTL yang disediakan oleh controller TTL untuk sumber daya yang telah selesai digunakan, dengan cara menspesifikasikan field .spec.ttlSecondsAfterFinished dari Job tersebut.

Ketika controller TTL melakukan proses clean up pada Job, maka controller tersebut akan menghapus objek-objek terkait seperti Pod, serta Job itu sendiri. Perhatikan bahwa ketika suatu Job dihapus, maka lifecycle-nya akan menjamin, mekanisme finalizer yang ada akan tetap dihargai.

Sebagai contoh:

apiVersion: batch/v1
kind: Job
metadata:
  name: pi-with-ttl
spec:
  ttlSecondsAfterFinished: 100
  template:
    spec:
      Containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

Job pi-with-ttl akan dihapus secara otomatis, dalam jangka waktu 100 detik setelah Job tersebut selesai dijalankan.

Jika field ini dispesifikasikan sebagai 0, maka Job akan secara otomatis dihapus segera setelah Job tersebut selesai dijalankan. Jika field tersebut tidak dispesifikasikan, maka Job ini tidak akan dihapus oleh controller TTL setelah Job ini selesai dijalankan.

Perhatikan bahwa mekanisme TTL ini merupakan fitur alpha, dengan gerbang fitur TTLAfterFinished. Untuk informasi lebih lanjut, kamu dapat membaca dokumentasi untuk controller TTL untuk sumber daya yang telah selesai dijalankan.

Pola Job

Sebuah objek Job dapat digunakan untuk mendukung eksekusi paralel yang dapat diandalkan pada Pod. Objek Job tidak di-desain untuk mendukung proses paralel bersifat closely-communicating, seperti yang secara umum ditemukan dalam komputasi ilmiah. Meskipun begitu objek ini mendukung set work item yang independen namun saling terkait satu sama lainnya. Ini termasuk surel yang harus dikirim, frame yang harus di-render, berkas yang harus di-transcoded, jangkauan key yang ada di dalam basis data NoSQL, dsb.

Pada suatu sistem yang kompleks, terdapat beberapa set work item yang berbeda. Di sini, kami hanya mempertimbangkan work item yang ingin digunakan oleh pengguna untuk melakukan manajemen secara bersamaan — sebuah batch job.

Terdapat beberapa perbedaan pola pada komputasi paralel, setiap pola memiliki kelebihan dan kekurangannya masing-masing. Kekurangan dan kelebihan ini dijabarkan sebagai berikut:

  • Satu objek Job untuk setiap work item, atau sebuah Job untuk semua work item. Pilihan kedua akan lebih baik apabila digunakan untuk jumlah work item yang lebih besar. Sementara itu, pilihan pertama akan mengakibatkan overhead bagi pengguna dan juga sistem untuk mengaur jumlah objek Job yang cukup banyak.
  • Jumlah Pod yang dibuat sesuai dengan jumlah work item atau setiap Pod dapat memproses beberapa work item sekaligus. Pilihan pertama secara umum memerlukan modifikasi lebih sedikit untuk kode dan Container yang suda ada. Pilihan kedua akan lebih baik jika digunakan untuk jumlah work item yang lebih banyak, untuk alasan yang sama dengan poin sebelumnya.
  • Beberapa pendekatan menggunakan prinsip work queue. Hal ini membutuhkan sebuah service queue yang dijalankan, serta modifikasi untuk program atau Container yang sudah ada untuk mengizinkannya menggunakan working queue. Pendekatan lain akan lebih mudah untuk digunakan bagi aplikasi yang sudah ada.

Tradeoff yang dirangkum di sini, dengan kolom 2 dan 4 berkaitan dengan tradeoff yang dijelaskan di atas. Nama dari pola yang ada juga terkait dengan contoh dan deskripsi lebih lanjut.

Pola Objek dengan satu Job Pod yang lebih sedikit tadi work items? Penggunaan app tanpa modifikasi? Dapat dijalankan pada Kube versi 1.1?
Perluasan Templat Job
Queue dengan Pod untuk setiap Work Item sometimes
Queue dengan Variabel Pod Count
Job Single dengan penempatan Kerja Statis

Ketika kamu menspesifikasikan completion dengan .spec.completions, setiap Pod yang dibuat oleh controller Job memiliki spec yang identik. Artinya semua Pod untuk sebuah task akan memiliki perintah yang sama serta image, volume, serta variabel environment yang (hampir) sama. Pola ini merupakan salah satu cara berbeda yang diterapkan untuk mengatur Pod agar dapat bekerja untuk hal yang berbeda-beda.

Tabel ini menunjukkan pengaturan yang dibutuhkan untuk .spec.parallelism dan .spec.completions bagi setiap pola. Disini, W merupakan jumlah dari work item.

Pattern .spec.completions .spec.parallelism
Job Template Expansion 1 should be 1
Queue with Pod Per Work Item W any
Queue with Variable Pod Count 1 any
Single Job with Static Work Assignment W any

Penggunaan Tingkat Lanjut

Menspesifikasikan Selektor Pod Kamu Sendiri

Secara umum, ketika kamu membuat sebuah objek Job, kamu tidak menspesifikasikan .spec.selector. Sistem akan memberikan nilai default pada field ini ketika Job dibuat. Sistem akan memilih nilai dari selektor yang ada dan memastikan nilainya tidak akan beririsan dengan Job lainnya.

Meskipun demikian, pada beberapa kasus, kamu bisa saja memiliki kebutuhan untuk meng-override nilai dari selektor ini. Untuk melakukannya, kamu dapat menspesifikasikan .spec.selector dari Job.

Berhati-hatilah ketika kamu melakukan proses ini. Jika kamu menspesifikasikan sebuah label selektor yang tidak unik pada Pod yang ada di dalam Job tersebut, serta sesuai dengan Pod yang tidak terkait dengan Job tadi, maka Pod dari Job yang tidak terkait dengan Job tadi akna dihapus, atau Job ini akan menghitung completion dari Pod lain sebagai tolak ukur suksesnya Job tersebut, atau bisa saja salah satu atau kedua Job tidak dapat membuat Pod baru yang digunakan untuk menyelesaikan Job tersebut. Jika selektor yang tidak unik dipilih, maka controller lain (misalnya ReplicationController) dan Pod yang ada di dalamnya bisa saja memiliki perilaku yang tidak dapat diprediksi. Kubernetes tidak akan mencegah kemungkinan terjadinya hal ini ketika kamu menspesifikasikan nilai .spec.selector.

Berikut merupakan contoh skenario dimana kamu ingin menggunakan fitur ini.

Misalnya saja Job dengan nama old sudah dijalankan. Dan kamu ingin Pod yang sudah dijalankan untuk tetap berada pada state tersebut, tapi kamu juga ingin Pod selanjutnya yang dibuat untuk menggunakan templat Pod yang berbeda dan agar Job tersebut memiliki nama yang berbeda. Kamu tidak dapat mengubah Job karena field ini merupakan nilai yang tidak bisa diubah. Dengan demikian, kamu menghapus Job old tetapi tetap membiarkan Pod yang ada untuk jalan, menggunakan perintah kubectl delete jobs/old --cascade=false. Sebelum menghapus Job tadi, kamu mencatat selektor yang digunakan oleh Job tadi:

kubectl get job old -o yaml
kind: Job
metadata:
  name: old
  ...
spec:
  selector:
    matchLabels:
      controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
  ...

Kemudian kamu membuat sebuah Job baru dengan nama new dan kamu secara eksplisit menspesifikasikan selektor yang sama. Karena Pod dengan selektor yang sama memiliki label controller-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002, maka Pod-Pod lama tadi dikendalikan juga oleh Job new.

Kamu harus menspesifikasikan manualSelector: true pada Job yang baru karena kamu tidak menggunakan selektor yang diberikan secara default oleh sistem.

kind: Job
metadata:
  name: new
  ...
spec:
  manualSelector: true
  selector:
    matchLabels:
      controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
  ...

Job yang baru tadi kemudian akan memiliki uid yang berbeda dari a8f3d00d-c6d2-11e5-9f87-42010af00002. Pengaturan manualSelector: true memberikan perintah pada sistem bahwa kamu mengetahui apa yang kamu lakukan dan untuk mengizikan ketidaksesuaian ini untuk terjadi.

Alternatif

Pod Polosan

Ketika node dimana Pod dijalankan berada dalam kondisi reboot atau gagal, Pod tadi akan dihentikan dan tidak akan di-restart. Meskipun demikian, sebuah Job akan membuat Pod baru yang menggantikan Pod lama yang dihentikan. Untuk alasan inilah, kami memberikan rekomendasi agar kamu menggunakan sebuah Job dibandingkan dengan Pod yang biasa, bahkan jika aplikasi yang kamu gunakan hanya memerlukan sebuah Pod.

Replication Controller

Job merupakan komplemen dari Replication Controller. Sebuah Replication Controller mengatur Pod yang diharapkan untuk tidak dihentikan (misalnya, web server), dan sebuah Job mengatur Pod yang diharapkan untuk berhenti (misalnya, batch task).

Seperti yang sudah dibahas pada Lifecycle Pod, Job hanya pantas digunakan untuk Pod dengan RestartPolicy yang sama dengan OnFailure atau Never. (Perhatikan bahwa: Jika RestartPolicy tidak dispesifikasikan, nilai defaultnya adalah Always.)

Job Tunggal akan menginisiasi Kontroller Pod

Pola lain yang mungkin diterapkan adalah untuk sebuah Job tunggal untuk membuat sebuah Pod yang kemudian akan membuat Pod lainnya, bersifat selayaknya controller kustom bagi Pod tersebut. Hal ini mengizinkan fleksibilitas optimal, tetapi cukup kompleks untuk digunakan dan memiliki integrasi terbatas dengan Kubernetes.

Salah satu contoh dari pola ini adalah sebuah Job yang akan menginisiasi sebuah Pod yang menjalankan script yang kemudian akan menjalankan controller master Spark (kamu dapat melihatnya di contoh Spark), yang menjalankan driver Spark, dan kemudian melakukan mekanisme clean up.

Keuntungan dari pendekatan ini adalah proses keseluruhan yang memiliki jaminan completion dari sebuah Job, tetapi kontrol secara mutlak atas Pod yang dibuat serta tugas yang diberikan pada Pod tersebut.

CronJob

Kamu dapat menggunakan CronJob untuk membuat Job yang akan dijalankan pada waktu/tanggal yang spesifik, mirip dengan perangkat lunak cron yang ada pada Unix.