Dynamische Slices mit Kueue und TAS planen

In diesem Dokument wird beschrieben, wie Sie TPU-Knotenpools bereitstellen und dynamische Slices in Google Kubernetes Engine (GKE) mit Kueue und Topology Aware Scheduling (TAS) planen.

Sie können auch dynamisches Aufteilen verwenden, indem Sie direkt mit Benutzerdefinierte Ressourcen aufteilen interagieren. Weitere Informationen finden Sie unter Dynamisches Aufteilen mit einem benutzerdefinierten Scheduler verwenden.

Bevor Sie diese Anleitung durcharbeiten, sollten Sie sich mit den Konzepten des dynamischen Aufteilens vertraut machen.

Voraussetzungen

Damit Sie dynamisches Slicing in GKE verwenden können, müssen die folgenden Anforderungen erfüllt sein:

  • Verwenden Sie einen Standardcluster in Version 1.35.2-gke.1842000 oder höher im Rapid Channel.
  • Verwenden Sie die Ironwood-Version (TPU7x).
  • Verwenden Sie das Container-Optimized OS-Image für Ihre Knoten.
  • Wenn Sie die inkrementelle Bereitstellung verwenden möchten, müssen Sie Reservierungen im Modus „Alle Kapazitäten“ verwenden. „Alle“ ist ein Kapazitätsmodus, der von TPU Cluster Director aktiviert wird.

Hinweis

Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:

  • Aktivieren Sie die Google Kubernetes Engine API.
  • Google Kubernetes Engine API aktivieren
  • Wenn Sie die Google Cloud CLI für diesen Task verwenden möchten, müssen Sie die gcloud CLI installieren und dann initialisieren. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die neueste Version mit dem Befehl gcloud components update ab. In früheren gcloud CLI-Versionen werden die Befehle in diesem Dokument möglicherweise nicht unterstützt.

Dynamisches Slicing in GKE mit Kueue verwenden

In diesem Abschnitt wird der Workflow für die Verwendung von dynamischem Slicing in GKE beschrieben.

  1. Topologie und Systemzustand von Reservierungen im Modus „Alle Kapazitäten“ ansehen
  2. Slice-Controller in Ihrem Cluster aktivieren
  3. TPU-Knotenpools erstellen
  4. Kueue so konfigurieren, dass eine benutzerdefinierte Slice-Ressource erstellt wird
  5. Arbeitslasten mit dynamischem Slicing mit Kueue ausführen
  6. Führen Sie eine Bereinigung durch.

Slice-Controller aktivieren

Wenn Sie dynamisches Slicing verwenden möchten, aktivieren Sie den Slice-Controller in Ihrem Cluster.

  1. Cluster aktualisieren:

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

    Ersetzen Sie Folgendes:

  2. Rufen Sie Anmeldedaten ab, damit Sie mit kubectl-Befehlen mit Ihrem Cluster kommunizieren können:

    gcloud config set container/cluster CLUSTER_NAME
    gcloud container clusters get-credentials CLUSTER_NAME \
        --location=LOCATION
    
  3. Prüfen Sie in der Ausgabe des folgenden Befehls, ob der Wert slices.accelerator.gke.io vorhanden ist:

    kubectl get crd slices.accelerator.gke.io
    

    Die Ausgabe sieht etwa so aus:

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

Knotenpools mit inkrementeller Bereitstellung erstellen

In diesem Abschnitt wird beschrieben, wie Sie die TPU-Knotenpools mit inkrementeller Bereitstellung erstellen. GKE konvertiert Ihre gesamte TPU-Kapazität in Knotenpools mit einer Gruppe von 16 TPU-VMs oder Unterblöcken. GKE stellt diese Knotenpools auch dann bereit, wenn nicht alle 16 fehlerfreien VMs gefunden werden können. Dazu werden Knoten auf fehlerfreien Teilen des Hostcomputers platziert und fehlerhafte Maschinen inkrementell bereitgestellt, während sie repariert werden.

Sie können Ihren Knotenpool auf eine der folgenden Optionen ausrichten:

  • Ein bestimmter TPU-Block, der in Reservierungen im Modus „Alle Kapazitäten“ verfügbar ist. Durch die Blockausrichtung kann GKE den Knotenpool in einem beliebigen verfügbaren Unterblock innerhalb des angegebenen Blocks erstellen.
  • Ein bestimmter Unterblock oder eine bestimmte Gruppe von 16 TPU-VMs für eine detailliertere Steuerung.

