使用 Kueue 和 TAS 排定動態配額

本文說明如何使用 Kueue拓撲感知排程 (TAS),在 Google Kubernetes Engine (GKE) 中佈建 TPU 節點集區,並排定動態切片。

您也可以直接與Slice 自訂資源互動,使用動態切片。詳情請參閱「使用自訂排程器進行動態切片」。

按照這些操作說明操作前,請務必瞭解動態切片的概念

需求條件

如要在 GKE 中使用動態切片,必須符合下列規定:

  • 在下列其中一個版本中,使用搶鮮版通道的 Standard 叢集:
    • 如要設定動態超級切片 (拓撲等於或大於 4x4x4),請使用 1.35.2-gke.1842000 以上版本。
    • 如要設定動態子切片 (拓撲小於 4x4x4),請使用 1.36.0-gke.3712000 以上版本。
  • 使用 Ironwood (TPU7x) 版本。
  • 為節點使用 Container-Optimized OS 映像檔。
  • 如要使用增量佈建,請使用「所有容量模式」預留項目。「所有」容量模式是由 TPU Cluster Director 啟用的功能。
  • 如要進行動態子切片,請確認節點有待處理的維護事件。監控執行個體是否有待處理的維護事件。 如果任何節點有待處理的維護事件,且結束時間介於 2026 年 9 月 18 日至 2026 年 9 月 30 日之間,您必須先在這些節點上手動觸發主機維護事件,才能使用子切片。

事前準備

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

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。較舊的 gcloud CLI 版本可能不支援執行本文件中的指令。

在 GKE 中使用 Kueue 進行動態切片

本節說明在 GKE 中使用動態切片的流程。

  1. 查看所有容量模式預訂的拓撲和健康狀態
  2. 在叢集中啟用切片控制器
  3. 安裝 Kueue、JobSet 和 LWS
  4. 建立 TPU 節點集區
  5. 設定 Kueue 建立 Slice 自訂資源
  6. 使用 Kueue 在動態切片上執行工作負載
  7. 清理

啟用 Slice 控制器

如要使用動態切片,請在叢集中啟用切片控制器。

  1. 更新叢集:

    gcloud container clusters update CLUSTER_NAME \
        --location=LOCATION \
        --enable-slice-controller
    

    更改下列內容:

  2. 取得憑證,以便使用 kubectl 指令與叢集通訊:

    gcloud config set container/cluster CLUSTER_NAME
    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=LOCATION
    
  3. 在下列指令的輸出內容中,確認是否顯示 slices.accelerator.gke.io 值:

    kubectl get crd slices.accelerator.gke.io
    

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

    slices.accelerator.gke.io                2026-01-09T23:58:02Z
    

安裝 Kueue、JobSet 和 LWS

如果已安裝 Kueue、JobSet 和 LWS,可以略過這個部分。

安裝 Kueue

請按照 Kueue 說明文件中的指示操作,或執行下列指令:

kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/KUEUE_VERSION/manifests.yaml

根據拓撲需求,將 KUEUE_VERSION 替換為所需的 Kueue 版本。如要使用動態子切片,請使用 Kueue v0.18.2 以上版本。如要使用動態超級切片,請使用 Kueue v0.16.6 以上版本。

安裝 JobSet

請按照 JobSet 說明文件中的操作說明,或執行下列指令:

kubectl apply --server-side -f https://github.com/kubernetes-sigs/jobset/releases/download/JOBSET_VERSION/manifests.yaml

根據拓撲需求,將 JOBSET_VERSION 替換為所需的 JobSet 版本。如要使用動態子切片,請使用 JobSet 0.12.0 以上版本。如要使用動態超級切片,請使用 JobSet v0.11.1 以上版本。

安裝 LWS

只有動態子切片需要 LeaderWorkerSet (LWS)。

請按照 LWS 說明文件中的指示操作,或執行下列指令:

kubectl apply --server-side -f https://github.com/kubernetes-sigs/lws/releases/download/LWS_VERSION/manifests.yaml

LWS_VERSION 替換為所需的 LWS 版本。使用 LWS v0.8.0 以上版本。

建立節點集區並啟用增量佈建

本節說明如何使用增量佈建建立 TPU 節點集區。GKE 會將所有 TPU 容量轉換為節點集區,這些集區包含 16 個節點的 Ironwood (TPU7x) VM 群組或子區塊。即使 GKE 無法找到所有狀況良好的 VM,也會佈建這些節點集區,方法是將節點放在主體機器狀況良好的部分,並在修復狀況不良的機器時,逐步佈建這些機器。

