使用 HPA 將 GKE 工作負載擴充至零,或從零擴充

本教學課程說明如何設定工作負載,在閒置時自動將副本數調為零,並在需求增加時調回,藉此在 Google Kubernetes Engine (GKE) 中提高資源使用率。這種做法會將水平 Pod 自動調度器 (HPA) 與 GKE 的受管理自動調度基礎架構整合,根據外部指標管理調度作業。

minReplicas 欄位的值設為 0,並在 HPA 資訊清單中定義 ExternalObject 類型的指標,即可將部署作業的規模縮減為零。GKE 會透過 AutoscalingMetric 自訂資源監控這些指標,確保應用程式的資源管理效率。

完成這項設定後,您不需要使用 KEDA 等第三方指標介面卡,即可調整 GKE 工作負載的資源配置。這項解決方案可直接在 GKE 控制層中管理指標擷取作業和資源調度建議,減少叢集管理負擔。

在本教學課程中,您將部署範例非同步工作站應用程式,處理 Pub/Sub 佇列中的訊息。您可以使用 AutoscalingMetric 自訂資源,設定水平 Pod 自動調度器來監控佇列深度 (pubsub.googleapis.com:num_undelivered_messages):

  • 當訊息送達訂閱項目時:GKE 會擴大 worker Pod,處理佇列中的訊息。
  • 佇列清空時:GKE 會自動將工作站 Deployment 縮減至零個副本。

本教學課程適用於應用程式開發人員、平台管理員和作業人員,以及想要在工作負載閒置時將其縮減為零,藉此最佳化 GKE 資源用量的 DevOps。

注意事項

將工作負載設定為縮減至零之前,請先考量下列事項:

  • 如要使用 HPA 將工作負載擴展至零或從零擴展,新叢集和升級後的現有叢集都必須執行 GKE 叢集控制層和節點 1.37 以上版本。如果您使用現有叢集,請確認叢集版本,或將叢集或節點升級至 1.37 以上版本。
  • 您的 HPA 資訊清單必須使用 apiVersion: autoscaling/v2 設定,才能支援 minReplicas: 0 設定和外部指標。
  • 將節點集區降級至 1.37 之前的版本前,請更新所有設定為從零開始擴縮的 HPA 資訊清單,將 minReplicas 欄位設為 1 以上。1.37 之前的版本不支援 minReplicas: 0 設定,這可能會導致工作負載停滯在零個副本。
  • 您必須在水平 Pod 自動調度器中,至少設定一項 ExternalObject 指標 (例如佇列深度)。當工作負載的 Pod 數量為零時,GKE 無法收集 CPU 或記憶體 (Resource) 指標,因此單靠資源指標無法從零觸發擴充作業。
  • AutoscalingMetric、HorizontalPodAutoscaler 和目標 Deployment 必須位於相同的 Kubernetes 命名空間。

事前準備

  1. 安裝 Google Cloud CLI。

  2. 設定 gcloud CLI,使用您的聯合身分。

    詳情請參閱「使用聯合身分登入 gcloud CLI」。

  3. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  4. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您在專案中獲派角色,即可選取該專案。
    • 建立專案:如要建立專案,您需要「專案建立者」角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  5. 確認專案已啟用計費功能 Google Cloud

  6. 啟用 GKE 和 Pub/Sub API:

    啟用 API 時所需的角色

    如要啟用 API,您必須具備 serviceusage.services.enable 權限。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「服務使用情形管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色

    gcloud services enable container.googleapis.com pubsub.googleapis.com

必要的角色

如要取得完成本教學課程所需的權限,請要求管理員在專案中授予您下列 IAM 角色:

如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

您或許也能透過自訂角色或其他預先定義的角色,取得必要權限。

設定環境

為簡化操作,本教學課程中的指令會在單一 Google Cloud 專案 (PROJECT_ID) 中建立所有資源 (GKE 叢集,以及 Pub/Sub 主題和訂閱項目)。