Arbeitslastrichtlinie erstellen

Wenn Sie einen TPU-Slice-Knotenpool mit Ironwood (TPU7x) erstellen möchten, müssen Sie zuerst eine Arbeitslastrichtlinie erstellen, bei der das Feld accelerator-topology-mode auf provision_only festgelegt ist. Diese Einstellung löst den inkrementellen Bereitstellungsprozess aus.

Arbeitslastrichtlinie erstellen:

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

Ersetzen Sie Folgendes:

  • WORKLOAD_POLICY_NAME: ein Name für Ihre Arbeitslastrichtlinie.
  • PROJECT_ID: Projekt-ID in Google Cloud .
  • REGION: die Region für die Arbeitslastrichtlinie.

Führen Sie in diesem Befehl folgende Schritte aus::

  • Legen Sie das Feld accelerator-topology immer auf 4x4x4 fest, damit es der Gesamtzahl der Chips in einem einzelnen Unterblock entspricht.
  • Legen Sie das Feld accelerator-topology-mode immer auf provision_only fest, damit der inkrementelle Bereitstellungsprozess ausgelöst wird. Wenn das Feld provision_only festgelegt ist, werden im Knotenpool TPU-Knoten bereitgestellt, ohne ICI- oder OCS-Verbindungen zu erstellen.
können Sie die Liste der Arbeitslastrichtlinien aufrufen.

Knotenpool auf einen Block oder Unterblock ausrichten

Sie können bestimmte Unterblöcke oder Blöcke in Ihrer Reservierung im Modus „Gesamte Kapazität“ targetieren.

  • Auf einen Block ausrichten:Jeder Knotenpool verwendet Kapazität aus einem bestimmten Block. GKE platziert den Knotenpool in einem verfügbaren Unterblock in diesem Block. Sie müssen so viele Knotenpools erstellen, wie es Unterblöcke im Block gibt, den Sie verwenden möchten.
  • Auf einen Unterblock ausrichten:Jeder Knotenpool wird einem bestimmten verfügbaren Unterblock zugeordnet. Wenn Sie die Ausrichtung auf Unterblöcke verwenden, erstellt GKE den Knotenpool, wenn mindestens eine VM fehlerfrei ist. Die inkrementelle Bereitstellung trägt dazu bei, dass alle Knoten innerhalb des angegebenen Unterblocks platziert werden.

Blockieren

  1. Wenn Sie den Namen des Blocks in einer Reservierung und die Anzahl der verfügbaren Unterblöcke im Block abrufen möchten, führen Sie die folgenden Schritte im Dokument Topologie und Status von Reservierungen im Modus „Alle Kapazitäten“ ansehen aus:

    1. Ermitteln Sie den Namen des Blocks, indem Sie alle Reservierungsblöcke auflisten und den Wert im Feld name: kopieren. Dieser Wert ist der Name des Blocks oder BLOCK_NAME in diesem Dokument.

    2. Ermitteln Sie, wie viele Knotenpools erstellt werden sollen, indem Sie einen Reservierungsblock beschreiben und den Wert im Feld reservationSubBlockCount ermitteln. Dieser Wert gibt die Anzahl der verfügbaren Unterblöcke an. Der Wert reservationSubBlockCount: 4 gibt beispielsweise an, dass für den Block vier Unterblöcke verfügbar sind und Sie vier separate Knotenpools erstellen müssen.

  2. Reservierungspfad festlegen:

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

    Ersetzen Sie Folgendes:

    • RESERVATION_NAME: Der Name Ihrer TPU-Reservierung.
    • BLOCK_NAME: der Name des Blocks.
  3. Erstellen Sie für jeden im vorherigen Schritt ermittelten Unterblock einen Knotenpool. Wenn die Anzahl beispielsweise 4 ist, führen Sie diesen Befehl viermal aus. Verwenden Sie für jeden Knotenpool einen eindeutigen Namen.

    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}
    

    Ersetzen Sie Folgendes:

    • NODE_POOL_NAME ist der Name des neuen Knotenpools.
    • CLUSTER_NAME: der Name Ihres GKE-Clusters.
    • WORKLOAD_POLICY_NAME: der Name der von Ihnen erstellten Workload-Richtlinie.
    • ZONE: die Zone für den Knotenpool, z. B. us-central1-a.