您可以將節點集區指定為下列任一項目:

  • 特定 TPU 區塊,在「所有容量」模式預留中公開。區塊目標設定可讓 GKE 在指定區塊內的任何可用子區塊中建立節點集區。
  • TPU 的特定子區塊,或 Ironwood (TPU7x) VM 的特定 16 節點群組,可進行更精細的控制。

建立工作負載政策

如要使用 Ironwood (TPU7x) 建立 TPU 節點集區,請先建立工作負載政策,並將 accelerator-topology-mode 欄位設為 provision_only。這項設定會觸發增量佈建程序。

建立工作負載政策:

gcloud compute resource-policies create workload-policy WORKLOAD_POLICY_NAME \
        --project=PROJECT_ID \
        --region=REGION  \
        --type=HIGH_THROUGHPUT \
        --accelerator-topology=4x4x4 \
        --accelerator-topology-mode=provision_only

更改下列內容:

  • WORKLOAD_POLICY_NAME:工作負載政策的名稱。
  • PROJECT_ID:您的 Google Cloud 專案 ID。
  • REGION:工作負載政策的區域。

這個指令各部分的說明如下:

  • 請務必將 accelerator-topology 欄位設為 4x4x4,以符合單一子區塊內的晶片總數。
  • 請務必將 accelerator-topology-mode 欄位設為 provision_only,確保系統觸發增量佈建程序。設定 provision_only 欄位後,節點集區會佈建 TPU 節點,但不形成 ICI 或 OCS 連結。

將節點集區指定為屬於區塊或子區塊

您可以在「所有容量」模式預訂中,指定特定子區塊或區塊。

  • 指定區塊:每個節點集區都會使用指定區塊的容量。GKE 會將節點集區放在該區塊的可用子區塊中。您必須建立與要使用的區塊中子區塊數量相同的節點集區。
  • 指定子區塊:每個節點集區都會對應至特定可用子區塊。使用子區塊目標時,只要至少有一個 VM 正常運作,GKE 就會建立節點集區。增量佈建可確保所有節點都放置在指定子區塊內。

封鎖

  1. 如要擷取預留項目中的區塊名稱,以及區塊中可用的子區塊數量,請按照「查看所有容量模式預留項目的拓撲和健康狀態」一文中的步驟操作:

    1. 如要找出區塊名稱,請列出所有預訂區塊,然後複製 name: 欄位中的值。這個值是這個文件中的區塊或 BLOCK_NAME 名稱。

    2. 如要判斷要建立多少節點集區,請說明預訂區塊,並找出 reservationSubBlockCount 欄位中的值。這個值代表可用的子區塊數量。舉例來說,reservationSubBlockCount: 4 值表示該區塊有四個子區塊,因此您需要建立四個不同的節點集區。

  2. 設定預訂路徑:

    export RESERVATION_PATH="projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME"
    

    更改下列內容:

    • RESERVATION_NAME:TPU 預留項目的名稱。
    • BLOCK_NAME:區塊名稱。
  3. 為上一步驟中識別的每個子區塊建立節點集區。 舉例來說,如果計數為 4,請執行這項指令四次。每個節點集區的名稱不得重複。

    gcloud container node-pools create NODE_POOL_NAME \
          --cluster=CLUSTER_NAME \
          --node-locations=ZONE \
          --machine-type=tpu7x-standard-4t \
          --num-nodes=16 \
          --placement-policy=WORKLOAD_POLICY_NAME \
          --reservation-affinity=specific \
          --reservation=${RESERVATION_PATH}
    

    更改下列內容:

    • NODE_POOL_NAME:新節點集區的名稱。
    • CLUSTER_NAME:GKE 叢集的名稱。
    • WORKLOAD_POLICY_NAME:您建立的工作負載政策名稱。
    • ZONE:節點集區的區域,例如 us-central1-a

