本文档介绍了如何通过直接与 Slice 自定义资源互动来使用动态切片。您可以创建切片、监控分区状态并验证切片健康状况。
在按照这些说明操作之前,请确保您了解动态切片的概念。
为何要将动态切片与自定义调度器搭配使用?
如果您有复杂的调度要求,或者想将动态切片与现有调度基础架构集成,请使用自己的调度器来管理 Slice 自定义资源。
如果您希望使用调度器而不是直接管理 Slice 自定义资源,GKE 可与 Kueue 和拓扑感知调度 (TAS) 集成。如需了解详情,请参阅使用 Kueue 和 TAS 调度动态切片。
工作流程概览
如需将动态切片与自定义调度器搭配使用,您需要执行本文档中的以下任务:
- 启用 slice 控制器。
- 创建具有增量预配的节点池。
- 根据工作负载要求创建 Slice 自定义资源。将 Slice 自定义资源应用到您的集群。
- 监控分区状态和切片健康状况。
- 完成后,删除切片。
如需详细了解 Slice 自定义资源的字段和状态,请参阅 Slice 自定义资源参考信息。
要求
如需在 GKE 中使用动态切分,必须满足以下要求:
- 使用快速渠道中 1.35.2-gke.1842000 版或更高版本的 Standard 集群。
- 使用 Ironwood (TPU7x) 版本。
- 为节点使用 Container-Optimized OS 映像。
- 如需使用增量配置,请使用全容量模式预留。全容量模式是一项由 TPU Cluster Director 启用的功能。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请通过运行
gcloud components update命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
- 确保您已有 1.35.2-gke.1842000 版或更高版本的 Standard 集群(位于快速渠道中)。如需创建新集群,请参阅创建区域级集群。
- 确保您在相应区域中拥有足够的 Ironwood (TPU7x) 配额。
- 如果您计划运行多切片工作负载,请安装 JobSet v0.10.1 或更高版本。
- 在全容量模式下请求 TPU 容量。
启用 Slice 控制器
如需使用动态切片,请在集群中启用切片控制器。
更新集群:
gcloud container clusters update CLUSTER_NAME \ --location=LOCATION \ --enable-slice-controller替换以下内容:
CLUSTER_NAME:您的集群的名称。LOCATION:具有可用 TPU 容量的区域。
获取凭据,以便您可以使用
kubectl命令与集群通信:gcloud config set container/cluster CLUSTER_NAME gcloud container clusters get-credentials CLUSTER_NAME \ --location=LOCATION在以下命令的输出中,验证是否存在
slices.accelerator.gke.io值:kubectl get crd slices.accelerator.gke.io输出类似于以下内容:
slices.accelerator.gke.io 2026-01-09T23:58:02Z
创建具有增量预配的节点池
本部分介绍了如何通过增量配置创建 TPU 节点池。GKE 会将所有 TPU 容量转换为由 16 个 TPU 虚拟机组成的节点池或子块。即使 GKE 无法找到所有 16 个健康虚拟机,它也会通过将节点放置在宿主机的健康部分,并在修复健康状况不佳的机器时逐步配置这些机器,来配置这些节点池。
您可以将节点池定位为属于以下任一对象:
- 在全容量模式预留中公开的特定 TPU 块。块定位功能可让 GKE 在指定块内的任何可用子块中创建节点池。
- TPU 的特定子块或特定 16 节点 TPU 虚拟机组,用于实现更精细的控制。
创建工作负载政策
如需使用 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 会将节点池放置在该块中的可用子块内。您必须创建与要使用的块中的子块数量相同的节点池。
以子块为目标:每个节点池都映射到特定的可用子块。使用子块定位时,如果至少有一个虚拟机的健康状况良好,GKE 就会创建节点池。增量配置有助于确保所有节点都放置在指定的子块内。
屏蔽
如需检索预留中的块名称以及块中可用子块的数量,请完成查看“所有容量模式”预留的拓扑和健康状况文档中的以下步骤:
设置预留路径:
export RESERVATION_PATH="projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME"替换以下内容:
RESERVATION_NAME:TPU 预留的名称。BLOCK_NAME:块的名称。
为上一步中确定的每个子块创建一个节点池。例如,如果数量为
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。
子区块
如需检索块的名称和可用子块的 ID,请在查看“所有容量模式”预留的拓扑和运行状况文档中完成以下步骤:
如需确定块的名称,请列出所有预留块,然后复制
name:字段中的值。此值是相应块或BLOCK_NAME在相应文档中的名称。如需确定子块的名称,请列出某个块的所有子块,然后复制
reservationSubBlocks下每个条目的name:字段中的值。此值是子块或SUBBLOCK_NAME的名称(如本文档中所述)。
设置预留路径:
export RESERVATION_PATH="projects/PROJECT_ID/reservations/RESERVATION_NAME/reservationBlocks/BLOCK_NAME/reservationSubBlocks/SUBBLOCK_NAME"替换以下内容:
RESERVATION_NAME:TPU 预留的名称。BLOCK_NAME:块的名称。SUBBLOCK_NAME:子块的名称。
创建节点池:
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 自定义资源来定义指定的拓扑,然后由 slice 控制器激活该拓扑,而不是使用 Pod。
- 通过 Kueue 和 TAS 安排 GKE 工作负载。Kueue 会自动处理 Slice 自定义资源的创建和删除。避免手动修改由 Kueue 创建的 Slice 自定义资源。
创建动态切片
创建节点池后,您可以通过创建 Slice 自定义资源来形成更大的动态 Slice。您可以使用 Slice 自定义资源来定义指定的拓扑,然后由 Slice 控制器激活该拓扑,而不是使用 Pod。
验证节点和分区状态
如需从节点池中获取节点名称,请运行以下命令:
kubectl get nodes -l cloud.google.com/gke-nodepool=${NODE_POOL_NAME}结果类似于以下内容:
NAME STATUS ROLES AGE VERSION gke-np-status-update-7b4c890c-0jhp Ready <none> 2d1h v1.35.1-gke.1396002 gke-np-status-update-7b4c890c-377r Ready <none> 2d1h v1.35.1-gke.1396002 gke-np-status-update-7b4c890c-gb51 Ready <none> 2d1h v1.35.1-gke.1396002验证节点的预配模型:
kubectl describe node NODE_NAME | grep "cloud.google.com/gke-accelerator-topology-mode"结果类似于以下内容:
cloud.google.com/gke-accelerator-topology-mode: PROVISION_ONLY此值与您在创建工作负载政策时定义的
accelerator-topology-mode=provision_only设置一致。检索节点标签信息:
kubectl describe node NODE_NAME | grep "cloud.google.com/gke-tpu-partition-4x4x4-id"将
NODE_NAME替换为节点池中其中一个节点的名称。结果类似于以下内容:
cloud.google.com/gke-tpu-partition-4x4x4-id=fba785f80d18552357dcdef6d3d16c27cloud.google.com/gke-tpu-partition-4x4x4-state注解用于指示节点是否可用于形成动态切片。此标签支持以下值:HEALTHY:节点健康且功能齐全。DEGRADED:节点受损,但仍可用于动态切片形成。UNHEALTHY:节点出现故障,无法用于形成切片。UNSET:由于节点池中的节点不足,状态未定义。INCOMPLETE:分区中的并非所有节点都已预配。
验证节点是否包含
node.gke.io/created-by-mig注解:kubectl describe node NODE_NAME | grep "node.gke.io/created-by-mig"将
NODE_NAME替换为节点池中其中一个节点的名称。结果类似于以下内容:
node.gke.io/created-by-mig: projects/735972712744/zones/us-central1-ai1a/team/string输出内容包含
node.gke.io/created-by-mig标签,可让 GKE 控制平面将 Kubernetes 节点与其底层 Compute Engine 资源相关联。
创建 Slice 自定义资源
定义 Slice 自定义资源:
apiVersion: accelerator.gke.io/v1beta1 kind: Slice metadata: # Name of the slice resource name: SLICE_NAME spec: # Specify the type of accelerator for this slice type: "tpu7x" # Define the desired topology for the accelerator slice topology: TOPOLOGY partitionIds: - PARTITION_ID # Example: a9476d1b02bd4f4e75ffffae3bd23c01 - PARTITION_ID_2 # ... add more partition IDs as needed替换以下内容:
SLICE_NAME:切片的名称。名称必须符合metadata.name条件。TOPOLOGY:动态切片的拓扑。拓扑必须满足以下条件:- 所请求拓扑的每个维度都必须是 4 的倍数,例如
4A x 4B x 4C。 - 拓扑维度中的三个值(即
AxBxC)必须按非递减顺序排列 (A ≤ B ≤ C)。例如,4x4x8有效,但4x8x4无效。此顺序有助于确保切片形成的一致性,并避免出现意外行为。 - 拓扑维度中三个值的乘积(即
A × B × C)不得超过 9,216。
- 所请求拓扑的每个维度都必须是 4 的倍数,例如
PARTITION_ID:一个字符串列表,用于标识构成切片的4x4x4分区。 根据芯片总数计算分区数,其中每个分区包含 64 个芯片。spec.partitionIds列表中的项数必须与计算出的分区数 ((A × B × C) / 64) 完全一致。partitionIds必须满足以下条件:- 每个分区都必须映射到预留子块。
- 所有关联的子块都必须属于同一预留。
- 所有关联的块都必须位于同一预留中。
- 关联的节点池中的所有节点都必须处于
ready状态。
type字段的值必须为tpu7x。- (可选)如需让切片控制器在切片形成期间自动重试,您可以向切片自定义资源添加
slice.gke.io/retry-on-failure: "true"注解。如果由于SliceCreationFailed状态原因而未创建切片,控制器将重试,直到成功创建切片。
例如,如需创建
4x8x8切片,您需要提供四个唯一的分区 ID。apiVersion: accelerator.gke.io/v1beta1 kind: Slice metadata: name: test-slice-example annotations: slice.gke.io/retry-on-failure: "true" # Optional annotation to retry slice formation spec: type: "tpu7x" topology: "4x8x8" # (4*8*8)/64 = 4 partitions partitionIds: - "p0" - "p1" - "p2" - "p3"应用 Slice 自定义资源:
kubectl apply -f test-slice-example.yaml此时,GKE 会尝试创建切片。如果出现以下问题之一,切片创建会失败,并且 Slice 自定义资源中的状态原因会更新为
SliceCreationFailed或FAILED:- 如果自定义资源上所选的节点不存在,则状态原因是
SliceCreationFailed。 - 如果自定义资源上的任何节点被其他 slice 使用,则状态原因是
SliceCreationFailed。 - 如果自定义资源上的节点不属于同一预留块,则状态原因是
FAILED。 - 如果节点不在同一预留中,则状态原因是
FAILED。 - 如果拓扑与分区数量不匹配,状态原因将为
SliceCreationFailed。
如需详细了解 Slice 自定义资源的状态,请参阅 Slice 状态。
- 如果自定义资源上所选的节点不存在,则状态原因是
监控 Slice 自定义资源的状态
如需检查 Slice 自定义资源的状态,请运行以下命令:
kubectl describe slice SLICE_NAME
将 SLICE_NAME 替换为切片的名称。
输出类似于以下内容:
Name: test-slice
Namespace:
Labels: <none>
Annotations: <none>
API Version: accelerator.gke.io/v1beta1
Kind: Slice
Metadata:
Creation Timestamp: 2026-01-11T23:45:15Z
Finalizers:
accelerator.gke.io/slice-finalizer
Generation: 1
Resource Version: 1768175347356335006
UID: d0b71e5c-be3f-4788-aead-930c7afec4f2
Spec:
Partition Ids:
2c79463990ff67c4e3c2648666bfedfa
ba898ffcac0ad0946e8ff036d771ee53
[more partition IDs]
Topology: 8x16x16
Type: tpu7x
Status:
Conditions:
Last Transition Time: 2026-01-11T23:45:38Z
Message: ""
Reason: FAILED
Status: False
Type: Ready
Events:
Slice 自定义资源状态中的 reason 字段表示 slice 的当前状态。Slice 自定义资源的生命周期遵循以下流程:
SliceNotCreated:控制器执行初始化和资源检查。- 如果不满足前提条件,状态会转换为
SliceCreationFailed。 - 如果验证通过,状态会转换为
ACTIVATING。
- 如果不满足前提条件,状态会转换为
ACTIVATING:GKE 正在形成切片。- 如果成功,状态将转换为
ACTIVE。 - 如果子块降级但切片可用,则状态会转换为
ACTIVE_DEGRADED。 - 如果组建失败,状态会转换为
FAILED。
- 如果成功,状态将转换为
DEACTIVATING:如果 Slice 自定义资源被删除,或者在有效状态或失败状态下发生严重故障,Slice 会开始拆解。INCOMPLETE:资源完全删除之前的最后一步。
如需详细了解 Slice 自定义资源的状态,请参阅 Slice 状态。
在动态切片上运行工作负载
当 Slice 自定义资源处于 ACTIVE 状态时,您可以在其上运行工作负载。以下部分包含使用动态切片的工作负载示例。工作负载以作业或 JobSet 的形式提交。
示例 1:单个工作负载使用单个切片
以下示例展示了使用单个子块切片的工作负载。
将以下示例清单保存为
tpu-job-jax-v7x-64.yaml:apiVersion: v1 kind: Service metadata: name: headless-svc spec: clusterIP: None selector: job-name: tpu-job-jax-v7x-64 --- apiVersion: batch/v1 kind: Job metadata: name: tpu-job-jax-v7x-64 spec: backoffLimit: 0 completions: 16 parallelism: 16 completionMode: Indexed template: metadata: annotations: cloud.google.com/gke-tpu-slice-topology: 4x4x4 spec: nodeSelector: cloud.google.com/gke-tpu-topology: 4x4x4 cloud.google.com/gke-tpu-accelerator: tpu7x cloud.google.com/gke-tpu-slice: test-slice subdomain: headless-svc restartPolicy: Never containers: - name: tpu-job-jax env: - name: TPU_ACCELERATOR_TYPE value: tpu7x-128 image: python:3.12 securityContext: privileged: false command: - bash - -c - | set -ex pip install -U --pre jax jaxlib libtpu requests -i https://us-python.pkg.dev/ml-oss-artifacts-published/jax/simple/ -f https://storage.googleapis.com/jax-releases/libtpu_releases.html pip list python -c 'import jax; print("Total TPU devices (cores):", jax.device_count())' resources: requests: google.com/tpu: 4 limits: google.com/tpu: 4在此清单中:
cloud.google.com/gke-tpu-slice-topology和cloud.google.com/gke-tpu-topology定义了动态切片的拓扑。env.value: tpu7x-128是 TPU 加速器类型和切片中的总核心数。 核心数量的计算方式是将拓扑的维度乘以每个芯片的核心数量。 例如,对于4x4x4拓扑,计算公式为4 × 4 × 4 × 2 = 128,其中2是tpu7x(Ironwood (TPU7x))的每芯片核心数。 因此,TPU_ACCELERATOR_TYPE为tpu7x-128。
应用
tpu-job-jax-v7x-64.yaml清单:kubectl apply -f tpu-job-jax-v7x-64.yaml
示例 2:使用 JobSet 在多切片节点池上部署工作负载
此示例演示了如何使用 JobSet 在多切片节点池上部署工作负载。
安装 JobSet:
kubectl apply --server-side -f https://github.com/kubernetes-sigs/jobset/releases/download/v0.10.1/manifests.yaml将以下示例清单保存为
tpu-multislice-jax.yaml:apiVersion: jobset.x-k8s.io/v1alpha2 kind: JobSet metadata: name: tpu-multislice-jax annotations: alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-tpu-slice spec: failurePolicy: maxRestarts: 3 replicatedJobs: - name: slice-job replicas: 2 template: spec: parallelism: 16 completions: 16 backoffLimit: 0 completionMode: Indexed template: metadata: annotations: # The shape of the slice cloud.google.com/gke-tpu-slice-topology: 4x4x4 spec: hostNetwork: true dnsPolicy: ClusterFirstWithHostNet nodeSelector: cloud.google.com/gke-tpu-topology: 4x4x4 cloud.google.com/gke-tpu-accelerator: tpu7x # IMPORTANT: Do NOT put 'cloud.google.com/gke-tpu-slice' here manually. # The exclusive-topology annotation handles the slice assignment automatically. containers: - name: jax-worker image: python:3.12 securityContext: privileged: true ports: - containerPort: 8471 command: - bash - -c - | set -ex pip install -U --pre jax jaxlib libtpu requests -f https://storage.googleapis.com/jax-releases/libtpu_releases.html # Verify JobSet injected the specific slice ID for this worker echo "JobSet Index: $JOB_COMPLETION_INDEX" python -c 'import jax; print("Total TPU devices:", jax.device_count())' resources: requests: google.com/tpu: 4 limits: google.com/tpu: 4应用
tpu-multislice-jax.yaml清单:kubectl apply -f tpu-multislice-jax.yaml在此清单中:
replicatedJobs下的replicas: 2字段表示 JobSet 创建两个单独的作业,每个作业对应一个4x4x4TPU 切片。alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-tpu-slice注解有助于确保每个作业都分配给唯一的 TPU 切片。cloud.google.com/gke-tpu-slice-topology: 4x4x4注解定义了每个动态切片的拓扑。- 在此示例中,未明确设置
TPU_ACCELERATOR_TYPE环境变量,因为 JobSet 会处理切片分配。JAX 代码会自动检测其分配的 slice 中的可用 TPU 设备。
删除切片
删除 slice:
kubectl patch slice $SLICE_NAME --type json \ -p='[{"op": "remove", "path": "/metadata/finalizers"}]'验证切片是否已删除:
kubectl get slices
停用 Slice 控制器
如需停用切片控制器,请将其从集群中移除。
检查 Slice 自定义资源是否为空:
kubectl get slice -A更新集群以停用切片控制器:
gcloud container clusters update ${CLUSTER_NAME} \ --location=${REGION} \ --no-enable-slice-controller删除 Slice 自定义资源:
kubectl delete crd slices.accelerator.gke.io验证 Slice 自定义资源是否已删除:
kubectl get crd | grep slices.accelerator.gke.io移除切片控制器添加的标签。需要移除以下标签:
cloud.google.com/gke-tpu-slicecloud.google.com/gke-tpu-topology
- 如需从特定节点中移除,请更新节点名称
export NODE_NAME="gke-tpu-bdac9600-3bdg" kubectl label node $NODE_NAME cloud.google.com/gke-tpu-slice- cloud.google.com/gke-tpu-slice-topology-- 如果您想从集群中的每个节点移除这些标签,请执行以下操作:
kubectl label nodes --all cloud.google.com/gke-tpu-slice- cloud.google.com/gke-tpu-slice-topology-- 检查节点标签并确认它们为空:
export NODE_NAME="gke-tpu-bdac9600-3bdg" kubectl describe node $NODE_NAME | grep "cloud.google.com/gke-tpu-slice"
后续步骤
- 详细了解动态切片概念。
- 了解 Slice 自定义资源。