Pekerjaan terdistribusi seperti Apache Spark, Apache Hadoop, dan pelatihan TensorFlow memerlukan semua Pod-nya berjalan secara simultan. Tanpa gang scheduling, beberapa Pod mulai berjalan dan menahan sumber daya sambil menunggu yang lainnya, yang dapat menyebabkan deadlock di seluruh kluster sehingga tidak ada pekerjaan yang dapat berjalan. Gang scheduling mengatasi hal ini dengan jaminan all-or-nothing: semua Pod yang diperlukan dijalankan bersamaan, atau tidak satu pun dijalankan. Topik ini menjelaskan cara mengaktifkan dan mengonfigurasi gang scheduling pada ACK.
Cara kerja
ACK menerapkan gang scheduling melalui resource PodGroup. Setiap Pod dalam pekerjaan terdistribusi ditetapkan ke sebuah PodGroup dan menentukan jumlah minimum Pod (min-available). Penjadwal menahan seluruh kelompok dalam status Pending hingga dapat memenuhi jumlah minimum tersebut. Setelah terpenuhi, semua Pod dalam kelompok tersebut dijalankan bersamaan.
ACK mendukung tiga metode untuk menentukan PodGroup:
| Metode | Cara pengelompokan Pod | Paling cocok untuk |
|---|---|---|
| Label | kube-scheduler membuat PodGroup secara otomatis | Pekerjaan sederhana, tidak perlu objek PodGroup terpisah |
| PodGroup CRD | Resource PodGroup eksplisit dengan kontrol timeout | Pekerjaan yang memerlukan scheduleTimeoutSeconds |
| Anotasi Koordinator | Pengelompokan berbasis anotasi | Kluster yang menggunakan stack penjadwalan Koordinator |
Ketiga metode tersebut mengharuskan Pod dan PodGroup-nya berada dalam namespace yang sama. Semua Pod dalam satu PodGroup harus memiliki prioritas yang sama.
Prasyarat
Sebelum memulai, pastikan Anda telah memiliki:
Kluster ACK managed Pro yang menjalankan Kubernetes 1.16 atau lebih baru. Tingkatkan kluster jika diperlukan.
Untuk konfigurasi lanjutan (GangGroup dan kebijakan pencocokan): kluster yang menjalankan Kubernetes 1.22 atau lebih baru dengan versi kube-scheduler lebih baru dari
1.xx.xx-aliyun-4.0.
Pastikan kapasitas sumber daya dari node pool elastis dan label node memenuhi persyaratan penjadwalan Pod. Jika tidak, Pod mungkin gagal dijadwalkan ke node dalam node pool tersebut.
Aktifkan gang scheduling
Metode 1: Label (direkomendasikan)
Tambahkan dua label ke setiap Pod. kube-scheduler secara otomatis membuat PodGroup dengan nama sesuai nilai pod-group.scheduling.sigs.k8s.io/name.
labels:
pod-group.scheduling.sigs.k8s.io/name: tf-smoke-gpu # Nama PodGroup (harus berupa subdomain DNS yang valid)
pod-group.scheduling.sigs.k8s.io/min-available: "3" # Jumlah minimum Pod yang diperlukan untuk memulai pekerjaanNilai pod-group.scheduling.sigs.k8s.io/name harus berupa nama subdomain DNS yang valid. Untuk aturan penamaan, lihat Nama dan ID Objek.
Metode 2: PodGroup CRD
Buat resource PodGroup secara eksplisit, lalu rujuk dari setiap Pod menggunakan label.
Sejak ACK versi 1.31, hanya versi API scheduling.x-k8s.io/v1alpha1 yang didukung. Versi scheduling.sigs.k8s.io/v1alpha1 tidak lagi didukung.
# Resource PodGroup
apiVersion: scheduling.x-k8s.io/v1alpha1
kind: PodGroup
metadata:
name: nginx
spec:
scheduleTimeoutSeconds: 10 # Jumlah detik menunggu sebelum menolak kelompok jika min-available tidak terpenuhi
minMember: 3 # Jumlah minimum Pod yang diperlukan untuk memulai pekerjaan
---
# Label Pod — harus sesuai dengan nama dan namespace PodGroup
labels:
pod-group.scheduling.sigs.k8s.io/name: nginxMetode 3: Anotasi Koordinator
Tambahkan anotasi ke setiap Pod. Metode ini tidak mendukung parameter total-number atau mode dari API Koordinator.
annotations:
gang.scheduling.koordinator.sh/name: "gang-example"
gang.scheduling.koordinator.sh/min-available: "2"Konfigurasi lanjutan
Kelompokkan beberapa gang (GangGroup)
Beberapa pekerjaan menggunakan peran berbeda dengan persyaratan min-available terpisah — misalnya, pekerjaan PyTorch dengan server parameter dan worker. Satu PodGroup tidak dapat menyatakan jumlah minimum per peran, dan PodGroup terpisah tidak dapat mengoordinasikan penjadwalan lintas peran.
GangGroup mengatasi hal ini dengan menghubungkan beberapa PodGroup. Pekerjaan hanya dimulai ketika setiap gang dalam kelompok memenuhi min-available-nya sendiri. Tambahkan label berikut ke setiap Pod atau PodGroup (gunakan kunci anotasi untuk metode Koordinator):
| Metode | Resource | Kunci |
|---|---|---|
| Label | Pod | pod-group.scheduling.sigs.k8s.io/groups |
| PodGroup CRD | PodGroup | pod-group.scheduling.sigs.k8s.io/groups |
| Anotasi Koordinator | Pod | gang.scheduling.koordinator.sh/groups |
Contoh nilai (array JSON berisi entri <namespace>/<nama-gang>):
pod-group.scheduling.sigs.k8s.io/groups: "[\"default/gang-example1\", \"default/gang-example2\"]"GangGroup memerlukan Kubernetes 1.22 atau lebih baru dengan versi kube-scheduler lebih baru dari 1.xx.xx-aliyun-4.0.Konfigurasi kebijakan pencocokan
Secara default, PodGroup hanya menghitung Pod yang telah menyelesaikan prealokasi sumber daya (only-waiting). Gunakan match-policy untuk menyertakan Pod dalam status lain ke dalam perhitungan jumlah minimum — misalnya, ketika beberapa Pod dari siklus penjadwalan sebelumnya masih berjalan dan harus dihitung sebagai bagian dari jumlah minimum.
Tambahkan label ke setiap Pod (metode label) atau ke resource PodGroup (metode PodGroup CRD). Metode anotasi Koordinator hanya mendukung once-satisfied.
| Kebijakan pencocokan | Pod yang diperhitungkan untuk min-available | Kapan digunakan |
|---|---|---|
only-waiting | Pod yang telah menyelesaikan prealokasi sumber daya | Paling ketat — mencegah Pod yang sudah berjalan dihitung dalam siklus penjadwalan baru. Gunakan untuk pekerjaan tanpa status yang tidak memiliki kelanjutan dari siklus sebelumnya. |
waiting-and-running | Pod dalam status Running + Pod yang telah menyelesaikan prealokasi | Gunakan ketika beberapa Pod dari siklus sebelumnya masih berjalan dan harus dihitung sebagai bagian dari jumlah minimum. Mengurangi risiko penahanan sumber daya menganggur akibat perhitungan yang terlalu ketat. |
waiting-running-succeed | Pod dalam status Succeeded + Running + yang telah menyelesaikan prealokasi | Gunakan untuk pekerjaan yang dapat mentolerir restart parsial — Pod yang sudah berhasil tetap dihitung. Menghindari penjadwalan ulang Pod yang telah selesai. |
once-satisfied | Pod yang telah menyelesaikan prealokasi sumber daya; PodGroup menjadi tidak valid setelah terpenuhi | Gunakan untuk pekerjaan sekali jalan. Setelah gang dijalankan, PodGroup menjadi tidak valid. |
Contoh berbasis label:
pod-group.scheduling.sigs.k8s.io/match-policy: "waiting-and-running"Contoh PodGroup CRD (tambahkan ke PodGroup, bukan ke Pod):
pod-group.scheduling.sigs.k8s.io/match-policy: "waiting-and-running"Konfigurasi kebijakan pencocokan memerlukan Kubernetes 1.22 atau lebih baru dengan versi kube-scheduler lebih baru dari 1.xx.xx-aliyun-4.0.Contoh: pekerjaan TensorFlow terdistribusi
Contoh ini menunjukkan perbedaan menjalankan pekerjaan TensorFlow terdistribusi dengan dan tanpa gang scheduling. Kluster memiliki 4 GPU. Pekerjaan menjalankan 1 Pod server parameter (PS) dan 4 Pod worker; setiap worker memerlukan 2 GPU, dengan jumlah minimum 5 Pod.
Langkah 1: Instal Arena dan siapkan kluster untuk menjalankan pekerjaan TensorFlow. Untuk instruksi penyiapan, lihat Instal Arena.
Arena adalah subproyek Kubeflow yang mengelola siklus hidup pekerjaan pembelajaran mesin — termasuk penyiapan lingkungan, persiapan data, pengembangan model, pelatihan model, dan prediksi — melalui CLI atau SDK.
Langkah 2: Kirim pekerjaan TensorFlow menggunakan manifes berikut. Baik templat PS maupun worker mencakup label gang scheduling dengan min-available: "5".
apiVersion: "kubeflow.org/v1"
kind: "TFJob"
metadata:
name: "tf-smoke-gpu"
spec:
tfReplicaSpecs:
PS:
replicas: 1
template:
metadata:
creationTimestamp: null
labels:
pod-group.scheduling.sigs.k8s.io/name: tf-smoke-gpu
pod-group.scheduling.sigs.k8s.io/min-available: "5"
spec:
containers:
- args:
- python
- tf_cnn_benchmarks.py
- --batch_size=32
- --model=resnet50
- --variable_update=parameter_server
- --flush_stdout=true
- --num_gpus=1
- --local_parameter_device=cpu
- --device=cpu
- --data_format=NHWC
image: registry.cn-hangzhou.aliyuncs.com/kubeflow-images-public/tf-benchmarks-cpu:v20171202-bdab599-dirty-284af3
name: tensorflow
ports:
- containerPort: 2222
name: tfjob-port
resources:
limits:
cpu: '1'
workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks
restartPolicy: OnFailure
Worker:
replicas: 4
template:
metadata:
creationTimestamp: null
labels:
pod-group.scheduling.sigs.k8s.io/name: tf-smoke-gpu
pod-group.scheduling.sigs.k8s.io/min-available: "5"
spec:
containers:
- args:
- python
- tf_cnn_benchmarks.py
- --batch_size=32
- --model=resnet50
- --variable_update=parameter_server
- --flush_stdout=true
- --num_gpus=1
- --local_parameter_device=cpu
- --device=gpu
- --data_format=NHWC
image: registry.cn-hangzhou.aliyuncs.com/kubeflow-images-public/tf-benchmarks-gpu:v20171202-bdab599-dirty-284af3
name: tensorflow
ports:
- containerPort: 2222
name: tfjob-port
resources:
limits:
nvidia.com/gpu: 2
workingDir: /opt/tf-benchmarks/scripts/tf_cnn_benchmarks
restartPolicy: OnFailureTanpa gang scheduling diaktifkan:
Jalankan perintah berikut untuk memeriksa status Pod:
kubectl get podsDengan hanya 4 GPU tersedia, 2 Pod worker mulai berjalan dan mengklaim semua GPU, sedangkan 2 worker lainnya tetap dalam status Pending. Worker yang berjalan terblokir menunggu yang lainnya:
NAME READY STATUS RESTARTS AGE
tf-smoke-gpu-ps-0 1/1 Running 0 6m43s
tf-smoke-gpu-worker-0 1/1 Running 0 6m43s
tf-smoke-gpu-worker-1 1/1 Running 0 6m43s
tf-smoke-gpu-worker-2 0/1 Pending 0 6m43s
tf-smoke-gpu-worker-3 0/1 Pending 0 6m43sPeriksa log worker yang berjalan:
kubectl logs -f tf-smoke-gpu-worker-0Log menunjukkan worker terhenti menunggu Pod yang berstatus Pending — GPU ditahan tetapi pelatihan tidak berjalan:
INFO|2020-05-19T07:02:18|/opt/launcher.py|27| 2020-05-19 07:02:18.199696: I tensorflow/core/distributed_runtime/master.cc:221] CreateSession still waiting for response from worker: /job:worker/replica:0/task:3
INFO|2020-05-19T07:02:28|/opt/launcher.py|27| 2020-05-19 07:02:28.199798: I tensorflow/core/distributed_runtime/master.cc:221] CreateSession still waiting for response from worker: /job:worker/replica:0/task:2Dengan gang scheduling diaktifkan:
Semua 5 Pod tetap dalam status Pending hingga kluster memiliki cukup sumber daya untuk memenuhi min-available: 5:
NAME READY STATUS RESTARTS AGE
tf-smoke-gpu-ps-0 0/1 Pending 0 43s
tf-smoke-gpu-worker-0 0/1 Pending 0 43s
tf-smoke-gpu-worker-1 0/1 Pending 0 43s
tf-smoke-gpu-worker-2 0/1 Pending 0 43s
tf-smoke-gpu-worker-3 0/1 Pending 0 43sSetelah 4 GPU ditambahkan ke kluster, penjadwal menjalankan semua 5 Pod secara simultan:
kubectl get podsOutput yang diharapkan:
NAME READY STATUS RESTARTS AGE
tf-smoke-gpu-ps-0 1/1 Running 0 3m16s
tf-smoke-gpu-worker-0 1/1 Running 0 3m16s
tf-smoke-gpu-worker-1 1/1 Running 0 3m16s
tf-smoke-gpu-worker-2 1/1 Running 0 3m16s
tf-smoke-gpu-worker-3 1/1 Running 0 3m16sPeriksa log worker untuk memastikan pelatihan telah dimulai:
kubectl logs -f tf-smoke-gpu-worker-0Output yang diharapkan:
INFO|2020-05-19T07:15:24|/opt/launcher.py|27| Running warm up
INFO|2020-05-19T07:21:04|/opt/launcher.py|27| Done warm up
INFO|2020-05-19T07:21:04|/opt/launcher.py|27| Step Img/sec loss
INFO|2020-05-19T07:21:05|/opt/launcher.py|27| 1 images/sec: 31.6 +/- 0.0 (jitter = 0.0) 8.318
INFO|2020-05-19T07:21:15|/opt/launcher.py|27| 10 images/sec: 31.1 +/- 0.4 (jitter = 0.7) 8.343
INFO|2020-05-19T07:21:25|/opt/launcher.py|27| 20 images/sec: 31.5 +/- 0.3 (jitter = 0.7) 8.142Pemecahan masalah
Error: "rejected by podgroup xxx"
Ketika beberapa PodGroup ada dalam kluster, antrean backoff kube-scheduler dapat menyebabkan Pod yang telah menyelesaikan prealokasi sumber daya dalam satu siklus penjadwalan ditolak saat PodGroup lain diproses.
Ini merupakan perilaku yang diharapkan. Anda dapat mengabaikan error ini jika situasi tersebut berlangsung tidak lebih dari 20 menit. Jika error berlanjut lebih dari 20 menit, kirim tiket.
Langkah selanjutnya
Bekerja dengan capacity scheduling — gunakan grup kuota elastis untuk meningkatkan pemanfaatan sumber daya kluster