Men-deploy sistem batch menggunakan Kueue


Tutorial ini menunjukkan cara men-deploy sistem batch menggunakan Kueue untuk menjalankan pengantrean Job di Google Kubernetes Engine (GKE). Selesaikan tutorial ini untuk mempelajari cara menyiapkan GKE dan Kueue untuk menjalankan Job dalam model masuk pertama keluar pertama (FIFO).

Latar belakang

Job adalah aplikasi yang berjalan hingga selesai, seperti machine learning, rendering, simulasi, analisis, CI/CD, dan workload sejenis.

Kueue adalah scheduler Job berbasis cloud yang dapat digunakan dengan scheduler Kubernetes default, pengontrol Job, dan autoscaler cluster untuk menyediakan sistem batch end-to-end. Kueue menerapkan pengantrean Job, dengan memutuskan kapan Job harus menunggu dan kapan harus dimulai, berdasarkan kuota dan hierarki untuk berbagi resource antar-tim secara adil.

Kueue memiliki karakteristik berikut:

  • Kueue dioptimalkan untuk arsitektur cloud, di mana resource bersifat heterogen, dapat dipertukarkan, dan skalabel.
  • Kueue menyediakan sekumpulan API untuk mengelola kuota yang elastis dan mengelola pengantrean Job.
  • Kueue tidak mengimplementasikan ulang fungsionalitas yang ada, seperti penskalaan otomatis, penjadwalan pod, atau pengelolaan siklus proses Job.
  • Kueue memiliki dukungan bawaan untuk API batch/v1.Job Kubernetes.
  • Kueue dapat berintegrasi dengan API Job lainnya.

Kueue mengacu pada tugas yang ditentukan dengan sembarang API sebagai Workload, untuk menghindari kerancuan dengan Kubernetes Job API tertentu.

Tujuan

Tutorial ini ditujukan untuk operator cluster dan pengguna lain yang ingin mengimplementasikan sistem batch di Kubernetes. Dalam tutorial ini, Anda akan menyiapkan cluster bersama untuk dua tim tenant. Setiap tim memiliki namespace masing-masing di mana mereka membuat Job dan berbagi resource global yang sama yang dikontrol dengan kuota terkaitnya.

Tutorial ini membahas langkah-langkah berikut:

  1. Membuat cluster GKE
  2. Membuat ResourceFlavor
  3. Membuat ClusterQueue
  4. Membuat LocalQueue
  5. Membuat Job dan mengamati workload yang diterima

Biaya

Tutorial ini menggunakan komponen Google Cloud yang dapat ditagih berikut:

Gunakan kalkulator harga untuk membuat perkiraan biaya berdasarkan penggunaan yang Anda proyeksikan.

Setelah menyelesaikan tutorial ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk informasi selengkapnya, lihat Membersihkan.

Sebelum memulai

Menyiapkan project

  1. Login ke akun Google Cloud Anda. Jika Anda baru menggunakan Google Cloud, buat akun untuk mengevaluasi performa produk kami dalam skenario dunia nyata. Pelanggan baru juga mendapatkan kredit gratis senilai $300 untuk menjalankan, menguji, dan men-deploy workload.
  2. Di konsol Google Cloud, pada halaman pemilih project, klik Buat project untuk mulai membuat project Google Cloud baru.

    Buka pemilih project

  3. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  4. Aktifkan API GKE.

    Mengaktifkan API

  5. Di konsol Google Cloud, pada halaman pemilih project, klik Buat project untuk mulai membuat project Google Cloud baru.

    Buka pemilih project

  6. Pastikan penagihan telah diaktifkan untuk project Google Cloud Anda.

  7. Aktifkan API GKE.

    Mengaktifkan API

Menetapkan setelan default untuk Google Cloud CLI

  1. Di konsol Google Cloud, mulai instance Cloud Shell:
    Buka Cloud Shell

  2. Download kode sumber untuk aplikasi contoh ini:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/batch/kueue-intro
    
  3. Tetapkan variabel lingkungan default:

    gcloud config set project PROJECT_ID
    gcloud config set compute/region COMPUTE_REGION
    

    Ganti nilai berikut:

Membuat cluster GKE

  1. Buat cluster GKE Autopilot dengan nama kueue-autopilot:

    gcloud container clusters create-auto kueue-autopilot \
      --release-channel "rapid" --region COMPUTE_REGION
    

    Cluster Autopilot terkelola sepenuhnya dan memiliki penskalaan otomatis bawaan. Pelajari GKE Autopilot lebih lanjut.

    Kueue juga mendukung GKE Standard dengan penyediaan node otomatis dan node pool yang diskalakan otomatis secara rutin.

    Setelah cluster dibuat, hasilnya tampak seperti berikut ini:

      NAME: kueue-autopilot
      LOCATION: us-central1
      MASTER_VERSION: 1.26.2-gke.1000
      MASTER_IP: 35.193.173.228
      MACHINE_TYPE: e2-medium
      NODE_VERSION: 1.26.2-gke.1000
      NUM_NODES: 3
      STATUS: RUNNING
    

    Dengan STATUS adalah RUNNING untuk kueue-autopilot.

  2. Dapatkan kredensial autentikasi untuk cluster:

    gcloud container clusters get-credentials kueue-autopilot
    
  3. Instal Kueue di cluster:

    VERSION=VERSION
    kubectl apply --server-side -f \
      https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
    

    Ganti VERSION dengan Kueue versi terbaru. Untuk informasi selengkapnya tentang versi Kueue, lihat rilis Kueue.

  4. Tunggu hingga Pod Kueue siap:

    watch kubectl -n kueue-system get pods
    

    Output-nya akan mirip dengan berikut ini sebelum Anda dapat melanjutkan:

    NAME                                        READY   STATUS    RESTARTS   AGE
    kueue-controller-manager-66d8bb946b-wr2l2   2/2     Running   0          3m36s
    
  5. Buat dua namespace baru bernama team-a dan team-b:

    kubectl create namespace team-a
    kubectl create namespace team-b
    

Membuat ResourceFlavor

ResourceFlavor adalah objek yang merepresentasikan variasi node yang tersedia di cluster Anda dengan mengaitkannya ke label dan taint node. Misalnya, Anda dapat menggunakan ResourceFlavors untuk merepresentasikan VM dengan perbedaan jaminan penyediaan (misalnya spot versus on-demand), arsitektur (misalnya CPU x86 versus ARM), merek, dan model (misalnya GPU Nvidia A100 versus T4).

Dalam tutorial ini, cluster kueue-autopilot memiliki resource yang homogen. Akibatnya, buat satu ResourceFlavor untuk CPU, memori, penyimpanan efemeral, dan GPU tanpa label atau taint.

apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
  name: default-flavor # This ResourceFlavor will be used for all the resources
Deploy ResourceFlavor:

kubectl apply -f flavors.yaml

Membuat ClusterQueue

ClusterQueue adalah objek dengan cakupan cluster yang mengelola sekumpulan resource seperti CPU, memori, dan GPU. Objek ini mengelola ResourceFlavors, dan membatasi penggunaan, serta menentukan urutan penerimaan workload.

apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
  name: cluster-queue
spec:
  namespaceSelector: {} # Available to all namespaces
  queueingStrategy: BestEffortFIFO # Default queueing strategy
  resourceGroups:
  - coveredResources: ["cpu", "memory", "nvidia.com/gpu", "ephemeral-storage"]
    flavors:
    - name: "default-flavor"
      resources:
      - name: "cpu"
        nominalQuota: 10
      - name: "memory"
        nominalQuota: 10Gi
      - name: "nvidia.com/gpu"
        nominalQuota: 10
      - name: "ephemeral-storage"
        nominalQuota: 10Gi

Deploy ClusterQueue:

kubectl apply -f cluster-queue.yaml

Urutan pemakaian ditentukan oleh .spec.queueingStrategy, yang memiliki dua konfigurasi:

  • BestEffortFIFO

    • Konfigurasi strategi pengantrean default.
    • Penerimaan workload mengikuti aturan masuk pertama keluar pertama (FIFO), tetapi jika tidak ada cukup kuota untuk menerima workload di kepala antrean, workload berikutnya akan dicoba.
  • StrictFIFO

    • Menjamin semantik FIFO.
    • Workload di kepala antrean dapat memblokir pengantrean hingga workload tersebut dapat diterima.

Di cluster-queue.yaml, Anda akan membuat ClusterQueue baru bernama cluster-queue. ClusterQueue ini mengelola empat resource: cpu, memory, nvidia.com/gpu, dan ephemeral-storage dengan ragam yang dibuat di flavors.yaml. Kuota dipakai oleh permintaan dalam spesifikasi Pod workload.

Setiap ragam mencakup batas penggunaan yang dinyatakan sebagai .spec.resourceGroups[].flavors[].resources[].nominalQuota. Dalam hal ini, ClusterQueue menerima workload jika dan hanya jika:

  • Jumlah permintaan CPU kurang dari atau sama dengan 10
  • Jumlah permintaan memori kurang dari atau sama dengan 10Gi
  • Jumlah permintaan GPU kurang dari atau sama dengan 10
  • Jumlah penyimpanan yang digunakan kurang dari atau sama dengan 10Gi

Membuat LocalQueue

LocalQueue adalah objek dengan namespace yang menerima workload dari pengguna di namespace itu. LocalQueue dari namespace berbeda dapat mengarah ke ClusterQueue yang sama di mana mereka dapat berbagi kuota resource. Dalam hal ini, LocalQueue dari namespace team-a dan team-b mengarah ke ClusterQueue cluster-queue yang sama di .spec.clusterQueue.

apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
  namespace: team-a # LocalQueue under team-a namespace
  name: lq-team-a
spec:
  clusterQueue: cluster-queue # Point to the ClusterQueue
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
  namespace: team-b # LocalQueue under team-b namespace
  name: lq-team-b
spec:
  clusterQueue: cluster-queue # Point to the ClusterQueue

