Kueue と TAS を使用して動的スライスをスケジュールする

このドキュメントでは、Kueueトポロジ対応スケジューリング(TAS)を使用して、Google Kubernetes Engine(GKE)で TPU ノードプールをプロビジョニングし、動的スライス をスケジュールする方法について説明します。

Slice カスタム リソースを直接操作して、動的スライスを使用することもできます。詳細については、カスタム スケジューラで動的スライスを使用するをご覧ください。

以下の手順を行う前に、動的スライスの コンセプトを理解しておいてください

要件

GKE で動的スライスを使用するには、次の要件を満たす必要があります。

  • 次のいずれかのバージョンの Rapid チャンネルで Standard クラスタを使用します。
    • 動的スーパースライス構成(トポロジが 4x4x4 以上)の場合は、バージョン 1.35.2-gke.1842000 以降を使用します。
    • 動的サブスライス構成(トポロジが 4x4x4 より小さい)の場合は、バージョン 1.36.0-gke.3712000 以降を使用します。
  • Ironwood(TPU7x)バージョンを使用します。
  • ノードに Container-Optimized OS イメージを使用します。
  • 増分プロビジョニングを使用するには、 All Capacity モードの予約を使用します。All Capacity モードは、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 では、このドキュメントのコマンドを実行できない場合があります。
  • Rapid チャンネルで、バージョン 1.35.2-gke.1842000 以降の既存の Standard クラスタがあることを確認します。新しいクラスタを作成するには、リージョン クラスタの作成をご覧ください。
  • リージョンに Ironwood(TPU7x)に十分な割り当てがあることを確認します。
  • マルチスライス ワークロードを実行する場合は、JobSet v0.10.1 以降をインストールします。
  • All Capacity モードで TPU 容量をリクエストします

Kueue を使用して GKE で動的スライスを使用する

このセクションでは、GKE で動的スライスを使用するワークフローについて説明します。

  1. All Capacity モードの予約のトポロジと健全性ステータスを表示します
  2. クラスタでスライス コントローラを有効にします
  3. Kueue、JobSet、LWS をインストールします
  4. TPU ノードプールを作成します
  5. Slice カスタム リソースを作成するように Kueue を構成します
  6. Kueue を使用して動的スライスでワークロードを実行します
  7. クリーンアップします

スライス コントローラを有効にする

動的スライスを使用するには、クラスタでスライス コントローラを有効にします。

  1. クラスタを更新します。

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

    次のように置き換えます。

    • CLUSTER_NAME: クラスタの名前。
    • LOCATION: 使用可能な TPU 容量があるリージョン
  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 v0.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 容量を Ironwood(TPU7x)VM の 16 ノードグループまたはサブブロックで構成されるノードプールに変換します。GKE は、健全な VM をすべて検出できない場合でも、ホストマシンの健全な部分にノードを配置し、修復中に異常なマシンを段階的にプロビジョニングすることで、これらのノードプールをプロビジョニングします。

ノードプールは、次のいずれかに属するようにターゲットを設定できます。

  • TPU の特定のブロック。これは All Capacity モードの予約で公開されます。 ブロック ターゲティングを使用すると、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 に設定して、1 つのサブブロック内のチップの総数と一致させます。
  • accelerator-topology-mode フィールドは常に provision_only に設定して、増分プロビジョニング プロセスがトリガーされるようにします。provision_only フィールドが設定されている場合、ノードプールは ICI リンクまたは OCS リンクを形成せずに TPU ノードをプロビジョニングします。

ノードプールがブロックまたはサブブロックに属するようにターゲットを設定する

All Capacity モードの予約内の特定のサブブロックまたはブロックをターゲットにできます。

  • ブロックをターゲットにする: 各ノードプールは、指定されたブロックの容量を使用します。GKE は、そのブロック内の使用可能なサブブロックにノードプールを配置します。使用するブロック内のサブブロックの数と同じ数のノードプールを作成する必要があります。
  • サブブロックをターゲットにする: 各ノードプールは、特定の利用可能なサブブロックにマッピングされます。サブブロック ターゲティングを使用する場合、GKE は少なくとも 1 つの VM が正常な場合にノードプールを作成します。 増分プロビジョニングにより、すべてのノードが指定されたサブブロック内に配置されます。

