設定精細的資源限制

如要更有效率地管理基礎架構成本和配額,您可以為 Google Kubernetes Engine (GKE) 叢集自動調度程式定義資源上限。本文說明如何使用 CapacityQuota 自訂資源,為節點子集指定自動調度資源限制。與叢集範圍資源限制不同,您可以使用 Kubernetes 標籤選取器,在 CapacityQuota 中選取特定節點。

本文適用於負責管理叢集擴充和基礎架構的平台管理員。您應熟悉 Kubernetes 節點標籤和 GKE 叢集自動調度器

CapacityQuota 資源限制的運作方式

CapacityQuota 是叢集範圍的 Kubernetes 自訂資源,您可以在資訊清單中設定,並套用至叢集。您可以在 CapacityQuota 規格中使用下列欄位選取節點,並指定資源限制:

  • selector:使用一或多個標籤選取器,篩選特定節點。舉例來說,您可以選取特定 ComputeClass 的所有節點,或是具有兩個特定標籤的節點。
  • limits:為符合選取器的節點指定資源限制上限。舉例來說,您可以限制特定自訂 ComputeClass 可使用的 CPU 數量,或限制特定類型的 GPU 數量。

擴充作業開始時,叢集自動配置器會根據所有符合節點標籤的 CapacityQuota,以及任何已設定的叢集資源限制,檢查提議的節點。只有在節點未違反任何已設定的資源限制時,GKE 才會建立節點。

限制

  • GKE 會拒絕指定 node.kubernetes.io/instance-typebeta.kubernetes.io/instance-type 標籤選取器的 CapacityQuota。如要限制使用特定機型的節點,請建立具有 machineType 優先順序規則的自訂 ComputeClass,並在 CapacityQuota 中選取該 ComputeClass。
  • 與叢集範圍限制類似,CapacityQuota 可能會阻礙 ComputeClass 作用中遷移。由於主動遷移是擴充作業,叢集自動調度器會根據所有適用的 CapacityQuota 和叢集資源限制,檢查潛在的新節點。如果新節點違反任何這些限制,GKE 就不會建立節點,也不會發生作用中的遷移作業。只有在 CapacityQuota 已達到或接近設定的限制時,才會發生這種情況。
  • CapacityQuota 限制並非嚴格限制。在極少數情況下,您可能會發現 GKE 超過設定的限制,但幅度不大。
  • 只有叢集自動調度器會強制執行 CapacityQuota 限制。您可以手動調高叢集規模,或將限制變更為低於目前用量,藉此超過限制。
  • 如果叢集中的節點超出設定的 CapacityQuota 限制,叢集自動配置器會禁止建立符合超出 CapacityQuota 的新節點。叢集自動配置器不會縮減符合 CapacityQuota 的現有節點。

事前準備

開始之前,請務必先完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。
  • 確認您現有的 Autopilot 或 Standard 叢集執行的是 1.36.2-gke.2064000 以上版本。如要建立新叢集,請參閱「建立 Autopilot 叢集」。

在 CapacityQuota 中設定資源限制

您可以透過下列一或兩種方法,選取 CapacityQuota 適用的節點:

  • 使用確切的節點標籤選取節點:在 matchLabels 欄位中指定一或多個節點標籤鍵值組。GKE 會找出具有您指定的所有標籤的節點。 這個方法類似於在 Pod 規格中使用 nodeSelector 欄位。

  • 使用運算式選取節點:指定標籤鍵、運算子和值,藉此指定一或多個標籤選取器運算式。這個方法類似於在 Pod 規格中使用 nodeAffinity 欄位。

使用節點標籤選取節點

