Menskalakan hingga nol menggunakan KEDA

Tutorial ini menunjukkan cara menurunkan skala workload GKE Anda hingga nol Pod menggunakan KEDA. Menskalakan deployment hingga nol Pod akan menghemat resource selama periode tidak aktif (seperti akhir pekan dan di luar jam kerja), atau untuk workload yang tidak rutin seperti tugas berkala.

Tujuan

Tutorial ini menjelaskan kasus penggunaan berikut:

Biaya

Dalam dokumen ini, Anda menggunakan komponen Google Cloud yang dapat ditagih berikut Google Cloud:

Untuk membuat perkiraan biaya berdasarkan proyeksi penggunaan Anda, gunakan kalkulator harga.

Pengguna baru mungkin memenuhi syarat untuk mendapatkan uji coba gratis. Google Cloud

Setelah menyelesaikan tugas yang dijelaskan dalam dokumen ini, Anda dapat menghindari penagihan berkelanjutan dengan menghapus resource yang Anda buat. Untuk mengetahui informasi selengkapnya, baca bagian Pembersihan.

Sebelum memulai

Dalam tutorial ini, Anda menggunakan Cloud Shell untuk menjalankan perintah. Cloud Shell adalah lingkungan shell untuk mengelola resource yang dihosting di Google Cloud. Cloud Shell telah diinstal lebih dulu dengan alat command line Google Cloud CLI, kubectl, Helm dan Terraform. Jika tidak menggunakan Cloud Shell, Anda harus menginstal Google Cloud CLI dan Helm.

  1. Untuk menjalankan perintah di halaman ini, siapkan gcloud CLI di salah satu lingkungan pengembangan berikut:

    Cloud Shell

    Untuk menggunakan terminal online dengan gcloud CLI yang sudah disiapkan, aktifkan Cloud Shell:

    Di bagian bawah halaman ini, sesi Cloud Shell akan dimulai dan menampilkan a perintah command line. Diperlukan waktu beberapa detik untuk melakukan inisialisasi sesi.

    Shell lokal

    Untuk menggunakan lingkungan pengembangan lokal, ikuti langkah-langkah berikut:

    1. Menginstal gcloud CLI.
    2. Lakukan inisialisasi gcloud CLI.
    3. Instal Helm, alat pengelolaan paket Kubernetes.
  2. Login keakun Anda. Google Cloud 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.
  3. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  4. Verify that billing is enabled for your Google Cloud project.

  5. Enable the Resource Manager, Compute Engine, GKE, Pub/Sub APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  6. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  7. Verify that billing is enabled for your Google Cloud project.

  8. Enable the Resource Manager, Compute Engine, GKE, Pub/Sub APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

Menyiapkan lingkungan Anda

Untuk menyiapkan lingkungan Anda dengan Cloud Shell, ikuti langkah-langkah berikut:

  1. Menetapkan variabel lingkungan:

    export PROJECT_ID=PROJECT_ID
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format 'get(projectNumber)')
    export LOCATION=LOCATION
    

    Ganti PROJECT_ID dengan Google Cloud project ID Anda dan LOCATION dengan region atau zona tempat cluster GKE Anda akan dibuat.

    Jika Anda tidak mengikuti seluruh tutorial dalam satu sesi, atau jika variabel lingkungan Anda tidak ditetapkan karena alasan tertentu, pastikan untuk menjalankan perintah ini lagi untuk menetapkan variabel lagi.

  2. Buat cluster GKE Standar dengan penskalaan otomatis cluster dan Workload Identity Federation untuk GKE diaktifkan:

    gcloud container clusters create scale-to-zero \
        --project=${PROJECT_ID} --location=${LOCATION} \
        --machine-type=n1-standard-2 \
        --enable-autoscaling --min-nodes=1 --max-nodes=5 \
        --workload-pool=${PROJECT_ID}.svc.id.goog
    

Menginstal KEDA

KEDA adalah komponen yang melengkapi Horizontal Pod Autoscaler Kubernetes. Dengan KEDA, Anda dapat menurunkan skala Deployment hingga nol Pod dan menaikkan skala dari nol Pod hingga satu Pod. Deployment adalah objek Kubernetes API yang memungkinkan Anda menjalankan beberapa replika Pod yang didistribusikan di antara node dalam cluster. Algoritma Horizontal Pod Autoscaler standar berlaku setelah GKE membuat setidaknya satu Pod.

Setelah GKE menurunkan skala Deployment hingga nol Pod, karena tidak ada Pod yang berjalan, penskalaan otomatis tidak dapat mengandalkan metrik Pod seperti penggunaan CPU. Akibatnya, KEDA memungkinkan pengambilan metrik yang berasal dari luar cluster menggunakan penerapan Kubernetes External Metrics API. Anda dapat menggunakan API ini untuk melakukan penskalaan otomatis berdasarkan metrik seperti jumlah pesan yang belum selesai di langganan Pub/Sub. Lihat dokumentasi KEDA untuk mengetahui daftar semua sumber metrik yang didukung.