ブロック

  1. 予約内のブロックの名前と、ブロック内の使用可能なサブブロックの数を取得するには、 All Capacity モードの予約のトポロジと健全性ステータスを表示するドキュメントの手順に沿って操作します。

    1. すべての予約ブロックを一覧表示し、name: フィールドの値をコピーして、ブロックの名前を特定します。この値は、このドキュメントのブロック名または BLOCK_NAME です。

    2. 予約ブロックを記述し、reservationSubBlockCount フィールドの値を確認して、作成するノードプールの数を決定します。この値は、使用可能なサブブロックの数です。たとえば、reservationSubBlockCount: 4 の値は、ブロックに使用可能なサブブロックが 4 つあることを示します。この場合、4 つの個別のノードプールを作成する必要があります。

  2. 予約パスを設定します。

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

    次のように置き換えます。

    • RESERVATION_NAME: TPU 予約の名前。
    • BLOCK_NAME: ブロックの名前。
  3. 前の手順で特定したサブブロックごとにノードプールを作成します。 たとえば、カウントが 4 の場合は、このコマンドを 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 を取得するには、All Capacity モードの 予約のトポロジと 健全性ステータスを表示するドキュメントの手順に沿って操作します。

    1. ブロックの名前を特定するには、すべての予約 ブロック を一覧表示し、name: フィールドの値をコピーします。この値は、このドキュメントのブロック名または BLOCK_NAME です。

    2. サブブロックの名前を特定するには、 ブロックのすべてのサブブロックを一覧表示しname: の各エントリの値を reservationSubBlocks の下にコピーします。この値は、このドキュメントのサブブロック名または 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 カスタム リソースを作成します。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 に割り当て、そのラベルと taint を確認するために必要です。
    • Ironwood(TPU7x)SuperSlice ResourceFlavor(superslice-rf: Ironwood(TPU7x)サブブロックのリソース フレーバーには、Ironwood(TPU7x)マシンとノードを照合するための cloud.google.com/gke-tpu-accelerator: tpu7x ラベルが含まれています。
    • SuperSlice AdmissionCheck(superslice-ac: このアドミッション チェックは、スライスがアクティブになったことを GKE スライス コントローラが確認するまで、ワークロードをスケジュールしないように Kueue に指示します。アドミッション チェックは最初に定義され、動的スライス ワークロードを処理する ClusterQueue に追加されます。
    • ClusterQueue(cq)と LocalQueue(lq: これらのフィールドは google.com/tpu リソースを管理します。cq ClusterQueue には superslice-ac アドミッション チェックが含まれています。google.com/tpunominalQuota フィールドは、次の 2 つの方法で構成できます。
      • 特定の割り当て: フェアシェアと割り当て管理のために、既存の容量と一致するように nominalQuota フィールドを設定します。
      • 無制限の割り当て: 無制限の割り当てをモデル化するには、nominalQuota フィールドを "999999"などの非常に大きな値に設定します。TAS と動的スライスに重点を置くため、この構成では Kueue の割り当て管理機能がバイパスされます。

パーティションの健全性の選択を定義する

GKE は、標準のノードの健全性と readiness に加えて、 各パーティション形状の特定の状態をcloud.google.com/gke-tpu-partition-[shape]-stateラベルを使用して公開します ([shape]はパーティション ID の形状(2x2x12x2x22x2x42x4x4、 または 4x4x4など)と一致します)。このラベルを使用すると、GKE はスライス 形成に影響する要因(TPU リンクの状態など)を考慮できます。動的サブスライス構成(トポロジが 4x4x4 より小さい)には、GKE バージョン 1.36.0-gke.3712000 以降が必要です。

パーティション状態ラベルの値は次のように定義できます。

  • HEALTHY: パーティションは正常で、完全に機能しています。
  • DEGRADED: パーティションのインフラストラクチャが劣化しています(OCS リンクの劣化など)。パーティションはスライスを形成できますが、健全なパーティションと比較して全体的なパフォーマンスが低下する可能性があります。この状態は、最上位の 4x4x4 トポロジにのみ適用されます。 トポロジが小さい場合、劣化状態はありません。
  • UNHEALTHY: パーティションが異常で、スライスを形成できません。
  • UNSET: GKE スライス コントローラの初期化が失敗したため、状態が未定義です。
  • INCOMPLETE: パーティション内のすべてのノードがプロビジョニングされていません。

Kueue スライス コントローラ ウェブフックは、ワークロードに特定のパーティションの健全性要件が含まれているかどうかを検証します。設定が指定されていない場合、ウェブフックはデフォルトのノード アフィニティを挿入します。

動作は次のとおりです。

  • cloud.google.com/gke-tpu-partition-[shape]-state ラベルをターゲットとする nodeSelector または nodeAffinity が存在する場合、変更されません。
  • このようなラベル構成が存在しない場合、使用可能なパーティションのみが使用されるように、ウェブフックは次のデフォルトのノード アフィニティを挿入します。

    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: 単一のワークロードが単一の動的スライスを使用する

次の例では、12 個のサブブロックで構成される 4x12x16 トポロジのスライスを使用してワークロードを作成する方法について説明します。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 アクセラレータ トポロジの要件には、次のルールが含まれます。
      • 動的サブスライスの場合: 2x2x12x2x22x2x42x4x4 など、4x4x4 より小さいトポロジを指定できます。 これらの小さなトポロジには、GKE バージョン 1.36.0-gke.3712000 以降が必要です。
      • 動的スーパースライスの場合: 4x4x4 以上のトポロジを指定できます。動的スーパースライス構成の場合、リクエストされたトポロジの各ディメンションは 4 の倍数にする必要があります(4A x 4B x 4C など)。
      • トポロジは、AxBxC 形式の 3 次元文字列にする必要があります(4x8x8 など)。
      • ディメンションは昇順で並べ替える必要があります: A <= B <= C。たとえば、4x8x4 は無効です。4x4x8 にする必要があります。
      • ディメンションの積(ABC)は 9,216 を超えないようにしてください。
      • サポートされている最大のスライス トポロジには、最大 32 個のサブブロックを含めることができます。たとえば、32 個のサブブロックを持つ 8x16x16、30 個のサブブロックを持つ 8x12x20、27 個のサブブロックを持つ 12x12x12 は、許容範囲内です。
    • cloud.google.com/gke-tpu-accelerator: tpu7x: Ironwood(TPU7x)を実行する VM に Pod をスケジュールします。
    • kueue.x-k8s.io/queue-name: JobSet を Kueue LocalQueue に割り当てます。
    • ウェブフックはデフォルトのノード アフィニティを挿入して、HEALTHY ノードと DEGRADED ノードが使用されるようにします。
  2. big-super-slice.yaml マニフェストを適用します。

    kubectl apply -f big-super-slice.yaml
    

    マニフェストを適用すると、Kueue は big-super-slice という名前の JobSet を作成します。 次に、Kueue は 4x12x16 トポロジで単一の動的スライスを形成しようとします。 スライスがアクティブになると、Kueue はワークロードを受け入れ、192 個の Pod がノードにスケジュールされて、ワークロードを実行する動的スライスが形成されます。

例 2: 複数のレプリカを持つワークロード

次の例では、2 つの動的スライスを使用するワークロードを作成する方法を示します。各スライスは 4 つのサブブロックで構成され、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 トポロジで 2 つの個別のスライスを形成しようとします。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 文字のクラスタ ハッシュを追加して、63 文字の制限がある Compute Engine リソース名を作成します。
  • [形式]: 名前は正規表現 ^[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 カスタム リソースのリファレンス情報を参照してください。

次のステップ