在ACK Edge集群中使用共享GPU调度能力

通过共享GPU调度能力,您可以将多个Pod调度到同一张GPU卡上,以共享GPU的计算资源,从而提高GPU的利用率并节省成本。在实现GPU共享调度的同时,确保运行在同一张GPU上的多个容器之间能够互相隔离,并根据各自申请的资源使用量运行,避免某个容器的资源使用量超标,进而影响其他容器的正常工作。本文介绍如何在ACK Edge集群中使用共享GPU调度能力。

前提条件

使用限制

  • ACK Edge集群的云端节点支持完整的共享GPU调度和显存隔离以及算力隔离能力。

  • ACK Edge集群的边缘节点池仅支持共享GPU调度,不支持显存隔离、算力隔离的能力。

注意事项

针对纳入K8s集群管理的GPU节点,为业务应用申请和使用GPU资源时,请关注以下注意事项。

  • 请勿直接在节点上运行GPU应用程序。

  • 请勿通过dockerpodmannerdctl等工具命令创建容器并为容器申请GPU资源。例如,执行docker run --gpus alldocker run -e NVIDIA_VISIBLE_DEVICES=all并运行GPU程序。

  • 请勿在Pod YAMLenv中直接添加环境变量NVIDIA_VISIBLE_DEVICES=allNVIDIA_VISIBLE_DEVICES=<GPU ID>等,通过容器的环境变量NVIDIA_VISIBLE_DEVICES直接为Pod申请GPU资源,并运行GPU程序。

  • Pod YAML中未设置环境变量NVIDIA_VISIBLE_DEVICES,制作Pod所使用的镜像时,请勿将环境变量默认配置为NVIDIA_VISIBLE_DEVICES=all,并运行GPU程序。

  • 请勿在PodsecurityContext中配置privileged: true,并运行GPU程序。

通过以上非标方式为业务应用申请的GPU资源,将存在如下安全隐患。

  • 通过以上方式为业务应用申请的GPU资源,并未在调度器的设备资源账本中统计,有可能造成节点GPU资源的分配情况与调度器设备资源账本中记录的值不一致。调度器仍然会调度某些申请GPU资源的Pod到这个节点上,导致用户业务因为在同一张GPU卡上出现资源争抢(比如GPU显存申请)而运行失败的情况。

  • 非标操作可能引发其他未知问题,例如NVIDIA社区的已知报错

步骤一:安装共享GPU组件

未部署云原生AI套件

  1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择应用 > 云原生AI套件

  3. 云原生AI套件页面,单击一键部署

  4. 在一键部署云原生AI套件页面,选中调度组件(批量任务调度、GPU共享、GPU拓扑感知、NPU调度)。1

  5. (可选)单击调度组件(批量任务调度、GPU共享、GPU拓扑感知、NPU调度)右侧的高级配置。在弹出的参数配置窗口,修改cGPUpolicy字段。修改完成后,单击确定

    如果对cGPU算力共享无特殊要求,建议使用默认policy: 5。cGPU支持的policy,请参见安装并使用cGPU服务2.jpg

  6. 云原生AI套件页面最下方,单击部署云原生AI套件

    组件安装成功后,在云原生AI套件页面的组件列表中能看到已安装的共享GPU组件ack-ai-installer

已部署云原生AI套件

  1. 登录容器服务管理控制台,在左侧导航栏选择集群列表

  2. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择应用 > 云原生AI套件

  3. 在组件ack-ai-installer所在行,单击操作列的部署

  4. (可选)在弹出的参数配置窗口,修改cGPUpolicy字段。

    如果对cGPU算力共享无特殊要求,建议使用默认policy: 5。cGPU支持的policy,请参见安装并使用cGPU服务2.jpg

  5. 修改完成后,单击确定

    组件安装完成后,ack-ai-installer状态已部署

步骤二:创建GPU节点池

  • 创建云端GPU节点池,以开启GPU共享调度能力、显存隔离和算力共享能力。

  • 创建边缘GPU节点池,以开启GPU共享调度能力。

云端节点池

  1. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择节点管理 > 节点池

  2. 节点池页面,单击创建节点池

  3. 创建节点池页面,设置创建节点池的配置项,然后单击确认配置

    以下为重要配置项的说明,其余配置项的配置方法,请参见创建和管理节点池

    配置项

    说明

    期望节点数

    设置节点池初始节点数量。如无需创建节点,可以填写为0。

    节点标签

    标签的值需根据您的业务需求添加。关于节点标签的详细说明,请参见GPU节点调度属性标签

    下文以标签值cgpu为例,该值表示节点开启共享GPU调度能力,每个Pod仅需申请GPU显存资源,多个Pod在一张卡上实行显存隔离和算力共享。

    单击节点标签节点标签,设置ack.node.gpu.schedule,cgpu。

    重要

