在離峰時段縮減 GKE 叢集,藉此降低成本

Last reviewed 2022-11-24 UTC

本教學課程說明如何在 Google Kubernetes Engine (GKE) 部署排程自動調整程式,以降低成本。這類自動調度器會根據時間或星期幾,按照排程調度叢集資源。如果流量的起伏可預測,例如你是區域零售商,或是軟體僅供員工在特定工作時間使用,排程自動調度器就非常實用。

本教學課程適用於開發人員和營運人員,可協助他們在尖峰時段來臨前,可靠地擴充叢集,並在夜間、週末或任何其他上線使用者較少的時段縮減叢集,藉此節省費用。本文假設您已熟悉 Docker、Kubernetes、Kubernetes CronJob、GKE 和 Linux。

簡介

許多應用程式的流量模式並不平均。舉例來說,機構的員工可能只會在白天使用應用程式。因此,該應用程式的資料中心伺服器在夜間會處於閒置狀態。

除了其他優點外, Google Cloud 還能根據流量負載動態分配基礎架構,協助您節省費用。在某些情況下,簡單的自動調度資源設定即可管理流量不均的分配問題。如果這是你的情況,請繼續使用。不過,在其他情況下,流量模式的劇烈變化需要更精細的自動調度資源設定,才能避免系統在擴充期間不穩定,以及避免叢集資源過度佈建。

本教學課程著重於流量模式急劇變化的情境,您想向自動調整程式提示基礎架構即將出現尖峰流量。本文說明如何在早上擴大 GKE 叢集,並在晚上縮減叢集,但您可以使用類似方法,針對任何已知事件 (例如尖峰擴展事件、廣告活動或週末流量) 增加及減少容量。

在享有承諾使用折扣時縮減叢集

本教學課程說明如何在離峰時段將 GKE 叢集縮減至最低,以降低成本。不過,如果您已購買承諾使用折扣,請務必瞭解這些折扣如何與自動調度功能搭配運作。

只要承諾支付一定數量的資源 (vCPU、記憶體等) 費用,就能透過承諾使用合約享有大幅折扣。不過,如要決定承諾使用資源的數量,您必須事先瞭解工作負載在一段時間內使用的資源數量。為協助您降低成本,下圖說明規劃時應納入和不應納入的資源。

資源分配情況,顯示一律會分配的已承諾資源,以及因應需求 (尖峰) 自動調度的資源。

如圖所示,承諾使用合約下的資源分配是固定的。合約涵蓋的資源必須經常使用,才能符合您所做的承諾。因此,計算已承諾資源時,不應納入尖峰期間使用的資源。如要處理資源用量尖峰,建議使用 GKE 自動調整選項。這些選項包括本文討論的排程自動調度器,或是在 GKE 上執行最具成本效益的 Kubernetes 應用程式的最佳做法中討論的其他代管選項。

如果您已簽訂特定資源用量的承諾使用合約,將叢集縮減至低於該最低用量,並不會降低費用。在這種情況下,建議您嘗試安排一些工作,在運算需求較低的期間填補空缺。

架構

下圖顯示您在本教學課程中部署的基礎架構和排程自動調整規模架構。排程自動配置器由一組元件組成,這些元件會共同管理排程資源調度。

架構:顯示組成排程自動調整程式的元件。

在這個架構中,一組 Kubernetes CronJobs 會將流量模式的已知資訊匯出至 Cloud Monitoring 自訂指標。Kubernetes 水平 Pod 自動配置器 (HPA) 會讀取這項資料,做為 HPA 應調度工作負載資源的輸入內容。水平 Pod 自動配置器會根據目標 CPU 使用率等其他負載指標,決定如何調整特定部署項目的副本。

目標

  • 建立 GKE 叢集。
  • 部署使用 Kubernetes HPA 的範例應用程式。
  • 設定排程自動調度器元件,並更新 HPA,從排程自訂指標讀取資料。
  • 設定快訊,在排定的自動調整大小功能無法正常運作時觸發。
  • 為應用程式產生負載。
  • 檢查 HPA 如何因應流量正常增加,以及您設定的排程自訂指標。

