在 GPU 节点上配置硬件加速器

随着业务数据的增加,尤其是在人工智能和数据分析等场景中,您可能希望在自建业务集群中利用 GPU 功能来加速数据处理。除了为集群节点准备 GPU 资源外,还需进行 GPU 配置。

本解决方案将集群中具有GPU计算能力的节点称为 GPU 节点

注意:除非另有说明,操作步骤适用于两种类型的节点。有关驱动程序安装相关问题,请参考 NVIDIA 官方安装文档

前提条件

在操作节点上已准备好 GPU 资源,该节点属于本节提到的 GPU 节点。

安装 GPU 驱动

注意:如果 GPU 节点使用 NVIDIA MPS 插件,请确保该节点的 GPU 架构为 Volta 或更新版本(Volta/Turing/Ampere/Hopper 等),且驱动程序支持 CUDA 版本 11.5 或更高版本。

获取驱动下载地址

  1. 登录到 GPU 节点,并运行命令 lspci |grep -i NVIDIA 检查该节点的 GPU 型号。

    在以下示例中,GPU 型号为 Tesla T4。

    lspci | grep NVIDIA 00:08.0 3D controller: NVIDIA Corporation TU104GL [Tesla T4] (rev a1)
  2. 访问 NVIDIA 官方网站 获取驱动下载链接。

    1. 点击首页顶部导航栏中的 Drivers

    2. 根据 GPU 节点型号填写下载驱动所需的信息。

    3. 点击 Search

    4. 点击 Download

    5. 右键点击 Download > Copy Link Address 复制驱动的下载链接。

  3. 在 GPU 节点上执行以下命令,创建 /home/gpu 目录,并将驱动文件下载并保存到该目录。

    # 创建 /home/gpu 目录 mkdir -p /home/gpu cd /home/gpu/ # 将驱动文件下载到 /home/gpu 目录,示例:wget https://cn.download.nvidia.com/tesla/515.65.01/NVIDIA-Linux-x86_64-515.65.01.run wget <驱动下载地址> # 验证驱动文件是否成功下载,如果返回驱动文件名(例如:NVIDIA-Linux-x86_64-515.65.01.run)则表示下载成功 ls <驱动文件名>

安装驱动

  1. 在 GPU 节点上执行以下命令,以安装与当前操作系统对应的 gcc 和 kernel-devel 包。

    sudo yum install dkms gcc kernel-devel-$(uname -r) -y
  2. 执行以下命令以安装 GPU 驱动。

    chmod a+x /home/gpu/<驱动文件名> /home/gpu/<驱动文件名> --dkms
  3. 安装完成后,执行 nvidia-smi 命令。如果返回类似以下示例的 GPU 信息,则表示驱动安装成功。

    # nvidia-smi Tue Sep 13 01:31:33 2022 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 515.65.01 Driver Version: 515.65.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 T4 Off | 00000000:00:08.0 Off | 0 | | N/A 55C P0 28W / 70W | 2MiB / 15360MiB | 5% Default | | | | N/A | +-------------------------------+-----------------------+---------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+

安装 NVIDIA 容器运行时

  1. GPU 节点 上添加 NVIDIA yum 仓库。

    distribution=$(. /etc/os-release;echo $ID$VERSION_ID) && curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.repo | sudo tee /etc/yum.repos.d/nvidia-container-toolkit.repo
    yum makecache -y
    

    当提示 "Metadata cache created." 出现时,表示添加成功。

  2. 安装 NVIDIA 容器运行时。

    yum install nvidia-container-toolkit -y
    

    当提示 Complete! 出现时,表示安装成功。

  3. 配置默认运行时。
    将以下配置添加到文件中。

    • Containerd: 修改 /etc/containerd/config.toml 文件。

      [plugins] [plugins."io.containerd.grpc.v1.cri"] [plugins."io.containerd.grpc.v1.cri".containerd] ... default_runtime_name = "nvidia" ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes] ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] runtime_type = "io.containerd.runc.v2" runtime_engine = "" runtime_root = "" privileged_without_host_devices = false base_runtime_spec = "" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia] privileged_without_host_devices = false runtime_engine = "" runtime_root = "" runtime_type = "io.containerd.runc.v1" [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.nvidia.options] BinaryName = "/usr/bin/nvidia-container-runtime" SystemdCgroup = true ...
    • Docker: 修改 /etc/docker/daemon.json 文件。

      { ... "default-runtime": "nvidia", "runtimes": { "nvidia": { "path": "/usr/bin/nvidia-container-runtime" } }, ... }
  4. 重启 Containerd / Docker。

    • Containerd

      systemctl restart containerd #重启 crictl info |grep Runtime #检查
    • Docker

      systemctl restart docker #重启 docker info |grep Runtime #检查