边缘节点池

  1. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择节点管理 > 节点池

  2. 节点池页面,单击创建边缘节点池

  3. 创建节点池页面,设置创建节点池的配置项,然后单击确认配置。此处仅介绍主要配置项,其余配置项请参见边缘节点池属性

    节点标签:单击节点标签节点标签,设置ack.node.gpu.scheduleshare。仅开启GPU共享调度能力。关于节点标签的更多信息,请参见GPU节点调度属性标签说明

步骤三:添加GPU节点

分别在云端节点池和边缘节点池中添加GPU节点。

云端节点

说明

如果您添加节点池时已经创建GPU节点,可以跳过此步骤。

完成创建节点池后,您还可以在节点池中添加GPU节点。添加GPU节点时,您需要将实例规格架构设置为GPU云服务器。具体操作,请参见添加已有节点创建和管理节点池

边缘节点

在边缘节点池中添加GPU节点的具体操作,请参见添加GPU节点

步骤四:在云端节点安装和使用GPU资源查询工具

  1. 下载kubectl-inspect-cgpu。需将执行文件下载至PATH环境变量包含目录下,本文以/usr/local/bin/为例。

    • 如果您使用的是Linux系统,您可以通过以下命令下载kubectl-inspect-cgpu。

      wget http://aliacs-k8s-cn-beijing.oss-cn-beijing.aliyuncs.com/gpushare/kubectl-inspect-cgpu-linux -O /usr/local/bin/kubectl-inspect-cgpu
    • 如果您使用的是macOS系统,您可以通过以下命令下载kubectl-inspect-cgpu。

      wget http://aliacs-k8s-cn-beijing.oss-cn-beijing.aliyuncs.com/gpushare/kubectl-inspect-cgpu-darwin -O /usr/local/bin/kubectl-inspect-cgpu
  2. 执行以下命令,为kubectl-inspect-cgpu添加执行权限。

    chmod +x /usr/local/bin/kubectl-inspect-cgpu
  3. 执行以下命令,查看集群GPU使用情况。

    kubectl inspect cgpu

    预期输出:

    NAME                       IPADDRESS      GPU0(Allocated/Total)  GPU Memory(GiB)
    cn-shanghai.192.168.6.104  192.168.6.104  0/15                   0/15
    ----------------------------------------------------------------------
    Allocated/Total GPU Memory In Cluster:
    0/15 (0%)

步骤五:部署共享GPU调度示例

云端节点池

  1. 执行以下命令查询集群的GPU共享能力。

    kubectl inspect cgpu
    NAME                     IPADDRESS    GPU0(Allocated/Total)  GPU1(Allocated/Total)  GPU Memory(GiB)
    cn-shanghai.192.168.0.4  192.168.0.4  0/7                    0/7                    0/14
    ---------------------------------------------------------------------
    Allocated/Total GPU Memory In Cluster:
    0/14 (0%)
    说明

    您可以执行命令kubectl inspect cgpu -d,查询GPU共享能力详细信息。

  2. 部署共享GPU示例应用,该示例应用申请3 GiB显存。

    apiVersion: batch/v1
    kind: Job
    metadata:
      name: gpu-share-sample
    spec:
      parallelism: 1
      template:
        metadata:
          labels:
            app: gpu-share-sample
        spec:
          nodeSelector:
            alibabacloud.com/nodepool-id: npxxxxxxxxxxxxxx # 此处需替换为您创建的云端节点池ID。
          containers:
          - name: gpu-share-sample
            image: registry.cn-hangzhou.aliyuncs.com/ai-samples/gpushare-sample:tensorflow-1.5
            command:
            - python
            - tensorflow-sample-code/tfjob/docker/mnist/main.py
            - --max_steps=100000
            - --data_dir=tensorflow-sample-code/data
            resources:
              limits:
                # 单位为GiB,该Pod总共申请了3 GiB显存。
                aliyun.com/gpu-mem: 3 # 设置GPU显存大小。
            workingDir: /root
          restartPolicy: Never

边缘节点池

部署共享GPU示例应用,该示例应用申请4 GiB显存。

apiVersion: batch/v1
kind: Job
metadata:
  name: tensorflow-mnist-share