如要使用 matchLabels 欄位,根據節點標籤比對結果建構 CapacityQuota,請按照下列步驟操作:

  1. 儲存下列其中一個 CapacityQuota 範例,每個範例都適用於特定用途:

    • 如要為整個自訂 ComputeClass 設定資源限制,請指定 cloud.google.com/compute-class 標籤:

      apiVersion: autoscaling.x-k8s.io/v1beta1
      kind: CapacityQuota
      metadata:
        name: capacity-quota-compute-class
      spec:
        selector:
          matchLabels:
            cloud.google.com/compute-class: my-class
        limits:
          resources:
            cpu: 12
      

      這個 CapacityQuota 會限制叢集自動調度器,在 GKE 為 my-class ComputeClass 建立的所有節點中,最多只能使用 12 個 CPU。

    • 使用 cloud.google.com/gke-accelerator 標籤和 nvidia.com/gpu 資源名稱,設定特定類型 GPU 的數量限制:

      apiVersion: autoscaling.x-k8s.io/v1beta1
      kind: CapacityQuota
      metadata:
        name: capacity-quota-gpu
      spec:
        selector:
          matchLabels:
            cloud.google.com/compute-class: my-gpu-class
            cloud.google.com/gke-accelerator: nvidia-tesla-t4
        limits:
          resources:
            nvidia.com/gpu: 16
      

      這項 CapacityQuota 會將叢集自動調度器限制為 my-gpu-class ComputeClass 中最多 16 個 NVIDIA Tesla T4 GPU。如果省略 ComputeClass 選取器,則限制會套用至叢集中的所有 NVIDIA Tesla T4 GPU 節點。

    • 使用 topology.kubernetes.io/zone 標籤和 nodes 資源名稱,為 GKE 在特定區域中建立的節點數量設定限制:

      apiVersion: autoscaling.x-k8s.io/v1beta1
      kind: CapacityQuota
      metadata:
        name: capacity-quota-zone
      spec:
        selector:
          matchLabels:
            topology.kubernetes.io/zone: us-central1-b
        limits:
          resources:
            nodes: 64
      

      這項 CapacityQuota 會將叢集自動配置器限制為 us-central1-b 可用區中的 64 個節點。

  2. 建立 CapacityQuota:

    kubectl apply -f PATH_TO_MANIFEST_FILE
    

    PATH_TO_MANIFEST_FILE 替換為您建立的 CapacityQuota 資訊清單檔案路徑。

使用運算式選取節點

如要指定更複雜的目標,除了 matchLabels 欄位,CapacityQuota 也支援定義 matchExpressions 欄位。matchExpressions 可啟用 InNotInExistsDoesNotExist 等運算子。

  1. 建立使用 matchExpressions 欄位的 CapacityQuota 資訊清單。以下 CapacityQuota 範例會使用 In 運算子將節點分組,並對在特定高效能機器系列上執行的節點套用 CPU 和記憶體限制:

    apiVersion: autoscaling.x-k8s.io/v1beta1
    kind: CapacityQuota
    metadata:
      name: capacity-quota-high-perf-machines
    spec:
      selector:
        matchExpressions:
          - key: cloud.google.com/machine-family
            operator: In
            values:
              - c2
              - c3
              - c3d
      limits:
        resources:
          cpu: 64
          memory: 128Gi
    
  2. 將資訊清單套用至叢集:

    kubectl apply -f PATH_TO_MANIFEST_FILE
    

    PATH_TO_MANIFEST_FILE 替換為您建立的 CapacityQuota 資訊清單檔案路徑。

驗證 CapacityQuota 設定

