Add job running into completion in ID Localization. (#16705)
parent
ac1b7eee8e
commit
80e5ceb0d1
|
@ -0,0 +1,505 @@
|
|||
---
|
||||
title: Job - Dijalankan Hingga Selesai
|
||||
content_template: templates/concept
|
||||
feature:
|
||||
title: Eksekusi batch
|
||||
description: >
|
||||
Selain Service, Kubernetes juga dapat melakukan manajemen workload batch dan CI, melakukan penggantian Container-Container yang gagal, jika diinginkan.
|
||||
weight: 70
|
||||
---
|
||||
|
||||
{{% capture overview %}}
|
||||
|
||||
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.
|
||||
|
||||
{{% /capture %}}
|
||||
|
||||
|
||||
{{% capture body %}}
|
||||
|
||||
## 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.
|
||||
|
||||
{{< codenew file="controllers/job.yaml" >}}
|
||||
|
||||
Kamu dapat menjalankan contoh tersebut dengan menjalankan perintah berikut:
|
||||
|
||||
```shell
|
||||
kubectl apply -f https://k8s.io/examples/controllers/job.yaml
|
||||
```
|
||||
```
|
||||
job "pi" created
|
||||
```
|
||||
|
||||
Perhatikan status dari Job yang baru dibuat dengan menggunakan perintah`kubectl`:
|
||||
|
||||
```shell
|
||||
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:
|
||||
|
||||
```shell
|
||||
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:
|
||||
|
||||
```shell
|
||||
kubectl logs $pods
|
||||
```
|
||||
Keluaran yang dihasilkan akan sama dengan:
|
||||
```shell
|
||||
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959508295331168617278558890750983817546374649393192550604009277016711390098488240128583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912933136770289891521047521620569660240580381501935112533824300355876402474964732639141992726042699227967823547816360093417216412199245863150302861829745557067498385054945885869269956909272107975093029553211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000816470600161452491921732172147723501414419735685481613611573525521334757418494684385233239073941433345477624168625189835694855620992192221842725502542568876717904946016534668049886272327917860857843838279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863067442786220391949450471237137869609563643719172874677646575739624138908658326459958133904780275901
|
||||
```
|
||||
|
||||
## Menulis Spek Job
|
||||
|
||||
Sama halnya dengan konfigurasi Kubernetes lainnya, sebuah Job memerlukan _field_
|
||||
`apiVersion`, `kind`, dan `metadata`.
|
||||
|
||||
Sebuah Job juga membutuhkan sebuah [bagian `.spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status).
|
||||
|
||||
### Templat Pod
|
||||
|
||||
_Field_ `.spec.template` merupakan satu-satunya _field_ wajib pada `.spec`.
|
||||
|
||||
_Field_ `.spec.template` merupakan sebuah [templat Pod](/docs/concepts/workloads/pods/pod-overview/#pod-templates). _Field_ ini memiliki skema yang sama dengan yang ada pada [Pod](/docs/user-guide/pods),
|
||||
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](#pod-selektor))
|
||||
dan sebuah mekanisme _restart_ yang sesuai.
|
||||
|
||||
Hanya sebuah [`RestartPolicy`](/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) 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](#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](#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 {{< glossary_tooltip term_id="controller" >}} 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](/docs/concepts/workloads/pods/pod-lifecycle/#example-states) 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.
|
||||
|
||||
{{< note >}}
|
||||
Isu [#54870](https://github.com/kubernetes/kubernetes/issues/54870) masih ada untuk versi Kubernetes sebelum 1.12.
|
||||
{{< /note >}}
|
||||
{{< note >}}
|
||||
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.
|
||||
{{< /note >}}
|
||||
|
||||
## 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:
|
||||
|
||||
```yaml
|
||||
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](/docs/concepts/workloads/pods/init-Containers/#detailed-behavior) 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](/docs/concepts/workloads/controllers/cron-jobs/), 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 for_k8s_version="v1.12" state="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](/docs/concepts/workloads/controllers/ttlafterfinished/) 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:
|
||||
|
||||
```yaml
|
||||
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](/docs/concepts/workloads/controllers/ttlafterfinished/) 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](/docs/tasks/job/parallel-processing-expansion/) | | | ✓ | ✓ |
|
||||
| [Queue dengan Pod untuk setiap _Work Item_](/docs/tasks/job/coarse-parallel-processing-work-queue/) | ✓ | | sometimes | ✓ |
|
||||
| [Queue dengan Variabel _Pod Count_](/docs/tasks/job/fine-parallel-processing-work-queue/) | ✓ | ✓ | | ✓ |
|
||||
| Job Single dengan penempatan Kerja Statis | ✓ | | ✓ | |
|
||||
|
||||
Ketika kamu menspesifikasikan _completion_ dengan `.spec.completions`, setiap Pod yang dibuat oleh _controller_ Job
|
||||
memiliki [`spec`](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status) 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](/docs/tasks/job/parallel-processing-expansion/) | 1 | should be 1 |
|
||||
| [Queue with Pod Per Work Item](/docs/tasks/job/coarse-parallel-processing-work-queue/) | W | any |
|
||||
| [Queue with Variable Pod Count](/docs/tasks/job/fine-parallel-processing-work-queue/) | 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](/docs/user-guide/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](/docs/concepts/workloads/pods/pod-lifecycle/), `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](https://github.com/kubernetes/examples/tree/{{< param "githubbranch" >}}/staging/spark/README.md)),
|
||||
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 {#cron-jobs}
|
||||
|
||||
Kamu dapat menggunakan [`CronJob`](/docs/concepts/workloads/controllers/cron-jobs/) untuk membuat Job yang akan
|
||||
dijalankan pada waktu/tanggal yang spesifik, mirip dengan perangkat lunak `cron` yang ada pada Unix.
|
||||
|
||||
{{% /capture %}}
|
|
@ -0,0 +1,13 @@
|
|||
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
|
Loading…
Reference in New Issue