如要設定環境,請按照下列步驟操作:

  1. 設定環境變數:

    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 叢集的區域或可用區,例如 us-central1。如果是 Autopilot 叢集,請指定區域。
  2. 建立執行 1.37 以上版本的 GKE 叢集,並啟用 Workload Identity Federation for GKE。 建議您使用 Autopilot 叢集,享有全代管 Kubernetes 體驗,並在工作負載縮減為零時,盡可能節省成本。如要選擇最適合工作負載的作業模式,請參閱「選擇 GKE 作業模式」:

    Autopilot

    建立 Autopilot 叢集:

    gcloud container clusters create-auto scale-to-zero \
        --project=${PROJECT_ID} \
        --location=${LOCATION}
    

    Autopilot 叢集預設會啟用 Workload Identity Federation for GKE。

    標準

    建立啟用 Workload Identity Federation for GKE 的 Standard 叢集:

    gcloud container clusters create scale-to-zero \
        --project=${PROJECT_ID} \
        --location=${LOCATION} \
        --workload-pool=${PROJECT_ID}.
    
  3. 設定 kubectl 與叢集通訊:

    gcloud container clusters get-credentials scale-to-zero \
        --project=${PROJECT_ID} \
        --location=${LOCATION}
    

建立 Pub/Sub 資源

本教學課程以 Pub/Sub 佇列深度為例,說明外部指標來源。

如要建立 Pub/Sub 主題和訂閱項目,請按照下列步驟操作:

  1. 建立 Pub/Sub 主題:

    gcloud pubsub topics create my-worker-topic \
        --project=${PROJECT_ID}
    
  2. 建立附加至主題的訂閱項目:

    gcloud pubsub subscriptions create my-worker-subscription \
        --topic=my-worker-topic \
        --project=${PROJECT_ID}
    

設定 Workload Identity Federation for GKE

設定 GKE 適用的工作負載身分聯盟,允許工作者應用程式向 Google Cloud API 進行驗證,並從 Pub/Sub 服務取用訊息。

對於相同專案中的 AutoscalingMetric 資源,GKE 會自動處理與 Cloud Monitoring 的驗證。如要進一步瞭解如何定義自動調度資源的指標,請參閱從 Cloud Monitoring 擷取自訂或外部指標

如要為工作負載設定 Workload Identity Federation for GKE,請按照下列步驟操作:

  1. default 命名空間中,為工作者應用程式建立 Kubernetes 服務帳戶:

    kubectl create serviceaccount async-worker-sa \
        --namespace default
    
  2. roles/pubsub.subscriber 角色授予 Kubernetes 服務帳戶,讓應用程式可以接收來自 Pub/Sub 訂閱項目的訊息:

    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}./subject/ns/default/sa/async-worker-sa
    

詳情請參閱「設定應用程式以使用 Workload Identity Federation for GKE」。

建立 Deployment 範例

必須先建立 HPA 物件要監控的工作負載,才能建立該 HPA 物件。

如要建立範例 Deployment,請按照下列步驟操作:

  1. 將下列資訊清單儲存為 async-worker.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: async-worker
      namespace: default
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: async-worker
      template:
        metadata:
          labels:
            app: async-worker
        spec:
          containers:
          - name: async-worker
            image: nginx:latest
            ports:
            - containerPort: 80
            resources:
              limits:
                memory: 100Mi
              requests:
                cpu: 50m
                memory: 100Mi
    
  2. 套用 async-worker.yaml Deployment:

    kubectl apply -f async-worker.yaml
    

設定工作負載,以便調度資源數量可從零開始,也能調度至零

在本節中,您會設定 async-worker Deployment,在 Pub/Sub 佇列為空時縮減至零,並在新訊息送達時擴增。

建立 AutoscalingMetric 資源

如要定義 GKE 監控的外部信號,請建立 AutoscalingMetric 自訂資源。在下列資訊清單範例中,指標會向 Cloud Monitoring 查詢 my-worker-subscription 訂閱中未遞送的 Pub/Sub 訊息數。

如要建立 AutoscalingMetric 資源,請按照下列步驟操作:

  1. 將下列資訊清單儲存為 pubsub-metric.yaml 檔案:

    apiVersion: autoscaling.gke.io/v1beta1
    kind: AutoscalingMetric
    metadata:
      name: pubsub-queue-depth
      namespace: default
    spec:
      metrics:
      - promql:
          name: pubsub-undelivered
          query: >
              {
                "pubsub.googleapis.com/subscription/num_undelivered_messages",
                subscription_id="my-worker-subscription"
              }
    
  2. 套用 pubsub-metric.yaml 資訊清單:

    kubectl apply -f pubsub-metric.yaml
    
  3. 驗證指標狀態並擷取指標 ID:

    kubectl describe autoscalingmetric pubsub-queue-depth
    

    在輸出內容的 Status 區段中,確認沒有列出任何錯誤,並記下 autoscaling.gke.io|CUSTOM_RESOURCE_NAME|METRIC_NAME 格式的 Hpa Name 值。您將在下一節建立 HorizontalPodAutoscaler 物件時,參照這個外部指標 ID。如果「Status」部分回報設定錯誤,或無法如預期擷取指標,請參閱「排解為自動調度擷取的指標問題」。

