本教學課程說明如何使用 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 工作階段,並顯示指令列提示。工作階段可能要幾秒鐘的時間才能初始化。
本機殼層
如要使用本機開發環境,請按照下列步驟操作:
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Resource Manager, Compute Engine, GKE, Pub/Sub APIs.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Resource Manager, Compute Engine, GKE, Pub/Sub APIs.
設定環境變數:
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
正在設定環境
如要使用 Cloud Shell 設定環境,請按照下列步驟操作:
安裝 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 長時間處於閒置狀態。
部署 Pub/Sub 工作負載
部署範例工作負載,處理 Pub/Sub 主題中排入佇列的訊息。為模擬實際工作負載,這個範例程式會在確認訊息前等待三秒。工作負載已設定為在 keda-pubsub-sa
服務帳戶下執行。
執行下列指令,在 keda-pubsub
命名空間下建立 Pub/Sub 主題和訂閱項目、設定權限,並建立啟動工作負載的部署。
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 和 Lamma 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.yaml
helm-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 中自動調度 LLM 推論工作負載。
- 探索 KEDA GitHub 存放區和說明文件。