物理 GPU 配置

在 GPU 业务集群上部署物理 GPU 插件

在 GPU 集群的管理界面上执行以下操作:

  1. 在目录左侧栏中,选择 "集群插件" 子栏,单击部署 "ACP GPU 设备插件" 并打开 "pGPU" 选项;

  2. 在 "节点" 选项卡中,选择需要部署物理 GPU 的节点,然后单击 "标签和污点管理器",添加 "设备标签" 并选择 "pGPU",然后单击 OK;

  3. 在 "Pods" 选项卡中,检查与 nvidia-device-plugin-ds 对应的容器组运行状态,查看是否有异常,并确保它在指定节点上运行。

NVIDIA MPS 配置(驱动支持 CUDA 版本必须 >= 11.5)

在 GPU 业务集群上部署 NVIDIA MPS 插件

在 GPU 集群的管理界面上执行以下操作:

  1. 在目录左侧栏中,选择 "集群插件" 子栏,单击部署 "ACP GPU 设备插件" 并打开 "MPS" 选项;

  2. 在 "节点" 选项卡中,选择需要部署物理 GPU 的节点,然后单击 "标签和污点管理器",添加 "设备标签" 并选择 "MPS",然后单击 OK;

  3. 在 "Pods" 选项卡中,检查与 nvidia-mps-device-plugin-daemonset 对应的容器组运行状态,查看是否有异常,并确保它在指定节点上运行。

配置 kube-scheduler(kubernetes >= 1.23)

  1. 业务集群控制节点 上,检查调度程序是否正确引用调度策略。

    cat /etc/kubernetes/manifests/kube-scheduler.yaml

    检查是否有 –config 选项,并且值为 /etc/kubernetes/scheduler-config.yaml,如下

    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: null
      labels:
        component: kube-scheduler
        tier: control-plane
      name: kube-scheduler
      namespace: kube-system
    spec:
      containers:
      - command:
        - kube-scheduler
        - --config=/etc/kubernetes/scheduler-config.yaml
    

注意:上述参数和配置为平台的默认配置。如果您已修改它们,请改回默认值。可以将原始自定义配置复制到调度策略文件中。

  1. 检查调度策略文件的配置。

    1. 执行命令: kubectl describe service kubernetes -n default |grep Endpoints

      期望效果 Endpoints: 192.168.130.240:6443
    2. 将所有 Master 节点上/etc/kubernetes/scheduler-config.yaml文件的内容替换为以下内容,其中${kube-apiserver}应该替换为第一步的输出。

      apiVersion: kubescheduler.config.k8s.io/v1beta2 kind: KubeSchedulerConfiguration clientConnection: kubeconfig: /etc/kubernetes/scheduler.conf extenders: - enableHTTPS: true filterVerb: predicates managedResources: - ignoredByScheduler: false name: nvidia.com/mps-core nodeCacheCapable: false urlPrefix: https://${kube-apiserver}/api/v1/namespaces/kube-system/services/nvidia-mps-scheduler-plugin/proxy/scheduler tlsConfig: insecure: false certFile: /etc/kubernetes/pki/apiserver-kubelet-client.crt keyFile: /etc/kubernetes/pki/apiserver-kubelet-client.key caFile: /etc/kubernetes/pki/ca.crt

      如果 schedule-config.yaml文件中已存在 extenders,则将 yaml 附加到末尾

      - enableHTTPS: true filterVerb: predicates managedResources: - ignoredByScheduler: false name: nvidia.com/mps-core nodeCacheCapable: false urlPrefix: https://${kube-apiserver}/api/v1/namespaces/kube-system/services/nvidia-mps-scheduler-plugin/proxy/scheduler tlsConfig: insecure: false certFile: /etc/kubernetes/pki/apiserver-kubelet-client.crt keyFile: /etc/kubernetes/pki/apiserver-kubelet-client.key caFile: /etc/kubernetes/pki/ca.crt
  2. 运行以下命令以获取容器 ID:

    • Containerd:执行 crictl ps |grep kube-scheduler,输出如下,第一列为容器 ID。

      1d113ccf1c1a9 03c72176d0f15 2 seconds ago Running kube-scheduler 3 ecd054bbdd465 kube-scheduler-192.168.176.47
    • Docker:运行 docker ps |grep kube-scheduler,输出如下,第一列为容器 ID。

      30528a45a118 d8a9fef7349c "kube-scheduler --au..." 37 minutes ago Up 37 minutes k8s_kube-scheduler_kube-scheduler-192.168.130.240_kube-system_3e9f7007b38f4deb6ffd1c7587621009_28
  3. 使用上一步获得的容器 ID 重启 Containerd/Docker 容器。

    • Containerd

      crictl stop <容器 ID>
  4. 重启 Kubelet。

    systemctl restart kubelet