Instal KEDA di cluster Anda dengan Helm atau dengan kubectl.

Helm

Jalankan perintah berikut untuk menambahkan repositori Helm KEDA, menginstal chart Helm KEDA, dan memberikan akses baca akun layanan KEDA ke Cloud Monitoring:

helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda --create-namespace --namespace keda

gcloud projects add-iam-policy-binding projects/${PROJECT_ID} \
     --role roles/monitoring.viewer \
     --member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/keda/sa/keda-operator

Perhatikan bahwa perintah ini juga menyiapkan aturan otorisasi yang mengharuskan cluster disiapkan dengan Workload Identity Federation untuk GKE.

kubectl

Jalankan perintah berikut untuk menginstal KEDA menggunakan kubectl apply dan memberikan akses baca akun layanan KEDA ke Cloud Monitoring:

kubectl apply --server-side  -f https://github.com/kedacore/keda/releases/download/v2.15.1/keda-2.15.1.yaml

gcloud projects add-iam-policy-binding projects/${PROJECT_ID} \
     --role roles/monitoring.viewer \
     --member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/keda/sa/keda-operator

Perhatikan bahwa perintah ini juga menyiapkan aturan otorisasi yang mengharuskan cluster disiapkan dengan Workload Identity Federation untuk GKE.

Pastikan semua resource KEDA muncul di namespace keda:

kubectl get all -n keda

Untuk mengetahui informasi selengkapnya tentang desain dan resource KEDA, lihat dokumentasi KEDA.

Menurunkan skala workload Pub/Sub Anda hingga nol

Bagian ini menjelaskan workload yang memproses pesan dari langganan Pub/Sub, menangani setiap pesan, dan mengonfirmasi penyelesaiannya. Workload diskalakan secara dinamis: seiring bertambahnya jumlah pesan yang tidak dikonfirmasi, penskalaan otomatis akan membuat lebih banyak Pod untuk memastikan pemrosesan tepat waktu.

Penskalaan hingga nol memastikan tidak ada Pod yang dibuat saat tidak ada pesan yang diterima untuk sementara waktu. Hal ini menghemat resource karena tidak ada Pod yang menganggur dalam jangka waktu yang lama.

Men-deploy workload Pub/Sub

Men-deploy workload contoh yang memproses pesan yang diantrekan di topik Pub/Sub. Untuk menyimulasikan workload yang realistis, program contoh ini menunggu tiga detik sebelum mengonfirmasi pesan. Workload dikonfigurasi untuk berjalan di bawah akun layanan keda-pubsub-sa.

Jalankan perintah berikut untuk membuat topik dan langganan Pub/Sub, mengonfigurasi izinnya, dan membuat Deployment yang memulai workload di bawah namespace keda-pubsub.

gcloud pubsub topics create keda-echo
gcloud pubsub subscriptions create keda-echo-read --topic=keda-echo
gcloud projects add-iam-policy-binding projects/${PROJECT_ID}  \
    --role=roles/pubsub.subscriber \
  --member=principal://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/${PROJECT_ID}.svc.id.goog/subject/ns/keda-pubsub/sa/keda-pubsub-sa

kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/cloud-pubsub/deployment/keda-pubsub-with-workload-identity.yaml

Mengonfigurasi penskalaan hingga nol

