GPU 环境搭建指南:使用 GPU Operator 加速 Kubernetes GPU 环境搭建

深入解析NVIDIA GPU Operator:实现Kubernetes环境下的GPU资源优化管理 NVIDIA GPU Operator凭借其对Kubernetes原生机制的深度整合,极大地简化了GPU资源在大规模集群环境中的管理工作。通过自动化部署、管理和监控GPU相关组件,不仅提高了集群的运营效率,也保障了GPU资源的充分利用,为深度学习、高性能计算等应用场景在云原生环境下的落地实践提供了坚实的基础支撑。:通过DCGMExporter,GPU Operator可以实时收集GPU的各种运行状态和性能数据,帮助运维人员及时发现并解决问题,确保GPU资源的高效利用和集群稳定性。 阅读详情
AI摘要

本文分享了使用GPU Operator快速搭建Kubernetes GPU环境的方法。介绍了GPU Operator涉及的组件及其作用,阐述了部署的准备工作、使用Helm部署的步骤和测试方法,还分析了Driver Installer和NVIDIA Container Toolkit Installer的原理。该工具简化了k8s中GPU的使用,但也有一定局限性。

gpu-operator.png

本文主要分享如何使用 GPU Operator 快速搭建 Kubernetes GPU 环境。


1. 概述

上一篇文章 GPU 使用指南:如何在裸机、Docker、K8s 等环境中使用 GPU 分享了裸机、Docker 环境以及 K8s 环境中如何使用 GPU。

整个流程还算比较简单,但是因为需要在节点上安装 GPU Driver、Container Toolkit 等组件,当集群规模较大时还是比较麻烦的。

为了解决这个问题,NVIDIA 推出了 GPU Operator],GPU Operator 旨在简化在 Kubernetes 环境中使用 GPU 的过程,通过自动化的方式处理 GPU 驱动程序安装、Controller Toolkit、Device-Plugin 、监控等组件。

基本上把需要手动安装、配置的地方全部自动化处理了,极大简化了 k8s 环境中的 GPU 使用。

ps:只有 NVIDIA GPU 可以使用,其他厂家现在基本还是手动安装。

2. 组件介绍

这部分主要分析下 GPU Operator 涉及到的各个组件及其作用。

NVIDIA GPU Operator总共包含如下的几个组件:

  • NFD(Node Feature Discovery):用于给节点打上某些标签,这些标签包括 cpu id、内核版本、操作系统版本、是不是 GPU 节点等,其中需要关注的标签是nvidia.com/gpu.present=true,如果节点存在该标签,那么说明该节点是 GPU 节点。
  • GFD(GPU Feature Discovery):用于收集节点的 GPU 设备属性(GPU 驱动版本、GPU型号等),并将这些属性以节点标签的方式透出。在k8s 集群中以 DaemonSet 方式部署,只有节点拥有标签nvidia.com/gpu.present=true时,DaemonSet 控制的 Pod 才会在该节点上运行。
  • NVIDIA Driver Installer:基于容器的方式在节点上安装 NVIDIA GPU 驱动,在 k8s 集群中以 DaemonSet 方式部署,只有节点拥有标签nvidia.com/gpu.present=true时,DaemonSet 控制的 Pod 才会在该节点上运行。
  • NVIDIA Container Toolkit Installer:能够实现在容器中使用 GPU 设备,在 k8s 集群中以 DaemonSet 方式部署,同样的,只有节点拥有标签nvidia.com/gpu.present=true时,DaemonSet 控制的 Pod 才会在该节点上运行。
  • NVIDIA Device Plugin:NVIDIA Device Plugin 用于实现将 GPU 设备以 Kubernetes 扩展资源的方式供用户使用,在 k8s 集群中以 DaemonSet 方式部署,只有节点拥有标签nvidia.com/gpu.present=true时,DaemonSet 控制的 Pod 才会在该节点上运行。
  • DCGM Exporter:周期性的收集节点 GPU 设备的状态(当前温度、总的显存、已使用显存、使用率等)并暴露 Metrics,结合 Prometheus 和 Grafana 使用。在 k8s 集群中以DaemonSet 方式部署,只有节点拥有标签nvidia.com/gpu.present=true时,DaemonSet 控制的 Pod 才会在该节点上运行。

首先是 GFD、NFD,二者都是用于发现 Node 上的信息,并以 label 形式添加到 k8s node 对象上,特别是 GFD 会添加nvidia.com/gpu.present=true 标签表示该节点有 GPU,只有携带该标签的节点才会安装后续组件。

然后则是 Driver Installer、Container Toolkit Installer 用于安装 GPU 驱动和 container toolkit。

接下来这是 device-plugin 让 k8s 能感知到 GPU 资源信息便于调度和管理。

最后的 exporter 则是采集 GPU 监控并以 Prometheus Metrics 格式暴露,用于做 GPU 监控。

这些组件基本就把需要手动配置的东西都自动化了。

NVIDIA GPU Operator 依如下的顺序部署各个组件,并且如果前一个组件部署失败,那么其后面的组件将停止部署:

  • NVIDIA Driver Installer
  • NVIDIA Container Toolkit Installer
  • NVIDIA Device Plugin
  • DCGM Exporter
  • GFD

每个组件都是以 DaemonSet 方式部署,并且只有当节点存在标签 nvidia.com/gpu.present=true 时,各 DaemonSet控制的 Pod 才会在节点上运行。

nvidia.com/gpu.deploy.driver=pre-installed

GFD & NFD

  • GFD:GPU Feature Discovery

  • NFD:Node Feature Discovery

根据名称基本能猜到这两个组件的功能,发现节点信息和 GPU 信息并以 Label 形式添加到 k8s 中的 node 对象上。

其中 NFD 添加的 label 以 feature.node.kubernetes.io 作为前缀,比如:

feature.node.kubernetes.io/cpu-cpuid.ADX=true
feature.node.kubernetes.io/system-os_release.ID=ubuntu
feature.node.kubernetes.io/system-os_release.VERSION_ID.major=22
feature.node.kubernetes.io/system-os_release.VERSION_ID.minor=04
feature.node.kubernetes.io/system-os_release.VERSION_ID=22.04

对于 GFD 则主要记录 GPU 信息

nvidia.com/cuda.runtime.major=12
nvidia.com/cuda.runtime.minor=2
nvidia.com/cuda.driver.major=535
nvidia.com/cuda.driver.minor=161
nvidia.com/gpu.product=Tesla-T4
nvidia.com/gpu.memory=15360

Driver Installer

NVIDIA 官方提供了一种基于容器安装 NVIDIA 驱动的方式,GPU Operator 安装 nvidia 驱动也是采用的这种方式。

当 NVIDIA 驱动基于容器化安装后,整个架构将演变成图中描述的样子:

gpu-operator-driver-container.png