子模塊

  1. 如要擷取區塊名稱和可用子區塊的 ID,請在「查看所有容量模式預訂的拓撲和健康狀態」文件中完成下列步驟:

    1. 如要找出區塊名稱,請列出所有預訂區塊,然後複製 name: 欄位中的值。這個值是這個文件中的區塊名稱或 BLOCK_NAME

    2. 如要找出子區塊的名稱,請列出區塊的所有子區塊,然後複製 reservationSubBlocks 底下每個項目的 name: 欄位值。這個值是本文件中子區塊或 SUBBLOCK_NAME 的名稱。

  2. 設定預訂路徑:

    export RESERVATION_PATH="projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME/reservationSubBlocks/SUBBLOCK_NAME"
    

    更改下列內容:

    • RESERVATION_NAME:TPU 預留項目的名稱。
    • BLOCK_NAME:區塊名稱。
    • SUBBLOCK_NAME:子區塊的名稱。
  3. 建立節點集區:

    gcloud container node-pools create NODE_POOL_NAME \
            --project=PROJECT_ID \
            --cluster=CLUSTER_NAME \
            --node-locations=ZONE \
            --machine-type=tpu7x-standard-4t \
            --num-nodes=16 \
            --placement-policy=WORKLOAD_POLICY_NAME \
            --reservation-affinity=specific \
            --reservation=${RESERVATION_PATH}
    

    更改下列內容:

    • NODE_POOL_NAME:新節點集區的專屬名稱,例如 sub-block-pool-1
    • PROJECT_ID:您的 Google Cloud 專案 ID。
    • CLUSTER_NAME:GKE 叢集名稱。
    • ZONE:節點集區的可用區,例如 us-central2-b
    • WORKLOAD_POLICY_NAME:您建立的工作負載政策名稱。

此時節點已建立,但晶片間互連 (ICI) 連結尚未啟用。因此,您無法直接在這些節點集區上執行工作負載。

如要啟用所有必要的 ICI 連結來形成切片,並允許排定工作負載,請使用下列其中一種方法建立動態切片:

  • 建立 Slice 自訂資源。您可以使用 Slice 自訂資源定義指定拓撲,而非 Pod,Slice 控制器會啟動該拓撲。
  • 使用 KueueTAS 安排 GKE 工作負載時程。Kueue 會自動處理 Slice 自訂資源的建立和刪除作業。請避免手動修改 Kueue 建立的 Slice 自訂資源。

使用 Kueue 和 TAS 建立動態切片

在本節中,您將使用 Kueue 和 TAS 排程 GKE 工作負載。