Untuk mengonfigurasi workload Pub/Sub Anda agar diskalakan hingga nol, gunakan KEDA untuk menentukan resource ScaledObject guna menentukan cara deployment harus diskalakan. KEDA kemudian akan otomatis membuat dan mengelola objek HorizontalPodAutoscaler (HPA) yang mendasarinya.

  1. Buat resource ScaledObject untuk menjelaskan perilaku penskalaan otomatis yang diharapkan:

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/cloud-pubsub/deployment/keda-pubsub-scaledobject.yaml | envsubst | kubectl apply -f -
    

    Tindakan ini akan membuat objek berikut:

    apiVersion: keda.sh/v1alpha1
    kind: ScaledObject
    metadata:
      name: keda-pubsub
      namespace: keda-pubsub
    spec:
      maxReplicaCount: 5
      scaleTargetRef:
        name: keda-pubsub
      triggers:
        - type: gcp-pubsub
          authenticationRef:
            name: keda-auth
          metadata:
            subscriptionName: "projects/${PROJECT_ID}/subscriptions/keda-echo-read"
    
  2. Periksa objek HorizontalPodAutoscaler (HPA) yang dibuat KEDA berdasarkan objek ScaledObject:

    kubectl get hpa keda-hpa-keda-pubsub -n keda-pubsub -o yaml
    

    Anda dapat membaca lebih lanjut tentang penskalaan otomatis di dokumentasi Kubernetes.

  3. Tunggu hingga KEDA mengonfirmasi bahwa langganan Pub/Sub kosong, dan menurunkan skala Deployment hingga nol replika.

    Periksa autoscaler workload:

    kubectl describe hpa keda-hpa-keda-pubsub -n keda-pubsub
    

    Perhatikan bahwa dalam respons perintah, kondisi ScalingActive adalah salah (false). Pesan terkait menunjukkan bahwa Horizontal Pod Autoscaler mengonfirmasi bahwa KEDA menurunkan skala deployment hingga nol, yang kemudian berhenti beroperasi hingga Deployment dinaikkan skalanya kembali ke satu Pod.

    Name:                                                  keda-hpa-keda-pubsub
    Namespace:                                             keda-pubsub
    Metrics:                                               ( current / target )
      "s0-gcp-ps-projects-[...]]" (target average value):  0 / 10
    Min replicas:                                          1
    Max replicas:                                          5
    Deployment pods:                                       5 current / 5 desired
    Conditions:
      Type            Status  Reason               Message
      ----            ------  ------               -------
      AbleToScale     True    ScaleDownStabilized  recent recommendations were higher than current one [...]
      ScalingActive   False   ScalingDisabled      scaling is disabled since the replica count of the target is zero
      ScalingLimited  True    TooManyReplicas      the desired replica count is more than the maximum replica count
    

Memicu peningkatan skala

Untuk menstimulasi Deployment agar dinaikkan skalanya:

  1. Antrekan pesan di topik Pub/Sub:

    for num in {1..20}
    do
      gcloud pubsub topics publish keda-echo --project=${PROJECT_ID} --message="Test"
    done
    
  2. Pastikan Deployment dinaikkan skalanya:

    kubectl get deployments -n keda-pubsub
    

    Dalam output, perhatikan bahwa kolom 'Siap' menampilkan satu replika:

    NAME          READY   UP-TO-DATE   AVAILABLE   AGE
    keda-pubsub   1/1     1            1           2d
    

KEDA menaikkan skala Deployment setelah mengamati bahwa antrean tidak kosong.

Menurunkan skala workload LLM Anda hingga nol

Bagian ini menjelaskan workload Large Language Model (LLM) yang men-deploy server Ollama dengan GPU terlampir. Ollama memungkinkan menjalankan LLM populer seperti Gemma dan Llama 2, serta mengekspos fiturnya terutama melalui HTTP.

Menginstal add-on KEDA-HTTP

Menurunkan skala layanan HTTP hingga nol Pod selama periode tidak aktif akan menyebabkan kegagalan permintaan, karena tidak ada backend untuk menangani permintaan.

Bagian ini menunjukkan cara mengatasi masalah ini menggunakan add-on KEDA-HTTP. KEDA-HTTP memulai proxy HTTP yang menerima permintaan pengguna dan meneruskannya ke Layanan yang dikonfigurasi untuk menurunkan skala hingga nol. Jika Layanan tidak memiliki Pod, proxy akan memicu Layanan untuk menaikkan skala, dan mem-buffer permintaan hingga Layanan dinaikkan skalanya hingga setidaknya satu Pod.

Instal add-on KEDA-HTTP menggunakan Helm. Untuk mengetahui informasi selengkapnya, lihat dokumentasi KEDA-HTTP.

helm repo add ollama-helm https://otwld.github.io/ollama-helm/
helm repo update

# Set the proxy timeout to 120s, giving Ollama time to start.
helm install http-add-on kedacore/keda-add-ons-http  \
  --create-namespace --namespace keda \
  --set interceptor.responseHeaderTimeout=120s

Men-deploy workload LLM Ollama

Untuk men-deploy workload LLM Ollama:

  1. Buat node pool yang berisi node g2-standard-4 dengan GPU terlampir, dan konfigurasikan penskalaan otomatis cluster untuk menyediakan antara nol dan dua node:

    gcloud container node-pools create gpu --machine-type=g2-standard-4 \
        --location=${LOCATION} --cluster=scale-to-zero \
        --min-nodes 0 --max-nodes 2 --num-nodes=1 --enable-autoscaling
    
  2. Tambahkan repositori chart Helm Ollama resmi, dan perbarui repositori klien Helm lokal Anda:

    helm repo add ollama-helm https://otwld.github.io/ollama-helm/
    helm repo update
    
  3. Deploy server Ollama menggunakan chart Helm:

    helm install ollama ollama-helm/ollama --create-namespace --namespace ollama \
      -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/ollama/helm-values-ollama.yaml
    

    Konfigurasi helm-values-ollama.yaml menentukan model LLM yang akan dimuat, persyaratan GPU, dan port TCP untuk server Ollama.