設定水平 Pod 自動配置器

如要設定自動調度資源行為,請建立以 Deployment 為目標的 HorizontalPodAutoscaler 資源。

如要設定水平 Pod 自動調度器,請按照下列步驟操作:

  1. 將下列資訊清單儲存為 worker-hpa.yaml 檔案:

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: async-worker-hpa
      namespace: default
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: async-worker
      minReplicas: 0
      maxReplicas: 20
      metrics:
      - type: External
        external:
          metric:
            name: autoscaling.gke.io|pubsub-queue-depth|pubsub-undelivered
          target:
            type: AverageValue
            averageValue: "10"
    

    這份資訊清單會設定下列重要欄位:

    • minReplicas: 0:啟用「將資源調度率降至零」功能,允許控制器在需求降至零時,將 Deployment 縮減至 0 個副本。
    • type: External:設定外部指標來源,以便在工作負載沒有任何 Pod 時,HPA 可以觸發擴充。
    • name: autoscaling.gke.io|pubsub-queue-depth|pubsub-undelivered:使用 autoscaling.gke.io|CUSTOM_RESOURCE_NAME|METRIC_NAME 識別碼格式,將 HPA 直接對應至上一步驟中建立的 AutoscalingMetric 資源。
  2. 套用 worker-hpa.yaml 資訊清單:

    kubectl apply -f worker-hpa.yaml
    

驗證零比例行為和條件

處理完 Pub/Sub 訂閱項目中的所有訊息後,水平 Pod 自動調度器會評估零需求,並將 Deployment 縮減至 0 個副本。

如要確認水平 Pod 自動配置器是否啟動零狀態,請執行下列指令,檢查資源的狀態條件:async-worker-hpa

kubectl describe hpa async-worker-hpa

輸出結果會與下列內容相似:

Name:             async-worker-hpa
Namespace:        default
Reference:        Deployment/async-worker
Metrics:          ( current / target )
  "autoscaling.gke.io|pubsub-queue-depth|pubsub-undelivered" (external metric):  0 / 10
Min replicas:     0
Max replicas:     20
Deployment pods:  0 current / 0 desired
Conditions:
  Type            Status  Reason               Message
  ----            ------  ------               -------
  AbleToScale     True    SucceededGetScale    the HPA controller was able to get the target's current scale
  ScalingActive   True    ValidMetricFound     the HPA was able to successfully calculate a replica count from external metric
  ScaledToZero    True    ScaledToZero         the HPA has scaled the target resource to 0 replicas due to zero metric demand

瞭解 ScaledToZero 條件

ScaledToZero 條件會指出水平 Pod 自動配置器是否已將工作負載縮減為零個副本:

  • ScaledToZero: True (Reason: ScaledToZero):表示 HPA 控制器已成功將工作負載擴展至 0 個副本,因為外部指標需求降至零。HPA 會保持啟用狀態 (ScalingActive: True),並持續輪詢 GKE,偵測工作負載需求何時增加。
  • ScaledToZero: False:表示工作負載已擴充至一或多個副本。

如果您手動將 Deployment 擴展至零個副本 (例如使用 kubectl scale --replicas=0 指令),HPA 會暫停自動調度資源 (ScalingActive: False),避免發生衝突的變更。如要恢復自動調度資源功能,請將 Deployment 調整為一或多個副本 (kubectl scale deployment async-worker --replicas=1)。

如要排解工作負載無法縮減至零或無法從零擴增的疑難,請參閱「使用 HPA 疑難排解 GKE 工作負載縮減至零或從零擴增的問題」。如果水平 Pod 自動調度器回報外部指標遺失或無效,請參閱「排解自動調度資源擷取的指標問題」。

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收取本教學課程所用資源的費用,請按照下列步驟操作:

  1. 刪除 GKE 叢集:

    gcloud container clusters delete scale-to-zero \
        --project=${PROJECT_ID} \
        --location=${LOCATION}
    
  2. 刪除 Pub/Sub 訂閱項目和主題:

    gcloud pubsub subscriptions delete my-worker-subscription \
        --project=${PROJECT_ID}
    gcloud pubsub topics delete my-worker-topic \
        --project=${PROJECT_ID}
    

後續步驟