使用 DRA 向工作负载动态分配设备


本页介绍了如何在 Google Kubernetes Engine 集群上部署动态资源分配 (DRA) 工作负载。在本页中,您将创建一个 ResourceClaimTemplate 以使用 DRA 请求硬件,然后部署一个基本工作负载,以演示 Kubernetes 如何灵活地在 Pod 上分配硬件。

本页面适用于运行 AI/ML 或高性能计算 (HPC) 等工作负载的应用运维人员数据工程师

动态资源分配简介

DRA 是一项内置的 Kubernetes 功能,可让您在集群中灵活地请求、分配和共享硬件资源,并将其分配给 Pod 和容器。如需了解详情,请参阅动态资源分配简介

关于使用 DRA 请求设备

为 DRA 设置 GKE 基础架构时,节点上的 DRA 驱动程序会在集群中创建 DeviceClass 对象。 DeviceClass 用于定义可供工作负载请求的设备类别(例如 GPU)。 平台管理员可以选择部署其他 DeviceClass,以限制您可以在特定工作负载中请求的设备。

如需请求 DeviceClass 中的设备,您可以创建以下任一对象:

  • ResourceClaim:借助 ResourceClaim,Pod 或用户可以通过在 DeviceClass 中过滤特定参数来请求硬件资源。
  • ResourceClaimTemplate:ResourceClaimTemplate 用于定义一个模板,Pod 可以使用该模板自动创建每个 Pod 的新 ResourceClaim。

如需详细了解 ResourceClaimResourceClaimTemplate 对象,请参阅何时使用 ResourceClaimsResourceClaimTemplates

本页中的示例使用基本 ResourceClaimTemplate 请求指定的设备配置。如需了解更多详情,请参阅 ResourceClaimTemplateSpec Kubernetes 文档

限制

  • 不支持节点自动预配。
  • Autopilot 集群不支持 DRA。
  • 您无法使用以下 GPU 共享功能:
    • 分时 GPU
    • 多实例 GPU
    • 多进程服务 (MPS)

要求

如需使用 DRA,您的 GKE 版本必须为 1.32.1-gke.1489001 或更高版本。

您还应熟悉以下要求和限制:

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

使用 DRA 部署工作负载

如需请求按 Pod 分配设备,您首先需要创建一个 ResourceClaimTemplate,该 ResourceClaimTemplate 会生成一个 ResourceClaim 来描述您对 GPU 或 TPU 的请求,Kubernetes 会将该 ResourceClaim 用作模板,为工作负载中的每个 Pod 创建新的 ResourceClaim 对象。当您在工作负载中指定 ResourceClaimTemplate 时,Kubernetes 会分配所请求的资源,并在相应的节点上调度 Pod。

GPU

  1. 将以下清单保存为 claim-template.yaml

    apiVersion: resource.k8s.io/v1beta1
    kind: ResourceClaimTemplate
    metadata:
      name: gpu-claim-template
    spec:
      spec:
        devices:
          requests:
          - name: single-gpu
            deviceClassName: gpu.nvidia.com
            allocationMode: ExactCount
            count: 1
    
  2. 创建 ResourceClaimTemplate

    kubectl create -f claim-template.yaml
    
  3. 如需创建引用 ResourceClaimTemplate 的工作负载,请将以下清单保存为 dra-gpu-example.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dra-gpu-example
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: dra-gpu-example
      template:
        metadata:
          labels:
            app: dra-gpu-example
        spec:
          containers:
          - name: ctr
            image: ubuntu:22.04
            command: ["bash", "-c"]
            args: ["while [ 1 ]; do date; echo $(nvidia-smi -L || echo Waiting...); sleep 60; done"]
            resources:
              claims:
              - name: single-gpu
          resourceClaims:
          - name: single-gpu
            resourceClaimTemplateName: gpu-claim-template
          tolerations:
          - key: "nvidia.com/gpu"
            operator: "Exists"
            effect: "NoSchedule"
    
  4. 部署工作负载:

    kubectl create -f dra-gpu-example.yaml
    