Driver Installer 组件对应的 DaemonSet 就是nvidia-driver-daemonset-5.15.0-105-generic-ubuntu22.04。

该 DaemonSet 对应的镜像为

root@test:~# kgo get ds nvidia-driver-daemonset-5.15.0-105-generic-ubuntu22.04 -oyaml|grep image
        image: nvcr.io/nvidia/driver:535-5.15.0-105-generic-ubuntu22.04

其中 DaemonSet 名称/镜像由几部分组件:

  • nvidia-driver-daemonset 这部分为前缀
  • 5.15.0-105-generic 为内核版本,使用uname -r 命令查看
  • ubuntu22.04 操作系统版本,使用cat /etc/os-release 命令查看
  • 535:这个是 GPU Driver 的版本号,这里表示安装 535 版本驱动,在部署时可以指定。

GPU Operator 会自动根据节点上的内核版本和操作系统生成 DaemonSet 镜像,因为是以 DaemonSet 方式运行的,所有节点上都是跑的同一个 Pod,因此要限制集群中的所有 GPU 节点操作系统和内核版本必须一致。

ps:如果提前手动在节点上安装 GPU 驱动,那么 GPU Operator 检测到之后就不会在该节点上启动 Installer Pod,这样该节点就可以不需要管操作系统和内核版本。

NVIDIA Container Toolkit Installer

该组件用于安装 NVIDIA Container Toolkit。

手动安装的时候有两个步骤:

  • 1)安装 NVIDIA Container Toolkit
  • 2)修改 Runtime 配置指定使用 nvidia-runtime

在整个调用链中新增 nvidia-container-runtime,以便处理 GPU 相关操作。

nv-container-runtime-call-flow

这个 Installer 做的操作也就是这两步:

  • 1)将容器中NVIDIA Container Toolkit组件所涉及的命令行工具和库文件移动到/usr/local/nvidia/toolkit目录下
  • 2)在 /usr/local/nvidia/toolkit/.config/nvidia-container-runtime创建nvidia-container-runtime的配置文件config.toml,并设置nvidia-container-cli.root的值为/run/nvidia/driver。

3. 部署

参考官方文档: operator-install-guide

准备工作

要求:

1)GPU 节点必须运行相同的操作系统,

  • 如果提前手动在节点上安装驱动的话,该节点可以使用不同的操作系统
  • CPU 节点操作系统没要求,因为 gpu-operator 只会在 GPU 节点上运行

2)GPU 节点必须配置相同容器引擎,例如都是 containerd 或者都是 docker

3)如果使用了 Pod Security Admission (PSA) ,需要为 gpu-operator 标记特权模式

kubectl create ns gpu-operator
kubectl label --overwrite ns gpu-operator pod-security.kubernetes.io/enforce=privileged

4)集群中不要安装 NFD,如果已经安装了需要再安装 gpu-operator 时禁用 NFD 部署。

使用以下命令查看集群中是否部署 NFD

kubectl get nodes -o json | jq '.items[].metadata.labels | keys | any(startswith("feature.node.kubernetes.io"))'

如果返回 true 则说明集群中安装了 NFD。

使用 Helm 部署

官方文档:operator-install-guide

# 添加 nvidia helm 仓库并更新
helm repo add nvidia https://helm.ngc.nvidia.com/nvidia \
    && helm repo update
# 以默认配置安装
helm install --wait --generate-name \
    -n gpu-operator --create-namespace \
    nvidia/gpu-operator

# 如果提前手动安装了 gpu 驱动,operator 中要禁止 gpu 安装
helm install --wait --generate-name \
     -n gpu-operator --create-namespace \
     nvidia/gpu-operator \
     --set driver.enabled=false

完成后 会启动 Pod 安装驱动,如果节点上已经安装了驱动了,那么 gpu-operaotr 就不会启动安装驱动的 Pod,通过 label 进行筛选。

  • 没安装驱动的节点会打上 nvidia.com/gpu.deploy.driver=true ,表示需要安装驱动
  • 已经手动安装过驱动的节点会打上nvidia.com/gpu.deploy.driver=pre-install,Daemonset 则不会在该节点上运行

当然,并不是每个操作系统+内核版本的组合,NVIDIA 都提供了对应的镜像,可以提前在 NVIDIA/driver tags 查看当前 NVIDIA 提供的驱动版本。

测试

部署后,会在gpu-operator namespace 下启动相关 Pod,查看一下 Pod 的运行情况,除了一个 Completed 之外其他应该都是 Running 状态。

root@test:~# kubectl -n gpu-operator get po
NAME                                                           READY   STATUS      RESTARTS      AGE
gpu-feature-discovery-jdqpb                                    1/1     Running     0             35d
gpu-operator-67f8b59c9b-k989m                                  1/1     Running     6 (35d ago)   35d
nfd-node-feature-discovery-gc-5644575d55-957rp                 1/1     Running     6 (35d ago)   35d
nfd-node-feature-discovery-master-5bd568cf5c-c6t9s             1/1     Running     6 (35d ago)   35d
nfd-node-feature-discovery-worker-sqb7x                        1/1     Running     6 (35d ago)   35d
nvidia-container-toolkit-daemonset-rqgtv                       1/1     Running     0             35d
nvidia-cuda-validator-9kqnf                                    0/1     Completed   0             35d
nvidia-dcgm-exporter-8mb6v                                     1/1     Running     0             35d
nvidia-device-plugin-daemonset-7nkjw                           1/1     Running     0             35d
nvidia-driver-daemonset-5.15.0-105-generic-ubuntu22.04-g5dgx   1/1     Running     5 (35d ago)   35d
nvidia-operator-validator-6mqlm                                1/1     Running     0             35d

然后进入nvidia-driver-daemonset-xxx Pod,该 Pod 负责 GPU Driver 的安装,在该 Pod 中可以执行 nvidia-smi 命令,比如查看 GPU 信息:

root@j99cloudvm:~# kubectl -n gpu-operator exec -it nvidia-driver-daemonset-5.15.0-105-generic-ubuntu22.04-g5dgx -- nvidia-smi
Defaulted container "nvidia-device-plugin" out of: nvidia-device-plugin, config-manager, toolkit-validation (init), config-manager-init (init)
Wed Jul 17 01:49:35 2024
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 525.147.05   Driver Version: 525.147.05   CUDA Version: 12.0     |
|-------------------------------+----------------------+----------------------+
| 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  NVIDIA A40          Off  | 00000000:00:07.0 Off |                    0 |
|  0%   46C    P0    88W / 300W |    484MiB / 46068MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  NVIDIA A40          Off  | 00000000:00:08.0 Off |                    0 |
|  0%   48C    P0    92W / 300W |  40916MiB / 46068MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
+-----------------------------------------------------------------------------+

最后再查看 Pod 信息