Unterblock

  1. Führen Sie die folgenden Schritte im Dokument Topologie und Integritätsstatus von Reservierungen im Modus „Alle Kapazitäten“ ansehen aus, um den Namen des Blocks und die IDs der verfügbaren Unterblöcke abzurufen:

    1. Wenn Sie den Namen des Blocks ermitteln möchten, listen Sie alle Reservierungsblöcke auf und kopieren Sie den Wert im Feld name:. Dieser Wert ist der Name des Blocks oder der BLOCK_NAME in diesem Dokument.

    2. Um den Namen der Unterblöcke zu ermitteln, listen Sie alle Unterblöcke eines Blocks auf und kopieren Sie den Wert im Feld name: für jeden Eintrag unter reservationSubBlocks. Dieser Wert ist der Name des Unterblocks oder SUBBLOCK_NAME in diesem Dokument.

  2. Reservierungspfad festlegen:

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

    Ersetzen Sie Folgendes:

    • RESERVATION_NAME: Der Name Ihrer TPU-Reservierung.
    • BLOCK_NAME: der Name des Blocks.
    • SUBBLOCK_NAME: der Name des Unterblocks.
  3. Knotenpool erstellen:

    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}
    

    Ersetzen Sie Folgendes:

    • NODE_POOL_NAME: ein eindeutiger Name für Ihren neuen Knotenpool, z. B. sub-block-pool-1.
    • PROJECT_ID: Projekt-ID in Google Cloud .
    • CLUSTER_NAME: Name Ihres GKE-Clusters.
    • ZONE: Die Zone für den Knotenpool, z. B. us-central2-b.
    • WORKLOAD_POLICY_NAME: der Name der von Ihnen erstellten Arbeitslastrichtlinie.

In dieser Phase werden die Knoten erstellt, ihre Inter-Chip Interconnect-Verbindungen (ICI) sind jedoch noch nicht aktiv. Daher können Sie Arbeitslasten nicht direkt in diesen Knotenpools ausführen.

Damit alle erforderlichen ICI-Links zum Erstellen des Slices und zum Planen von Arbeitslasten verwendet werden können, erstellen Sie einen dynamischen Slice mit einer der folgenden Methoden:

  • Erstellen Sie eine benutzerdefinierte Slice-Ressource. Anstelle von Pods verwenden Sie eine benutzerdefinierte Slice-Ressource, um die angegebene Topologie zu definieren, die vom Slice-Controller aktiviert wird.
  • GKE-Arbeitslasten mit Kueue und TAS planen. Kueue übernimmt automatisch das Erstellen und Löschen von benutzerdefinierten Slice-Ressourcen. Sie sollten von Kueue erstellte benutzerdefinierte Slice-Ressourcen nicht manuell ändern.

Dynamischen Slice mit Kueue und TAS erstellen

In diesem Abschnitt planen Sie GKE-Arbeitslasten mit Kueue und TAS.