TPU

  1. 将以下清单保存为 claim-template.yaml

    apiVersion: resource.k8s.io/v1beta1
    kind: ResourceClaimTemplate
    metadata:
      name: tpu-claim-template
    spec:
      spec:
        devices:
          requests:
          - name: all-tpus
            deviceClassName: tpu.google.com
            allocationMode: All
    

    ResourceClaimTemplate 会请求 GKE 为每个 ResourceClaim 分配整个 TPU 节点池。

  2. 创建 ResourceClaimTemplate

    kubectl create -f claim-template.yaml
    
  3. 如需创建引用 ResourceClaimTemplate 的工作负载,请将以下清单保存为 dra-tpu-example.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dra-tpu-example
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: dra-tpu-example
      template:
        metadata:
          labels:
            app: dra-tpu-example
        spec:
          containers:
          - name: ctr
            image: ubuntu:22.04
            command:
              - /bin/sh
              - -c
              - |
                echo "Environment Variables:"
                env
                echo "Sleeping indefinitely..."
                sleep infinity
            resources:
              claims:
              - name: all-tpus
          resourceClaims:
          - name: all-tpus
            resourceClaimTemplateName: tpu-claim-template
          tolerations:
          - key: "google.com/tpu"
            operator: "Exists"
            effect: "NoSchedule"
    
  4. 部署工作负载:

    kubectl create -f dra-tpu-example.yaml
    

验证硬件分配

您可以通过检查 ResourceClaim 或查看 pod 的日志,验证您的工作负载是否已分配硬件。

GPU

  1. 获取与您部署的工作负载关联的 ResourceClaim

    kubectl get resourceclaims
    

    输出应类似于以下内容:

    NAME                                               STATE                AGE
    dra-gpu-example-64b75dc6b-x8bd6-single-gpu-jwwdh   allocated,reserved   9s
    
  2. 如需详细了解分配给 Pod 的硬件,请运行以下命令:

    kubectl describe resourceclaims RESOURCECLAIM
    

    RESOURCECLAIM 替换为您从上一步的输出中获取的 ResourceClaim 的完整名称。

    输出应类似于以下内容:

    Name:         dra-gpu-example-64b75dc6b-x8bd6-single-gpu-jwwdh
    Namespace:    default
    Labels:       
    Annotations:  resource.kubernetes.io/pod-claim-name: single-gpu
    API Version:  resource.k8s.io/v1beta1
    Kind:         ResourceClaim
    Metadata:
      Creation Timestamp:  2025-03-31T17:11:37Z
      Finalizers:
        resource.kubernetes.io/delete-protection
      Generate Name:  dra-gpu-example-64b75dc6b-x8bd6-single-gpu-
      Owner References:
        API Version:           v1
        Block Owner Deletion:  true
        Controller:            true
        Kind:                  Pod
        Name:                  dra-gpu-example-64b75dc6b-x8bd6
        UID:                   cb3cb1db-e62a-4961-9967-cdc7d599105b
      Resource Version:        12953269
      UID:                     3e0c3925-e15a-40e9-b552-d03610fff040
    Spec:
      Devices:
        Requests:
          Allocation Mode:    ExactCount
          Count:              1
          Device Class Name:  gpu.nvidia.com
          Name:               single-gpu
    Status:
      Allocation:
        Devices:
          Results:
            Admin Access:  
            Device:        gpu-0
            Driver:        gpu.nvidia.com
            Pool:          gke-cluster-gpu-pool-11026a2e-zgt1
            Request:       single-gpu
        Node Selector:
          # lines omitted for clarity
      Reserved For:
        Name:      dra-gpu-example-64b75dc6b-x8bd6
        Resource:  pods
        UID:       cb3cb1db-e62a-4961-9967-cdc7d599105b
    Events:        
    
  3. 如需获取您部署的工作负载的日志,请运行以下命令:

    kubectl logs deployment/dra-gpu-example --all-pods=true | grep "GPU"
    

    输出应类似于以下内容:

    [pod/dra-gpu-example-64b75dc6b-x8bd6/ctr] GPU 0: Tesla T4 (UUID: GPU-2087ac7a-f781-8cd7-eb6b-b00943cc13ef)
    

    执行上述步骤的输出结果显示,GKE 向 Pod 分配了一个 GPU。

