Jika pod berbasis ECI di satu zona gagal dibuat, semua replika yang terkonsentrasi di zona tersebut menjadi tidak tersedia. Dua pola kegagalan umum terjadi: semua replika ditempatkan di zona yang sama saat penjadwalan, dan kegagalan pembuatan ECI di beberapa zona secara diam-diam melanggar jaminan penyebaran. Topik ini menjelaskan cara menggunakan batasan penyebaran topologi Kubernetes dan aturan afinitas untuk mencegah kedua masalah tersebut dalam kluster ACK managed Pro.
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
Kluster ACK managed Pro yang memenuhi persyaratan berikut:
Versi Kubernetes 1.22 atau lebih baru
Versi komponen ACK Virtual Node 2.10.0 atau lebih baru
Versi komponen kube-scheduler 5.9 atau lebih baru, dengan kebijakan penjadwalan pod berbasis node virtual diaktifkan
Beberapa zona (vSwitch) dikonfigurasi dalam eci-profile sehingga pod dapat dijadwalkan di berbagai zona
Bidang
nodeAffinity,podAffinity, atautopologySpreadConstraintsditetapkan dalam spesifikasi pod Anda, atau ResourcePolicy dikonfigurasi untuk pod tersebut
Untuk menjadwalkan pod ke node virtual berbasis ARM, tambahkan toleransi yang sesuai dengan taint pada node tersebut.
Catatan penggunaan
Tetapkan
topologyKeyketopology.kubernetes.io/zone.Perilaku penjadwalan yang dijelaskan dalam topik ini tidak berlaku ketika:
Anotasi
k8s.aliyun.com/eci-schedule-strategy: "VSwitchOrdered"ditetapkan pada pod (penjadwalan multi-zona mengikuti urutan vSwitch tetap).Anotasi
k8s.aliyun.com/eci-fail-strategy: "fail-fast"ditetapkan pada pod.
Pilih pendekatan
Dua mekanisme Kubernetes melayani tujuan yang berbeda:
| Tujuan | Mekanisme | Kapan digunakan |
|---|---|---|
| Sebarkan pod secara merata di semua zona yang tersedia | topologySpreadConstraints | Ketersediaan tinggi — replika didistribusikan sehingga kegagalan satu zona hanya memengaruhi sebagian kecil replika |
| Patok pod ke zona tertentu atau pertahankan agar berada di lokasi yang sama | podAffinity + nodeAffinity | Performa — latensi rendah antar-pod penting, atau workload Anda harus ditempatkan di zona tertentu |
Kedua contoh di bawah menggunakan bidang yang sama yang diperlukan oleh ECI: toleransi untuk virtual-kubelet.io/provider dan afinitas node preferredDuringSchedulingIgnoredDuringExecution yang lebih memilih node Elastic Compute Service (ECS) daripada node virtual. Satu-satunya hal yang berubah hanyalah aturan penyebaran atau afinitas itu sendiri.
Contoh 1: Sebarkan pod secara merata di berbagai zona
Contoh ini membuat Penyebaran dengan 10 replika yang didistribusikan secara merata di semua zona yang tersedia.
Langkah 2: Verifikasi hasil penjadwalan
Jalankan perintah berikut untuk melihat node tempat pod ditempatkan:
kubectl get po -lapp=with-pod-topology-spread \
-o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName \
--no-headers | grep -v "<none>"Untuk menghitung jumlah pod per zona:
kubectl get po -lapp=with-pod-topology-spread \
-o custom-columns=NODE:.spec.nodeName \
--no-headers | grep -v "<none>" \
| xargs -I {} kubectl get no {} -o json \
| jq '.metadata.labels["topology.kubernetes.io/zone"]' \
| sort | uniq -cContoh 2: Sebarkan pod di zona tertentu
Contoh ini membuat Penyebaran dengan 3 replika yang semuanya harus ditempatkan di zona yang sama. Gunakan pola ini ketika latensi rendah antar-pod lebih penting daripada penyebaran di berbagai zona.
Langkah 1: Buat Penyebaran
Simpan YAML berikut ke deployment.yaml dan jalankan kubectl apply -f deployment.yaml.
apiVersion: apps/v1
kind: Deployment
metadata:
name: with-affinity
labels:
app: with-affinity
spec:
replicas: 3
selector:
matchLabels:
app: with-affinity
template:
metadata:
labels:
app: with-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- with-affinity
topologyKey: topology.kubernetes.io/zone
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: type
operator: NotIn
values:
- virtual-kubelet
tolerations:
- key: "virtual-kubelet.io/provider"
operator: "Exists"
effect: "NoSchedule"
containers:
- name: with-affinity
image: registry.k8s.io/pause:2.0Tiga bagian yang relevan dengan penjadwalan adalah:
| Bagian | Fungsinya |
|---|---|
podAffinity (requiredDuringSchedulingIgnoredDuringExecution, topologyKey: topology.kubernetes.io/zone) | Mengharuskan semua pod dengan label app: with-affinity ditempatkan di zona yang sama. kube-scheduler tidak akan menempatkan pod kecuali hal ini dapat dipenuhi. Lihat Node affinity. |
nodeAffinity (preferredDuringSchedulingIgnoredDuringExecution, type NotIn virtual-kubelet) | Lebih memilih node ECS; mundur ke node virtual jika tidak ada node ECS yang tersedia. Lihat Node affinity. |
tolerations (virtual-kubelet.io/provider: Exists, NoSchedule) | Memungkinkan kube-scheduler menempatkan pod di node virtual. Lihat Taints and tolerations. |
Untuk mematok pod ke zona tertentu alih-alih membiarkannya berada di lokasi yang sama di mana pun pod pertama ditempatkan, ganti blok podAffinity dengan afinitas node requiredDuringSchedulingIgnoredDuringExecution. Konfigurasi berikut menjadwalkan pod secara eksklusif ke Zona A Beijing:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- cn-beijing-aLangkah 2: Verifikasi hasil penjadwalan
Jalankan perintah berikut untuk melihat node tempat pod ditempatkan:
kubectl get po -lapp=with-affinity \
-o custom-columns=NAME:.metadata.name,NODE:.spec.nodeName \
--no-headers | grep -v "<none>"Untuk menghitung jumlah pod per zona:
kubectl get po -lapp=with-affinity \
-o custom-columns=NODE:.spec.nodeName \
--no-headers | grep -v "<none>" \
| xargs -I {} kubectl get no {} -o json \
| jq '.metadata.labels["topology.kubernetes.io/zone"]' \
| sort | uniq -cPenyebaran topologi pod ECI mode ketat
Secara default, kube-scheduler menargetkan distribusi zona yang merata tetapi tidak memblokir penempatan pod ketika pembuatan ECI gagal di beberapa zona. Hal ini dapat secara diam-diam melanggar kendala maxSkew.
Sebagai contoh, dengan maxSkew: 1 dan tiga zona (A, B, C), kube-scheduler mendistribusikan pod workload secara merata di semua zona. Jika pembuatan ECI gagal di Zona B dan Zona C, pod hanya berjalan di Zona A — melanggar kendala yang ditentukan oleh maxSkew.
Aktifkan penyebaran topologi pod ECI mode ketat untuk menjamin kendala tersebut dipatuhi. Dengan mode ketat aktif, kube-scheduler terlebih dahulu mengirimkan satu pod ke setiap zona dan menahan pod yang tertunda hingga pod yang dijadwalkan berhasil dibuat. Gambar berikut menunjukkan kondisi awal: satu pod dikirim ke setiap zona, sisanya tertunda.
Bahkan setelah Pod A1 dibuat, kube-scheduler tidak menjadwalkan pod berikutnya — karena jika Zona B atau Zona C gagal, kendala akan dilanggar. Hanya setelah Pod B1 juga dibuat, kube-scheduler menjadwalkan pod ke Zona C. Pod dengan bayangan hijau menunjukkan pod yang telah dibuat.
Untuk menonaktifkan penyebaran ketat dan memungkinkan kube-scheduler menjadwalkan pod tanpa memperhatikan pemenuhan kendala, tetapkan whenUnsatisfiable: ScheduleAnyway. Untuk detail parameter, lihat Definisi kendala penyebaran.