JobSet- und Kueue-Ressourcen für dynamisches Slicing installieren

  1. JobSet installieren:

    helm install jobset oci://registry.k8s.io/jobset/charts/jobset \
            --version 0.11.1 \
            --namespace jobset-system \
            --create-namespace \
            --set controller.resources.requests.cpu=4 \
            --set controller.resources.requests.memory=16Gi
    
  2. Installieren Sie Kueue:

    helm install kueue oci://registry.k8s.io/kueue/charts/kueue \
            --version 0.16.6 \
            --namespace kueue-system \
            --create-namespace \
            --wait \
            --set controllerManager.replicas=3 \
            --set controllerManager.manager.resources.requests.cpu=16 \
            --set controllerManager.manager.resources.requests.memory=64Gi
    
  3. Speichern Sie zum Installieren des Kueue-Slice-Controllers das folgende Manifest als slice-controller.yaml:

    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
      verbs:
      - get
      - list
      - watch
    - apiGroups:
      - kueue.x-k8s.io
      resources:
      - 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
    
  4. Wenden Sie das slice-controller.yaml-Manifest an:

    kubectl apply -f slice-controller.yaml
    
  5. Speichern Sie zum Konfigurieren von Kueue für dynamisches Slicing das folgende Manifest als dynamic-slice-topology.yaml:

    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
    
  6. Wenden Sie das dynamic-slice-topology.yaml-Manifest an:

    kubectl apply -f dynamic-slice-topology.yaml
    

    In diesem Manifest konfigurieren Sie Kueue für das dynamische Aufteilen in Scheiben, indem Sie die folgenden Ressourcen definieren:

    • Dynamische Slice-Topologie für Ironwood (TPU7x) (superslice-topology): Die Topologie definiert die Ebenen, die Kueue bei der Planung von Arbeitslasten mit dynamischen Slices berücksichtigt. Folgende Ebenen sind verfügbar:
      • Label für cloud.google.com/gce-topology-block: Diese Ebene ist erforderlich, um zu verstehen, welche Unterblöcke zu welchen Blöcken gehören, da nur Unterblöcke aus demselben Block einen Slice bilden können.
      • Label cloud.google.com/gke-tpu-partition-4x4x4-id: Diese Ebene stellt einzelne Ironwood-Unterblöcke (TPU7x) mit der Topologie 4x4x4 dar.
      • Label kubernetes.io/hostname: Diese Ebene ist erforderlich, um Pods bestimmten VMs zuzuweisen und ihre Labels und Taints zu beobachten.
    • Ironwood (TPU7x) SuperSlice-ResourceFlavor (superslice-rf): Der ResourceFlavor für Ironwood-Unterblöcke (TPU7x) enthält das Label cloud.google.com/gke-tpu-accelerator: tpu7x, um Knoten mit Ironwood-Maschinen (TPU7x) abzugleichen.
    • SuperSlice AdmissionCheck (superslice-ac): Dieser Admission-Check weist Kueue an, eine Arbeitslast erst dann zu planen, wenn der GKE-Slice-Controller bestätigt, dass der Slice aktiv geworden ist. Die Zulassungsprüfung wird zuerst definiert und dann der ClusterQueue hinzugefügt, der dynamische Slicing-Arbeitslasten verarbeitet.
    • ClusterQueue (cq) und LocalQueue (lq): Mit diesen Feldern werden google.com/tpu-Ressourcen verwaltet. Die cq-ClusterQueue umfasst die superslice-ac-Aufnahmeüberprüfung. Die nominalQuota für google.com/tpu kann auf zwei Arten konfiguriert werden:
      • Spezifisches Kontingent: Legen Sie nominalQuota so fest, dass es der vorhandenen Kapazität entspricht, um eine faire Nutzung und ein faires Kontingentmanagement zu ermöglichen.
      • Unbegrenztes Kontingent: Setzen Sie nominalQuota auf einen sehr hohen Wert wie "999999", um ein unbegrenztes Kontingent zu modellieren. Um sich auf TAS und dynamisches Slicing zu konzentrieren, wird mit dieser Konfiguration die Kontingentverwaltungsfunktion von Kueue umgangen.

Auswahl der Unterblock-Systemdiagnose definieren

Neben dem Standardstatus für Knoten und der Bereitschaft stellt GKE den spezifischen Status jedes Unterblocks über das Label cloud.google.com/gke-tpu-partition-4x4x4-state bereit. Mit diesem Label kann GKE Faktoren berücksichtigen, die die Slice-Bildung beeinflussen, z. B. den Status von TPU-Links.

Sie können den Wert des Labels cloud.google.com/gke-tpu-partition-4x4x4-state so definieren:

  • HEALTHY: Die Infrastruktur ist fehlerfrei.
  • DEGRADED: Die Infrastruktur des Unterblocks ist in einem schlechten Zustand, z. B. aufgrund einer OCS-Link-Verschlechterung. Der Unterblock kann weiterhin einen Slice bilden, aber die Gesamtleistung ist möglicherweise geringer als bei fehlerfreien Unterblöcken.
  • UNHEALTHY: Der Unterblock ist fehlerhaft und kann keinen Slice bilden.

Der Kueue Slice Controller-Webhook prüft, ob eine Arbeitslast eine bestimmte Anforderung für den Status eines Unterblocks enthält. Wenn keine Präferenz angegeben ist, fügt der Webhook eine Standardknotenaffinität ein.