spec:
  parallelism: 1
  template:
    metadata:
      labels:
        app: tensorflow-mnist-share
    spec:
      nodeSelector:
        alibabacloud.com/nodepool-id: npxxxxxxxxxxxxxx # 此处需替换为您创建的边缘节点池ID。 
      containers:
      - name: tensorflow-mnist-share
        image: registry.cn-beijing.aliyuncs.com/ai-samples/gpushare-sample:tensorflow-1.5
        command:
        - python
        - tensorflow-sample-code/tfjob/docker/mnist/main.py
        - --max_steps=100000
        - --data_dir=tensorflow-sample-code/data
        resources:
          limits:
            aliyun.com/gpu-mem: 4 # 总共申请4 GiB显存。
        workingDir: /root
      restartPolicy: Never

步骤六:结果验证

云端节点池

  1. 登录目标Master节点。

  2. 执行以下命令,查看已部署应用的日志,验证cGPU显存隔离是否部署成功。

    kubectl logs gpu-share-sample --tail=1

    预期输出:

    2023-08-07 09:08:13.931003: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1326] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 2832 MB memory) -> physical GPU (device: 0, name: Tesla T4, pci bus id: 0000:00:07.0, compute capability: 7.5)

    预期输出表明,容器申请的显存为2832 MB。

  3. 执行以下命令,登录容器查看容器被分配显存总量。

    kubectl exec -it gpu-share-sample nvidia-smi

    预期输出:

    Mon Aug 7 08:52:18 2023
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 418.87.01    Driver Version: 418.87.01    CUDA Version: 10.1     |
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |===============================+======================+======================|
    |   0  Tesla T4            On   | 00000000:00:07.0 Off |                    0 |
    | N/A   41C    P0    26W /  70W |   3043MiB /  3231MiB |      0%      Default |
    +-------------------------------+----------------------+----------------------+
    
    +-----------------------------------------------------------------------------+
    | Processes:                                                       GPU Memory |
    |  GPU       PID   Type   Process name                             Usage      |
    |=============================================================================|
    +-----------------------------------------------------------------------------+

    预期输出表明,该容器被分配显存总量为3231 MiB 。

  4. 登录带有GPU设备的节点,查看示例应用所在节点的GPU显存总量。

    nvidia-smi

    预期输出:

    Mon Aug  7 09:18:26 2023 
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 418.87.01    Driver Version: 418.87.01    CUDA Version: 10.1     |
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |===============================+======================+======================|
    |   0  Tesla T4            On   | 00000000:00:07.0 Off |                    0 |
    | N/A   40C    P0    26W /  70W |   3053MiB / 15079MiB |      0%      Default |
    +-------------------------------+----------------------+----------------------+
    
    +-----------------------------------------------------------------------------+
    | Processes:                                                       GPU Memory |
    |  GPU       PID   Type   Process name                             Usage      |
    |=============================================================================|
    |    0      8796      C   python3                                     3043MiB |
    +-----------------------------------------------------------------------------+
    
                            

    预期输出表明,主机上的显存总量为15079 MiB,其中3053 MiB分配给容器。

边缘节点池

  1. 集群列表页面,单击目标集群名称,然后在左侧导航栏,选择工作负载 > 容器组

  2. 在创建的容器所在行(例如tensorflow-mnist-multigpu-***),单击操作列的终端。然后从下拉列表中选择需要登录的容器,执行如下命令。

    nvidia-smi

    预期输出:

    Wed Jun 14 06:45:56 2023
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 515.105.01   Driver Version: 515.105.01   CUDA Version: 11.7     |
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |                               |                      |               MIG M. |
    |===============================+======================+======================|
    |   0  Tesla V100-SXM2...  On   | 00000000:00:09.0 Off |                    0 |
    | N/A   35C    P0    59W / 300W |    334MiB / 16384MiB |      0%      Default |
    |                               |                      |                  N/A |
    +-------------------------------+----------------------+----------------------+
    
    +-----------------------------------------------------------------------------+
    | Processes:                                                                  |
    |  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
    |        ID   ID                                                   Usage      |
    |=============================================================================|
    +-----------------------------------------------------------------------------+

    Pod内部能够发现整张GPU卡的总显存16384 MiB(本文示例使用GPU卡为V100),而在有隔离模块参与的场景下,该值与Pod申请值一致(本文示例为4 GiB),说明配置生效。

    业务应用需要从两个环境变量中读取该业务能够使用的显存值。

    ALIYUN_COM_GPU_MEM_CONTAINER=4 # 该Pod能够使用的显存值。
    ALIYUN_COM_GPU_MEM_DEV=16 # 每张GPU卡总共的显存值。

    如果应用需要的是显存的百分比,可以使用上述两个环境变量计算:

    percetange = ALIYUN_COM_GPU_MEM_CONTAINER / ALIYUN_COM_GPU_MEM_DEV = 4 / 16 = 0.25

相关文档