TPU

  1. 获取与您部署的工作负载关联的 ResourceClaim

    kubectl get resourceclaims | grep dra-tpu-example
    

    输出应类似于以下内容:

    NAME                                               STATE                AGE
    dra-tpu-example-64b75dc6b-x8bd6-all-tpus-jwwdh     allocated,reserved   9s
    
  2. 如需详细了解分配给 Pod 的硬件,请运行以下命令:

    kubectl describe resourceclaims RESOURCECLAIM -o yaml
    

    RESOURCECLAIM 替换为您从上一步的输出中获取的 ResourceClaim 的完整名称。

    输出应类似于以下内容:

    apiVersion: resource.k8s.io/v1beta1
    kind: ResourceClaim
    metadata:
      annotations:
        resource.kubernetes.io/pod-claim-name: all-tpus
      creationTimestamp: "2025-03-04T21:00:54Z"
      finalizers:
      - resource.kubernetes.io/delete-protection
      generateName: dra-tpu-example-59b8785697-k9kzd-all-gpus-
      name: dra-tpu-example-59b8785697-k9kzd-all-gpus-gnr7z
      namespace: default
      ownerReferences:
      - apiVersion: v1
        blockOwnerDeletion: true
        controller: true
        kind: Pod
        name: dra-tpu-example-59b8785697-k9kzd
        uid: c2f4fe66-9a73-4bd3-a574-4c3eea5fda3f
      resourceVersion: "12189603"
      uid: 279b5014-340b-4ef6-9dda-9fbf183fbb71
    spec:
      devices:
        requests:
        - allocationMode: All
          deviceClassName: tpu.google.com
          name: all-tpus
    status:
      allocation:
        devices:
          results:
          - adminAccess: null
            device: "0"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "1"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "2"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "3"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "4"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "5"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "6"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
          - adminAccess: null
            device: "7"
            driver: tpu.google.com
            pool: gke-tpu-2ec29193-bcc0
            request: all-tpus
        nodeSelector:
          nodeSelectorTerms:
          - matchFields:
            - key: metadata.name
              operator: In
              values:
              - gke-tpu-2ec29193-bcc0
      reservedFor:
      - name: dra-tpu-example-59b8785697-k9kzd
        resource: pods
        uid: c2f4fe66-9a73-4bd3-a574-4c3eea5fda3f
    
  3. 如需获取您部署的工作负载的日志,请运行以下命令:

    kubectl logs deployment/dra-tpu-example --all-pods=true | grep "TPU"
    

    输出应类似于以下内容:

    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_CHIPS_PER_HOST_BOUNDS=2,4,1
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_TOPOLOGY_WRAP=false,false,false
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_SKIP_MDS_QUERY=true
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_RUNTIME_METRICS_PORTS=8431,8432,8433,8434,8435,8436,8437,8438
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_WORKER_ID=0
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_WORKER_HOSTNAMES=localhost
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_TOPOLOGY=2x4
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_ACCELERATOR_TYPE=v6e-8
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_HOST_BOUNDS=1,1,1
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_TOPOLOGY_ALT=false
    [pod/dra-tpu-example-59b8785697-tm2lc/ctr] TPU_DEVICE_0_RESOURCE_CLAIM=77e68f15-fa2f-4109-9a14-6c91da1a38d3
    

    执行上述步骤的输出表明,节点池中的所有 TPU 都分配给了该 Pod。

后续步骤