安裝 Kueue 切片控制器

  1. 如要安裝 Kueue 切片控制器,請將下列資訊清單儲存為 slice-controller.yaml

    # Copyright 2026 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: v1
    kind: Namespace
    metadata:
      labels:
        app.kubernetes.io/managed-by: kustomize
        app.kubernetes.io/name: slice-controller
        control-plane: controller-manager
      name: slice-controller-system
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      labels:
        app.kubernetes.io/managed-by: kustomize
        app.kubernetes.io/name: slice-controller
        control-plane: controller-manager
      name: slice-controller-controller-manager
      namespace: slice-controller-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      labels:
        app.kubernetes.io/managed-by: kustomize
        app.kubernetes.io/name: slice-controller
        control-plane: controller-manager
      name: slice-controller-leader-election-role
      namespace: slice-controller-system
    rules:
    - apiGroups:
      - ""
      resources:
      - configmaps
      verbs:
      - get
      - list
      - watch
      - create
      - update
      - patch
      - delete
    - apiGroups:
      - coordination.k8s.io
      resources:
      - leases
      verbs:
      - get
      - list
      - watch
      - create
      - update
      - patch
      - delete
    - apiGroups:
      - ""
      resources:
      - events
      verbs:
      - create
      - patch
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      labels:
        control-plane: controller-manager
      name: slice-controller-manager-role
    rules:
    - apiGroups:
      - ""
      resources:
      - events
      verbs:
      - create
      - patch
      - update
      - watch
    - apiGroups:
      - ""
      resources:
      - nodes
      - pods
      verbs:
      - get
      - list
      - watch
    - apiGroups:
      - ""
      resources:
      - secrets
      verbs:
      - get
      - list
      - update
      - watch
    - apiGroups:
      - accelerator.gke.io
      resources:
      - slices
      verbs:
      - create
      - delete
      - get
      - list
      - patch
      - update
      - watch
    - apiGroups:
      - accelerator.gke.io
      resources:
      - slices/finalizers
      verbs:
      - update
    - apiGroups:
      - admissionregistration.k8s.io
      resources:
      - mutatingwebhookconfigurations
      verbs:
      - get
      - list
      - update
      - watch
    - apiGroups:
      - batch
      resources:
      - jobs
      verbs:
      - get
      - list
      - patch
      - update
      - watch
    - apiGroups:
      - jobset.x-k8s.io
      resources:
      - jobsets
      verbs:
      - get
      - list
      - patch
      - update
      - watch
    - apiGroups:
      - leaderworkerset.x-k8s.io
      resources:
      - leaderworkersets
      verbs:
      - get
      - list
      - patch
      - update
      - watch
    - apiGroups:
      - kueue.x-k8s.io
      resources:
      - admissionchecks
      - admissionchecks/status
      - workloads/status
      verbs:
      - get
      - patch
      - update
    - apiGroups:
      - kueue.x-k8s.io
      resources:
      - workloads
      verbs:
      - create
      - get
      - list
      - patch
      - update
      - watch
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      labels:
        control-plane: controller-manager
      name: slice-controller-metrics-auth-role
    rules:
    - apiGroups:
      - authentication.k8s.io
      resources:
      - tokenreviews
      verbs:
      - create
    - apiGroups:
      - authorization.k8s.io
      resources:
      - subjectaccessreviews
      verbs:
      - create
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      labels:
        control-plane: controller-manager
      name: slice-controller-metrics-reader
    rules:
    - nonResourceURLs:
      - /metrics
      verbs:
      - get
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      labels:
        app.kubernetes.io/managed-by: kustomize
        app.kubernetes.io/name: slice-controller
        control-plane: controller-manager
      name: slice-controller-leader-election-rolebinding
      namespace: slice-controller-system
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: slice-controller-leader-election-role
    subjects:
    - kind: ServiceAccount
      name: slice-controller-controller-manager
      namespace: slice-controller-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      labels:
        app.kubernetes.io/managed-by: kustomize
        app.kubernetes.io/name: slice-controller
        control-plane: controller-manager
      name: slice-controller-manager-rolebinding
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: slice-controller-manager-role
    subjects:
    - kind: ServiceAccount
      name: slice-controller-controller-manager
      namespace: slice-controller-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      labels:
        control-plane: controller-manager
      name: slice-controller-metrics-auth-rolebinding
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: slice-controller-metrics-auth-role
    subjects:
    - kind: ServiceAccount
      name: slice-controller-controller-manager
      namespace: slice-controller-system
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      labels:
        control-plane: controller-manager
      name: slice-controller-webhook-server-cert
      namespace: slice-controller-system
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app.kubernetes.io/managed-by: kustomize
        app.kubernetes.io/name: slice-controller
        control-plane: controller-manager
      name: slice-controller-controller-manager-metrics-service
      namespace: slice-controller-system
    spec:
      ports:
      - name: https
        port: 8443
        protocol: TCP
        targetPort: 8443
      selector:
        app.kubernetes.io/name: slice-controller
        control-plane: controller-manager
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        control-plane: controller-manager
      name: slice-controller-webhook-service
      namespace: slice-controller-system
    spec:
      ports:
      - port: 443
        protocol: TCP
        targetPort: 9443
      selector:
        control-plane: controller-manager
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/managed-by: kustomize
        app.kubernetes.io/name: slice-controller
        control-plane: controller-manager
      name: slice-controller-controller-manager
      namespace: slice-controller-system
    spec:
      replicas: 1
      selector:
        matchLabels:
          app.kubernetes.io/name: slice-controller
          control-plane: controller-manager
      template:
        metadata:
          annotations:
            kubectl.kubernetes.io/default-container: manager
          labels:
            app.kubernetes.io/name: slice-controller
            control-plane: controller-manager
        spec:
          containers:
          - args:
            - --metrics-bind-address=:8443
            - --leader-elect
            - --health-probe-bind-address=:8081
            - --zap-log-level=3
            - --feature-gates=UseRetryMechanismForSliceCreation=true
            - --activation-timeout=6m
            command:
            - /manager
            image: tpuongke/kueue-slice-controller:latest
            livenessProbe:
              httpGet:
                path: /healthz
                port: 8081
              initialDelaySeconds: 15
              periodSeconds: 20
            name: manager
            ports:
            - containerPort: 9443
              name: webhook-server
              protocol: TCP
            readinessProbe:
              httpGet:
                path: /readyz
                port: 8081
              initialDelaySeconds: 5
              periodSeconds: 10
            resources:
              limits:
                cpu: 12000m
                memory: 32Gi
              requests:
                cpu: 8000m
                memory: 16Gi
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                drop:
                - ALL
            volumeMounts:
            - mountPath: /tmp/k8s-webhook-server/serving-certs
              name: cert
              readOnly: true
          securityContext:
            runAsNonRoot: true
            seccompProfile:
              type: RuntimeDefault
          serviceAccountName: slice-controller-controller-manager
          terminationGracePeriodSeconds: 10
          volumes:
          - name: cert
            secret:
              defaultMode: 420
              secretName: slice-controller-webhook-server-cert
    ---
    apiVersion: admissionregistration.k8s.io/v1
    kind: MutatingWebhookConfiguration
    metadata:
      labels:
        control-plane: controller-manager
      name: slice-controller-mutating-webhook-configuration
    webhooks:
    - admissionReviewVersions:
      - v1
      clientConfig:
        service:
          name: slice-controller-webhook-service
          namespace: slice-controller-system
          path: /mutate-batch-v1-job
      failurePolicy: Fail
      name: mjob.kb.io
      rules:
      - apiGroups:
        - batch
        apiVersions:
        - v1
        operations:
        - CREATE
        resources:
        - jobs
      sideEffects: None
    - admissionReviewVersions:
      - v1
      clientConfig:
        service:
          name: slice-controller-webhook-service
          namespace: slice-controller-system
          path: /mutate-jobset-x-k8s-io-v1alpha2-jobset
      failurePolicy: Fail
      name: mjobset.kb.io
      rules:
      - apiGroups:
        - jobset.x-k8s.io
        apiVersions:
        - v1alpha2
        operations:
        - CREATE
        resources:
        - jobsets
      sideEffects: None
    - admissionReviewVersions:
      - v1
      clientConfig:
        service:
          name: slice-controller-webhook-service
          namespace: slice-controller-system
          path: /mutate-leaderworkerset-x-k8s-io-v1-leaderworkerset
      failurePolicy: Fail
      name: mleaderworkerset.kb.io
      rules:
      - apiGroups:
        - leaderworkerset.x-k8s.io
        apiVersions:
        - v1
        operations:
        - CREATE
        resources:
        - leaderworkersets
      sideEffects: None
    
  2. 套用 slice-controller.yaml 資訊清單:

    kubectl apply -f slice-controller.yaml
    
  3. 如要設定 Kueue 進行動態切片,請將下列資訊清單儲存為 dynamic-slice-topology.yaml

    # Copyright 2026 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: kueue.x-k8s.io/v1beta1
    kind: Topology
    metadata:
      name: superslice-topology
    spec:
      levels:
      # Label to identify the physical block a sub-block belongs to.
      # Only sub-blocks from the same block can form a slice.
      - nodeLabel: cloud.google.com/gce-topology-block
      # Label to identify individual TPU sub-blocks (4x4x4 topology).
      - nodeLabel: cloud.google.com/gke-tpu-partition-4x4x4-id
      # Standard Kubernetes label for individual nodes.
      # Required to assign Pods to specific VMs.
      - nodeLabel: kubernetes.io/hostname
    ---
    apiVersion: kueue.x-k8s.io/v1beta1
    kind: ResourceFlavor
    metadata:
      name: superslice-rf
    spec:
      nodeLabels:
        cloud.google.com/gke-tpu-accelerator: tpu7x
      topologyName: superslice-topology
    ---
    apiVersion: kueue.x-k8s.io/v1beta1
    kind: AdmissionCheck
    metadata:
      name: superslice-ac
    spec:
      controllerName: accelerator.gke.io/slice
    ---
    apiVersion: kueue.x-k8s.io/v1beta1
    kind: ClusterQueue
    metadata:
      name: cq
    spec:
      namespaceSelector: {}
      admissionChecks:
      - superslice-ac
      resourceGroups:
      - coveredResources:
        - google.com/tpu
        flavors:
        - name: superslice-rf
          resources:
          - name: google.com/tpu
            nominalQuota: "999999"  # modeling unlimited quota
    ---
    apiVersion: kueue.x-k8s.io/v1beta1
    kind: LocalQueue
    metadata:
      name: lq
      namespace: default
    spec:
      clusterQueue: cq
    
  4. 套用 dynamic-slice-topology.yaml 資訊清單:

    kubectl apply -f dynamic-slice-topology.yaml
    

    在這個資訊清單中,您將定義下列資源,為動態切片設定 Kueue:

    • Ironwood (TPU7x) 動態配量拓撲 (superslice-topology):拓撲定義 Kueue 排程動態配量工作負載時考量的層級。這些等級如下:
      • cloud.google.com/gce-topology-block 標籤:這個層級是瞭解哪些子區塊屬於哪些區塊的必要條件,因為只有來自相同區塊的子區塊才能形成切片。
      • cloud.google.com/gke-tpu-partition-4x4x4-id 標籤:這個層級代表個別的 Ironwood (TPU7x) 子區塊 (4x4x4 拓撲)。
      • kubernetes.io/hostname 標籤:您必須具備這個層級,才能將 Pod 指派給特定 VM,並觀察其標籤和汙點。
    • Ironwood (TPU7x) SuperSlice ResourceFlavor (superslice-rf):Ironwood (TPU7x) 子區塊的資源規格包含 cloud.google.com/gke-tpu-accelerator: tpu7x 標籤,可與 Ironwood (TPU7x) 機器節點相符。
    • SuperSlice AdmissionCheck (superslice-ac):這項准入檢查會告知 Kueue,在 GKE 區塊控制器確認區塊已啟用前,請勿排定工作負載。首先定義准入檢查,然後新增至處理動態切片工作負載的 ClusterQueue
    • ClusterQueue (cq) 和 LocalQueue (lq):這些欄位會管理google.com/tpu資源。cq ClusterQueue 包含 superslice-ac 准入檢查。google.com/tpunominalQuota 欄位可透過下列兩種方式設定:
      • 特定配額:將 nominalQuota 欄位設為符合現有容量,以利公平分享和配額管理。
      • 無限制配額:將 nominalQuota 欄位設為極高的值,例如 "999999",模擬無限制配額。為著重說明 TAS 和動態切片,這項設定會略過 Kueue 的配額管理功能。