本教學課程的程式碼位於 GitHub 存放區。

費用

在本文件中,您會使用下列 Google Cloud計費元件:

如要根據預測用量估算費用,請使用 Pricing Calculator。

初次使用 Google Cloud 的使用者可能符合免費試用期資格。

事前準備

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自體驗產品的實際應用成效。新客戶還能獲得價值 $300 美元的免費抵免額,用於執行、測試及部署工作負載。
  2. 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

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

  4. Enable the GKE, Artifact Registry and the Cloud Monitoring APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  5. 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

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

  7. Enable the GKE, Artifact Registry and the Cloud Monitoring APIs, if any are not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

準備環境

  1. 在 Google Cloud 控制台中啟用 Cloud Shell。

    啟用 Cloud Shell

    Google Cloud 控制台底部會開啟 Cloud Shell 工作階段,並顯示指令列提示。Cloud Shell 是已安裝 Google Cloud CLI 的殼層環境,並已設定適用於您目前專案的值。工作階段可能要幾秒鐘的時間才能初始化。

  2. 在 Cloud Shell 中,設定 Google Cloud 專案 ID、電子郵件地址、運算可用區和區域:

    PROJECT_ID=YOUR_PROJECT_ID
    ALERT_EMAIL=YOUR_EMAIL_ADDRESS
    gcloud config set project $PROJECT_ID
    gcloud config set compute/region us-central1
    gcloud config set compute/zone us-central1-f
    

    更改下列內容:

    • YOUR_PROJECT_ID:您使用的專案 Google Cloud 專案名稱。
    • YOUR_EMAIL_ADDRESS:當排定的自動配置器無法正常運作時,系統會通知這個電子郵件地址。

    如要,您可以為本教學課程選擇其他區域和可用區。

  3. 複製 kubernetes-engine-samples GitHub 存放區:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples/
    cd kubernetes-engine-samples/cost-optimization/gke-scheduled-autoscaler
    

    本範例中的程式碼會整理在下列資料夾中:

    • 根目錄:包含 CronJob 用於將自訂指標匯出至 Cloud Monitoring 的程式碼。
    • k8s/:包含具有 Kubernetes HPA 的部署作業範例。
    • k8s/scheduled-autoscaler/:包含 CronJob,可匯出自訂指標和更新版 HPA,以便從自訂指標讀取資料。
    • k8s/load-generator/:包含 Kubernetes Deployment,其中有應用程式可模擬每小時用量。Deployment 是 Kubernetes API 物件,可讓您執行多個 Pod 副本,這些副本會分散在叢集的節點中。
    • monitoring/:包含您在本教學課程中設定的 Cloud Monitoring 元件。

建立 GKE 叢集

  1. 在 Cloud Shell 中,建立 GKE 叢集來執行排定的自動調整功能:

    gcloud container clusters create scheduled-autoscaler \
        --enable-ip-alias \
        --release-channel=stable \
        --machine-type=e2-standard-2 \
        --enable-autoscaling --min-nodes=1 --max-nodes=10 \
        --num-nodes=1 \
        --autoscaling-profile=optimize-utilization
    

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

    NAME                   LOCATION       MASTER_VERSION   MASTER_IP      MACHINE_TYPE   NODE_VERSION     NUM_NODES  STATUS
    scheduled-autoscaler   us-central1-f  1.22.15-gke.100  34.69.187.253  e2-standard-2  1.22.15-gke.100  1          RUNNING
    

    這不是正式環境設定,但適合本教學課程。在這個設定中,您會使用最少 1 個節點和最多 10 個節點,設定叢集自動配置器。您也可以啟用 optimize-utilization 設定檔,加快縮減程序。