$ kubectl get node xxx -oyaml
status:
  addresses:
  - address: 172.18.187.224
    type: InternalIP
  - address: izj6c5dnq07p1ic04ei9vwz
    type: Hostname
  allocatable:
    cpu: "4"
    ephemeral-storage: "189889991571"
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 15246720Ki
    nvidia.com/gpu: "1"
    pods: "110"
  capacity:
    cpu: "4"
    ephemeral-storage: 206043828Ki
    hugepages-1Gi: "0"
    hugepages-2Mi: "0"
    memory: 15349120Ki
    nvidia.com/gpu: "1"
    pods: "110"

确认 capacity 是否包含 GPU,正常应该是有的,比如这样:

  capacity:
    nvidia.com/gpu: "1"

至此,说明我们的 GPU Operator 已经安装成功,K8s 也能感知到节点上的 GPU,接下来就可以在 Pod 中使用 GPU 了。

创建一个测试 Pod,申请一个 GPU:

apiVersion: v1
kind: Pod
metadata:
  name: cuda-vectoradd
spec:
  restartPolicy: OnFailure
  containers:
  - name: cuda-vectoradd
    image: "nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda11.7.1-ubuntu20.04"
    resources:
      limits:
        nvidia.com/gpu: 1

正常的 Pod 日志如下:

$ kubectl logs pod/cuda-vectoradd
[Vector addition of 50000 elements]
Copy input data from the host memory to the CUDA device
CUDA kernel launch with 196 blocks of 256 threads
Copy output data from the CUDA device to the host memory
Test PASSED
Done

至此,我们已经可以在 k8s 中使用 GPU 了。

4. 原理

这部分主要分析一下 Driver Installer 和 NVIDIA Container Toolkit Installer 这两个组件是怎么实现的,大致原理。

Driver Installer

NVIDIA 官方提供了一种基于容器安装 NVIDIA 驱动的方式,GPU Operator 安装 nvidia 驱动也是采用的这种方式。

当 NVIDIA 驱动基于容器化安装后,整个架构将演变成图中描述的样子:

gpu-operator-driver-container.png

安装

Driver Installer 组件对应的 DaemonSet 就是nvidia-driver-daemonset-5.15.0-105-generic-ubuntu22.04。

该 DaemonSet 对应的镜像为

root@test:~# kgo get ds nvidia-driver-daemonset-5.15.0-105-generic-ubuntu22.04 -oyaml|grep image
        image: nvcr.io/nvidia/driver:535-5.15.0-105-generic-ubuntu22.04

其中 DaemonSet 名称/镜像由几部分组件:

  • nvidia-driver-daemonset 这部分为前缀
  • 5.15.0-105-generic 为内核版本,使用uname -r 命令查看
  • ubuntu22.04 操作系统版本,使用cat /etc/os-release 命令查看
  • 535:这个是 GPU Driver 的版本号,这里表示安装 535 版本驱动,在部署时可以指定。

查看一下 Pod 日志:

root@test:~# kubectl -n gpu-operaator logs -f nvidia-driver-daemonset-5.15.0-105-generic-ubuntu22.04-g5dgx

========== NVIDIA Software Installer ==========

Starting installation of NVIDIA driver branch 535 for Linux kernel version 5.15.0-105-generic

Stopping NVIDIA persistence daemon...
Unloading NVIDIA driver kernel modules...
Unmounting NVIDIA driver rootfs...
Installing NVIDIA driver kernel modules...
Reading package lists...
Building dependency tree...
Reading state information...
The following packages were automatically installed and are no longer required:
 ...
Setting up linux-modules-nvidia-535-server-5.15.0-105-generic (5.15.0-105.115+1) ...
linux-image-nvidia-5.15.0-105-generic: constructing .ko files
nvidia-drm.ko: OK
nvidia-modeset.ko: OK
nvidia-peermem.ko: OK
nvidia-uvm.ko: OK
nvidia.ko: OK
Processing triggers for linux-image-5.15.0-105-generic (5.15.0-105.115) ...
/etc/kernel/postinst.d/dkms:
 * dkms: running auto installation service for kernel 5.15.0-105-generic
   ...done.
Parsing kernel module parameters...
Loading ipmi and i2c_core kernel modules...
Loading NVIDIA driver kernel modules...
+ modprobe nvidia
+ modprobe nvidia-uvm
+ modprobe nvidia-modeset
+ set +o xtrace -o nounset
Starting NVIDIA persistence daemon...
Mounting NVIDIA driver rootfs...
Done, now waiting for signal

可以看到,先是在安装驱动,安装完成后又加载了一些内核模块。

为了实现在容器中安装驱动,该 Pod 通过 hostPath 将安装驱动相关的目录都挂载到容器中了,

      volumes:
      - hostPath:
          path: /run/nvidia
          type: DirectoryOrCreate
        name: run-nvidia
      - hostPath:
          path: /etc/os-release
          type: ""
        name: host-os-release
      - hostPath:
          path: /run/nvidia-topologyd
          type: DirectoryOrCreate
        name: run-nvidia-topologyd
        name: run-mellanox-drivers
      - hostPath:
          path: /run/nvidia/validations
          type: DirectoryOrCreate
        name: run-nvidia-validations
      - hostPath:
          path: /sys
          type: Directory
镜像构建

根据 Dockerfile 来看下镜像是怎么构建的,以 CentOS8 的 Dockerfile 为例

文件来自:https://gitlab.com/nvidia/container-images/driver/-/blob/master/centos8/Dockerfile

FROM nvidia/cuda:11.4.1-base-centos8

ENV NVIDIA_VISIBLE_DEVICES=void

RUN NVIDIA_GPGKEY_SUM=d0664fbbdb8c32356d45de36c5984617217b2d0bef41b93ccecd326ba3b80c87 && \
    curl -fsSL https://developer.download.nvidia.com/compute/cuda/repos/rhel8/x86_64/D42D0685.pub | sed '/^Version/d' > /etc/pki/rpm-gpg/RPM-GPG-KEY-NVIDIA && \
    echo "$NVIDIA_GPGKEY_SUM  /etc/pki/rpm-gpg/RPM-GPG-KEY-NVIDIA" | sha256sum -c --strict -