Das Verhalten ist wie folgt:

  • Wenn ein nodeSelector- oder nodeAffinity-Element vorhanden ist, das auf das Label cloud.google.com/gke-tpu-partition-4x4x4-state ausgerichtet ist, bleibt es unverändert.
  • Wenn keine solche Labelkonfiguration vorhanden ist, fügt der Webhook die folgende Standardknotenaffinität ein, um sicherzustellen, dass nur verfügbare Unterblöcke verwendet werden:

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

Im folgenden Abschnitt finden Sie Beispiele, in denen das Label cloud.google.com/gke-tpu-partition-4x4x4-state konfiguriert ist, um die verschiedenen Konfigurationen für die Gesundheit von Unterblöcken anzugeben.

Testarbeitslasten mit dynamischem Slicing mit Kueue ausführen

In diesem Abschnitt wird beschrieben, wie Sie Arbeitslasten mit Kueue und TAS auf dynamischen Slices bereitstellen. Es enthält Beispiele, die zeigen, wie Sie eine dynamische Slice-Arbeitslast und eine Arbeitslast erstellen, die aus mehreren Slices besteht. Die Arbeitslasten werden als JobSets eingereicht.

Beispiel 1: Eine einzelne Arbeitslast verwendet einen einzelnen dynamischen Slice

Im folgenden Beispiel wird beschrieben, wie Sie einen Arbeitslast mithilfe eines Slice mit einer 4x12x16-Topologie erstellen, der aus 12 Unterblöcken besteht. Die Anzahl der Pods wurde so berechnet: (4 * 12 * 16) / 4 Chips pro Knoten = 192 Pods.

  1. Speichern Sie das folgende Manifest als big-super-slice.yaml:

    apiVersion: jobset.x-k8s.io/v1alpha2
    kind: JobSet
    metadata:
      name: big-super-slice
      labels:
        kueue.x-k8s.io/queue-name: lq
      annotations:
    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
    

    In diesem Manifest geben die folgenden Annotationen an, wie Kueue die Slice-Merkmale und -Topologie konfigurieren soll:

    • cloud.google.com/gke-tpu-slice-topology: Gibt "4x12x16" als dynamische Slice-Topologie an. Für die tpu7x-Beschleunigertopologie gelten die folgenden Regeln:
      • Die Mindesttopologie ist 4x4x4.
      • Die Topologie muss ein dreidimensionaler String im Format AxBxC sein. Beispiel: 4x8x8.
      • Jede Dimension (A, B und C) muss ein Vielfaches von vier sein.
      • Die Dimensionen müssen in nicht absteigender Reihenfolge sortiert sein: A <= B <= C. 4x8x4 ist beispielsweise ungültig und sollte 4x4x8 lauten.
      • Das Produkt der Abmessungen (ABC) darf 9.216 nicht überschreiten.
      • Die größten unterstützten Slice-Topologien können bis zu 32 Unterblöcke enthalten. Beispiele: 8x16x16 mit 32 Unterblöcken, 8x12x20 mit 30 Unterblöcken oder 12x12x12 mit 27 Unterblöcken liegen innerhalb der zulässigen Grenzwerte.
    • cloud.google.com/gke-tpu-accelerator: tpu7x: Plant Pods auf VMs, auf denen Ironwood (TPU7x) ausgeführt wird.
    • kueue.x-k8s.io/queue-name: Weist das JobSet einer Kueue LocalQueue zu.
    • Der Webhook fügt die Standardknotenaffinität ein, um sicherzustellen, dass HEALTHY- und DEGRADED-Knoten verwendet werden.
  2. Wenden Sie das big-super-slice.yaml-Manifest an:

    kubectl apply -f big-super-slice.yaml
    

    Nachdem Sie das Manifest angewendet haben, erstellt Kueue einen JobSet mit dem Namen big-super-slice. Kueue versucht dann, ein einzelnes dynamisches Slice mit einer 4x12x16-Topologie zu erstellen. Nachdem das Slice aktiv ist, lässt Kueue die Arbeitslast zu und die 192 Pods werden auf den Knoten geplant, um das dynamische Slice zu bilden, auf dem Ihre Arbeitslasten ausgeführt werden.

Beispiel 2: Arbeitslast mit mehr als einem Replikat