本節說明如何部署違反限制的範例工作負載,驗證 CapacityQuota 是否主動強制執行限制。如要進行這項驗證,請按照下列步驟操作:

  1. 將下列 ComputeClass 範例儲存為 test-capacityquota-class.yaml

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: test-capacityquota-class
    spec:
      priorities:
      - machineFamily: n2
      nodePoolAutoCreation:
        enabled: true
    

    這個 ComputeClass 可以自動建立使用 N2 機器系列的節點。

  2. 建立 ComputeClass:

    kubectl apply -f test-capacityquota-class.yaml
    
  3. 將下列 CapacityQuota 範例儲存為 test-capacityquota.yaml

    apiVersion: autoscaling.x-k8s.io/v1beta1
    kind: CapacityQuota
    metadata:
      name: test-capacityquota
    spec:
      selector:
        matchLabels:
          cloud.google.com/compute-class: test-capacityquota-class
      limits:
        resources:
          cpu: 8
    

    這項 CapacityQuota 會將自動調度器限制為 test-capacityquota-class ComputeClass 的 CPU 資源上限為 8 個。

  4. 建立 CapacityQuota:

    kubectl apply -f test-capacityquota.yaml
    
  5. 將下列 Deployment 儲存為 test-capacityquota-workload.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: test-capacityquota-workload
    spec:
      replicas: 16
      selector:
        matchLabels:
          app: test-capacityquota-workload
      template:
        metadata:
          labels:
            app: test-capacityquota-workload
        spec:
          containers:
          - name: test
            image: gcr.io/google_containers/pause
            resources:
              limits:
                cpu: 500m
          nodeSelector:
            cloud.google.com/compute-class: test-capacityquota-class
    

    這個 Deployment 會建立 16 個 Pod,每個 Pod 都要求 500 mCPU。由於節點會保留部分 CPU 給系統元件,因此 GKE 必須建立的節點總 CPU 資源,才能執行 16 個 Pod,總和會大於 8

  6. 建立 Deployment:

    kubectl apply -f test-capacityquota-workload.yaml
    
  7. 等待約兩分鐘,然後驗證 Pod 排程狀態:

    kubectl get pods -l app=test-capacityquota-workload
    

    叢集自動調度器會將節點擴充至 8 個 CPU 的 CapacityQuota 限制。 達到上限後,自動調度器就不會再建立節點。因此,Deployment 中的部分 Pod 仍處於 Pending 狀態。

  8. 如要確認 Pending 狀態是由 CapacityQuota 造成,請描述其中一個待處理的 Pod:

    kubectl describe pod PENDING_POD_NAME
    

    PENDING_POD_NAME 替換為處於 Pending 狀態的 Pod 名稱。

    輸出內容會與下列內容相似,這表示 CapacityQuota 封鎖了節點擴充:

    Pod didn't trigger scale-up: 1 exceeded quota: "CapacityQuota/test-capacityquota", resources: cpu
    

    您也可以使用叢集自動配置器可見度記錄檔查看這些事件。檢查 noScaleUp 事件,如下列範例所示:

    {
      "jsonPayload": {
        "noDecisionStatus": {
          "noScaleUp": {
            "skippedMigs": [
              {
                "reason": {
                  "parameters": [
                    "exceeded quota: \"CapacityQuota/test-capacityquota\", resources: cpu"
                  ],
                  "messageId": "no.scale.up.mig.skipped"
                },
                "mig": {
                  "name": "gke-test-grp",
                  "zone": "us-central1-f",
                  "nodepool": "nap-n2-highcpu-2-test"
                }
              }
            ]
          }
        }
      }
    }
    

檢查 CapacityQuotas 的用量和有效性

CapacityQuota API 資源中的 status 欄位會提供與 CapacityQuota 相符節點的資源用量資訊,以及 CapacityQuota 規格的有效性。

如要檢查 CapacityQuota 的狀態,請執行下列指令:

kubectl describe capacityquota CAPACITY_QUOTA_NAME

CAPACITY_QUOTA_NAME 替換為要檢查的 CapacityQuota 名稱。

在輸出內容中,檢查下列欄位:

  • 如要檢查相符節點的資源用量,請使用 status.used 欄位:

    status:
      conditions:
      - lastTransitionTime: "2026-07-27T10:00:00Z"
        message: "CapacityQuota is valid"
        reason: "Valid"
        status: "True"
        type: "cluster-autoscaler.kubernetes.io/valid"
      used:
        resources:
          cpu: 32
          memory: 128Gi
    

    status.used 欄位用於可觀測性,叢集自動配置器不會使用這個欄位強制執行限制。只有在擴充作業成功後,這個欄位才會顯示用量。叢集自動配置器也會在內部追蹤待處理的節點,並將這些節點納入後續的擴充評估。這項內部追蹤功能有助於避免超出限制。

  • 如要檢查 CapacityQuota 是否有效,請使用 status.conditions 欄位:

    status:
      conditions:
      - lastTransitionTime: "2026-07-27T10:00:00Z"
        message: "CapacityQuota is valid"
        reason: "Valid"
        status: "True"
        type: "cluster-autoscaler.kubernetes.io/valid"
      used:
        resources:
          cpu: 32
          memory: 128Gi
    

    cluster-autoscaler.kubernetes.io/valid 條件會驗證 CapacityQuota 是否使用有效設定,例如格式正確的選取器。如果這項條件的「status」欄位值為「True」,則 CapacityQuota 有效,系統會強制執行限制。不過,如果 status 欄位中的值為 False,或條件尚未存在,系統就不會強制執行限制。「message」欄位會提供 CapacityQuota 無效的詳細原因。

後續步驟