diff --git a/content/id/docs/concepts/workloads/controllers/jobs-run-to-completion.md b/content/id/docs/concepts/workloads/controllers/jobs-run-to-completion.md new file mode 100644 index 0000000000000..1cfe36117cd18 --- /dev/null +++ b/content/id/docs/concepts/workloads/controllers/jobs-run-to-completion.md @@ -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: +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: + Mounts: + Volumes: +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 %}} diff --git a/content/id/examples/controllers/job.yaml b/content/id/examples/controllers/job.yaml new file mode 100644 index 0000000000000..ee1d89fdd88f5 --- /dev/null +++ b/content/id/examples/controllers/job.yaml @@ -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