GPU 管理器配置

配置 kube-scheduler(kubernetes >= 1.23)

  1. 业务集群控制节点 上,检查调度程序是否正确引用调度策略。

    cat /etc/kubernetes/manifests/kube-scheduler.yaml

    检查是否有 –config 选项,并且值为 /etc/kubernetes/scheduler-config.yaml,如下所示

    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: null
      labels:
        component: kube-scheduler
        tier: control-plane
      name: kube-scheduler
      namespace: kube-system
    spec:
      containers:
      - command:
        - kube-scheduler
        - --config=/etc/kubernetes/scheduler-config.yaml
    

注意:上述参数和配置为平台的默认配置。如果您已修改它们,请改回默认值。可以将原始自定义配置复制到调度策略文件中。

  1. 检查调度策略文件的配置。

    1. 执行命令: kubectl describe service kubernetes -n default |grep Endpoints

      期望效果 Endpoints: 192.168.130.240:6443
    2. 将所有 Master 节点上/etc/kubernetes/scheduler-config.yaml文件的内容替换为以下内容,其中${kube-apiserver}应该替换为第一步的输出。

      apiVersion: kubescheduler.config.k8s.io/v1beta2 kind: KubeSchedulerConfiguration clientConnection: kubeconfig: /etc/kubernetes/scheduler.conf extenders: - enableHTTPS: true filterVerb: predicates managedResources: - ignoredByScheduler: false name: tencent.com/vcuda-core nodeCacheCapable: false urlPrefix: https://${kube-apiserver}/api/v1/namespaces/kube-system/services/gpu-quota-admission/proxy/scheduler tlsConfig: insecure: false certFile: /etc/kubernetes/pki/apiserver-kubelet-client.crt keyFile: /etc/kubernetes/pki/apiserver-kubelet-client.key caFile: /etc/kubernetes/pki/ca.crt
  2. 运行以下命令以获取容器 ID:

    • Containerd:执行 crictl ps |grep kube-scheduler,输出如下,第一列为容器 ID。

      1d113ccf1c1a9 03c72176d0f15 2 seconds ago Running kube-scheduler 3 ecd054bbdd465 kube-scheduler-192.168.176.47
    • Docker:运行 docker ps |grep kube-scheduler,输出如下,第一列为容器 ID。

      30528a45a118 d8a9fef7349c "kube-scheduler --au..." 37 minutes ago Up 37 minutes k8s_kube-scheduler_kube-scheduler-192.168.130.240_kube-system_3e9f7007b38f4deb6ffd1c7587621009_28
  3. 使用上一步获得的容器 ID 重启 Containerd/Docker 容器。

    • Containerd

      crictl stop <容器 ID>
  4. 重启 Kubelet。

    systemctl restart kubelet

在 GPU 业务集群上部署 GPU 管理器插件

在 GPU 集群的管理界面上执行以下操作:

  1. 在目录左侧栏中,选择 "集群插件" 子栏,单击部署 "ACP GPU 设备插件" 并打开 "GPU-管理器" 选项;

  2. 在 "节点" 选项卡中,选择需要部署物理 GPU 的节点,然后单击 "标签和污点管理器",添加 "设备标签" 并选择 "vGPU",然后单击 OK;

  3. 在 "Pods" 选项卡中,检查与 gpu-manager-daemonset 对应的容器组运行状态,查看是否有异常,并确保它在指定节点上运行。

结果验证

方法 1:在业务集群的控制节点上运行以下命令检查 GPU 节点上是否有可用的 GPU 资源:

kubectl get node ${nodeName} -o=jsonpath='{.status.allocatable}'

方法 2:在平台上通过指定所需的 GPU 资源量来部署 GPU 应用程序。部署后,进入 Pod 并执行以下命令:

# nvidia-smi Tue Sep 13 01:31:33 2022 +-----------------------------------------------------------------------------+ | NVIDIA-SMI 515.65.01 Driver Version: 515.65.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 T4 Off | 00000000:00:08.0 Off | 0 | | N/A 55C P0 28W / 70W | 2MiB / 15360MiB | 5% Default | | | | N/A | +-------------------------------+-----------------------+---------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+

检查是否正确检索到 GPU 信息。