定義分割區健康狀態選取項目

除了標準節點健康狀態和就緒狀態外,GKE 還會使用 cloud.google.com/gke-tpu-partition-[shape]-state 標籤,顯示每個分割區形狀的特定狀態 (其中 [shape] 符合分割區 ID 形狀,例如 2x2x12x2x22x2x42x4x44x4x4)。這個標籤可讓 GKE 考量影響切片形成的因素,例如 TPU 連結的狀態。動態子切片設定 (拓撲小於 4x4x4) 需要 GKE 1.36.0-gke.3712000 以上版本。

您可以按照下列方式定義分區狀態標籤的值:

  • HEALTHY:分割區運作正常。
  • DEGRADED:磁碟分割區的基礎架構處於降級狀態,例如 OCS 連結降級。分區仍可形成切片,但整體效能可能比健全的分區低。這個狀態只適用於頂層 4x4x4 拓撲。 較小的拓撲不會處於降級狀態。
  • UNHEALTHY:磁碟分割區狀況不佳,無法形成切片。
  • UNSET:由於 GKE 切片控制器初始化失敗,狀態為未定義。
  • INCOMPLETE:分區內並非所有節點都已佈建。

Kueue Slice Controller 網路鉤子會驗證工作負載是否包含特定分割區健康狀態需求。如未指明偏好設定,Webhook 會插入預設節點親和性。

