moving "assign-pod" and "taint & toleration" into scheduling-eviction.
This commit is contained in:
@@ -0,0 +1,325 @@
|
||||
---
|
||||
title: Menetapkan Pod ke Node
|
||||
content_type: concept
|
||||
weight: 30
|
||||
---
|
||||
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
Kamu dapat memaksa sebuah [pod](/id/docs/concepts/workloads/pods/pod/) untuk hanya dapat berjalan pada [node](/id/docs/concepts/architecture/nodes/) tertentu atau mengajukannya agar berjalan pada node tertentu. Ada beberapa cara untuk melakukan hal tersebut. Semua cara yang direkomendasikan adalah dengan menggunakan [_selector_ label](/id/docs/concepts/overview/working-with-objects/labels/) untuk menetapkan pilihan yang kamu inginkan. Pada umumnya, pembatasan ini tidak dibutuhkan, sebagaimana _scheduler_ akan melakukan penempatan yang proporsional dengan otomatis (seperti contohnya menyebar pod di node-node, tidak menempatkan pod pada node dengan sumber daya yang tidak memadai, dst.) tetapi ada keadaan-keadaan tertentu yang membuat kamu memiliki kendali lebih terhadap node yang menjadi tempat pod dijalankan, contohnya untuk memastikan pod dijalankan pada mesin yang telah terpasang SSD, atau untuk menempatkan pod-pod dari dua servis yang berbeda yang sering berkomunikasi bersamaan ke dalam zona ketersediaan yang sama.
|
||||
|
||||
Kamu dapat menemukan semua berkas untuk contoh-contoh berikut pada [dokumentasi yang kami sediakan di sini](https://github.com/kubernetes/website/tree/{{< param "docsbranch" >}}/content/en/docs/concepts/configuration/)
|
||||
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## nodeSelector
|
||||
|
||||
Penggunaan `nodeSelector` adalah cara pembatasan pemilihan node paling sederhana yang direkomendasikan. `nodeSelector` adalah sebuah _field_ pada PodSpec. `nodeSelector` memerinci sebuah map berisi pasangan kunci-nilai. Agar pod dapat dijalankan pada sebuah node yang memenuhi syarat, node tersebut harus memiliki masing-masing dari pasangan kunci-nilai yang dinyatakan sebagai label (namun node juga dapat memiliki label tambahan diluar itu). Penggunaan paling umum adalah satu pasang kunci-nilai.
|
||||
|
||||
Mari kita telusuri contoh dari penggunaan `nodeSelector`.
|
||||
|
||||
### Langkah Nol: Prasyarat
|
||||
|
||||
Contoh ini mengasumsikan bahwa kamu memiliki pemahaman dasar tentang pod Kubernetes dan kamu telah [membuat klaster Kubernetes](https://github.com/kubernetes/kubernetes#documentation).
|
||||
|
||||
### Langkah Satu: Menyematkan label pada node
|
||||
|
||||
Jalankan `kubectl get nodes` untuk mendapatkan nama dari node-node yang ada dalam klaster kamu. Temukan node yang akan kamu tambahkan label, kemudian jalankan perintah `kubectl label nodes <node-name> <label-key>=<label-value>` untuk menambahkan label pada node yang telah kamu pilih. Sebagai contoh, jika nama node yang saya pilih adalah 'kubernetes-foo-node-1.c.a-robinson.internal' dan label yang ingin saya tambahkan adalah 'disktype=ssd', maka saya dapat menjalankan `kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd`.
|
||||
|
||||
Jika terjadi kegagalan dengan kesalahan perintah yang tidak _valid_ ("_invalid command_"), kemungkinan besar kamu menggunakan kubectl dengan versi lebih lama yang tidak memiliki perintah `label`. Dalam hal ini, lihat [versi sebelumnya] (https://github.com/kubernetes/kubernetes/blob/a053dbc313572ed60d89dae9821ecab8bfd676dc/examples/node-selection/README.md) dari petunjuk ini untuk instruksi tentang cara menetapkan label pada node.
|
||||
|
||||
Kamu dapat memastikan perintah telah berhasil dengan menjalankan ulang perintah `kubectl get nodes --show-labels` and memeriksa bahwa node yang dipilih sekarang sudah memiliki label yang ditambahkan. Kamu juga dapat menggunakan `kubectl describe node "nodename"` untuk melihat daftar lengkap label yang dimiliki sebuah node.
|
||||
|
||||
### Langkah Dua: Menambahkan sebuah nodeSelector ke konfigurasi pod kamu
|
||||
|
||||
Ambil berkas konfigurasi pod manapun yang akan kamu jalankan, dan tambahkan sebuah bagian `nodeSelector` pada berkas tersebut, seperti berikut. Sebagai contoh, jika berikut ini adalah konfigurasi pod saya:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
env: test
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
```
|
||||
|
||||
Kemudian tambahkan sebuah `nodeSelector` seperti berikut:
|
||||
|
||||
{{< codenew file="pods/pod-nginx.yaml" >}}
|
||||
|
||||
Ketika kamu menjalankan perintah `kubectl apply -f https://k8s.io/examples/pods/pod-nginx.yaml`, pod tersebut akan dijadwalkan pada node yang memiliki label yang dirinci. Kamu dapat memastikan penambahan nodeSelector berhasil dengan menjalankan `kubectl get pods -o wide` dan melihat "NODE" tempat Pod ditugaskan.
|
||||
|
||||
## Selingan: label node _built-in_
|
||||
|
||||
Sebagai tambahan dari label yang kamu [sematkan](#step-one-attach-label-to-the-node), node sudah terisi dengan satu set label standar. Pada Kubernetes v1.4 label tersebut adalah
|
||||
|
||||
* `kubernetes.io/hostname`
|
||||
* `failure-domain.beta.kubernetes.io/zone`
|
||||
* `failure-domain.beta.kubernetes.io/region`
|
||||
* `beta.kubernetes.io/instance-type`
|
||||
* `kubernetes.io/os`
|
||||
* `kubernetes.io/arch`
|
||||
|
||||
{{< note >}}
|
||||
Nilai dari label-label tersebut spesifik untuk setiap penyedia layanan _cloud_ dan tidak dijamin reliabilitasnya.
|
||||
Contohnya, nilai dari `kubernetes.io/hostname` bisa saja sama dengan nama node pada beberapa lingkungan dan berbeda pada lingkungan lain.
|
||||
{{< /note >}}
|
||||
|
||||
## Isolasi/pembatasan Node
|
||||
|
||||
Menambahkan label pada objek node memungkinkan penargetan pod pada node atau grup node yang spesifik. Penambahan label ini dapat digunakan untuk memastikan pod yang spesifik hanya berjalan pada node dengan isolasi, keamanan, atau pengaturan tertentu. Saat menggunakan label untuk tujuan tersebut, memilih kunci label yang tidak bisa dimodifikasi oleh proses kubelet pada node sangat direkomendasikan. Hal ini mencegah node yang telah diubah untuk menggunakan kredensial kubelet-nya untuk mengatur label-label pada objek nodenya sediri, dan mempengaruhi scheduler untuk menjadwalkan _workload_ ke node yang telah diubah tersebut.
|
||||
|
||||
_Plugin_ penerimaan `NodeRestriction` mencegah kubeletes untuk megatur atau mengubah label dengan awalan `node-restriction.kubernetes.io/`.
|
||||
Untuk memanfaatkan awalan label untuk isolasi node:
|
||||
|
||||
1. Pastikan kamu menggunakan [_authorizer_ node](/docs/reference/access-authn-authz/node/) dan mengaktifkan [_plugin admission NodeRestriction_(/docs/reference/access-authn-authz/admission-controllers/#noderestriction).
|
||||
|
||||
2. Tambah label dengan awalan `node-restriction.kubernetes.io/` ke objek node kamu, dan gunakan label tersebut pada node _selector_ kamu. Contohnya, `example.com.node-restriction.kubernetes.io/fips=true` or `example.com.node-restriction.kubernetes.io/pci-dss=true`.
|
||||
|
||||
## Afinitas dan anti-afinitas
|
||||
|
||||
`_Field_ nodeSelector` menyediakan cara yang sangat sederhana untuk membatasi pod ke node dengan label-label tertentu. Fitur afinitas/anti-afinitas saat ini bersifat beta dan memperluas tipe pembatasan yang dapat kamu nyatakan. Peningkatan kunci dari fitur ini adalah
|
||||
|
||||
1. Bahasa yang lebih ekspresif (tidak hanya "AND of exact match")
|
||||
2. Kamu dapat memberikan indikasi bahwa aturan yang dinyatakan bersifat rendah/preferensi dibanding dengan persyaratan mutlak sehingga jika scheduler tidak dapat memenuhinya, pod tetap akan dijadwalkan
|
||||
3. Kamu dapat membatasi dengan label pada pod-pod lain yang berjalan pada node (atau domain _topological_ lain), daripada dengan label pada node itu sendiri, yang memungkinkan pengaturan tentang pod yang dapat dan tidak dapat dilokasikan bersama.
|
||||
|
||||
Fitur afinitas terdiri dari dua tipe afinitas yaitu "node afinitas" dan "inter-pod afinitas/anti-afinitas"
|
||||
Node afinitas adalah seperti `nodeSelector` yang telah ada (tetapi dengam dua kelebihan pertama yang terdaftar di atas), sementara inter-pod afinitas/anti-afinitas membatasi pada label pod daripada label node, seperti yang dijelaskan pada item ketiga pada daftar di atas, sebagai tambahan dari item pertama dan kedua.
|
||||
|
||||
_Field_ `nodeSelector` tetap berjalan seperti biasa, namun pada akhirnya akan ditinggalkan karena afinitas node dapat menyatakan semua yang `nodeSelector` dapat nyatakan.
|
||||
|
||||
### Afinitas node (fitur beta)
|
||||
|
||||
Afinitas node diperkenalkan sebagai fitur alfa pada Kubernetes 1.2.
|
||||
Afinitas node secara konseptual mirip dengan `nodeSelector` yang memungkinkan kamu untuk membatasi node yang memenuhi syarat untuk penjadwalan pod, berdasarkan label pada node.
|
||||
|
||||
Saat ini ada dia tipe afinitas node, yaitu `requiredDuringSchedulingIgnoredDuringExecution` dan
|
||||
`preferredDuringSchedulingIgnoredDuringExecution`. Kamu dapat menganggap dua tipe ini sebagai "kuat" dan "lemah" secara berurutan, dalam arti tipe pertama menyatakan peraturan yang *harus* dipenuhi agar pod dapat dijadwalkan pada node (sama seperti `nodeSelector` tetapi menggunakan sintaksis yang lebih ekpresif), sementara tipe kedua menyatakan *preferensi* yang akan dicoba dilaksanakan tetapi tidak akan dijamin oleh scheduler. Bagian "IgnoredDuringExecution" dari nama tipe ini berarti, mirip dengan cara kerja `nodeSelector`, jika label pada node berubah pada _runtime_ yang menyebabkan aturan afinitas pada pod tidak lagi terpenuhi, pod akan tetap berjalan pada node. Pada masa yang akan datang kami berencana menawarkan `requiredDuringSchedulingRequiredDuringExecution` yang akan berjalan seperti `requiredDuringSchedulingIgnoredDuringExecution` hanya saja tipe ini akan mengeluarkan pod dari node yang gagal untuk memenuhi persyaratan afinitas node pod.
|
||||
|
||||
Dengan denikian, contoh dari `requiredDuringSchedulingIgnoredDuringExecution` adalah "hanya jalankan pod pada node dengan Intel CPU" dan contoh dari `preferredDuringSchedulingIgnoredDuringExecution` adalah "coba jalankan set pod ini dalam zona ketersediaan XYZ, tetapi jika tidak memungkinkan, maka biarkan beberapa pod berjalan di tempat lain".
|
||||
|
||||
Afinitas node dinyatakan sebagai _field_ `nodeAffinity` dari _field_ `affinity` pada PodSpec.
|
||||
|
||||
Berikut ini contoh dari pod yang menggunakan afinitas node:
|
||||
|
||||
{{< codenew file="pods/pod-with-node-affinity.yaml" >}}
|
||||
|
||||
Aturan afinitas node tersebut menyatakan pod hanya bisa ditugaskan pada node dengan label yang memiliki kunci `kubernetes.io/e2e-az-name` dan bernilai `e2e-az1` atau `e2e-az2`. Selain itu, dari semua node yang memenuhi kriteria tersebut, mode dengan label dengan kunci `another-node-label-key` and bernilai `another-node-label-value` harus lebih diutamakan.
|
||||
|
||||
Kamu dapat meilhat operator `In` digunakan dalam contoh berikut. Sitaksis afinitas node yang baru mendukung operator-operator berikut: `In`, `NotIn`, `Exists`, `DoesNotExist`, `Gt`, `Lt`. Kamu dapat menggunakan `NotIn` dan `DoesNotExist` untuk mewujudkan perilaku node anti-afinitas, atau menggunakan [node taints](/id/docs/concepts/scheduling-eviction/taint-and-toleration/) untuk menolak pod dari node tertentu.
|
||||
|
||||
Jika kamu menyatakan `nodeSelector` dan `nodeAffinity`. *keduanya* harus dipenuhi agar pod dapat dijadwalkan pada node kandidat.
|
||||
|
||||
Jika kamu menyatakan beberapa `nodeSelectorTerms` yang terkait dengan tipe `nodeAffinity`, maka pod akan dijadwalkan pada node **jika salah satu** dari `nodeSelectorTerms` dapat terpenuhi.
|
||||
|
||||
Jika kamu menyatakan beberapa `matchExpressions` yang terkait dengan `nodeSelectorTerms`, makan pod dapat dijadwalkan pada node **hanya jika semua** `matchExpressions` dapat terpenuhi.
|
||||
|
||||
Jika kamu menghapus atau mengubah label pada node tempat pod dijadwalkan, pod tidak akan dihapus. Dengan kata lain, pemilihan afinitas hanya bekerja pada saat waktu penjadwalan pod.
|
||||
|
||||
_Field_ `weight` pada `preferredDuringSchedulingIgnoredDuringExecution` berada pada rentang nilai 1-100. Untuk setiap node yang memenuhi semua persyaratan penjadwalan (permintaan sumber daya, pernyataan afinitas RequiredDuringScheduling, dll.), _scheduler_ akan menghitung nilai jumlah dengan melakukan iterasi pada elemen-elemen dari _field_ ini dan menambah "bobot" pada jumlah jika node cocok dengan MatchExpressions yang sesuai. Nilai ini kemudian digabungkan dengan nilai dari fungsi prioritas lain untuk node. Node dengan nilai tertinggi adalah node lebih diutamakan.
|
||||
|
||||
Untuk informasi lebih lanjut tentang afinitas node kamu dapat melihat [design doc](https://git.k8s.io/community/contributors/design-proposals/scheduling/nodeaffinity.md).
|
||||
|
||||
|
||||
### Afinitas and anti-afinitas antar pod (fitur beta)
|
||||
|
||||
Afinitas and anti-afinitas antar pod diperkenalkan pada Kubernetes 1.4. Afinitas and anti-afinitas antar pod memungkinkan kamu untuk membatasi node yang memenuhi syarat untuk penjadwalan pod *berdasarkan label-label pada pod yang sudah berjalan pada node* daripada berdasarkan label-label pada node. Aturan tersebut berbentuk "pod ini harus (atau, dalam kasus
|
||||
anti-afinitas, tidak boleh) berjalan dalam X jika X itu sudah menjalankan satu atau lebih pod yang memenuhi aturan Y". Y dinyatakan sebagai sebuah LabelSelector dengan daftar namespace terkait; tidak seperti node, karena pod are namespaced (maka dari itu label-label pada pod diberi namespace secara implisit), sebuah label selector di atas label-label pod harus menentukan namespace yang akan diterapkan selector. Secara konsep X adalah domain topologi seperti node, rack, zona penyedia cloud, daerah penyedia cloud, dll. Kamu dapat menyatakannya menggunakan `topologyKey` yang merupakan kunci untuk label node yang digunakan sistem untuk menunjukkan domain topologi tersebut, contohnya lihat kunci label yang terdaftar di atas pada bagian [Selingan: label node built-in](#interlude-built-in-node-labels).
|
||||
|
||||
{{< note >}}
|
||||
Afinitas and anti-afinitas antar pod membutuhkan jumlah pemrosesan yang substansial yang dapat memperlambat penjadwalan pada klaster berukuran besar secara signifikan. Kami tidak merekomendasikan penggunaan mereka pada klaster yang berukuran lebih besar dari beberapa ratus node.
|
||||
{{< /note >}}
|
||||
|
||||
{{< note >}}
|
||||
Anti-afinitas pod mengharuskan node untuk diberi label secara konsisten, misalnya setiap node dalam klaster harus memiliki label sesuai yang cocok dengan `topologyKey`. Jika sebagian atau semua node tidak memiliki label `topologyKey` yang dinyatakan, hal ini dapat menyebabkan perilaku yang tidak diinginkan.
|
||||
{{< /note >}}
|
||||
|
||||
Seperti afinitas node, ada dua tipe afinitas dan anti-afinitas pod, yaitu `requiredDuringSchedulingIgnoredDuringExecution` dan
|
||||
`preferredDuringSchedulingIgnoredDuringExecution` yang menunjukan persyaratan "kuat" vs. "lemah". Lihat deskripsi pada bagian afinitas node sebelumnya.
|
||||
Sebuah contoh dari afinitas `requiredDuringSchedulingIgnoredDuringExecution` adalah "Tempatkan bersamaan pod layanan A dan layanan B di zona yang sama, karena mereka banyak berkomunikasi satu sama lain"
|
||||
dan contoh `preferDuringSchedulingIgnoredDuringExecution` anti-afinitas akan menjadi "sebarkan pod dari layanan ini di seluruh zona" (persyaratan kuat tidak masuk akal, karena kamu mungkin memiliki lebih banyak pod daripada zona).
|
||||
|
||||
Afinitas antar pod dinyatakan sebagai _field_ `podAffinity` dari _field_ `affinity` pada PodSpec dan anti-afinitas antar pod dinyatakan sebagai _field_ `podAntiAffinity` dari _field_ `affinity` pada PodSpec.
|
||||
|
||||
#### Contoh pod yang menggunakan pod affinity:
|
||||
|
||||
{{< codenew file="pods/pod-with-pod-affinity.yaml" >}}
|
||||
|
||||
Afinitas pada pod tersebut menetapkan sebuah aturan afinitas pod dan aturan anti-afinitas pod. Pada contoh ini, `podAffinity` adalah `requiredDuringSchedulingIgnoredDuringExecution`
|
||||
sementara `podAntiAffinity` adalah `preferredDuringSchedulingIgnoredDuringExecution`. Aturan afinitas pod menyatakan bahwa pod dapat dijadwalkan pada node hanya jika node tersebut berada pada zona yang sama dengan minimal satu pod yang sudah berjalan yang memiliki label dengan kunci "security" dan bernilai "S1". (Lebih detail, pod dapat berjalan pada node N jika node N memiliki label dengan kunci `failure-domain.beta.kubernetes.io/zone`dan nilai V sehingga ada minimal satu node dalam klaster dengan kunci `failure-domain.beta.kubernetes.io/zone` dan bernilai V yang menjalankan pod yang memiliki label dengan kunci "security" dan bernilai "S1".) Aturan anti-afinitas pod menyatakan bahwa pod memilih untuk tidak dijadwalkan pada sebuah node jika node tersebut sudah menjalankan pod yang memiliki label dengan kunci "security" dan bernilai "S2". (Jika `topologyKey` adalah `failure-domain.beta.kubernetes.io/zone` maka dapat diartikan bahwa pod tidak dapat dijadwalkan pada node jika node berada pada zona yang sama dengan pod yang memiliki label dengan kunci "security" dan bernilai "S2".) Lihat [design doc](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md) untuk lebih banyak contoh afinitas dan anti-afinitas pod, baik `requiredDuringSchedulingIgnoredDuringExecution`
|
||||
maupun `preferredDuringSchedulingIgnoredDuringExecution`.
|
||||
|
||||
Operator yang sah untuk afinitas dan anti-afinitas pod adalah `In`, `NotIn`, `Exists`, `DoesNotExist`.
|
||||
|
||||
Pada dasarnya, `topologyKey` dapat berupa label-kunci apapun yang sah. Namun, untuk alasan performa dan keamanan, ada beberapa batasan untuk `topologyKey`:
|
||||
|
||||
1. Untuk afinitas and anti-afinitas pod `requiredDuringSchedulingIgnoredDuringExecution`, `topologyKey` tidak boleh kosong.
|
||||
2. Untuk anti-afinitas pod `requiredDuringSchedulingIgnoredDuringExecution`, pengontrol penerimaan `LimitPodHardAntiAffinityTopology` diperkenalkan untuk membatasi `topologyKey` pada `kubernetes.io/hostname`. Jika kamu menginginkan untuk membuatnya tersedia untuk topologi khusus, kamu dapat memodifikasi pengontrol penerimaan, atau cukup menonaktifkannya saja.
|
||||
3. Untuk anti-afinitas pod `preferredDuringSchedulingIgnoredDuringExecution`, `topologyKey` yang kosong diinterpretasikan sebagai "semua topologi" ("semua topologi" sekarang dibatasi pada kombinasi dari `kubernetes.io/hostname`, `failure-domain.beta.kubernetes.io/zone` dan `failure-domain.beta.kubernetes.io/region`).
|
||||
4. Kecuali untuk kasus-kasus di atas, `topologyKey` dapat berupa label-kunci apapun yang sah.
|
||||
|
||||
Sebagai tambahan untuk `labelSelector` and `topologyKey`, kamu secara opsional dapat menyatakan daftar `namespaces` dari namespaces yang akan digunakan untuk mencocokan `labelSelector` (daftar ini berjalan pada level definisi yang sama dengan `labelSelector` dan `topologyKey`)
|
||||
|
||||
Jika dihilangkan atau kosong, daftar ini sesuai standar akan merujuk pada _namespace_ dari pod tempat definisi afinitas/anti-afinitas dinyatakan.
|
||||
|
||||
Semua `matchExpressions` berkaitan dengan afinitas and anti-afinitas `requiredDuringSchedulingIgnoredDuringExecution` harus dipenuhi agar pod dapat dijadwalkan pada node.
|
||||
|
||||
#### Penggunaan yang lebih praktikal
|
||||
|
||||
Afinitas and anti-afinitas antar pod dapat menjadi lebih berguna saat digunakan bersamaan dengan koleksi dengan level yang lebih tinggi seperti ReplicaSets, StatefulSets, Deployments, dll. Pengguna dapat dengan mudah mengkonfigurasi bahwa satu set workload harus
|
||||
ditempatkan bersama dalam topologi yang didefinisikan sama, misalnya, node yang sama.
|
||||
|
||||
##### Selalu ditempatkan bersamaan pada node yang sama
|
||||
|
||||
Dalam klaster berisi 3 node, sebuah aplikasi web memiliki in-memory cache seperti redis. Kita menginginkan agar _web-server_ dari aplikasi ini sebisa mungkin ditempatkan bersamaan dengan cache.
|
||||
|
||||
Berikut ini kutipan yaml dari deployment redis sederhana dengan 3 replika dan label selector `app=store`, Deployment memiliki konfigurasi `PodAntiAffinity` untuk memastikan _scheduler_ tidak menempatkan replika bersamaan pada satu node.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis-cache
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: store
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: store
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: redis-server
|
||||
image: redis:3.2-alpine
|
||||
```
|
||||
|
||||
Kutipan yaml dari deployment webserver berikut ini memiliki konfigurasi `podAntiAffinity` dan `podAffinity`. Konfigurasi ini menginformasikan scheduler bahwa semua replika harus ditempatkan bersamaan dengan pod yang memiliki label selector `app=store`. Konfigurasi ini juga memastikan bahwa setiap replika webserver tidak ditempatkan bersamaan pada satu node.
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: web-server
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web-store
|
||||
replicas: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: web-store
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- web-store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
podAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- store
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
containers:
|
||||
- name: web-app
|
||||
image: nginx:1.12-alpine
|
||||
```
|
||||
|
||||
Jika kita membuat kedua dployment di atas, klaster berisi 3 node kita seharusnya menjadi seperti berikut.
|
||||
|
||||
| node-1 | node-2 | node-3 |
|
||||
|:--------------------:|:-------------------:|:------------------:|
|
||||
| *webserver-1* | *webserver-2* | *webserver-3* |
|
||||
| *cache-1* | *cache-2* | *cache-3* |
|
||||
|
||||
|
||||
st
|
||||
Seperti yang kamu lihat, semua 3 replika dari `web-server` secara otomatis ditempatkan bersama dengan cache seperti yang diharapkan.
|
||||
|
||||
```
|
||||
$ kubectl get pods -o wide
|
||||
NAME READY STATUS RESTARTS AGE IP NODE
|
||||
redis-cache-1450370735-6dzlj 1/1 Running 0 8m 10.192.4.2 kube-node-3
|
||||
redis-cache-1450370735-j2j96 1/1 Running 0 8m 10.192.2.2 kube-node-1
|
||||
redis-cache-1450370735-z73mh 1/1 Running 0 8m 10.192.3.1 kube-node-2
|
||||
web-server-1287567482-5d4dz 1/1 Running 0 7m 10.192.2.3 kube-node-1
|
||||
web-server-1287567482-6f7v5 1/1 Running 0 7m 10.192.4.3 kube-node-3
|
||||
web-server-1287567482-s330j 1/1 Running 0 7m 10.192.3.2 kube-node-2
|
||||
```
|
||||
|
||||
##### Tidak akan pernah ditempatkan bersamaan dalam node yang sama
|
||||
|
||||
|
||||
Contoh di atas menggunakan aturan `PodAntiAffinity` dengan` topologyKey: "kubernetes.io/hostname"` untuk melakukan deploy klaster redis sehingga tidak ada dua instance terletak pada hos yang sama.
|
||||
Lihat [tutorial ZooKeeper](/docs/tutorials/stateful-application/zookeeper/#tolerating-node-failure) untuk contoh dari konfigurasi StatefulSet dengan anti-afinitas untuk ketersediaan tinggi, menggunakan teknik yang sama.
|
||||
|
||||
Untuk informasi lebih lanjut tentang afinitas/anti-afinitas antar pod, lihat [design doc](https://git.k8s.io/community/contributors/design-proposals/scheduling/podaffinity.md).
|
||||
|
||||
Kamu juga dapat mengecek [Taints](/id/docs/concepts/scheduling-eviction/taint-and-toleration/), yang memungkinkan sebuah *node* untuk *menolak* sekumpulan pod.
|
||||
|
||||
## nodeName
|
||||
|
||||
`nodeName` adalah bentuk paling sederhana dari pembatasan pemilihan node, tetapi karena
|
||||
keterbatasannya biasanya tidak digunakan. `nodeName` adalah sebuah _field_ dari
|
||||
PodSpec. Jika tidak kosong, scheduler mengabaikan pod dan
|
||||
kubelet yang berjalan pada node tersebut yang mencoba menjalankan pod. Maka, jika
|
||||
`nodeName` disediakan dalam PodSpec, ia memiliki hak yang lebih tinggi dibanding metode-metode di atas untuk pemilihan node.
|
||||
|
||||
Beberapa keterbatasan dari penggunaan `nodeName` untuk memilih node adalah:
|
||||
|
||||
- Jika node yang disebut tidak ada, maka pod tidak akan dijalankan, dan dalam beberapa kasus akan
|
||||
dihapus secara otomatis.
|
||||
- Jika node yang disebut tidak memiliki resource yang cukup untuk mengakomodasi pod, pod akan gagal
|
||||
dan alasannya akan mengindikasikan sebab kegagalan, misalnya OutOfmemory atau OutOfcpu.
|
||||
- Nama node pada lingkungan cloud tidak selalu dapat diprediksi atau stabil.
|
||||
|
||||
Berikut ini contoh konfigurasi pod menggunakan _field_ `nodeName`:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
nodeName: kube-01
|
||||
```
|
||||
Pod di atas akan berjalan pada node kube-01.
|
||||
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: Penjadwal Kubernetes
|
||||
content_type: concept
|
||||
weight: 50
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
Dalam Kubernetes, _scheduling_ atau penjadwalan ditujukan untuk memastikan
|
||||
{{< glossary_tooltip text="Pod" term_id="pod" >}} mendapatkan
|
||||
{{< glossary_tooltip text="Node" term_id="node" >}} sehingga
|
||||
{{< glossary_tooltip term_id="kubelet" >}} dapat menjalankannya.
|
||||
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## Ikhtisar Penjadwalan {#penjadwalan}
|
||||
|
||||
Sebuah penjadwal mengawasi Pod yang baru saja dibuat dan belum ada Node yang
|
||||
dialokasikan untuknya. Untuk setiap Pod yang ditemukan oleh penjadwal, maka
|
||||
penjadwal tersebut bertanggung jawab untuk menemukan Node terbaik untuk
|
||||
menjalankan Pod. Penjadwal dapat menetapkan keputusan penempatan ini dengan
|
||||
mempertimbangkan prinsip-prinsip penjadwalan yang dijelaskan di bawah ini.
|
||||
|
||||
Jika kamu ingin memahami mengapa Pod ditempatkan pada Node tertentu, atau jika
|
||||
kamu berencana untuk mengimplementasikan penjadwal kustom sendiri, halaman ini
|
||||
akan membantu kamu belajar tentang penjadwalan.
|
||||
|
||||
## Kube-scheduler
|
||||
|
||||
[_Kube-scheduler_](https://kubernetes.io/docs/reference/command-line-tools-reference/kube-scheduler/)
|
||||
adalah penjadwal standar untuk Kubernetes dan dijalankan sebagai bagian dari
|
||||
{{< glossary_tooltip text="_control plane_" term_id="control-plane" >}}.
|
||||
_Kube-scheduler_ dirancang agar jika kamu mau dan perlu, kamu bisa menulis
|
||||
komponen penjadwalan kamu sendiri dan menggunakannya.
|
||||
|
||||
Untuk setiap Pod yang baru dibuat atau Pod yang tak terjadwal lainnya,
|
||||
_kube-scheduler_ memilih Node yang optimal untuk menjalankannya. Namun, setiap
|
||||
kontainer masuk Pod memiliki persyaratan sumber daya yang berbeda dan setiap Pod
|
||||
juga memiliki persyaratan yang berbeda juga. Oleh karena itu, Node yang ada
|
||||
perlu dipilih sesuai dengan persyaratan khusus penjadwalan.
|
||||
|
||||
Dalam sebuah Klaster, Node yang memenuhi persyaratan penjadwalan untuk suatu Pod
|
||||
disebut Node _feasible_. Jika tidak ada Node yang cocok, maka Pod tetap tidak
|
||||
terjadwal sampai penjadwal yang mampu menempatkannya.
|
||||
|
||||
Penjadwal menemukan Node-Node yang layak untuk sebuah Pod dan kemudian
|
||||
menjalankan sekumpulan fungsi untuk menilai Node-Node yang layak dan mengambil
|
||||
satu Node dengan skor tertinggi di antara Node-Node yang layak untuk menjalankan
|
||||
Pod. Penjadwal kemudian memberi tahu server API tentang keputusan ini dalam
|
||||
proses yang disebut dengan _binding_.
|
||||
|
||||
Beberapa faktor yang perlu dipertimbangkan untuk keputusan penjadwalan termasuk
|
||||
persyaratan sumber daya individu dan kolektif, aturan kebijakan / perangkat keras /
|
||||
lunak, spesifikasi persamaan dan anti-persamaan, lokalitas data, interferensi
|
||||
antar Workloads, dan sebagainya.
|
||||
|
||||
### Pemilihan node pada kube-scheduler {#kube-scheduler-implementation}
|
||||
|
||||
_Kube-scheduler_ memilih node untuk pod dalam 2 langkah operasi:
|
||||
|
||||
1. Filtering
|
||||
2. Scoring
|
||||
|
||||
Langkah _filtering_ menemukan sekumpulan Nodes yang layak untuk menjadwalkan
|
||||
Pod. Misalnya, penyarin PodFitsResources memeriksa apakah Node kandidat
|
||||
memiliki sumber daya yang cukup untuk memenuhi permintaan spesifik sumber daya dari
|
||||
Pod. Setelah langkah ini, daftar Node akan berisi Node-node yang sesuai;
|
||||
seringkali, akan terisi lebih dari satu. Jika daftar itu kosong, maka Pod itu
|
||||
tidak (belum) dapat dijadwalkan.
|
||||
|
||||
Pada langkah _scoring_, penjadwal memberi peringkat pada Node-node yang tersisa
|
||||
untuk memilih penempatan paling cocok untuk Pod. Penjadwal memberikan skor
|
||||
untuk setiap Node yang sudah tersaring, memasukkan skor ini pada aturan
|
||||
penilaian yang aktif.
|
||||
|
||||
Akhirnya, _kube-scheduler_ memberikan Pod ke Node dengan peringkat tertinggi.
|
||||
Jika ada lebih dari satu node dengan skor yang sama, maka _kube-scheduler_
|
||||
memilih salah satunya secara acak.
|
||||
|
||||
Ada dua cara yang didukung untuk mengkonfigurasi perilaku penyaringan dan
|
||||
penilaian oleh penjadwal:
|
||||
|
||||
1. [Aturan Penjadwalan](/docs/reference/scheduling/policies) yang memungkinkan
|
||||
kamu untuk mengkonfigurasi _Predicates_ untuk pemfilteran dan _Priorities_
|
||||
untuk penilaian.
|
||||
1. [Profil Penjadwalan](/docs/reference/scheduling/profiles) yang memungkinkan
|
||||
kamu mengkonfigurasi _Plugin_ yang menerapkan tahapan penjadwalan berbeda,
|
||||
termasuk: `QueueSort`, `Filter`, `Score`, `Bind`, `Reserve`, `Permit`, dan
|
||||
lainnya. Kamu juga bisa mengonfigurasi _kube-scheduler_ untuk menjalankan
|
||||
profil yang berbeda.
|
||||
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
* Baca tentang [penyetelan performa penjadwal](/id/docs/concepts/scheduling/scheduler-perf-tuning/)
|
||||
* Baca tentang [pertimbangan penyebarang topologi pod](/id/docs/concepts/workloads/pods/pod-topology-spread-constraints/)
|
||||
* Baca [referensi dokumentasi](/docs/reference/command-line-tools-reference/kube-scheduler/) untuk _kube-scheduler_
|
||||
* Pelajari tentang [mengkonfigurasi beberapa penjadwal](/docs/tasks/administer-cluster/configure-multiple-schedulers/)
|
||||
* Pelajari tentang [aturan manajemen topologi](/docs/tasks/administer-cluster/topology-manager/)
|
||||
* Pelajari tentang [pengeluaran tambahan Pod](/id/docs/concepts/configuration/pod-overhead/)
|
||||
|
||||
@@ -0,0 +1,314 @@
|
||||
---
|
||||
title: Taint dan Toleration
|
||||
content_type: concept
|
||||
weight: 40
|
||||
---
|
||||
|
||||
|
||||
<!-- overview -->
|
||||
Afinitas Node, seperti yang dideskripsikan [di sini](/id/docs/concepts/configuration/assign-pod-node/#node-affinity-beta-feature),
|
||||
adalah salah satu properti dari Pod yang menyebabkan pod tersebut memiliki preferensi
|
||||
untuk ditempatkan di sekelompok Node tertentu (preferensi ini dapat berupa _soft constraints_ atau
|
||||
_hard constraints_ yang harus dipenuhi). _Taint_ merupakan kebalikan dari afinitas --
|
||||
properti ini akan menyebabkan Pod memiliki preferensi untuk tidak ditempatkan pada sekelompok Node tertentu.
|
||||
|
||||
_Taint_ dan _toleration_ bekerja sama untuk memastikan Pod dijadwalkan pada Node
|
||||
yang sesuai. Satu atau lebih _taint_ akan diterapkan pada suatu node; hal ini akan menyebabkan
|
||||
node tidak akan menerima pod yang tidak mengikuti _taint_ yang sudah diterapkan.
|
||||
|
||||
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## Konsep
|
||||
|
||||
Kamu dapat menambahkan _taint_ pada sebuah _node_ dengan menggunakan perintah [kubectl taint](/docs/reference/generated/kubectl/kubectl-commands#taint).
|
||||
Misalnya,
|
||||
|
||||
```shell
|
||||
kubectl taint nodes node1 key=value:NoSchedule
|
||||
```
|
||||
|
||||
akan menerapkan _taint_ pada _node_ `node1`. _Taint_ tersebut memiliki _key_ `key`, _value_ `value`,
|
||||
dan _effect_ _taint_ `NoSchedule`. Hal ini artinya pod yang ada tidak akan dapat dijadwalkan pada `node1`
|
||||
kecuali memiliki _taint_ yang sesuai.
|
||||
|
||||
Untuk menghilangkan _taint_ yang ditambahkan dengan perintah di atas, kamu dapat menggunakan
|
||||
perintah di bawah ini:
|
||||
```shell
|
||||
kubectl taint nodes node1 key:NoSchedule-
|
||||
```
|
||||
|
||||
Kamu dapat memberikan spesifikasi _toleration_ untuk _pod_ pada bagian PodSpec.
|
||||
Kedua _toleration_ yang diterapkan di bawa ini "sesuai" dengan _taint_ yang
|
||||
_taint_ yang dibuat dengan perintah `kubectl taint` di atas, sehingga sebuah _pod_
|
||||
dengan _toleration_ yang sudah didefinisikan akan mampu di-_schedule_ ke node `node`:
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "key"
|
||||
operator: "Equal"
|
||||
value: "value"
|
||||
effect: "NoSchedule"
|
||||
```
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "key"
|
||||
operator: "Exists"
|
||||
effect: "NoSchedule"
|
||||
```
|
||||
|
||||
Sebuah _toleration_ "sesuai" dengan sebuah _taint_ jika _key_ dan efek yang
|
||||
ditimbulkan sama:
|
||||
|
||||
* `operator` dianggap `Exists` (pada kasus dimana tidak ada `value` yang diberikan), atau
|
||||
* `operator` dianggap `Equal` dan `value` yang ada sama
|
||||
|
||||
`Operator` bernilai `Equal` secara _default_ jika tidak diberikan spesifikasi khusus.
|
||||
|
||||
{{< note >}}
|
||||
Terdapat dua kasus khusus:
|
||||
|
||||
* Sebuah `key` dengan operator `Exists` akan sesuai dengan semua _key_, _value_, dan _effect_ yang ada.
|
||||
Dengan kata lain, _tolaration_ ini akan menerima semua hal yang diberikan.
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- operator: "Exists"
|
||||
```
|
||||
|
||||
* Sebuah `effect` yang kosong akan dianggap sesuai dengan semua _effect_ dengan _key_ `key`.
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "key"
|
||||
operator: "Exists"
|
||||
```
|
||||
{{< /note >}}
|
||||
|
||||
Contoh yang diberikan di atas menggunakan `effect` untuk `NoSchedule`.
|
||||
Alternatif lain yang dapat digunakan adalah `effect` untuk `PreferNoSchedule`.
|
||||
`PreferNoSchedule` merupakan "preferensi" yang lebih fleksibel dari `NoSchedule` --
|
||||
sistem akan mencoba untuk tidak menempatkan pod yang tidak menoleransi _taint_
|
||||
pada _node_, tapi hal ini bukan merupakan sesuatu yang harus dipenuhi. Jenis ketiga
|
||||
dari `effect` adalah `NoExecute`, akan dijelaskan selanjutnya.
|
||||
|
||||
Kamu dapat menerapkan beberapa _taint_ sekaligus pada _node_ atau
|
||||
beberapa _toleration_ sekaligus pada sebuah _pod_. Mekanisme Kubernetes dapat
|
||||
memproses beberapa _taint_ dan _toleration_ sekaligus sama halnya seperti sebuah
|
||||
_filter_: memulai dengan _taint_ yang ada pada _node_, kemudian mengabaikan
|
||||
_taint_ yang sesuai pada pod yang memiliki _toleration_ yang sesuai; kemudian
|
||||
_taint_ yang diterapkan pada pod yang sudah disaring tadi akan menghasilkan suatu
|
||||
_effect_ pada pod. Secara khusus:
|
||||
|
||||
* jika terdapat _taint_ yang tidak tersaring dengan _effect_ `NoSchedule` maka Kubernetes tidak akan menempatkan
|
||||
_pod_ pada _node_ tersebut
|
||||
* jika tidak terdapat _taint_ yang tidak tersaring dengan _effect_ `NoSchedule`
|
||||
tapi terdapat setidaknya satu _taint_ yang tidak tersaring dengan
|
||||
_effect_ `PreferNoSchedule` maka Kubernetes akan mencoba untuk tidak akan menempatkan
|
||||
_pod_ pada _node_ tersebut
|
||||
* jika terdapat _taint_ yang tidak tersaring dengan _effect_ `NoExecute` maka _pod_ akan
|
||||
berada dalam kondisi _evicted_ dari _node_ (jika _pod_ tersebut sudah terlanjur ditempatkan pada _node_
|
||||
tersebut), dan tidak akan di-_schedule_ lagi pada _node_ tersebut.
|
||||
|
||||
Sebagai contoh, bayangkan kamu memberikan _taint_ pada _node_ sebagai berikut:
|
||||
|
||||
```shell
|
||||
kubectl taint nodes node1 key1=value1:NoSchedule
|
||||
kubectl taint nodes node1 key1=value1:NoExecute
|
||||
kubectl taint nodes node1 key2=value2:NoSchedule
|
||||
```
|
||||
|
||||
Dan _pod_ memiliki dua _toleration_:
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "key1"
|
||||
operator: "Equal"
|
||||
value: "value1"
|
||||
effect: "NoSchedule"
|
||||
- key: "key1"
|
||||
operator: "Equal"
|
||||
value: "value1"
|
||||
effect: "NoExecute"
|
||||
```
|
||||
|
||||
Pada kasus ini, _pod_ tidak akan di-_schedule_ pada _node_, karena tidak ada
|
||||
_toleration_ yang sesuai dengan _taint_ ketiga. Akan tetapi, _pod_ yang sebelumnya
|
||||
sudah dijalankan di _node_ dimana _taint_ ditambahkan akan tetap jalan, karena _taint_
|
||||
ketiga merupakan _taint_ yang tidak ditoleransi oleh _pod_.
|
||||
|
||||
Pada umumnya, jika sebuah _taint_ memiliki _effect_ `NoExecute` ditambahkan pada _node_,
|
||||
maka semua pod yang tidak menoleransi _taint_ tersebut akan berada dalam _state_
|
||||
_evicted_ secara langsung, dan semua _pod_ yang menoleransi _taint_ tersebut
|
||||
tidak akan berjalan seperti biasanya (tidak dalam _state_ _evicted_). Meskipun demikian,
|
||||
_toleration_ dengan _effect_ `NoExecute` dapat dispesfikasikan sebagai _field_ opsional
|
||||
`tolerationSeconds` yang memberikan perintah berapa lama suatu _pod_ akan berada
|
||||
pada _node_ apabila sebuah _taint_ ditambahkan. Contohnya:
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "key1"
|
||||
operator: "Equal"
|
||||
value: "value1"
|
||||
effect: "NoExecute"
|
||||
tolerationSeconds: 3600
|
||||
```
|
||||
|
||||
ini berarti apabila sebuah _pod_ sedang dalam berada dalam _state_ _running_,
|
||||
kemudian sebuah _taint_ yang sesuai ditambahkan pada _node_, maka _pod_ tersebut
|
||||
akan tetap berada di dalam _node_ untuk periode 3600 detik sebelum _state_-nya
|
||||
berubah menjadi _evicted_. Jika _taint_ dihapus sebelum periode tersebut, maka _pod_
|
||||
tetap berjalan sebagaimana mestinya.
|
||||
|
||||
## Contoh Penggunaan
|
||||
|
||||
_Taint_ dan _toleration_ adalah mekanisme fleksibel yang digunakan untuk
|
||||
memaksa _pod_ agar tidak dijadwalkan pada _node-node_ tertentu atau
|
||||
mengubah _state_ _pod_ menjadi _evicted_. Berikut adalah beberapa contoh penggunaannya:
|
||||
|
||||
* **Node-Node yang Sifatnya _Dedicated_**: Jika kamu ingin menggunakan
|
||||
sekumpulan _node_ dengan penggunaan eksklusif dari sekumpulan pengguna,
|
||||
kamu dapat menambahkan _taint_ pada _node-node_ tersebut (misalnya,
|
||||
`kubectl taint nodes nodename dedicated=groupName:NoSchedule`) dan kemudian
|
||||
menambahkan _toleration_ yang sesuai pada _pod-pod_ yang berada di dalamnya (hal ini
|
||||
dapat dilakukan dengan mudah dengan cara menulis
|
||||
[_admission controller_](/docs/reference/access-authn-authz/admission-controllers/) yang
|
||||
bersifat khusus). _Pod-pod_ dengan _toleration_ nantinya akan diperbolehkannya untuk menggunakan
|
||||
_node_ yang sudah di-_taint_ (atau dengan kata lain didedikasikan penggunaannya) maupun
|
||||
_node_ lain yang ada di dalam klaster. Jika kamu ingin mendedikasikan _node_ khusus
|
||||
yang hanya digunakan oleh _pod-pod_ tadi serta memastikan _pod-pod_ tadi hanya menggunakan
|
||||
_node_ yang didedikasikan, maka kamu harus menambahkan sebuah _label_ yang serupa dengan
|
||||
_taint_ yang diberikan pada sekelompok _node_ (misalnya, `dedicated=groupName`), dan
|
||||
_admission controller_ sebaiknya menambahkan afininitas _node_ untuk memastikan _pod-pod_
|
||||
tadi hanya dijadwalkan pada _node_ dengan _label_ `dedicated=groupName`.
|
||||
|
||||
* **Node-Node dengan Perangkat Keras Khusus**: Pada suatu klaster dimana
|
||||
sebagian kecuali _node_ memiliki perangkat keras khusus (misalnya GPU), kita ingin
|
||||
memastikan hanya _pod-pod_ yang membutuhkan GPU saja yang dijadwalkan di _node_ dengan GPU.
|
||||
Hal ini dapat dilakukan dengan memberikan _taint_ pada _node_ yang memiliki perangkat keras
|
||||
khusus (misalnya, `kubectl taint nodes nodename special=true:NoSchedule` atau
|
||||
`kubectl taint nodes nodename special=true:PreferNoSchedule`) serta menambahkan _toleration_
|
||||
yang sesuai pada _pod_ yang menggunakan _node_ dengan perangkat keras khusus. Seperti halnya pada
|
||||
kebutuhan _dedicated_ _node_, hal ini dapat dilakukan dengan mudah dengan cara menulis
|
||||
[_admission controller_](/docs/reference/access-authn-authz/admission-controllers/) yang
|
||||
bersifat khusus. Misalnya, kita dapat menggunakan [_Extended Resource_](/id/docs/concepts/configuration/manage-compute-resources-container/#extended-resources)
|
||||
untuk merepresentasikan perangkat keras khusus, kemudian _taint_ _node_ dengan perangkat keras khusus
|
||||
dengan nama _extended resource_ dan jalankan _admission controller_
|
||||
[ExtendedResourceToleration](/docs/reference/access-authn-authz/admission-controllers/#extendedresourcetoleration).
|
||||
Setelah itu, karena _node_ yang ada sudah di-_taint_, maka tidak akan ada _pod_ yang
|
||||
tidak memiliki _toleration_ yang akan dijadwalkan pada _node_ tersebut_.
|
||||
Meskipun begitu, ketika kamu membuat suatu _pod_ yang membutuhkan _extended resource_,
|
||||
maka _admission controller_ dari `ExtendedResourceToleration` akan mengoreksi
|
||||
_toleration_ sehingga _pod_ tersebut dapat dijadwalkan pada _node_ dengan perangkat keras khusus.
|
||||
Dengan demikian, kamu tidak perlu menambahkan _toleration_ secara manual pada pod yang ada.
|
||||
|
||||
* **_Eviction_ berbasis _Taint_ (fitur beta)**: Konfigurasi _eviction_ per _pod_
|
||||
yang terjadi ketika _pod_ mengalami gangguan, hal ini akan dibahas lebih lanjut di bagian
|
||||
selanjutnya.
|
||||
|
||||
## _Eviction_ berbasis _Taint_
|
||||
|
||||
Sebelumnya, kita sudah pernah membahas soal _effect_ _taint_ `NoExecute`,
|
||||
yang memengaruhi _pod_ yang sudah dijalankan dengan cara sebagai berikut:
|
||||
|
||||
* _pod_ yang tidak menoleransi _taint_ akan segera diubah _state_-nya menjadi _evicted_
|
||||
* _pod_ yang menoleransi _taint_ yang tidak menspesifikasikan `tolerationSeconds` pada
|
||||
spesifikasi _toleration_ yang ada akan tetap berada di dalam _node_ tanpa adanya batas waktu tertentu
|
||||
* _pod_ yang menoleransi _taint_ yang menspesifikasikan `tolerationSeconds`
|
||||
spesifikasi _toleration_ yang ada akan tetap berada di dalam _node_ hingga batas waktu tertentu
|
||||
|
||||
Sebagai tambahan, Kubernetes 1.6 memperkenalkan dukungan alfa untuk merepresentasikan
|
||||
_node_ yang bermasalah. Dengan kata lain, _node controller_ akan secara otomatis memberikan _taint_
|
||||
pada sebuah _node_ apabila _node_ tersebut memenuhi kriteria tertentu. Berikut merupakan _taint_
|
||||
yang secara _default_ disediakan:
|
||||
|
||||
* `node.kubernetes.io/not-ready`: _Node_ berada dalam _state_ _not ready_. Hal ini terjadi apabila
|
||||
_value_ dari _NodeCondition_ `Ready` adalah "`False`".
|
||||
* `node.kubernetes.io/unreachable`: _Node_ berada dalam _state_ _unreachable_ dari _node controller_
|
||||
Hal ini terjadi apabila _value_ dari _NodeCondition_ `Ready` adalah "`Unknown`".
|
||||
* `node.kubernetes.io/out-of-disk`: _Node_ kehabisan kapasitas _disk_.
|
||||
* `node.kubernetes.io/memory-pressure`: _Node_ berada diambang kapasitas memori.
|
||||
* `node.kubernetes.io/disk-pressure`: _Node_ berada diambang kapasitas _disk_.
|
||||
* `node.kubernetes.io/network-unavailable`: Jaringan pada _Node_ bersifat _unavailable_.
|
||||
* `node.kubernetes.io/unschedulable`: _Node_ tidak dapat dijadwalkan.
|
||||
* `node.cloudprovider.kubernetes.io/uninitialized`: Ketika _kubelet_ dijalankan dengan
|
||||
penyedia layanan _cloud_ "eksternal", _taint_ ini akan diterapkan pada _node_ untuk menandai
|
||||
_node_ tersebut tidak digunakan. Setelah kontroler dari _cloud-controller-manager_ melakukan
|
||||
inisiasi _node_ tersebut, maka _kubelet_ akan menghapus _taint_ yang ada.
|
||||
|
||||
Pada versi 1.13, fitur `TaintBasedEvictions` diubah menjadi beta dan diaktifkan secara _default_,
|
||||
dengan demikian _taint-taint_ tersebut secara otomatis ditambahkan oleh _NodeController_ (atau _kubelet_)
|
||||
dan logika normal untuk melakukan _eviction_ pada _pod_ dari suatu _node_ tertentu berdasarkan _value_
|
||||
dari _Ready_ yang ada pada _NodeCondition_ dinonaktifkan.
|
||||
|
||||
{{< note >}}
|
||||
Untuk menjaga perilaku [_rate limiting_](/id/docs/concepts/architecture/nodes/) yang
|
||||
ada pada _eviction_ _pod_ apabila _node_ mengalami masalah, sistem sebenarnya menambahkan
|
||||
_taint_ dalam bentuk _rate limiter_. Hal ini mencegah _eviction_ besar-besaran pada _pod_
|
||||
pada skenario dimana master menjadi terpisah dari _node_ lainnya.
|
||||
{{< /note >}}
|
||||
|
||||
Fitur beta ini, bersamaan dengan `tolerationSeconds`, mengizinkan sebuah _pod_
|
||||
untuk menspesifikasikan berapa lama _pod_ harus tetap sesuai dengan sebuah _node_
|
||||
apabila _node_ tersebut bermasalah.
|
||||
|
||||
Misalnya, sebuah aplikasi dengan banyak _state_ lokal akan lebih baik untuk tetap
|
||||
berada di suatu _node_ pada saat terjadi partisi jaringan, dengan harapan partisi jaringan
|
||||
tersebut dapat diselesaikan dan mekanisme _eviction_ _pod_ tidak akan dilakukan.
|
||||
_Toleration_ yang ditambahkan akan berbentuk sebagai berikut:
|
||||
|
||||
```yaml
|
||||
tolerations:
|
||||
- key: "node.kubernetes.io/unreachable"
|
||||
operator: "Exists"
|
||||
effect: "NoExecute"
|
||||
tolerationSeconds: 6000
|
||||
```
|
||||
|
||||
Perhatikan bahwa Kubernetes secara otomatis menambahkan _toleration_ untuk
|
||||
`node.kubernetes.io/not-ready` dengan `tolerationSeconds=300`
|
||||
kecuali konfigurasi lain disediakan oleh pengguna.
|
||||
Kubernetes juga secara otomatis menambahkan _toleration_ untuk
|
||||
`node.kubernetes.io/unreachable` dengan `tolerationSeconds=300`
|
||||
kecuali konfigurasi lain disediakan oleh pengguna.
|
||||
|
||||
_Toleration_ yang ditambahkan secara otomatis ini menjamin bahwa
|
||||
perilaku _default_ dari suatu _pod_ adalah tetap bertahan selama 5 menit pada
|
||||
_node_ apabila salah satu masalah terdeteksi.
|
||||
Kedua _toleration_ _default_ tadi ditambahkan oleh [DefaultTolerationSeconds
|
||||
_admission controller_](https://git.k8s.io/kubernetes/plugin/pkg/admission/defaulttolerationseconds).
|
||||
|
||||
_Pod-pod_ pada [DaemonSet](/id/docs/concepts/workloads/controllers/daemonset/) dibuat dengan _toleration_
|
||||
`NoExecute` untuk _taint_ tanpa `tolerationSeconds`:
|
||||
|
||||
* `node.kubernetes.io/unreachable`
|
||||
* `node.kubernetes.io/not-ready`
|
||||
|
||||
Hal ini menjamin _pod-pod_ yang merupakan bagian dari DaemonSet tidak pernah berada di dalam
|
||||
_state_ _evicted_ apabila terjadi permasalahan pada _node_.
|
||||
|
||||
## _Taint_ pada _Node_ berdasarkan Kondisi Tertentu
|
||||
|
||||
Pada versi 1.12, fitur `TaintNodesByCondition` menjadi fitur beta, dengan demikian _lifecycle_
|
||||
dari kontroler _node_ akan secara otomatis menambahkan _taint_ sesuai dengan kondisi _node_.
|
||||
Hal yang sama juga terjadi pada _scheduler_, _scheduler_ tidak bertugas memeriksa kondisi _node_
|
||||
tetapi kondisi _taint_. Hal ini memastikan bahwa kondisi _node_ tidak memengaruhi apa
|
||||
yang dijadwalkan di _node_. Pengguna dapat memilih untuk mengabaikan beberapa permasalahan yang
|
||||
ada pada _node_ (yang direpresentasikan oleh kondisi _Node_) dengan menambahkan _toleration_ _Pod_ `NoSchedule`.
|
||||
Sedangkan _taint_ dengan _effect_ `NoExecute` dikendalikan oleh `TaintBasedEviction` yang merupakan
|
||||
fitur beta yang diaktifkan secara _default_ oleh Kubernetes sejak versi 1.13.
|
||||
|
||||
Sejak Kubernetes versi 1.8, kontroler DaemonSet akan secara otomatis
|
||||
menambahkan _toleration_ `NoSchedule` pada semua _daemon_ untuk menjaga
|
||||
fungsionalitas DaemonSet.
|
||||
|
||||
* `node.kubernetes.io/memory-pressure`
|
||||
* `node.kubernetes.io/disk-pressure`
|
||||
* `node.kubernetes.io/out-of-disk` (hanya untuk pod yang bersifat _critical_)
|
||||
* `node.kubernetes.io/unschedulable` (versi 1.10 atau yang lebih baru)
|
||||
* `node.kubernetes.io/network-unavailable` (hanya untuk jaringan _host_)
|
||||
|
||||
Menambahkan _toleration_ ini menjamin _backward compatibility_.
|
||||
Kamu juga dapat menambahkan _toleration_ lain pada DaemonSet.
|
||||
Reference in New Issue
Block a user