Kubernetes adalah sistem terdistribusi yang dirancang untuk menskalakan replika layanan Anda di berbagai lingkungan fisik. Dalam banyak kasus, ini bekerja dengan baik di luar kotak. Penjadwal Kubernetes secara otomatis menempatkan Pod Anda (instance container) ke dalam Node (mesin pekerja) yang memiliki sumber daya yang cukup untuk mendukungnya.
Terlepas dari upaya terbaiknya, terkadang penjadwal tidak akan memilih paket yang Anda setujui. Anda mungkin ingin Pod di-colocated jika Pod tersebut berinteraksi secara teratur dengan jaringan; Sebagai alternatif, beberapa Pod yang membutuhkan komputasi intensif mungkin paling baik dialokasikan untuk memisahkan Node jika memungkinkan.
Kubernetes memiliki beberapa mekanisme yang memungkinkan Anda untuk memandu proses pengambilan keputusan penjadwal sehingga Pod mendarat di Node tertentu. Dalam artikel ini, kami akan fokus secara khusus pada konsep “afinitas” dan “anti-afinitas” yang memberi Anda kontrol penjadwalan terperinci. Afinitas mendefinisikan aturan yang harus atau harus dipenuhi sebelum sebuah Pod dapat dialokasikan ke sebuah Node.
Bagaimana Afinitas Bekerja?
Afinitas digunakan untuk mengekspresikan batasan penjadwalan Pod yang dapat cocok dengan karakteristik Node kandidat dan Pod yang sudah berjalan pada Node tersebut. Pod dengan “afinitas” ke Node tertentu kemungkinan besar akan dijadwalkan untuk itu; sebaliknya, “anti-afinitas” membuatnya lebih kecil kemungkinannya untuk dijadwalkan. Total keseimbangan dari bobot ini digunakan untuk menentukan penempatan akhir setiap Pod.
Tes afinitas dapat menghasilkan hasil yang keras atau lunak. Hasil “keras” berarti bahwa Node harus dengan properti yang ditentukan oleh ekspresi afinitas. Afinitas “Lembut” bertindak sebagai preferensi, memberi tahu penjadwal bahwa ia harus menggunakan Node dengan atribut jika tersedia. Node yang tidak memenuhi kondisi akan tetap dipilih jika diperlukan.
Jenis Kondisi Afinitas
Saat ini ada dua jenis afinitas berbeda yang dapat Anda definisikan:
- Afinitas Node – Digunakan untuk membatasi Node yang dapat menerima Pod dengan mencocokkan label Node tersebut. Afinitas Node hanya dapat digunakan untuk menetapkan afinitas positif yang menarik Pod ke Node.
- Afinitas Antar Pod – Digunakan untuk membatasi Node yang dapat menerima Pod dengan mencocokkan label dari Pod yang ada yang sudah berjalan di masing-masing Node tersebut. Afinitas Antar Pod dapat berupa afinitas yang menarik atau anti-afinitas yang menolak.
Dalam contoh yang paling sederhana, sebuah Pod dengan kondisi Node Affinity sebesar label=value
hanya akan dijadwalkan pada Node dengan label=value
label. Sebuah Pod dengan kondisi yang sama tetapi didefinisikan sebagai Inter-Pod Affinity akan dijadwalkan ke Node yang sudah menjadi host Polong dengan label=value
label.
Mengatur Afinitas Node
Node Affinity memiliki dua subtipe yang berbeda:
requiredDuringSchedulingIgnoredDuringExecution
– Ini adalah pencocokan afinitas “keras” itu sedang membutuhkan Node memenuhi batasan yang Anda tentukan.preferredDuringSchedulingIgnoredDuringExecution
– Ini adalah kecocokan “lunak” untuk mengungkapkan keinginan yang diabaikan ketika tidak dapat dipenuhi.
Itu IgnoredDuringExecution
bagian dari nama verbose ini secara eksplisit memperjelas bahwa afinitas hanya dipertimbangkan saat menjadwalkan Pod. Setelah Pod mendarat di Node, afinitas tidak akan diperiksa lagi. Perubahan node tidak akan menyebabkan eviction Pod karena perubahan nilai afinitas. Rilis Kubernetes di masa mendatang dapat menambahkan dukungan untuk perilaku ini secara default requiredDuringSchedulingRequiredDuringExecution
frasa.
Node afinitas dilampirkan ke Pod melalui spec.affinity.nodeAffinity
bidang manifes:
apiVersion: v1 kind: Pod metadata: name: demo-pod spec: containers: - name: demo-container # ... affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: hardware-class operator: In values: - a - b - c - matchExpressions: - key: internal operator: Exists
Manifes ini membuat aturan afinitas keras yang menjadwalkan Pod ke Node yang memenuhi kriteria berikut:
- Ini memiliki
hardware-class
label jugaa
,b
Haic
sebagai nilai. - Ini memiliki
internal
label dengan nilai apa pun.
Anda dapat melampirkan ketentuan tambahan dengan mengulangi matchExpressions
ayat. Operator yang didukung untuk perbandingan nilai adalah In
, NotIn
, Exists
, DoesNotExist
, Gt
(lebih besar dari), dan Lt
(kurang dari).
Itu matchExpression
klausa dikelompokkan di bawah satu nodeSelectorTerms
klausa digabungkan dengan boolean AND
. Mereka semua harus cocok agar sebuah Pod memiliki afinitas dengan Node tertentu. Anda dapat menggunakan beberapa nodeSelectorTerms
juga klausa; mereka akan digabungkan menjadi satu yang logis OR
operasi. Anda dapat dengan mudah membangun kriteria penjadwalan yang kompleks dengan menggunakan kedua struktur ini.
Preferensi penjadwalan “Lembut” diatur dengan cara yang sama. Menggunakan nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution
bukannya atau juga requiredDuringSchedulingIgnoredDuringExecution
untuk mengkonfigurasi mereka. Identifikasi setiap kendala opsional Anda sebagai matchExpressions
klausa dalam a preference
bidang:
apiVersion: v1 kind: Pod metadata: name: demo-pod spec: containers: - name: demo-container # ... affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: hardware-class operator: In values: - a - b - c
Aturan berbasis preferensi memiliki bidang tambahan yang disebut weight
yang menerima bilangan bulat dari 1 hingga 100. Setiap Node yang cocok dengan preferensi memiliki bobot afinitas total yang ditingkatkan dengan nilai yang ditetapkan; Node yang berakhir dengan total bobot tertinggi akan dialokasikan ke Pod.
Mengatur Afinitas Antar-Pod
Inter-Pod Affinities bekerja dengan Node Affinities tetapi dengan beberapa perbedaan penting. Mode “Keras” dan “lunak” ditunjukkan dengan menggunakan yang sama requiredDuringSchedulingIgnoredDuringExecution
dan preferredDuringSchedulingIgnoredDuringExecution
Kosong. Mereka harus bersarang di bawah spec.affinity.podAffinity
Hai spec.affinity.podAntiAffinity
bidang tergantung pada apakah Anda ingin menambah atau mengurangi afinitas Pod selama pertandingan yang berhasil.
Berikut adalah contoh sederhana yang menunjukkan afinitas dan anti-afinitas:
apiVersion: v1 kind: Pod metadata: name: demo-pod spec: containers: - name: demo-container # ... affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: hardware-class operator: In values: - a - b - c topologyKey: topology.kubernetes.io/zone podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 podAffinityTerm: - labelSelector: matchExpressions: - key: app-component operator: In values: - background-worker topologyKey: topology.kubernetes.io/zone
Formatnya sedikit berbeda dari Node Affinity. Setiap matchExpressions
Batasan perlu disarangkan di bawah a labelSelector
. Untuk pertandingan lunak, ini pada gilirannya harus ditempatkan di dalam podAffinityTerm
. Afinitas pod juga menawarkan serangkaian operator perbandingan yang dikurangi: Anda dapat menggunakan In
, NotIn
, Exists
dan DoesNotExist
.
Butuh afinitas pod topologyKey
bidang. Ini digunakan untuk membatasi kumpulan umum Node yang dianggap memenuhi syarat untuk penjadwalan, sebelum matchExpressions
ditinjau. Aturan di atas akan menjadwalkan Pod pada Node dengan topology.kubernetes.io/zone
label dan Pod yang ada dengan hardware-class
label diatur ke a
, b
Hai c
. Node yang juga memiliki Pod dengan app-component=background-worker
label akan diberikan afinitas yang berkurang.
Afinitas antar Pod adalah mekanisme yang kuat untuk mengontrol kolokasi Pod. Namun, mereka memiliki dampak kinerja yang signifikan: Kubernetes memperingatkan agar tidak menggunakannya dalam cluster dengan lebih dari beberapa ratus Node. Setiap permintaan penjadwalan Pod baru harus memeriksa setiap Pod lainnya dengan semua Node lainnya untuk memeriksa kompatibilitasnya.
Kendala penjadwalan lainnya
Sementara kami fokus pada afinitas dalam artikel ini, Kubernetes juga menyediakan mekanisme penjadwalan lainnya. Ini umumnya adalah teknik yang lebih sederhana tetapi kurang otomatis yang bekerja dengan baik untuk cluster dan penerapan yang lebih kecil.
Kendala utamanya adalah nodeSelector
bidang. Ini didefinisikan dalam Pod sebagai sekumpulan pasangan nilai kunci berlabel yang harus ada pada Node yang menghosting Pod:
apiVersion: v1 kind: Pod metadata: name: demo spec: containers: - name: demo # ... nodeSelector: hardware-class: a internal: true
Manifes ini menginstruksikan Kubernetes untuk menjadwalkan Pod hanya pada Node yang memiliki hal yang sama hardware-class: a
dan internal: true
label.
Memilih simpul dengan nodeSelector
Bidang adalah cara yang bagus untuk membuat perancah konfigurasi statis dengan cepat berdasarkan sifat jangka panjang dari Node Anda. Sistem afinitas lebih fleksibel ketika Anda ingin mengekspresikan aturan kompleks dan preferensi opsional.
Kesimpulan
Afinitas dan anti-afinitas digunakan untuk mengatur batasan penjadwalan Pod serbaguna di Kubernetes. Dibandingkan dengan opsi lain seperti nodeSelector
afinitas rumit tetapi memberi Anda lebih banyak cara untuk mengidentifikasi Node yang kompatibel.
Afinitas dapat bertindak sebagai preferensi lunak yang menunjukkan lingkungan “ideal” Pod di Kubernetes meskipun tidak segera dipenuhi. Sistem ini juga memiliki kemampuan unik untuk memfilter Node berdasarkan beban kerjanya saat ini sehingga Anda dapat menerapkan aturan colocation Pod.
Satu poin terakhir yang perlu diperhatikan adalah bahwa korelasi bukanlah akhir dari proses penjadwalan. Sebuah Pod dengan afinitas terkomputasi yang kuat ke sebuah Node mungkin masih berakhir di tempat lain karena masukan dari Node taint. Mekanisme ini memungkinkan Anda mengelola permintaan penjadwalan dari perspektif Node Anda. Noda secara aktif mengusir Pod yang masuk dari Node lain, secara efektif kebalikan dari daya tarik magnet afinitas. Selektor node, afinitas, tant, dan toleransi semuanya seimbang untuk menentukan lokasi akhir dalam cluster dari setiap Pod baru.