行為如下:

  • 如果存在指定 cloud.google.com/gke-tpu-partition-[shape]-state 標籤的 nodeSelectornodeAffinity,則這些標籤不會變更。
  • 如果沒有這類標籤設定,Webhook 會插入下列預設節點親和性,確保只使用可用分割區:

    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: cloud.google.com/gke-tpu-partition-4x4x4-state
            operator: In
            values:
            - "HEALTHY"
            - "DEGRADED"
    

下一節的範例會設定 cloud.google.com/gke-tpu-partition-4x4x4-state 標籤,指定不同的子區塊健康狀態設定。

使用 Kueue 在動態切片上執行測試工作負載

本節說明如何使用 Kueue 和 TAS,在動態切片上部署工作負載。包括如何建立動態切片工作負載,以及由多個切片組成的工作負載。工作負載會以 JobSet 形式提交。

範例 1:單一工作負載使用單一動態切片

以下範例說明如何使用具有 4x12x16 拓撲的切片建立工作負載,該拓撲由 12 個子區塊組成。Pod 數量的計算方式如下:(4 * 12 * 16) / 每個節點 4 個晶片 = 192 個 Pod。

  1. 將下列資訊清單儲存為 big-super-slice.yaml

    # Copyright 2026 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: jobset.x-k8s.io/v1alpha2
    kind: JobSet
    metadata:
      name: big-super-slice
      labels:
        kueue.x-k8s.io/queue-name: lq
    spec:
      replicatedJobs:
        - name: job-jax
          replicas: 1
          template:
            spec:
              parallelism: 192  # pods per slice calculation: 4*12*16 / 4 = 192
              completions: 192
              backoffLimit: 10
              template:
                metadata:
                  annotations:
                    cloud.google.com/gke-tpu-slice-topology: 4x12x16
                spec:
                  tolerations:
                    - key: "google.com/tpu"
                      operator: "Equal"
                      value: "present"
                      effect: "NoSchedule"
                  nodeSelector:
                    cloud.google.com/gke-tpu-accelerator: tpu7x
                  containers:
                    - name: jax
                      image: python:latest
                      command:
                        - bash
                        - -c
                        - |
                          printenv
                          pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
                          python -c 'import jax; print("Global device count:", jax.device_count(), "Local device count:", jax.local_device_count())'
                      resources:
                        limits:
                          google.com/tpu: 4
                  restartPolicy: Never
    

    在這個資訊清單中,下列註解會告知 Kueue 切片特徵和拓撲,以設定下列項目:

    • cloud.google.com/gke-tpu-slice-topology:將 "4x12x16" 指定為動態切片拓撲。tpu7x加速器拓撲的相關規定包括下列規則:
      • 動態子切片:您可以指定小於 4x4x4 的拓撲,例如 2x2x12x2x22x2x42x4x4。這些較小的拓撲需要 GKE 1.36.0-gke.3712000 以上版本。
      • 動態超級切片:您可以指定大於或等於 4x4x4 的拓撲。如要設定動態超級切片,所要求拓撲的每個維度都必須是四的倍數,例如 4A x 4B x 4C
      • 拓撲必須是三維字串,格式為 AxBxC,例如 4x8x8
      • 尺寸必須以非遞減順序排序:A <= B <= C。舉例來說,4x8x4 無效,應為 4x4x8
      • 尺寸 (ABC) 的乘積不得超過 9,216。
      • 支援的最大切片拓撲最多可包含 32 個子區塊。舉例來說,8x16x16 有 32 個子區塊、8x12x20 有 30 個子區塊,或 12x12x12 有 27 個子區塊,都符合可接受的限制。
    • cloud.google.com/gke-tpu-accelerator: tpu7x:在執行 Ironwood (TPU7x) 的 VM 上排定 Pod。
    • kueue.x-k8s.io/queue-name:將 JobSet 指派給 Kueue LocalQueue。
    • Webhook 會插入預設節點相依性,確保使用 HEALTHYDEGRADED 節點。
  2. 套用 big-super-slice.yaml 資訊清單:

    kubectl apply -f big-super-slice.yaml
    

    套用資訊清單後,Kueue 會建立名為 big-super-sliceJobSet。 Kueue 接著會嘗試使用 4x12x16 拓撲形成單一動態切片。切片啟用後,Kueue 會允許工作負載,並在節點上排定 192 個 Pod,形成動態切片來執行工作負載。