部署範例應用程式

  1. 部署範例應用程式,但不使用排程自動調度器:

    kubectl apply -f ./k8s
    
  2. 開啟 k8s/hpa-example.yaml 檔案。

    以下列出檔案內容。

    spec:
      maxReplicas: 20
      minReplicas: 10
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: php-apache
      metrics:
      - type: Resource
        resource:
          name: cpu
          target:
            type: Utilization
            averageUtilization: 60

    請注意,副本數量下限 (minReplicas) 已設為 10。 這項設定也會根據 CPU 使用率 (name: cpu 和 type: Utilization 設定) 調整叢集資源。

  3. 等待應用程式上架:

    kubectl wait --for=condition=available --timeout=600s deployment/php-apache
    EXTERNAL_IP=''
    while [ -z $EXTERNAL_IP ]
    do
        EXTERNAL_IP=$(kubectl get svc php-apache -o jsonpath={.status.loadBalancer.ingress[0].ip})
        [ -z $EXTERNAL_IP ] && sleep 10
    done
    curl -w '\n' http://$EXTERNAL_IP
    

    如果應用程式可用,輸出內容如下:

    OK!
    
  4. 確認設定:

    kubectl get hpa php-apache
    

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

    NAME         REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
    php-apache   Deployment/php-apache   9%/60%    10        20        10         6d19h
    

    REPLICAS 欄會顯示 10,與 hpa-example.yaml 檔案中 minReplicas 欄位的值相符。

  5. 確認節點數量是否已增加至 4 個:

    kubectl get nodes
    

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

    NAME                                                  STATUS   ROLES    AGE   VERSION
    gke-scheduled-autoscaler-default-pool-64c02c0b-9kbt   Ready    <none>   21S   v1.17.9-gke.1504
    gke-scheduled-autoscaler-default-pool-64c02c0b-ghfr   Ready    <none>   21s   v1.17.9-gke.1504
    gke-scheduled-autoscaler-default-pool-64c02c0b-gvl9   Ready    <none>   21s   v1.17.9-gke.1504
    gke-scheduled-autoscaler-default-pool-64c02c0b-t9sr   Ready    <none>   21s   v1.17.9-gke.1504
    

    建立叢集時,您使用 min-nodes=1 旗標設定了最低設定。不過,由於 hpa-example.yaml 檔案中的 minReplicas 設為 10,因此您在本程序開頭部署的應用程式會要求更多基礎架構。

    將 minReplicas 設為 10 等值是零售商等公司常用的策略,因為他們預期在營業日的前幾小時,流量會突然增加。不過,為 HPA minReplicas 設定高值可能會增加成本,因為叢集無法縮減,即使在應用程式流量較低的夜間也是如此。

