本教學課程說明如何使用 KEDA,將 GKE 工作負載縮減至零個 Pod。將部署項目縮放至零個 Pod,可在閒置期間 (例如週末和非上班時間) 節省資源,或用於間歇性工作負載 (例如定期工作)。
目標
本教學課程將說明下列用途:
- 將 Pub/Sub 工作負載縮減為零: 根據 Pub/Sub 主題中排入佇列的訊息數量,按比例縮減 Pod 數量。佇列清空後,工作負載會自動縮減至零個 Pod。
- 將 LLM 工作負載縮放至零。 在搭載 GPU 的節點上部署 LLM 模型伺服器。服務閒置時,工作負載會自動縮減為零個 Pod。
費用
在本文件中,您會使用下列 Google Cloud的計費元件:
- GKE
- GPU resources used by GKE
- Pub/Sub
如要根據預測用量估算費用,請使用 Pricing Calculator。
完成本文所述工作後,您可以刪除建立的資源,避免繼續計費,詳情請參閱「清除所用資源」。
事前準備
在本教學課程中,您將使用 Cloud Shell 執行指令。Cloud Shell 是殼層環境,用於管理託管在 Google Cloud的資源。這個環境已預先安裝 Google Cloud CLI、kubectl、Helm 和 Terraform 指令列工具。如果您未使用 Cloud Shell,則必須安裝 Google Cloud CLI 和 Helm。
-
如要執行本頁的指令,請在下列其中一種開發環境中設定 gcloud CLI:
Cloud Shell
如要使用已設定 gcloud CLI 的線上終端機,請啟用 Cloud Shell:
頁面底部會開啟 Cloud Shell 工作階段,並顯示指令列提示。工作階段可能要幾秒鐘的時間才能初始化。
本機殼層
如要使用本機開發環境,請按照下列步驟操作:
- 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
-
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 theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
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 theserviceusage.services.enablepermission. Learn how to grant roles.-
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 theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
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 theserviceusage.services.enablepermission. Learn how to grant roles.
設定環境
如要使用 Cloud Shell 設定環境,請按照下列步驟操作:
設定環境變數:
export PROJECT_ID=PROJECT_ID export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format 'get(projectNumber)') export LOCATION=LOCATION請將
PROJECT_ID替換為您的 Google Cloud 專案 ID,並將LOCATION替換為要建立 GKE 叢集的區域或可用區。如果您未在單一工作階段中完成整個教學課程,或環境變數因故未設定,請務必再次執行這項指令,重新設定變數。
建立啟用叢集自動調度和 GKE 適用的工作負載身分聯盟的 Standard GKE 叢集:
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
安裝 KEDA
KEDA 是 Kubernetes 水平 Pod 自動配置器的輔助元件,使用 KEDA,您可以將 Deployment 調度至零個 Pod,也可以從零個 Pod 調度至一個 Pod。Deployment 是 Kubernetes API 物件,可讓您執行多個 Pod 副本,並將這些副本分配到叢集中的節點。GKE 建立至少一個 Pod 後,就會套用標準的水平 Pod 自動配置器演算法。
GKE 將 Deployment 擴充至零個 Pod 後,由於沒有任何 Pod 正在執行,自動調度無法依據 CPU 使用率等 Pod 指標運作。因此,KEDA 允許使用 Kubernetes External Metrics API 的實作項目,擷取叢集外部的指標。您可以透過這項 API,根據指標 (例如 Pub/Sub 訂閱中的未處理訊息數) 自動調度資源。如需所有支援的指標來源清單,請參閱 KEDA 說明文件。
使用 Helm 或 kubectl 在叢集上安裝 KEDA。
Helm
執行下列指令,新增 KEDA Helm 存放區、安裝 KEDA Helm 資訊套件,並授予 KEDA 服務帳戶 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
請注意,這項指令也會設定授權規則,要求叢集必須透過 Workload Identity Federation for GKE 設定。
kubectl
執行下列指令,使用 kubectl apply 安裝 KEDA,並授予 KEDA 服務帳戶 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
請注意,這項指令也會設定授權規則,要求叢集必須透過 Workload Identity Federation for GKE 設定。
確認所有 KEDA 資源都顯示在 keda 命名空間下:
kubectl get all -n keda
如要進一步瞭解 KEDA 設計和資源,請參閱 KEDA 說明文件。
將 Pub/Sub 工作負載的資源調度降到零
本節說明如何處理 Pub/Sub 訂閱項目的訊息、處理每則訊息,以及確認訊息處理完成的工作負載。工作負載會動態調度資源:隨著未確認訊息數量增加,自動調度資源會例項化更多 Pod,確保及時處理訊息。
如果一段時間未收到任何訊息,將 Pod 數量調至零可確保系統不會例項化任何 Pod。這樣可節省資源,因為不會有 Pod 長時間閒置。
部署 Pub/Sub 工作負載
部署範例工作負載,處理 Pub/Sub 主題中排入佇列的訊息。為模擬實際工作負載,這個範例程式會在確認訊息前等待三秒。工作負載已設定為在 keda-pubsub-sa 服務帳戶下執行。
執行下列指令,在 keda-pubsub 命名空間下建立 Pub/Sub 主題和訂閱項目、設定權限,並建立啟動工作負載的 Deployment。
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
設定「將資源調度率降至零」功能
如要將 Pub/Sub 工作負載設定為縮減至零,請使用 KEDA 定義 ScaledObject 資源,指定部署作業的縮放方式。接著,KEDA 會自動建立及管理基礎 HorizontalPodAutoscaler (HPA) 物件。
建立
ScaledObject資源,說明預期的自動調度資源行為: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 -這會建立下列物件:
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"檢查 KEDA 根據
ScaledObject物件建立的HorizontalPodAutoscaler(HPA) 物件:kubectl get hpa keda-hpa-keda-pubsub -n keda-pubsub -o yaml如要進一步瞭解自動調度,請參閱 Kubernetes 說明文件。
等待 KEDA 確認 Pub/Sub 訂閱項目為空,並將 Deployment 擴展至零個副本。
檢查工作負載自動調度資源功能:
kubectl describe hpa keda-hpa-keda-pubsub -n keda-pubsub請注意,在指令回應中,
ScalingActive條件為 false。 相關訊息顯示,水平 Pod 自動配置器確認 KEDA 已將 Deployment 縮減至零,此時會停止運作,直到 Deployment 重新擴增至一個 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
觸發擴充作業
如要刺激 Deployment 擴大規模,請執行下列步驟:
將訊息加入 Pub/Sub 主題的佇列:
for num in {1..20} do gcloud pubsub topics publish keda-echo --project=${PROJECT_ID} --message="Test" done確認 Deployment 正在擴充:
kubectl get deployments -n keda-pubsub在輸出中,觀察「Ready」欄是否顯示一個副本:
NAME READY UP-TO-DATE AVAILABLE AGE keda-pubsub 1/1 1 1 2d
KEDA 觀察到佇列不為空後,會擴大 Deployment。
將 LLM 工作負載的資源調度降到零
本節說明如何部署大型語言模型 (LLM) 工作負載,並附加 GPU 來部署 Ollama 伺服器。Ollama 可執行熱門的 LLM,例如 Gemma 和 Llama 2,並主要透過 HTTP 公開其功能。
安裝 KEDA-HTTP 外掛程式
如果 HTTP 服務在閒置期間縮減至零個 Pod,要求就會失敗,因為沒有後端可處理要求。
本節說明如何使用 KEDA-HTTP 外掛程式解決這個問題。KEDA-HTTP 會啟動 HTTP Proxy,接收使用者要求並轉送至設定為將資源調度率降至零的服務。如果 Service 沒有 Pod,Proxy 會觸發 Service 擴大,並緩衝處理要求,直到 Service 擴大至至少一個 Pod 為止。
使用 Helm 安裝 KEDA-HTTP 外掛程式。詳情請參閱 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
部署 Ollama LLM 工作負載
如要部署 Ollama LLM 工作負載,請按照下列步驟操作:
建立包含
g2-standard-4個節點的節點集區,並附加 GPU,然後設定叢集自動調度功能,提供零到兩個節點: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新增官方 Ollama Helm 資訊套件存放區,並更新本機 Helm 用戶端的存放區:
helm repo add ollama-helm https://otwld.github.io/ollama-helm/ helm repo update使用 Helm 資訊套件部署 Ollama 伺服器:
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.yamlhelm-values-ollama.yaml設定會指定要載入的 LLM 模型、GPU 需求,以及 Ollama 伺服器的 TCP 連接埠。
設定「將資源調度率降至零」功能
如要將 Ollama 工作負載設定為縮減至零,KEDA-HTTP 會使用 HTTPScaledObject。
建立
HTTPScaledObject資源,說明預期的自動調度資源行為:kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/refs/heads/main/cost-optimization/gke-keda/ollama/keda-ollama-httpscaledobject.yaml這會建立
HTTPScaledObject物件,定義下列欄位:scaleTargetRef:指定 KEDA-HTTP 應將要求轉送至的服務。在本範例中,所有含有主機ollama.ollama的要求都會轉送至 Ollama 伺服器。scaledownPeriod:指定在未收到任何要求時,縮減規模的速度 (以秒為單位)。replicas:指定要為 Ollama 部署作業維護的 Pod 數量下限和上限。scalingMetric:指定用於自動調度資源的指標,例如本例中的要求率。如需更多指標選項,請參閱 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執行下列指令,確認 KEDA-HTTP 已順利處理上一個步驟中建立的
HTTPScaledObject:kubectl get hpa,scaledobject -n ollama輸出內容會顯示
HorizontalPodAutoscaler(由 KEDA 建立) 和ScaledObject(由 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確認 Deployment 會將 Pod 數量縮減至零。
等待
scaledownPeriod欄位中設定的時間長度,然後執行指令:kubectl get deployments -n ollama輸出結果顯示 KEDA 已縮減 Ollama 部署作業,且沒有任何 Pod 正在執行:
NAME READY UP-TO-DATE AVAILABLE AGE ollama 0/0 0 0 2d
觸發擴充作業
如要刺激 Deployment 擴充,請使用 KEDA-HTTP 外掛程式設定的 Proxy 呼叫 Ollama 服務。這會導致要求率指標值增加,並觸發第一個 Pod 的建立作業。
由於 Proxy 不會向外公開,因此請使用 kubectl 通訊埠轉送功能存取 Proxy。
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!" }'
curl 指令會將「Hello!」提示傳送至 Gemma 模型。觀察回覆中傳回的答案權杖。如需 API 規格,請參閱 Ollama 指南。
清除所用資源
為避免因為本教學課程所用資源,導致系統向 Google Cloud 帳戶收取費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。
清除 Pub/Sub 訂閱與主題:
gcloud pubsub subscriptions delete keda-echo-read gcloud pubsub topics delete keda-echo刪除您的 GKE 叢集:
gcloud container clusters delete scale-to-zero --location=${LOCATION}
後續步驟
- 進一步瞭解如何在 GKE 中自動調度大型語言模型推論工作負載。
- 探索 KEDA GitHub 存放區和說明文件。