#首先安装一些依赖
RUN dnf install -y \
        ca-certificates \
        curl \
        gcc \
        glibc.i686 \
        make \
        dnf-utils \
        kmod && \
    rm -rf /var/cache/dnf/*

RUN curl -fsSL -o /usr/local/bin/donkey https://github.com/3XX0/donkey/releases/download/v1.1.0/donkey && \
    curl -fsSL -o /usr/local/bin/extract-vmlinux https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux && \
    chmod +x /usr/local/bin/donkey /usr/local/bin/extract-vmlinux

#ARG BASE_URL=http://us.download.nvidia.com/XFree86/Linux-x86_64
ARG BASE_URL=https://us.download.nvidia.com/tesla
ARG DRIVER_VERSION
ENV DRIVER_VERSION=$DRIVER_VERSION

# 然后下载驱动文件并安装,注意 --no-kernel-module,这里只安装了 userspace 部分
RUN cd /tmp && \
    curl -fSsl -O $BASE_URL/$DRIVER_VERSION/NVIDIA-Linux-x86_64-$DRIVER_VERSION.run && \
    sh NVIDIA-Linux-x86_64-$DRIVER_VERSION.run -x && \
    cd NVIDIA-Linux-x86_64-$DRIVER_VERSION && \
    ./nvidia-installer --silent \
                       --no-kernel-module \
                       --install-compat32-libs \
                       --no-nouveau-check \
                       --no-nvidia-modprobe \
                       --no-rpms \
                       --no-backup \
                       --no-check-for-alternate-installs \
                       --no-libglx-indirect \
                       --no-install-libglvnd \
                       --x-prefix=/tmp/null \
                       --x-module-path=/tmp/null \
                       --x-library-path=/tmp/null \
                       --x-sysconfig-path=/tmp/null && \
    mkdir -p /usr/src/nvidia-$DRIVER_VERSION && \
    mv LICENSE mkprecompiled kernel /usr/src/nvidia-$DRIVER_VERSION && \
    sed '9,${/^\(kernel\|LICENSE\)/!d}' .manifest > /usr/src/nvidia-$DRIVER_VERSION/.manifest && \
    rm -rf /tmp/*

COPY nvidia-driver /usr/local/bin

WORKDIR /usr/src/nvidia-$DRIVER_VERSION

ARG PUBLIC_KEY=empty
COPY ${PUBLIC_KEY} kernel/pubkey.x509

ARG PRIVATE_KEY

# Remove cuda repository to avoid GPG errors
RUN rm -f /etc/yum.repos.d/cuda.repo

# Add NGC DL license from the CUDA image
RUN mkdir /licenses && mv /NGC-DL-CONTAINER-LICENSE /licenses/NGC-DL-CONTAINER-LICENSE

ENTRYPOINT ["nvidia-driver", "init"]

最后执行的 nvidia-driver 是一个脚本文件,init 部分内容如下:

init() {
    echo -e "\n========== NVIDIA Software Installer ==========\n"
    echo -e "Starting installation of NVIDIA driver version ${DRIVER_VERSION} for Linux kernel version ${KERNEL_VERSION}\n"

    exec 3> ${PID_FILE}
    if ! flock -n 3; then
        echo "An instance of the NVIDIA driver is already running, aborting"
        exit 1
    fi
    echo $$ >&3

    trap "echo 'Caught signal'; exit 1" HUP INT QUIT PIPE TERM
    trap "_shutdown" EXIT

    _unload_driver || exit 1
    _unmount_rootfs

    if _kernel_requires_package; then
        _update_package_cache
        _resolve_kernel_version || exit 1
        _install_prerequisites
        _create_driver_package
        #_remove_prerequisites
        _cleanup_package_cache
    fi

    _install_driver
    _load_driver
    _mount_rootfs
    _write_kernel_update_hook

    echo "Done, now waiting for signal"
    sleep infinity &
    trap "echo 'Caught signal'; _shutdown && { kill $!; exit 0; }" HUP INT QUIT PIPE TERM
    trap - EXIT
    while true; do wait $! || continue; done
    exit 0
}

然后_install_driver 部分在安装驱动,因为之前构建镜像时就安装了 userspace 部分,因此这里指定了--kernel-module-only 来限制安装驱动部分。

这也是为什么容器方式安装很快,因为在构建镜像时就不 驱动的 userspace 部分安装好了。

# Link and install the kernel modules from a precompiled package using the nvidia-installer.
_install_driver() {
    local install_args=()

    echo "Installing NVIDIA driver kernel modules..."
    cd /usr/src/nvidia-${DRIVER_VERSION}
    rm -rf /lib/modules/${KERNEL_VERSION}/video

    if [ "${ACCEPT_LICENSE}" = "yes" ]; then
        install_args+=("--accept-license")
    fi
    nvidia-installer --kernel-module-only --no-drm --ui=none --no-nouveau-check ${install_args[@]+"${install_args[@]}"}
}

_load_driver 加载相关内核模块

# Load the kernel modules and start persistenced.
_load_driver() {
    echo "Loading ipmi and i2c_core kernel modules..."
    modprobe -a i2c_core ipmi_msghandler ipmi_devintf

    echo "Loading NVIDIA driver kernel modules..."
    modprobe -a nvidia nvidia-uvm nvidia-modeset

    echo "Starting NVIDIA persistence daemon..."
    nvidia-persistenced --persistence-mode
}

_mount_rootfs 将驱动程序挂载到 /var/run 目录下

# Mount the driver rootfs into the run directory with the exception of sysfs.
_mount_rootfs() {
    echo "Mounting NVIDIA driver rootfs..."
    mount --make-runbindable /sys
    mount --make-private /sys
    mkdir -p ${RUN_DIR}/driver
    mount --rbind / ${RUN_DIR}/driver
}

这就是驱动安装的部分流程,和我们看到的 Pod 日志也是匹配的。

卸载的话就是相反的操作了。

NVIDIA Container Toolkit Installer

该组件用于安装 NVIDIA Container Toolkit。

手动安装的时候有两个步骤:

  • 1)安装 NVIDIA Container Toolkit
  • 2)修改 Runtime 配置指定使用 nvidia-runtime

在整个调用链中新增 nvidia-container-runtime,以便处理 GPU 相关操作。

nv-container-runtime-call-flow

这个 Installer 做的操作也就是这两步:

  • 1)将容器中NVIDIA Container Toolkit组件所涉及的命令行工具和库文件移动到/usr/local/nvidia/toolkit目录下
  • 2)在 /usr/local/nvidia/toolkit/.config/nvidia-container-runtime创建nvidia-container-runtime的配置文件config.toml,并设置nvidia-container-cli.root的值为/run/nvidia/driver。
安装

该 Installer 对应的 DaemonSet 为nvidia-container-toolkit-daemonset。

Pod 启动命令如下:

      containers:
      - args:
        - /bin/entrypoint.sh
        command:
        - /bin/bash
        - -c      

这个entrypoint.sh内容存放在nvidia-container-toolkit-entrypoint Configmap 中,内容如下:

apiVersion: v1
data:
  entrypoint.sh: |-
    #!/bin/bash

    set -e

    driver_root=/run/nvidia/driver
    driver_root_ctr_path=$driver_root
    if [[ -f /run/nvidia/validations/host-driver-ready ]]; then
      driver_root=/
      driver_root_ctr_path=/host
    fi

    export NVIDIA_DRIVER_ROOT=$driver_root
    export DRIVER_ROOT_CTR_PATH=$driver_root_ctr_path

    #
    # The below delay is a workaround for an issue affecting some versions
    # of containerd starting with 1.6.9. Staring with containerd 1.6.9 we
    # started seeing the toolkit container enter a crashloop whereby it
    # would recieve a SIGTERM shortly after restarting containerd.
    #
    # Refer to the commit message where this workaround was implemented
    # for additional details:
    #   https://github.com/NVIDIA/gpu-operator/commit/963b8dc87ed54632a7345c1fcfe842f4b7449565
    #
    sleep 5

    exec nvidia-toolkit

设置了驱动相关环境变量,真正执行配置的是exec nvidia-toolkit 这一句。

该同样使用 hostPath 方式把宿主机目录挂载到容器中,便于对宿主机上的内容进行修改。

      volumes:
      - hostPath:
          path: /run/nvidia
          type: DirectoryOrCreate
        name: nvidia-run-path
      - hostPath:
          path: /run/nvidia/validations
          type: DirectoryOrCreate
        name: run-nvidia-validations
      - hostPath:
          path: /run/nvidia/driver
          type: ""
        name: driver-install-path
        name: host-root
      - hostPath:
          path: /usr/local/nvidia
          type: ""
        name: toolkit-install-dir
      - hostPath:
          path: /run/containers/oci/hooks.d
          type: ""
        name: crio-hooks
      - hostPath:
          path: /dev/char
          type: ""
        name: host-dev-char
      - hostPath:
          path: /var/run/cdi
          type: DirectoryOrCreate
        name: cdi-root
      - hostPath:
          path: /etc/docker
          type: DirectoryOrCreate
        name: docker-config
      - hostPath:
          path: /var/run
          type: ""
        name: docker-socket

查看 Pod 日志,看看安装流程

root@test:~# kubectl -n gpu-operator logs -f nvidia-container-toolkit-daemonset-rqgtv
# 安装 container toolkit
time="2024-06-12T02:07:58Z" level=info msg="Parsing arguments"
time="2024-06-12T02:07:58Z" level=info msg="Starting nvidia-toolkit"
time="2024-06-12T02:07:58Z" level=info msg="Verifying Flags"
time="2024-06-12T02:07:58Z" level=info msg=Initializing
time="2024-06-12T02:07:58Z" level=info msg="Installing toolkit"
time="2024-06-12T02:07:58Z" level=info msg="Installing NVIDIA container toolkit to '/usr/local/nvidia/toolkit'"

# 修改配置
time="2024-06-12T02:07:58Z" level=info msg="Installing NVIDIA container toolkit config '/usr/local/nvidia/toolkit/.config/nvidia-container-runtime/config.toml'"
time="2024-06-12T02:07:58Z" level=info msg="Skipping unset option: nvidia-container-runtime.debug"
time="2024-06-12T02:07:58Z" level=info msg="Skipping unset option: nvidia-container-runtime.log-level"
time="2024-06-12T02:07:58Z" level=info msg="Skipping unset option: nvidia-container-runtime.mode"
time="2024-06-12T02:07:58Z" level=info msg="Skipping unset option: nvidia-container-runtime.modes.cdi.annotation-prefixes"
time="2024-06-12T02:07:58Z" level=info msg="Skipping unset option: nvidia-container-runtime.runtimes"
time="2024-06-12T02:07:58Z" level=info msg="Skipping unset option: nvidia-container-cli.debug"
Using config:
accept-nvidia-visible-devices-as-volume-mounts = false
accept-nvidia-visible-devices-envvar-when-unprivileged = true
disable-require = false

[nvidia-container-cli]
  environment = []
  ldconfig = "@/run/nvidia/driver/sbin/ldconfig.real"
  load-kmods = true
  path = "/usr/local/nvidia/toolkit/nvidia-container-cli"
  root = "/run/nvidia/driver"

[nvidia-container-runtime]
  log-level = "info"
  mode = "auto"
  runtimes = ["docker-runc", "runc"]

  [nvidia-container-runtime.modes]

    [nvidia-container-runtime.modes.cdi]
      default-kind = "management.nvidia.com/gpu"

    [nvidia-container-runtime.modes.csv]
      mount-spec-path = "/etc/nvidia-container-runtime/host-files-for-container.d"

[nvidia-container-runtime-hook]
  path = "/usr/local/nvidia/toolkit/nvidia-container-runtime-hook"
  skip-mode-detection = true

[nvidia-ctk]
  path = "/usr/local/nvidia/toolkit/nvidia-ctk"
time="2024-06-12T02:07:58Z" level=info msg="Setting up runtime"
time="2024-06-12T02:07:58Z" level=info msg="Parsing arguments: [/usr/local/nvidia/toolkit]"
time="2024-06-12T02:07:58Z" level=info msg="Successfully parsed arguments"
time="2024-06-12T02:07:58Z" level=info msg="Starting 'setup' for docker"
time="2024-06-12T02:07:58Z" level=info msg="Loading docker config from /runtime/config-dir/daemon.json"
time="2024-06-12T02:07:58Z" level=info msg="Successfully loaded config"
time="2024-06-12T02:07:58Z" level=info msg="Flushing config to /runtime/config-dir/daemon.json"

和手动安装类似,分为两步。

查看宿主机上 Docker 的配置文件,也确实是被修改过的,default-runtime 改成了 nvidia。

root@test:~# cat /etc/docker/daemon.json
{
    "data-root": "/var/lib/docker",
    "default-runtime": "nvidia",
    "exec-opts": [
        "native.cgroupdriver=systemd"
    ],
    "log-driver": "json-file",
    "log-opts": {
        "max-file": "3",
        "max-size": "100m"
    },
    "registry-mirrors": [
        "https://docker.chenby.cn"
    ],
    "runtimes": {
        "nvidia": {
            "args": [],
            "path": "/usr/local/nvidia/toolkit/nvidia-container-runtime"
        },
        "nvidia-cdi": {
            "args": [],
            "path": "/usr/local/nvidia/toolkit/nvidia-container-runtime.cdi"
        },
        "nvidia-experimental": {
            "args": [],
            "path": "/usr/local/nvidia/toolkit/nvidia-container-runtime.experimental"
        },
        "nvidia-legacy": {
            "args": [],
            "path": "/usr/local/nvidia/toolkit/nvidia-container-runtime.legacy"
        }
    },
    "storage-driver": "overlay2",
    "storage-opts": [
        "overlay2.override_kernel_check=true"
    ]
}

这就是 NVIDIA Container Toolkit Installer 的安装部分,具体代码实现可以看下一节 镜像构建 部分。

镜像构建

Installer 代码合并到了 nvidia-container-toolkit 仓库 tools 目录,分别为不同的 Runtime 做了不同的实现,比如 Containerd 的实现就在 containerd.go 中,部分代码如下:

// Setup updates a containerd configuration to include the nvidia-containerd-runtime and reloads it
func Setup(c *cli.Context, o *options) error {
	log.Infof("Starting 'setup' for %v", c.App.Name)

	cfg, err := containerd.New(
		containerd.WithPath(o.Config),
		containerd.WithRuntimeType(o.runtimeType),
		containerd.WithUseLegacyConfig(o.useLegacyConfig),
		containerd.WithContainerAnnotations(o.containerAnnotationsFromCDIPrefixes()...),
	)
	if err != nil {
		return fmt.Errorf("unable to load config: %v", err)
	}

	runtimeConfigOverride, err := o.runtimeConfigOverride()
	if err != nil {
		return fmt.Errorf("unable to parse config overrides: %w", err)
	}
	err = o.Configure(cfg, runtimeConfigOverride)
	if err != nil {
		return fmt.Errorf("unable to configure containerd: %v", err)
	}

	err = RestartContainerd(o)
	if err != nil {
		return fmt.Errorf("unable to restart containerd: %v", err)
	}

	log.Infof("Completed 'setup' for %v", c.App.Name)

	return nil
}
// Cleanup reverts a containerd configuration to remove the nvidia-containerd-runtime and reloads it
func Cleanup(c *cli.Context, o *options) error {
	log.Infof("Starting 'cleanup' for %v", c.App.Name)

	cfg, err := containerd.New(
		containerd.WithPath(o.Config),
		containerd.WithRuntimeType(o.runtimeType),
		containerd.WithUseLegacyConfig(o.useLegacyConfig),
		containerd.WithContainerAnnotations(o.containerAnnotationsFromCDIPrefixes()...),
	)
	if err != nil {
		return fmt.Errorf("unable to load config: %v", err)
	}

	err = o.Unconfigure(cfg)
	if err != nil {
		return fmt.Errorf("unable to unconfigure containerd: %v", err)
	}

	err = RestartContainerd(o)
	if err != nil {
		return fmt.Errorf("unable to restart containerd: %v", err)
	}

	log.Infof("Completed 'cleanup' for %v", c.App.Name)

	return nil
}

其中

  • Setup 为修改 Runtime 配置,增加 nvidia runtime
  • Cleanup 则是取消 Runtime 配置中 nvidia runtime

对应的 Dockerfile内容如下:

# Copyright (c) 2019-2021, NVIDIA CORPORATION.  All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

ARG GOLANG_VERSION=x.x.x
ARG VERSION="N/A"

FROM nvidia/cuda:12.5.1-base-ubi8 as build

RUN yum install -y \
    wget make git gcc \
     && \
    rm -rf /var/cache/yum/*

ARG GOLANG_VERSION=x.x.x
RUN set -eux; \
    \
    arch="$(uname -m)"; \
    case "${arch##*-}" in \
        x86_64 | amd64) ARCH='amd64' ;; \
        ppc64el | ppc64le) ARCH='ppc64le' ;; \
        aarch64 | arm64) ARCH='arm64' ;; \
        *) echo "unsupported architecture" ; exit 1 ;; \
    esac; \
    wget -nv -O - https://storage.googleapis.com/golang/go${GOLANG_VERSION}.linux-${ARCH}.tar.gz \
    | tar -C /usr/local -xz


ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH

WORKDIR /build
COPY . .

# NOTE: Until the config utilities are properly integrated into the
# nvidia-container-toolkit repository, these are built from the `tools` folder
# and not `cmd`.
RUN GOPATH=/artifacts go install -ldflags="-s -w -X 'main.Version=${VERSION}'" ./tools/...


FROM nvidia/cuda:12.5.1-base-ubi8

ENV NVIDIA_DISABLE_REQUIRE="true"
ENV NVIDIA_VISIBLE_DEVICES=void
ENV NVIDIA_DRIVER_CAPABILITIES=utility

ARG ARTIFACTS_ROOT
ARG PACKAGE_DIST
COPY ${ARTIFACTS_ROOT}/${PACKAGE_DIST} /artifacts/packages/${PACKAGE_DIST}

WORKDIR /artifacts/packages

ARG PACKAGE_VERSION
ARG TARGETARCH
ENV PACKAGE_ARCH ${TARGETARCH}
RUN PACKAGE_ARCH=${PACKAGE_ARCH/amd64/x86_64} && PACKAGE_ARCH=${PACKAGE_ARCH/arm64/aarch64} && \
    yum localinstall -y \
    ${PACKAGE_DIST}/${PACKAGE_ARCH}/libnvidia-container1-1.*.rpm \
    ${PACKAGE_DIST}/${PACKAGE_ARCH}/libnvidia-container-tools-1.*.rpm \
    ${PACKAGE_DIST}/${PACKAGE_ARCH}/nvidia-container-toolkit*-${PACKAGE_VERSION}*.rpm

WORKDIR /work

COPY --from=build /artifacts/bin /work

ENV PATH=/work:$PATH

LABEL io.k8s.display-name="NVIDIA Container Runtime Config"
LABEL name="NVIDIA Container Runtime Config"
LABEL vendor="NVIDIA"
LABEL version="${VERSION}"
LABEL release="N/A"
LABEL summary="Automatically Configure your Container Runtime for GPU support."
LABEL description="See summary"

RUN mkdir /licenses && mv /NGC-DL-CONTAINER-LICENSE /licenses/NGC-DL-CONTAINER-LICENSE

ENTRYPOINT ["/work/nvidia-toolkit"]

这部分比较简单,就是编译生成二进制文件,以及安装部分依赖的 RPM 包。


**【Kubernetes 系列】**持续更新中,搜索公众号【探索云原生】订阅,阅读更多文章。


5. 小结

本文主要分享如何使用 GPU Operator 自动化完成 GPU Driver、NVIDIA Container Toolkit、device-plugin、exporter 等组件的部署,快速实现在 k8s 环境中使用 GPU。

最后简单分析了 Driver Installer 和 NVIDIA Container Toolkit Installer 这两个组件的工作原理。


GPU Operator 极大简化了在 k8s 中使用 GPU 的繁琐过程,但是也存在一些缺点:

  • Driver Installer 以 DaemonSet 方式运行的,每个节点上运行的 Pod 都一样,但是镜像由 驱动版本+内核版本+操作系统版本拼接而成,因此需要集群中所有节点操作系统一致。
  • NVIDIA Container Toolkit Installer 同样是以 DaemonSet 方式运行的,另外安装时需要指定 Runtime,这也造成了集群的节点必须安装相同的 Container Runtime。
在 KubeVirt 中使用 GPU Operator KubeVirt 是 Kubernetes 的一个虚拟机管理插件,允许您在 Kubernetes 集群中运行和管理虚拟机。它消除了为虚拟机和容器工作负载管理独立集群的需求,二者现在可以在单一 Kubernetes 集群中共存。在此之前,GPU Operator 仅支持为运行 GPU 加速的容器配置工作节点。现在,GPU Operator 也可以用于为运行 GPU 加速的虚拟机配置工作节点。运行带有 GPU 的容器和虚拟机所需的前提条件不同,主要区别在于所需的驱动程序。 阅读详情

相关推荐

NVIDIA GPU Operator简易说明

中发现GPU,需要安装驱动、部署device plugin等一系列操作,使用GPU。方案,MPS方案目前可以单独试用部署,相信很快会集成到Operator中。的方式对节点单独设置驱动型号,驱动版本推荐见。个人经验是推荐使用较高版本。Operator可以。

2401_83124266的博客 1504

nvidia gpu-operator

用于给集群环境调度 gpu ,由 n 个子组件组成。分别如下描述: GPU Operator 是一个 Kubernetes Operator,用于自动化 NVIDIA GPU 的配置和管理。它可以部署、管理和监控 GPU 驱动、容器工具包、设备插件等组件。作用: 负责协调和管理整个 GPU Operator 的运行,确保 GPU 相关的组件都正确部署和配置。描述: 这个组件通常与 Node Feature Discovery (NFD) 相关,可能用于清理或管理节点特征信息。

weixin_46546444的博客 2297

KubeVirt下gpu operator实践(GPU直通)

参考《在 KubeVirt 中使用 GPU Operator》,记录gpu operator在KubeVirt下实践的过程,包括虚拟机配置GPU直通,容器挂载GPU设备等。KubeVirt 提供了一种将主机设备分配给虚拟机的机制。该机制具有通用性,支持分配各种类型的 PCI 设备,例如加速器(包括 GPU)或其他连接到 PCI 总线的设备。

lldhsds的专栏 1675

GPU 环境搭建指南:使用 GPU Operator 加速 (k8s)Kubernetes GPU 环境搭建

上一篇文章 GPU 使用指南:如何在裸机、Docker、K8s 等环境中使用 GPU[1] 分享了裸机、Docker 环境以及 K8s 环境中如何使用 GPU。整个流程还算比较简单,但是因为需要在节点上安装 GPU Driver、Container Toolkit 等组件,当集群规模较大时还是比较麻烦的。为了解决这个问题,NVIDIA 推出了 GPU Operator[2],

Richardlygo的博客 1283

KubeVirt 与 GPU Operator 的深度集成:实现虚拟机 GPU 加速的完整指南

本文详细介绍了KubeVirt与GPU Operator的深度集成方案,实现虚拟机GPU加速的完整指南。通过解析核心组件、安装配置步骤及优化技巧,帮助用户在Kubernetes集群中高效管理GPU资源,提升容器和虚拟机工作负载的性能与资源利用率。特别适用于需要GPU加速的AI训练和虚拟化应用场景。

weixin_42531923的博客 325

vcenter server6.0上vmware inventory 、virtualvcenter等服务无法开启

描述:一天,vcenter访问不了,因此Windows远程到vcenter server上。相关服务未开启,开启virtualCenter server服务提示相关依赖服务未开启,于是开启依赖项服务Inventory服务报错。然后打算使用 C:\Program Files\VMware\vCenter Server\bin\servcivce-control来开启vmware服务 1....

Pespi_Co1a的博客 3069

在 Kubernetes(k8s)集群中部署AI大模型 ollama并启用GPU加速

进入 Ollama 服务对应的 pod 内部,执行 ollama run llama3 命令进行模型安装。若提前构建了模型的镜像并在部署步骤中进行了部署,则可省略此手动安装步骤。命令,即可获取模型对职场冲突处理相关问题的回答,展示了 Ollama 服务在 Kubernetes 环境中正常运行并能够对外提供大模型服务的能力。模型安装完成后,在 namespace 下的其他 pod 中可通过 curl 命令向 Ollama 服务请求已安装的模型。:在本教程中,Ollama 只会使用 1 个 GPU。

进击的Blazor 6255

VoLTE吞字断续优化方案

网络侧通过各节点探针的数据采集,能够进行RTP和RTCP包的分析,确定各节点的上行或下行丢包情况。1.基于测试语音分析,每2秒中大约8个字,每个字约10个RTP语音包。通话过程中,语音有短暂停顿,收音段听语音中会出现“吞字/断续现象”2.连续丢3~5个RTP以上就可能会出现吞字断续的感觉。下行评价的丢包问题,很难有效指导定界定位分析,无从下手。2.部分终端可能存在RTCP不反馈,导致无法获取丢包。1.语音包为UDP包,无反馈,终端无法判定是否丢包。终端可依据自身的调度反馈或弃包进行上行丢包判决。

m0_73503557的博客 1512

NVIDIA GPU Operator完整安装指南:从零开始部署GPU加速的Kubernetes集群

NVIDIA GPU Operator是Kubernetes生态系统中革命性的工具,它通过Operator框架自动化管理所有NVIDIA软件组件,让GPU资源在Kubernetes集群中的部署变得前所未有的简单。🚀 本文将为您提供从零开始的完整安装指南,帮助您快速搭建GPU加速的Kubernetes环境。 ## 📋 前置条件与系统要求 在开始安装之前,请确保您的环境满足以下要求: - *

gitblog_00896的博客 1204

MuJoCo与Isaac Sim的无缝对接:利用USD导出功能实现强化学习场景的跨平台迁移

本文详细介绍了如何通过USD导出功能实现MuJoCo与Isaac Sim的无缝对接,助力强化学习场景的跨平台迁移。文章解析了USD格式的核心优势,包括分层合成、物理属性继承和时间轴动画,并提供了从MJCF到USD的完整转换流程及在Isaac Sim中的高级应用技巧,帮助开发者高效迁移和优化强化学习环境。

weixin_29073241的博客 517

FPGA新手避坑指南:手把手教你搞定RTL8211千兆网PHY的时序配置(附Verilog代码)

本文详细解析了FPGA与RTL8211千兆网PHY芯片的时序配置问题,重点介绍了TXDLY/RXDLY引脚设置、FPGA发送端和接收端的Verilog实现,以及调试与验证的完整流程。通过硬件电路设计和代码示例,帮助开发者解决网络连接不稳定、丢包等常见问题,提升千兆网通信的稳定性。

weixin_28732953的博客 542

k8s-nim-operator:加速AI微服务部署与管理

k8s-nim-operator:加速AI微服务部署与管理 在当今快速发展的云计算和人工智能领域,Kubernetes已成为容器编排的标准工具。而在此之上,NVIDIA推出的k8s-nim-operator项目,为Kubernetes集群中的AI微服务部署与管理提供了强大的支持。 项目介绍 k8s-nim-operator是一个Kubernetes Operator,专门设计用于简化NVIDIA ...

gitblog_00029的博客 1020

自动驾驶仿真 (三)—— 基于PreScan与Simulink的AEB系统仿真

自动驾驶仿真三—— 基于PreScan&Simulink的AEB系统仿真1. AEB自动紧急制动系统1. 1 TTC碰撞时间模型1. 2 C-NCAP法规部分术语与定义1. 3 主动安全ADAS系统试验项目2. AEB仿真分析建模2.1 搭建场景2.2 传感器建模2.3 添加AEB控制系统3. 典型工况仿真3.1 CCRs仿真测试3.1 CCRm仿真测试4. 参考学习的书目教材 博主前面的博文已经介绍了Prescan&Simulink基本的场景建模及仿真分析流程,《自动驾驶仿真 (二)——

zhudj08的博客 1万+

如何使用NVIDIA GPU Operator:简化Kubernetes集群GPU管理的完整指南

NVIDIA GPU Operator是一款强大的工具,它能够在Kubernetes集群上自动创建、配置和管理GPU资源,帮助用户轻松实现GPU在容器环境中的高效利用。无论是AI训练、深度学习还是高性能计算场景,这款工具都能显著简化GPU的部署和运维流程。 ## 为什么选择NVIDIA GPU Operator? 在传统的Kubernetes GPU管理中,用户需要手动配置驱动、设备插件、监控

gitblog_00009的博客 648

使用STM32制作简易数字时钟

连接LED数码管的电源和地线到STM32单片机的对应引脚,将数码管的A、B、C、D引脚连接到STM32单片机的I/O口引脚。通过编写和调试这个项目,可以熟悉STM32单片机的GPIO口和定时器的使用,以及数字显示的控制。步骤六:测试和调试 通过观察数码管的显示,可以验证时钟功能是否正常工作。步骤四:编写代码 在主程序中,我们将使用定时器中断来控制时钟的运行,并使用GPIO口控制LED数码管的显示。步骤五:编译和下载 编译代码并下载到STM32单片机中,通过调试器和串口监视器进行调试和查看输出结果。

qq_67153941的博客 1303

MIKE水动力笔记13_数字化海图2之克里金插值

在进行MIKE水动力建模之初,需要准备好水深数据,本专题系列博文主要讲解如何将扫描版JPG格式海图数据在ArcGIS中进行数字化并制作成xyz水深地形数据,用的克里金插值方法,仅供参考。

晏长街的博客 2881

NVIDIA DGX Spark (ARM64/Blackwell) Kubernetes 集群 + GPU Operator 完整部署指南

摘要:本文详细介绍了在NVIDIA DGX Spark服务器(ARM64架构)上部署Kubernetes集群的全过程,重点解决四大技术难题:1)ARM64架构适配问题,2)Grace Blackwell GB10芯片的CDI配置,3)DGX OS驱动兼容性问题,4)国内网络环境下的镜像拉取问题。通过优化containerd配置、使用Helm国内源部署Cilium网络插件,以及关键性地禁用GPU Operator驱动安装(直接使用预装驱动)并启用CDI支持,最终成功构建了完整的GPU加速K8s环境。文档特别提

伟大的大威的博客 1573

1分钟吃透一篇文献,借助AI辅助各部分精读,效率提升10倍(附AI提示词)

你现在是一名【研究领域】的资深博士,非常擅长阅读与分析长篇论文,那么接下来我会给你上传一篇论文,请你按照我的要求辅助我阅读。

qq_64378896的博客 641

Kubernetes GPU 调度和 Device Plugin、CDI、NFD、GPU Operator 概述

通过CDINFD和Operator机制,Kubernetes 实现了对 GPU 等特殊硬件资源的自动化管理与高效调度。然而,特定厂商的硬件仍然存在差异化的部署与配置,使用时需要额外关注。

凌虚Blog 1248

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

使用NVIDIA GPU Operator构建边缘计算GPU集群:边缘AI部署终极指南

NVIDIA GPU Operator是Kubernetes生态系统中管理GPU资源的革命性工具,专门为边缘计算场景下的AI部署提供完整的解决方案。本文将为您详细介绍如何利用NVIDIA GPU Operator快速构建高效的边缘GPU集群,实现AI工作负载的快速部署和管理。 ## 🚀 NVIDIA GPU Operator核心优势 NVIDIA GPU Operator基于Kubernet

gitblog_01108的博客 959

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

【亲测免费】 NVIDIA GPU Operator 操作指南

**NVIDIA GPU Operator** 是一个由NVIDIA维护的开源项目,它旨在简化在Kubernetes集群上管理和配置GPU资源的过程。通过利用Kubernetes的Operator框架,GPU Operator自动化处理NVIDIA软件组件的安装和升级,包括驱动程序、容器运行时和其他必要的库。这样可以确保在部署GPU密集型工作负载时,系统始终保持最新且配置正确。 ## 2. 项目...

gitblog_00143的博客 862

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Paddle-on-K8s-Operator 使用教程

Paddle-on-K8s-Operator 使用教程 paddle-on-k8s-operatorKubernetes operator for managing the lifecycle of PaddlePaddle job.项目地址:https://gitcode.com/gh_mirrors/pa/paddle-on-k8s-operator 项目介绍 Paddle-on-K8s-O...

gitblog_00473的博客 947

ubuntu2204 + k8s 1.32.5 +GPU-Operator 24.9.2搭建GPU-k8s平台

ubuntu2204 + k8s 1.32.5 +GPU-Operator 24.9.2搭建GPU-k8s平台

大新新大浩浩的博客 770

如何快速部署NVIDIA k8s-device-plugin:10分钟搞定Kubernetes GPU支持

想要在Kubernetes集群中快速启用GPU支持吗?NVIDIA k8s-device-plugin是您的完美解决方案!这款官方设备插件让您能够在短短10分钟内为Kubernetes集群添加GPU计算能力,轻松运行AI训练、机器学习推理等GPU加速工作负载。 ## 🔧 准备工作:确保GPU节点就绪 在部署插件之前,需要确保所有GPU节点满足以下要求: - NVIDIA驱动程序版本 ~=

gitblog_01137的博客 835

NVIDIA GPU Operator: 简化Kubernetes中的GPU管理

NVIDIA GPU Operator 是一个开源项目,旨在通过Kubernetes自动化管理NVIDIA GPU相关的软件组件。该项目主要使用Go语言开发。 ## 项目基础介绍 NVIDIA GPU Operator 利用Kubernetes的Operator框架,自动化地配置和管理NVIDIA GPU所需的多种软件组件,如NVIDIA驱动程序(用于启用CUDA)、Kubernetes GP...

gitblog_00556的博客 501
上一篇: GPU 环境搭建指南:如何在裸机、Docker、K8s 等环境中使用 GPU
下一篇: 大模型推理指南:使用 vLLM 实现高效推理
探索云原生
博客等级 码龄9年 730粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值