設定排定的自動配置器

  1. 在 Cloud Shell 中,將自訂指標 - Cloud Monitoring 轉接器安裝到 GKE 叢集:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/k8s-stackdriver/master/custom-metrics-stackdriver-adapter/deploy/production/adapter_new_resource_model.yaml
    kubectl wait --for=condition=available --timeout=600s deployment/custom-metrics-stackdriver-adapter -n custom-metrics
    

    這個轉接器可根據 Cloud Monitoring 自訂指標,自動調度 Pod 資源。

  2. 在 Artifact Registry 中建立存放區,並授予讀取權限:

    gcloud artifacts repositories create gke-scheduled-autoscaler \
      --repository-format=docker --location=us-central1
    gcloud auth configure-docker us-central1-docker.pkg.dev
    gcloud artifacts repositories add-iam-policy-binding gke-scheduled-autoscaler \
       --location=us-central1 --member=allUsers --role=roles/artifactregistry.reader
    
  3. 建構並推送自訂指標匯出工具程式碼:

    docker build -t us-central1-docker.pkg.dev/$PROJECT_ID/gke-scheduled-autoscaler/custom-metric-exporter .
    docker push us-central1-docker.pkg.dev/$PROJECT_ID/gke-scheduled-autoscaler/custom-metric-exporter
    
  4. 部署 CronJob 來匯出自訂指標,並部署從這些自訂指標讀取資料的 HPA 更新版本:

    sed -i.bak s/PROJECT_ID/$PROJECT_ID/g ./k8s/scheduled-autoscaler/scheduled-autoscale-example.yaml
    kubectl apply -f ./k8s/scheduled-autoscaler
    
  5. 開啟並檢查 k8s/scheduled-autoscaler/scheduled-autoscale-example.yaml 檔案。

    以下列出檔案內容。

    apiVersion: batch/v1
    kind: CronJob
    metadata:
      name: scale-up
    spec:
      schedule: "50-59/1 * * * *"
      jobTemplate:
        spec:
          template:
            spec:
              containers:
              - name: custom-metric-extporter
                image: us-central1-docker.pkg.dev/PROJECT_ID/gke-scheduled-autoscaler/custom-metric-exporter
                command:
                  - /export
                  - --name=scheduled_autoscaler_example
                  - --value=10
              restartPolicy: OnFailure
          backoffLimit: 1
    ---
    apiVersion: batch/v1
    kind: CronJob
    metadata:
      name: scale-down
    spec:
      schedule: "1-49/1 * * * *"
      jobTemplate:
        spec:
          template:
            spec:
              containers:
              - name: custom-metric-extporter
                image: us-central1-docker.pkg.dev/PROJECT_ID/gke-scheduled-autoscaler/custom-metric-exporter
                command:
                  - /export
                  - --name=scheduled_autoscaler_example
                  - --value=1
              restartPolicy: OnFailure
          backoffLimit: 1

    這項設定會指定 CronJob 應根據一天中的時間,將建議的 Pod 副本計數匯出至名為 custom.googleapis.com/scheduled_autoscaler_example 的自訂指標。為方便本教學課程的監控部分,排程欄位設定會定義每小時的擴充和縮減。在正式環境中,您可以自訂這個時間表,配合業務需求。

  6. 開啟並檢查 k8s/scheduled-autoscaler/hpa-example.yaml 檔案。

    以下清單顯示檔案內容。

    spec:
      maxReplicas: 20
      minReplicas: 1
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: php-apache
      metrics:
      - type: Resource
        resource:
          name: cpu
          target:
            type: Utilization
            averageUtilization: 60
      - type: External
        external:
          metric:
            name: custom.googleapis.com|scheduled_autoscaler_example
          target:
              type: AverageValue
              averageValue: 1

    這項設定指定 HPA 物件應取代先前部署的 HPA。請注意,這項設定會將 minReplicas 中的值減少為 1。這表示工作負載可縮減至最低限度。這項設定也會新增外部指標 (type: External)。新增這項指標後,自動調度機制現在會根據兩個因素觸發。

    在這種多指標情境中,HPA 會計算每個指標的建議副本數量,然後選擇傳回最高值的指標。請務必瞭解這一點,因為排定的自動調度器可能會建議在特定時間點,Pod 數量應為 1。但如果某個 Pod 的實際 CPU 使用率高於預期,HPA 會建立更多副本。

  7. 再次執行下列指令,檢查節點和 HPA 副本數量:

    kubectl get nodes
    kubectl get hpa php-apache
    

    您看到的輸出內容取決於排定的自動調度器最近執行的動作,特別是 minReplicas 和 nodes 的值在調度週期中的不同時間點會有所不同。

    舉例來說,在每小時約 51 到 60 分鐘 (代表流量高峰期),minReplicas 的 HPA 值會是 10,nodes 的值會是 4。

    反之,在第 1 到 50 分鐘 (代表流量較低的期間),HPA minReplicas 值會是 1,而 nodes 值則會是 1 或 2,視已分配及移除的 Pod 數量而定。如果值較低 (1 到 50 分鐘),叢集最多可能需要 10 分鐘才能完成縮減。

設定排定的自動配置器無法正常運作時的快訊

在正式環境中,您通常會想知道 CronJob 何時未填入自訂指標。為此,您可以建立快訊,在任何 custom.googleapis.com/scheduled_autoscaler_example 串流五分鐘內沒有出現時觸發。

  1. 在 Cloud Shell 建立通知管道:

    gcloud beta monitoring channels create \
        --display-name="Scheduled Autoscaler team (Primary)" \
        --description="Primary contact method for the Scheduled Autoscaler team lead"  \
        --type=email \
        --channel-labels=email_address=${ALERT_EMAIL}
    

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

    Created notification channel NOTIFICATION_CHANNEL_ID.
    

    這個指令會建立 通知管道 (類型為 email),簡化教學課程步驟。在正式環境中,建議您將通知管道設為 sms 或 pagerduty,採用較不非同步的策略。

  2. 設定變數,其值為 NOTIFICATION_CHANNEL_ID 預留位置中顯示的值:

    NOTIFICATION_CHANNEL_ID=NOTIFICATION_CHANNEL_ID
    
  3. 部署快訊政策:

    gcloud monitoring policies create \
        --policy-from-file=./monitoring/alert-policy.yaml \
        --notification-channels=$NOTIFICATION_CHANNEL_ID
    

    alert-policy.yaml 檔案包含規格,如果五分鐘後仍未收到指標,就會傳送快訊。

  4. 前往 Cloud Monitoring 的「Alerting」(快訊) 頁面,查看快訊政策。

    前往「Alerting」(快訊)

  5. 按一下「Scheduled Autoscaler Policy」(排定的自動配置器政策),然後驗證警告政策的詳細資料。

