All Products
Search
Document Center

Container Service for Kubernetes:Sebarkan Pod ECI di berbagai zona dan konfigurasikan penjadwalan afinitas

Last Updated:Mar 26, 2026

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:

  • Beberapa zona (vSwitch) dikonfigurasi dalam eci-profile sehingga pod dapat dijadwalkan di berbagai zona

  • Bidang nodeAffinity, podAffinity, atau topologySpreadConstraints ditetapkan dalam spesifikasi pod Anda, atau ResourcePolicy dikonfigurasi untuk pod tersebut

Catatan

Untuk menjadwalkan pod ke node virtual berbasis ARM, tambahkan toleransi yang sesuai dengan taint pada node tersebut.

Catatan penggunaan

  • Tetapkan topologyKey ke topology.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:

TujuanMekanismeKapan digunakan
Sebarkan pod secara merata di semua zona yang tersediatopologySpreadConstraintsKetersediaan tinggi — replika didistribusikan sehingga kegagalan satu zona hanya memengaruhi sebagian kecil replika
Patok pod ke zona tertentu atau pertahankan agar berada di lokasi yang samapodAffinity + nodeAffinityPerforma — 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 1: Buat Penyebaran

Simpan YAML berikut ke deployment.yaml dan jalankan kubectl apply -f deployment.yaml.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: with-pod-topology-spread
  labels:
    app: with-pod-topology-spread
spec:
  replicas: 10
  selector:
    matchLabels:
      app: with-pod-topology-spread
  template:
    metadata:
      labels:
        app: with-pod-topology-spread
    spec:
      affinity:
        nodeAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 1
            preference:
              matchExpressions:
              - key: type
                operator: NotIn
                values:
                - virtual-kubelet
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: with-pod-topology-spread
      tolerations:
        - key: "virtual-kubelet.io/provider"
          operator: "Exists"
          effect: "NoSchedule"
      containers:
      - name: with-pod-topology-spread
        image: registry.k8s.io/pause:2.0
        resources:
          requests:
            cpu: "1"
            memory: "256Mi"

Tiga bagian yang relevan dengan penjadwalan adalah:

BagianFungsinya
nodeAffinity (preferredDuringSchedulingIgnoredDuringExecution, type NotIn virtual-kubelet)Lebih memilih node ECS; mundur ke node virtual jika tidak ada node ECS yang tersedia. Lihat Node affinity.
topologySpreadConstraints (maxSkew: 1, topologyKey: topology.kubernetes.io/zone, whenUnsatisfiable: DoNotSchedule)Menjaga perbedaan jumlah pod antara dua zona mana pun paling banyak 1. kube-scheduler memblokir penempatan jika kendala ini tidak dapat dipenuhi. Lihat topologySpreadConstraints field.
tolerations (virtual-kubelet.io/provider: Exists, NoSchedule)Memungkinkan kube-scheduler menempatkan pod di node virtual, yang secara default memiliki taint ini. Lihat Taints and tolerations.
Catatan

Untuk menjadwalkan pod ke node virtual berbasis ARM, tambahkan toleransi untuk taint khusus ARM.

Bidang topologySpreadConstraints menerima beberapa parameter. Tabel berikut mencakup parameter yang digunakan dalam contoh ini dan parameter opsional yang tersedia di versi Kubernetes terbaru:

ParameterWajibDeskripsi
maxSkewYaSelisih maksimum yang diizinkan dalam jumlah pod antara dua zona mana pun
topologyKeyYaHarus topology.kubernetes.io/zone untuk pod berbasis ECI
whenUnsatisfiableYaDoNotSchedule memblokir penempatan jika kendala tidak dapat dipenuhi; ScheduleAnywayDefinisi kendala penyebaran memungkinkan penempatan dengan upaya terbaik
labelSelectorYaMemilih pod yang akan dihitung saat mengevaluasi ketimpangan
minDomainsTidakJumlah minimum zona yang memenuhi syarat untuk dipertimbangkan. Beta sejak Kubernetes 1.25.
matchLabelKeysTidakKunci label tambahan yang digunakan untuk mengidentifikasi pod yang termasuk dalam kelompok yang sama. Beta sejak Kubernetes 1.27.
nodeAffinityPolicyTidakApakah aturan afinitas node diperhatikan saat menghitung jumlah pod per zona. Beta sejak Kubernetes 1.26.
nodeTaintsPolicyTidakApakah taint node diperhatikan saat menghitung jumlah pod per zona. Beta sejak Kubernetes 1.26.

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 -c

Contoh 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.0

Tiga bagian yang relevan dengan penjadwalan adalah:

BagianFungsinya
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-a

Langkah 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 -c

Penyebaran 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.

image

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.

image

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.

image

Untuk menonaktifkan penyebaran ketat dan memungkinkan kube-scheduler menjadwalkan pod tanpa memperhatikan pemenuhan kendala, tetapkan whenUnsatisfiable: ScheduleAnyway. Untuk detail parameter, lihat Definisi kendala penyebaran.