Setiap tim mengirimkan workload ke LocalQueue di namespace masing-masing, yang kemudian diberi alokasi resource oleh ClusterQueue.

Deploy LocalQueues:

kubectl apply -f local-queue.yaml

Membuat Job dan mengamati workload yang diterima

apiVersion: batch/v1
kind: Job
metadata:
  namespace: team-a # Job under team-a namespace
  generateName: sample-job-team-a-
  annotations:
    kueue.x-k8s.io/queue-name: lq-team-a # Point to the LocalQueue
spec:
  ttlSecondsAfterFinished: 60 # Job will be deleted after 60 seconds
  parallelism: 3 # This Job will have 3 replicas running at the same time
  completions: 3 # This Job requires 3 completions
  suspend: true # Set to true to allow Kueue to control the Job when it starts
  template:
    spec:
      nodeSelector:
        cloud.google.com/gke-accelerator: "nvidia-tesla-t4" # Specify the GPU hardware
      containers:
      - name: dummy-job
        image: gcr.io/k8s-staging-perf-tests/sleep:latest
        args: ["10s"] # Sleep for 10 seconds
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
            ephemeral-storage: "512Mi"
            nvidia.com/gpu: "1"
          limits:
            cpu: "500m"
            memory: "512Mi"
            ephemeral-storage: "512Mi"
            nvidia.com/gpu: "1"
      restartPolicy: Never

Job dibuat di namespace team-a. Job ini mengarah ke LocalQueue lq-team-a. Untuk meminta resource GPU, nodeSelector ditetapkan ke nvidia-tesla-t4.

Job ini terdiri atas tiga Pod yang tidur selama 10 detik secara paralel. Job akan dibersihkan setelah 60 detik menurut ttlSecondsAfterFinished.

Job ini memerlukan 1500 miliCPU, memori 1536 Mi, penyimpanan efemeral 1536 Mi, dan tiga GPU karena terdapat tiga Pod.

Job juga dibuat di file job-team-b.yaml di mana namespace-nya berada di team-b, dengan permintaan untuk merepresentasikan berbagai tim dengan kebutuhan berbeda-beda.

Untuk mempelajari lebih lanjut, lihat men-deploy workload GPU di Autopilot.

  1. Di terminal baru, amati status ClusterQueue yang diperbarui setiap dua detik:

    watch -n 2 kubectl get clusterqueue cluster-queue -o wide
    
  2. Di terminal baru, amati status node:

    watch -n 2 kubectl get nodes -o wide
    
  3. Di terminal baru, buat Job ke LocalQueue dari namespace team-a dan team-b setiap 10 detik:

    ./create_jobs.sh job-team-a.yaml job-team-b.yaml 10
    
  4. Amati Job yang diantrekan, diterima di ClusterQueue, dan node yang dimunculkan dengan GKE Autopilot.

  5. Dapatkan Job dari namespace team-a:

    kubectl -n team-a get jobs
    

    Output-nya mirip dengan berikut ini:

    NAME                      COMPLETIONS   DURATION   AGE
    sample-job-team-b-t6jnr   3/3           21s        3m27s
    sample-job-team-a-tm7kc   0/3                      2m27s
    sample-job-team-a-vjtnw   3/3           30s        3m50s
    sample-job-team-b-vn6rp   0/3                      40s
    sample-job-team-a-z86h2   0/3                      2m15s
    sample-job-team-b-zfwj8   0/3                      28s
    sample-job-team-a-zjkbj   0/3                      4s
    sample-job-team-a-zzvjg   3/3           83s        4m50s
    
  6. Salin nama Job dari langkah sebelumnya, lalu amati status penerimaan dan peristiwa untuk Job melalui Workloads API:

    kubectl -n team-a describe workload JOB_NAME
    
  7. Saat Job yang tertunda mulai meningkat dari ClusterQueue, akhiri skrip dengan menekan CTRL + C pada skrip yang berjalan.

  8. Setelah semua Job selesai, perhatikan node diturunkan skalanya.

Pembersihan

Agar tidak perlu membayar biaya pada akun Google Cloud Anda untuk resource yang digunakan dalam tutorial ini, hapus project yang berisi resource tersebut, atau simpan project dan hapus setiap resource.

Menghapus project

  1. Di konsol Google Cloud, buka halaman Manage resource.

    Buka Manage resource

  2. Pada daftar project, pilih project yang ingin Anda hapus, lalu klik Delete.
  3. Pada dialog, ketik project ID, lalu klik Shut down untuk menghapus project.

Menghapus resource satu per satu

  1. Hapus sistem kuota Kueue:

    kubectl delete -n team-a localqueue lq-team-a
    kubectl delete -n team-b localqueue lq-team-b
    kubectl delete clusterqueue cluster-queue
    kubectl delete resourceflavor default-flavor
    
  2. Hapus manifes Kueue:

    VERSION=VERSION
    kubectl delete -f \
      https://github.com/kubernetes-sigs/kueue/releases/download/$VERSION/manifests.yaml
    
  3. Hapus kluster:

    gcloud container clusters delete kueue-autopilot --region=COMPUTE_REGION
    

Langkah selanjutnya