範例 2:具備多個副本的工作負載

以下範例說明如何建立工作負載,使用兩個動態切片,每個切片都由四個子區塊組成,只以 HEALTHY 節點為目標。

  1. 將下列資訊清單儲存為 two-super-slices.yaml

    # Copyright 2026 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: jobset.x-k8s.io/v1alpha2
    kind: JobSet
    metadata:
      name: two-super-slices
      labels:
        kueue.x-k8s.io/queue-name: lq
    spec:
      replicatedJobs:
        - name: job-jax
          replicas: 2
          template:
            spec:
              parallelism: 64  # Pods per slice calculation: (4*8*8) / 4 = 64
              completions: 64
              backoffLimit: 10
              template:
                metadata:
                  annotations:
                    cloud.google.com/gke-tpu-slice-topology: 4x8x8
                spec:
                  tolerations:
                    - key: "google.com/tpu"
                      operator: "Equal"
                      value: "present"
                      effect: "NoSchedule"
                  nodeSelector:
                    cloud.google.com/gke-tpu-accelerator: tpu7x
                    cloud.google.com/gke-tpu-partition-4x4x4-state: "HEALTHY"
                  containers:
                    - name: jax
                      image: python:latest
                      command:
                        - bash
                        - -c
                        - |
                          printenv
                          pip install "jax[tpu]" -f https://storage.googleapis.com/jax-releases/libtpu_releases.html
                          python -c 'import jax; print("Global device count:", jax.device_count(), "Local device count:", jax.local_device_count())'
                      resources:
                        limits:
                          google.com/tpu: 4
                  restartPolicy: Never
    
  2. 套用 two-super-slices.yaml 資訊清單:

    kubectl apply -f two-super-slices.yaml
    