Mengonfigurasi penskalaan hingga nol

Untuk mengonfigurasi workload Ollama Anda agar diskalakan hingga nol, KEDA-HTTP menggunakan HTTPScaledObject.

  1. Buat resource HTTPScaledObject untuk menjelaskan perilaku penskalaan otomatis yang diharapkan:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/ollama/keda-ollama-httpscaledobject.yaml
    

    Tindakan ini akan membuat objek HTTPScaledObject yang menentukan kolom berikut:

    • scaleTargetRef: menentukan Layanan yang harus diteruskan permintaannya oleh KEDA-HTTP. Dalam contoh ini, semua permintaan dengan host ollama.ollama dirutekan ke server Ollama.
    • scaledownPeriod: menentukan (dalam detik) seberapa cepat penurunan skala saat tidak ada permintaan yang diterima.
    • replicas: menentukan jumlah minimum dan maksimum Pod yang akan dipertahankan untuk deployment Ollama.
    • scalingMetric: menentukan metrik yang digunakan untuk mendorong penskalaan otomatis, seperti kecepatan permintaan dalam contoh ini. Untuk opsi metrik lainnya, lihat dokumentasi KEDA-HTTP.
    kind: HTTPScaledObject
    apiVersion: http.keda.sh/v1alpha1
    metadata:
        namespace: ollama
        name: ollama
    spec:
        hosts:
        - ollama.ollama
        scaleTargetRef:
            name: ollama
            kind: Deployment
            apiVersion: apps/v1
            service: ollama
            port: 11434
        replicas:
            min: 0
            max: 2
        scaledownPeriod: 3600
        scalingMetric:
            requestRate:
                targetValue: 20
    
  2. Jalankan perintah berikut untuk memverifikasi bahwa KEDA-HTTP telah berhasil memproses HTTPScaledObject yang dibuat pada langkah sebelumnya:

    kubectl get hpa,scaledobject -n ollama
    

    Output menunjukkan resource HorizontalPodAutoscaler (dibuat oleh KEDA), dan ScaledObject (dibuat oleh KEDA-HTTP):

    NAME                                                  REFERENCE           TARGETS       MINPODS   MAXPODS   REPLICAS   AGE
    horizontalpodautoscaler.autoscaling/keda-hpa-ollama   Deployment/ollama   0/100 (avg)   1         2         1          2d
    
    NAME                          SCALETARGETKIND      SCALETARGETNAME   MIN   MAX   TRIGGERS        AUTHENTICATION   READY   ACTIVE   FALLBACK   PAUSED    AGE
    scaledobject.keda.sh/ollama   apps/v1.Deployment   ollama            0     2     external-push                    True    False    False      Unknown   2d
    
  3. Pastikan Deployment diturunkan skalanya hingga nol Pod.

    Tunggu jangka waktu yang ditetapkan di kolom scaledownPeriod dan jalankan perintah:

    kubectl get deployments -n ollama
    

    Output menunjukkan bahwa KEDA menurunkan skala deployment Ollama, dan tidak ada Pod yang berjalan:

    NAME     READY   UP-TO-DATE   AVAILABLE   AGE
    ollama   0/0     0            0           2d
    

Memicu peningkatan skala

Untuk menstimulasi Deployment agar dinaikkan skalanya, panggil layanan Ollama menggunakan proxy yang disiapkan oleh add-on KEDA-HTTP. Hal ini menyebabkan nilai metrik kecepatan permintaan meningkat, dan memicu pembuatan Pod pertama.

Gunakan kemampuan penerusan port kubectl untuk mengakses proxy karena proxy tidak diekspos secara eksternal.

kubectl port-forward svc/keda-add-ons-http-interceptor-proxy -n keda 8080:8080 &

# Set the 'Host' HTTP header so that the proxy routes requests to the Ollama server.
curl -H "Host: ollama.ollama" \
  http://localhost:8080/api/generate \
  -d '{ "model": "gemma:7b", "prompt": "Hello!" }'

Perintah curl mengirimkan prompt "Halo!" ke model Gemma. Amati token jawaban yang kembali dalam respons. Untuk mengetahui spesifikasi API, lihat panduan Ollama.

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.

  1. Bersihkan langganan Pub/Sub dan topik:

    gcloud pubsub subscriptions delete keda-echo-read
    gcloud pubsub topics delete keda-echo
    
  2. Hapus cluster GKE Anda:

    gcloud container clusters delete scale-to-zero --location=${LOCATION}
    

Langkah berikutnya