Im folgenden Beispiel wird gezeigt, wie Sie eine Arbeitslast erstellen, die zwei dynamische Slices verwendet, die jeweils aus vier Unterblöcken bestehen, die nur auf HEALTHY-Knoten ausgerichtet sind.

  1. Speichern Sie das folgende Manifest als two-super-slices.yaml:

    apiVersion: jobset.x-k8s.io/v1alpha2
    kind: JobSet
    metadata:
    name: two-super-slices
    labels:
        kueue.x-k8s.io/queue-name: lq
    annotations:
    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. Wenden Sie das two-super-slices.yaml-Manifest an:

    kubectl apply -f two-super-slices.yaml
    

In diesem Manifest legen Sie replicas: 2 im Feld replicatedJobs fest. Nachdem Sie das Manifest angewendet haben, versucht Kueue, zwei separate Slices mit einer 4x8x8-Topologie zu erstellen. Kueue erstellt für jedes in jobset.spec.replicatedJobs[].replicas definierte Replikat ein dynamisches Slice. Wenn n Replikate angegeben sind, erstellt Kueue n dynamische Slices für die Arbeitslast und wartet, bis alle Slices aktiv werden, bevor die Arbeitslast zugelassen wird.

Segment beobachten

Sie können den Status des Slice ansehen und die Slice-Messwerte mit GKE-Systemmesswerten überwachen.

Status des Segments überwachen

Führen Sie den folgenden Befehl aus, um den Status Ihrer dynamischen Slices zu prüfen:

kubectl describe slice SLICE_NAME

Ersetzen Sie SLICE_NAME durch den Namen Ihres Slices. Der Slice-Name wird in der Regel aus dem JobSet-Namen und dem Replikatindex abgeleitet. Im Beispiel 1 hätte ein von Kueue erstellter Slice einen Namen wie default-jobset-big-super-slice-yyyyy-job-jax-0.

Die Ausgabe sieht etwa so aus:

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>

Der Segmentname entspricht den folgenden Regeln, um die Kompatibilität mit den zugrunde liegenden Compute Engine-Ressourcennamenkonventionen zu gewährleisten:

  • Vorlage: {namespace}-jobset-{jobset.metadata.name}-kueueHash[5-character]-{jobset.spec.replicatedJobs[].name}-sliceIndex.
  • Länge: Der Name darf maximal 49 Zeichen lang sein. Der Controller hängt einen Bindestrich und einen 8‑stelligen Cluster-Hash an, um Compute Engine-Ressourcennamen zu erstellen, die ein Limit von 63 Zeichen haben.
  • Format: Der Name entspricht dem regulären Ausdruck ^[a-z]([-a-z0-9]*[a-z0-9])?$. Der Name hat folgende Merkmale:
    • Muss mit einem Kleinbuchstaben beginnen.
    • Darf nur Kleinbuchstaben, Ziffern und Bindestriche (-) enthalten.
    • Endet mit einem Kleinbuchstaben oder einer Ziffer (darf nicht mit einem Bindestrich enden).

Messwerte des Segments überwachen

Sie können die folgenden GKE-Systemmesswerte überwachen, die den Zustand eines Slice angeben:

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

Weitere Informationen zu den Messwerten finden Sie unter GKE-Systemmesswerte.

Bereinigen

Um unerwartete Kosten zu vermeiden, löschen Sie Ihre Slices, bevor Sie Knotenpools löschen.

  1. Löschen Sie das JobSet. Diese Aktion löst aus, dass Kueue die zugehörigen benutzerdefinierten Slice-Ressourcen löscht.

    kubectl delete jobset JOBSET_NAME
    

    Ersetzen Sie JOBSET_NAME durch den Namen Ihres JobSets, z. B. big-super-slice.

  2. Löschen Sie den TPU-Knotenpool:

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

(Optional) Dynamisches Slicing mit Ihrem eigenen Scheduler verwenden

In diesem Dokument geht es um die Verwendung von Kueue und TAS. Sie können das dynamische Aufteilen jedoch auch mit einem eigenen benutzerdefinierten Scheduler verwalten. Wenn Sie einen anderen Scheduler verwenden möchten, folgen Sie den Referenzinformationen zur benutzerdefinierten Slice-Ressource.

Nächste Schritte