對範例應用程式產生負載

  • 在 Cloud Shell 中部署負載產生器:

    kubectl apply -f ./k8s/load-generator
    

    以下清單顯示 load-generator 指令碼:

    command: ["/bin/sh", "-c"]
    args:
    - while true; do
        RESP=$(wget -q -O- http://php-apache.default.svc.cluster.local);
        echo "$(date +%H)=$RESP";
        sleep $(date +%H | awk '{ print "s("$0"/3*a(1))*0.5+0.5" }' | bc -l);
      done;
    

    這個指令碼會在叢集中執行,直到您刪除 load-generator 部署作業為止。每隔幾毫秒,就會向你的 php-apache 服務提出要求。sleep 指令會模擬一天內負載分配的變化。透過這種方式產生流量的指令碼,您可以瞭解在 HPA 設定中結合 CPU 使用率和自訂指標時會發生什麼情況。

根據流量或排定的指標,以視覺化方式呈現資源增減情況

在本節中,您將查看顯示擴大和縮減效果的視覺化內容。

  1. 在 Cloud Shell 中建立新的資訊主頁:

    gcloud monitoring dashboards create \
        --config-from-file=./monitoring/dashboard.yaml
    
  2. 前往 Cloud Monitoring 的「Dashboards」(資訊主頁) 頁面:

    前往資訊主頁

  3. 按一下「Scheduled Autoscaler Dashboard」(自動配置器排程資訊主頁)。

    資訊主頁會顯示三張圖表。您需要等待至少 2 小時 (最好是 24 小時以上),才能查看擴充和縮減資源的動態,以及一天中不同負載分配情形如何影響自動調度資源。

    如要瞭解圖表顯示的內容,請參考下列圖表,這些圖表呈現的是全天檢視畫面:

    • 「排定的指標 (所需的 Pod 數量)」會顯示透過 CronJob 匯出至 Cloud Monitoring 的自訂指標時間序列,這些 CronJob 是您在「設定排定的自動調度資源」中設定。

      Pod 需求圖表,顯示每小時都會出現尖峰。

    • CPU 使用率 (要求量與使用量) 會顯示要求 CPU (紅色) 和實際 CPU 使用率 (藍色) 的時間序列。負載較低時,水平 Pod 自動配置器會根據排定的自動調度資源器做出使用率決策。不過,當流量增加時,HPA 會視需要增加 Pod 數量,如下午 12 點到 6 點之間的資料點所示。

      CPU 使用率圖表:顯示需求在下午 4 點前持續成長,之後開始下降。

    • 「Pod 數量 (排程與實際) + 平均 CPU 使用率」會顯示與先前類似的檢視畫面。Pod 數量 (紅色) 每小時會按照排程 (藍色) 增加至 10 個。隨著負載變化,Pod 數量會自然增加和減少 (下午 12 點和下午 6 點)。平均 CPU 使用率 (橘色) 仍低於您設定的目標 (60%)。

      2 張圖表。其中一個顯示 Pod 的需求,每小時需求都會激增。另一個圖表則顯示 CPU 使用率上下波動,但最高不超過設定的高值。

清除所用資源

為避免因為本教學課程所用資源,導致系統向 Google Cloud 收取費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。

刪除專案

  1. 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。

    前往「Manage resources」(管理資源)

  2. 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)。
  3. 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。

後續步驟