在這個資訊清單中,您會在 replicatedJobs 區段中將 replicas 欄位設為 2。 套用資訊清單後,Kueue 會嘗試以 4x8x8 拓撲形成兩個獨立的切片。Kueue 會為 jobset.spec.replicatedJobs[].replicas 中定義的每個副本建立動態切片。如果指定 n 副本,Kueue 會為工作負載建立 n 個動態切片,並等待所有切片都處於啟用狀態,再允許工作負載。

監控切片

您可以查看切片狀態,並使用 GKE 系統指標監控切片指標。

監控切片狀態

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

kubectl describe slice SLICE_NAME

SLICE_NAME 替換為切片名稱。切片名稱通常衍生自 JobSet 名稱和副本索引。以「範例 1」來說,Kueue 建立的切片名稱會類似於 default-jobset-big-super-slice-yyyyy-job-jax-0

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

Name:         test-slice
Namespace:
Labels:       <none>
Annotations:  <none>
API Version:  accelerator.gke.io/v1beta1
Kind:         Slice
Metadata:
  Creation Timestamp:  2026-02-12T23:44:28Z
  Finalizers:
    accelerator.gke.io/slice-finalizer
  Generation:        1
  Resource Version:  1770939905695871008
  UID:               6dbbfe14-4486-4462-864d-e078d0ca8b5b
Spec:
  Partition Ids:
    5eae6a4f59d59cf30a9bf49de618eb2b
  Topology:  4x4x4
  Type:      tpu7x
Status:
  Conditions:
    Last Transition Time:  2026-02-12T23:45:05Z
    Message:
    Reason:                ACTIVE
    Status:                True
    Type:                  Ready
    Last Transition Time:  2026-02-12T23:45:05Z
    Message:               NodeLabelingCompleted
    Reason:                NodeLabelIsAdded
    Status:                True
    Type:                  NodeLabeled
Events:                    <none>

為確保與基礎 Compute Engine 資源命名慣例相容,切片名稱須遵守下列規則:

  • 範本: {namespace}-jobset-{jobset.metadata.name}-kueueHash[5-character]-{jobset.spec.replicatedJobs[].name}-sliceIndex
  • 長度:名稱不得超過 49 個半形字元。控制器會附加連字號和 8 個半形字元的叢集雜湊值,建立 Compute Engine 資源名稱,這些名稱的長度上限為 63 個半形字元。
  • 格式:名稱符合規則運算式 ^[a-z]([-a-z0-9]*[a-z0-9])?$。名稱具有下列特徵:
    • 開頭為小寫英文字母。
    • 只能包含小寫字母、數字和連字號 (-)。
    • 結尾為小寫英文字母或數字 (不得為連字號)。

監控切片的指標

您可以監控下列 GKE 系統指標,瞭解切片的狀況:

  • kubernetes.io/accelerator/slice/state
  • kubernetes.io/accelerator/partition/state
  • kubernetes.io/accelerator/slice/deformation_durations
  • kubernetes.io/accelerator/slice/formation_durations

如要進一步瞭解指標,請參閱「GKE 系統指標」。

清除所用資源

為避免產生非預期的費用,請先刪除節點片段,再刪除節點集區。

  1. 刪除 JobSet。這項操作會觸發 Kueue 刪除相關聯的 Slice 自訂資源。

    kubectl delete jobset JOBSET_NAME
    

    JOBSET_NAME 替換為 JobSet 的名稱,例如 big-super-slice

  2. 刪除 TPU 節點集區:

    gcloud container node-pools delete NODE_POOL_NAME \
        --cluster=CLUSTER_NAME \
        --location=LOCATION
    

(選用) 使用自己的排程器搭配動態配量

本文著重於使用 Kueue 和 TAS。不過,您也可以使用自己的自訂排程器管理動態切片。如要使用其他排程器,請參閱 Slice 自訂資源參考資訊。

後續步驟