在離峰時段縮減 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. 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.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the GKE, Artifact Registry and the Cloud Monitoring APIs.

    Enable the APIs

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

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the GKE, Artifact Registry and the Cloud Monitoring APIs.

    Enable the APIs

準備環境

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

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

    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: cputype: 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 旗標設定了最低設定。不過,您在本程序開頭部署的應用程式要求更多基礎架構,因為 minReplicas 檔案中的 hpa-example.yaml 設為 10。

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

設定排程自動配置器

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

    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
    

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

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

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

設定快訊,在排定的自動調度資源功能無法正常運作時收到通知

在實際工作環境中,您通常會想知道 CronJobs 何時未填入自訂指標。為此,您可以建立快訊,在任何 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 類型的通知管道,簡化教學課程步驟。在實際工作環境中,建議您將通知管道設為 smspagerduty,採用較不非同步的策略。

  2. 設定變數,該變數的值會顯示在 NOTIFICATION_CHANNEL_ID 預留位置中:

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

    gcloud alpha 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 小時以上),才能查看擴充和縮減的動態,以及一天中不同負載分配方式對自動調度資源的影響。

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

    • 「Scheduled Metric (desired # of Pods)」(排定指標 (所需 Pod 數量)) 會顯示透過您在設定排定自動調度器中設定的 CronJob 匯出至 Cloud Monitoring 的自訂指標時間序列。

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

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

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

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

      2 張圖表。其中一個顯示 Pod 的需求,每小時需求都會大幅增加。另一個圖表則顯示 CPU 使用率起伏不定,但最高值不會超過設定的高值。

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收取本教學課程中所用資源的相關費用,請刪除含有該項資源的專案,或者保留專案但刪除個別資源。

刪除專案

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

後續步驟