适用于 Kubernetes 的 NVIDIA GPU 设备发现的Plugin插件

目录

一、介绍

二、先决条件

三、快速上手

3.1 准备 GPU 节点

3.2 针对基于 Debian 的系统与 Docker 和 containerd 的示例:

3.2.1 安装 NVIDIA 容器工具包

关于 CRI-O 配置的说明

3.2.2 在 Kubernetes 中启用 GPU 支持

3.2.3 运行 GPU 作业

3.3 配置 NVIDIA 设备插件二进制文件

3.3.1 作为命令行标志或环境

3.3.2 作为配置文件

3.3.3 配置选项详细信息

3.4 对 GPU 的共享访问

3.5 使用 CUDA MPS

3.6 通过Helm部署

3.7 配置设备插件的Helm图表

3.7.1 单个配置文件示例

3.7.2 多个配置文件示例

3.7.3 设置其他Helm图表值

3.8 以独立模式部署gpu-feature-discovery

3.9 通过直接URL安装Helm包进行部署

3.10 本地构建和运行

更改日志

问题和贡献

版本控制

使用设备插件升级 Kubernetes


一、介绍

NVIDIA 设备插件用于 Kubernetes,它是一个 Daemonset,可以自动执行以下操作:

  • 显示集群中每个节点的 GPU 数量
  • 跟踪 GPU 的健康状态
  • 在 Kubernetes 集群中运行启用 GPU 的容器

该存储库包含 NVIDIA 官方实现的 Kubernetes 设备插件。自 v0.16.1 版本起,该存储库还包含 GPU 特性发现标签的实现,关于 GPU 特性发现的更多信息,请参见此处。

请注意:

  • 截至 Kubernetes v1.10,NVIDIA 设备插件 API 处于 Beta 阶段。
  • 当前 NVIDIA 设备插件缺乏
    • 综合的 GPU 健康检查功能
    • GPU 清理功能
  • 仅对官方的 NVIDIA 设备插件提供支持(不支持该插件的分支或其他变体)。

二、先决条件

运行 NVIDIA 设备插件的先决条件列表如下:

  • NVIDIA 驱动程序 ~= 384.81
  • nvidia-docker >= 2.0 || nvidia-container-toolkit >= 1.7.0 (在 Tegra 系统上使用集成 GPU 需要 >= 1.11.0)
  • 将 nvidia-container-runtime 配置为默认的低级运行时
  • Kubernetes 版本 >= 1.10

三、快速上手

3.1 准备 GPU 节点

以下步骤需要在您所有的 GPU 节点上执行。本 README 假设您已经预先安装了 NVIDIA 驱动程序和 nvidia-container-toolkit。同时假设您已经将 nvidia-container-runtime 配置为默认的低级运行时。

请参阅:https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html

3.2 针对基于 Debian 的系统与 Docker 和 containerd 的示例:

3.2.1 安装 NVIDIA 容器工具包

有关安装和开始使用 NVIDIA 容器工具包的说明,请参考安装指南。

同时请注意以下的配置说明:

  • containerd
  • CRI-O
  • docker (已弃用)

请记得在应用配置更改后重启每个运行时。

如果 nvidia 运行时需要设置为默认运行时(Docker 的要求),则上述命令中必须包含 --set-as-default 参数。如果未执行此操作,则需要定义一个 RuntimeClass。

关于 CRI-O 配置的说明

在使用 CRI-O 运行 Kubernetes 时,请将配置文件添加到 /etc/crio/crio.conf.d/99-nvidia.conf,以将 nvidia-container-runtime 设置为默认的低级 OCI 运行时。这将优先于默认的 crun 配置文件 /etc/crio/crio.conf.d/10-crun.conf

[crio]

  [crio.runtime]
    default_runtime = "nvidia"

    [crio.runtime.runtimes]

      [crio.runtime.runtimes.nvidia]
        runtime_path = "/usr/bin/nvidia-container-runtime"
        runtime_type = "oci"

如链接文档中所述,可以使用 nvidia-ctk 命令自动生成此文件:

$ sudo nvidia-ctk runtime configure --runtime=crio --set-as-default --config=/etc/crio/crio.conf.d/99-nvidia.conf

CRI-O使用crun作为默认的低级OCI运行时,因此需要在/etc/nvidia-container-runtime/config.toml的配置文件中将crun添加到nvidia-container-runtime的运行时中:

[nvidia-container-runtime]
runtimes = ["crun", "docker-runc", "runc"]

然后重新启动:CRI-O

$ sudo systemctl restart crio

3.2.2 在 Kubernetes 中启用 GPU 支持

一旦在集群中的所有GPU节点上配置了上述选项,您就可以通过部署以下Daemonset来启用GPU支持:

$ kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.16.1/deployments/static/nvidia-device-plugin.yml

注意:这是一个简单的静态DaemonSet,旨在演示nvidia-device-plugin的基本功能。请参阅下面的说明,在生产环境中通过Helm部署该插件。

3.2.3 运行 GPU 作业

随着DaemonSet的部署,容器现在可以使用nvidia.com/gpu资源类型请求NVIDIA GPU:

$ cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: gpu-pod
spec:
  restartPolicy: Never
  containers:
    - name: cuda-container
      image: nvcr.io/nvidia/k8s/cuda-sample:vectoradd-cuda10.2
      resources:
        limits:
          nvidia.com/gpu: 1 # requesting 1 GPU
  tolerations:
  - key: nvidia.com/gpu
    operator: Exists
    effect: NoSchedule
EOF
$ kubectl logs gpu-pod
[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

警告:如果在使用NVIDIA镜像时不请求GPU,则机器上的所有GPU将会在您的容器内暴露。

3.3 配置 NVIDIA 设备插件二进制文件

NVIDIA设备插件有多个可以配置的选项。这些选项可以在启动设备插件时通过命令行标志、环境变量或配置文件进行配置。我们将在这里解释这些选项的含义以及如何直接在插件二进制文件上进行配置。以下部分将解释在通过Helm部署插件时如何设置这些配置。

3.3.1 作为命令行标志或环境

FlagEnvvarDefault Value
--mig-strategy$MIG_STRATEGY"none"
--fail-on-init-error$FAIL_ON_INIT_ERRORtrue
--nvidia-driver-root$NVIDIA_DRIVER_ROOT"/"
--pass-device-specs$PASS_DEVICE_SPECSfalse
--device-list-strategy$DEVICE_LIST_STRATEGY"envvar"
--device-id-strategy$DEVICE_ID_STRATEGY"uuid"
--config-file$CONFIG_FILE""

3.3.2 作为配置文件

version: v1
flags:
  migStrategy: "none"
  failOnInitError: true
  nvidiaDriverRoot: "/"
  plugin:
    passDeviceSpecs: false
    deviceListStrategy: "envvar"
    deviceIDStrategy: "uuid"

3.3.3 配置选项详细信息

MIG_STRATEGY:在支持它的GPU上公开MIG设备的期望策略

[none | single | mixed](默认值为'none')

MIG_STRATEGY选项配置了守护进程集能够在支持它们的GPU上公开多实例GPU(MIG)的能力。有关这些策略是什么以及应该如何使用它们的更多信息,请参阅在Kubernetes中支持多实例GPU(MIG)。

注意:使用mixed的MIG_STRATEGY,您将获得额外的资源,形式为nvidia.com/mig-<slice_count>g.<memory_size>gb,您可以在您的pod规范中设置这些资源,以访问特定的MIG设备。

FAIL_ON_INIT_ERROR:如果在初始化期间遇到错误,则使插件失败,否则无限期阻止

(默认值为'true')

当设置为true时,FAIL_ON_INIT_ERROR选项会在初始化期间遇到错误时使插件失败。当设置为false时,它会打印错误消息,并无限期阻止插件,而不是失败。无限期阻止遵循允许插件在没有GPU的节点上(并且不应该在这些节点上有GPU)成功部署的传统语义,而不会抛出错误。通过这种方式,您可以在集群中的所有节点上盲目部署带有插件的守护进程,无论它们是否具有GPU,而不会遇到错误。但是,这样做意味着在应该具有GPU的节点上无法检测到实际错误。如果遇到初始化错误,则失败现在是默认设置,并且应该被所有新部署采用。

NVIDIA_DRIVER_ROOT:NVIDIA驱动程序安装的根路径(默认值为'/')

当NVIDIA驱动程序直接安装在主机上时,应将其设置为'/'。当在其他位置安装(例如通过驱动程序容器)时,应将其设置为安装驱动程序的根文件系统(例如'/run/nvidia/driver')。

注意:仅在与下面描述的$PASS_DEVICE_SPECS选项一起使用时才需要此选项。它告诉插件在作为设备规格的一部分传递回的任何设备文件路径上添加什么前缀。

PASS_DEVICE_SPECS:传递分配给容器的任何NVIDIA设备的路径和所需设备节点权限

(默认值为'false')

此选项仅用于允许设备插件与Kubernetes中的CPUManager进行互操作。设置此标志还需要以提升的权限部署守护进程,因此只有在您知道需要与CPUManager进行互操作时才这样做。

DEVICE_LIST_STRATEGY:将设备列表传递给底层运行时的期望策略

[envvar | volume-mounts | cdi-annotations | cdi-cri](默认值为'envvar')

注意:可以指定多个设备列表策略(作为逗号分隔的列表)。

DEVICE_LIST_STRATEGY标志允许选择插件将用于向容器分配的GPU列表进行广告的策略。可能的值包括:

envvar(默认值):使用此处描述的NVIDIA_VISIBLE_DEVICES环境变量来选择要由NVIDIA容器运行时注入的设备。 volume-mounts:将设备列表作为一组卷挂载传递,而不是作为环境变量传递,以指示NVIDIA容器运行时注入设备。有关此策略背后的原因的详细信息,请参阅此处。 cdi-annotations:使用CDI注释来选择要注入的设备。

请注意,这不需要NVIDIA容器运行时,但需要一个启用了CDI的容器引擎。 cdi-cri:使用CDIDevices CRI字段来选择要注入的

3.4 对 GPU 的共享访问

NVIDIA设备插件通过其配置文件中的一组扩展选项允许GPU的超额订阅。可用的共享有两种形式:时间切片(Time-Slicing)和多进程服务(MPS)。

注意:时间切片和MPS的使用是相互排斥的。

在时间切片的情况下,使用CUDA时间切片来允许共享GPU的工作负载相互交错。然而,对于从同一底层GPU获得副本的工作负载,未采取任何特殊措施来隔离它们,每个工作负载都可以访问GPU内存,并且与其他所有工作负载处于同一故障域(这意味着如果一个工作负载崩溃,所有工作负载都会崩溃)。

在MPS的情况下,使用控制守护进程来管理对共享GPU的访问。与时间切片相比,MPS进行空间划分,允许内存和计算资源被显式划分,并对每个工作负载强制执行这些限制。

使用CUDA时间切片 使用时间切片进行共享的扩展选项如下所示:

version: v1
sharing:
  timeSlicing:
    renameByDefault: <bool>
    failRequestsGreaterThanOne: <bool>
    resources:
    - name: <resource-name>
      replicas: <num-replicas>
    ...

也就是说,对于共享.timeSlicing.resources下的每个命名资源,现在可以为该资源类型指定多个副本。这些副本表示将为该资源类型所代表的GPU授予的共享访问次数。

如果renameByDefault=true,则每个资源将以<resource-name>.shared的名称而不是简单的<resource-name>进行发布。

如果failRequestsGreaterThanOne=true,则如果容器请求超过一个共享资源,插件将无法分配任何共享资源给该容器。该容器的pod将因UnexpectedAdmissionError而失败,并需要手动删除、更新和重新部署。

例如:

version: v1
sharing:
  timeSlicing:
    resources:
    - name: nvidia.com/gpu
      replicas: 10

如果将此配置应用于具有8个GPU的节点,则插件将向Kubernetes发布80个nvidia.com/gpu资源,而不是8个。

$ kubectl describe node
...
Capacity:
  nvidia.com/gpu: 80
...

同样,如果将以下配置应用于一个节点,则将向Kubernetes发布80个nvidia.com/gpu.shared资源,而不是8个nvidia.com/gpu资源。

version: v1
sharing:
  timeSlicing:
    renameByDefault: true
    resources:
    - name: nvidia.com/gpu
      replicas: 10
    ...
$ kubectl describe node
...
Capacity:
  nvidia.com/gpu.shared: 80
...

在这两种情况下,插件只是创建了每个GPU的10个引用,并不加区分地将它们分配给任何请求它们的用户。

如果在这两种配置中的任何一种中设置了failRequestsGreaterThanOne=true,并且用户在其pod规范中请求超过一个nvidia.com/gpu或nvidia.com/gpu.shared资源,则容器将因以下错误而失败:

$ kubectl describe pod gpu-pod
...
Events:
  Type     Reason                    Age   From               Message
  ----     ------                    ----  ----               -------
  Warning  UnexpectedAdmissionError  13s   kubelet            Allocate failed due to rpc error: code = Unknown desc = request for 'nvidia.com/gpu: 2' too large: maximum request size for shared resources is 1, which is unexpected
...

注意:与“正常”的GPU请求不同,请求多个共享GPU并不意味着您将获得保证的相应计算能力访问。它仅意味着您将访问一个被其他客户共享的GPU(每个客户可以自由地在底层GPU上运行任意数量的进程)。在后台,CUDA将简单地为所有客户的所有GPU进程分配相等的时间份额。failRequestsGreaterThanOne标志旨在帮助用户理解这一细微差别,通过将请求1视为访问请求而不是独占资源请求。建议将failRequestsGreaterThanOne设置为true,但默认设置为false以保持向后兼容性。

截至目前,支持的时间切片资源仅为nvidia.com/gpu,以及通过混合MIG策略配置节点时出现的任何资源类型。

例如,T4卡上可以进行时间切片的资源完整列表为:

nvidia.com/gpu

在A100 40GB卡上可以进行时间切片的资源完整列表为:

nvidia.com/gpu
nvidia.com/mig-1g.5gb
nvidia.com/mig-2g.10gb
nvidia.com/mig-3g.20gb
nvidia.com/mig-7g.40gb

同样,在A100 80GB卡上,它们将是:

nvidia.com/gpu
nvidia.com/mig-1g.10gb
nvidia.com/mig-2g.20gb
nvidia.com/mig-3g.40gb
nvidia.com/mig-7g.80gb

3.5 使用 CUDA MPS

注意:启用了 MIG 的设备目前不支持与 MPS 共享。

使用 MPS 进行共享的扩展选项如下所示:

version: v1
sharing:
  mps:
    renameByDefault: <bool>
    resources:
    - name: <resource-name>
      replicas: <num-replicas>
    ...

也就是说,对于共享.mps.resources下的每个命名资源,可以为该资源类型指定多个副本。与时间切片相同,这些副本表示将为与该资源类型相关联的GPU授予的共享访问次数。与时间切片不同,每个客户(即每个分区)允许使用的内存量由MPS控制守护进程管理,并限制为总设备内存的相等份额。除了控制每个客户可以消耗的内存量外,MPS控制守护进程还限制了客户可以消耗的计算能力。

如果renameByDefault=true,则每个资源将以<resource-name>.shared的名称而不是简单的<resource-name>进行发布。

例如:

version: v1
sharing:
  mps:
    resources:
    - name: nvidia.com/gpu
      replicas: 10

如果将此配置应用于具有8个GPU的节点,则插件将向Kubernetes广告80个nvidia.com/gpu资源,而不是8个。

$ kubectl describe node
...
Capacity:
  nvidia.com/gpu: 80
...

同样,如果将以下配置应用于一个节点,则将向Kubernetes广告80个nvidia.com/gpu.shared资源,而不是8个nvidia.com/gpu资源。

version: v1
sharing:
  mps:
    renameByDefault: true
    resources:
    - name: nvidia.com/gpu
      replicas: 10
    ...
$ kubectl describe node
...
Capacity:
  nvidia.com/gpu.shared: 80
...

此外,这些资源——无论是nvidia.com/gpu还是nvidia.com/gpu.shared——都将访问GPU总内存和计算资源的相同份额(1/10)。

注意:截至目前,支持的MPS资源仅为nvidia.com/gpu资源,并且仅适用于完整的GPU。

3.6 通过Helm部署

部署设备插件的首选方法是使用Helm作为一个守护进程。安装Helm的说明可以在这里找到。

首先设置插件的Helm仓库,并按照以下步骤进行更新:

$ helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
$ helm repo update

然后验证插件的最新版本(v0.16.1)是否可用:

$ helm search repo nvdp --devel
NAME                     	  CHART VERSION  APP VERSION	DESCRIPTION
nvdp/nvidia-device-plugin	  0.16.1	 0.16.1		A Helm chart for ...

一旦这个仓库被更新,你就可以开始安装来自它的软件包,以部署nvidia-device-plugin Helm图表。

最基本的安装命令没有任何选项,如下所示:

helm upgrade -i nvdp nvdp/nvidia-device-plugin \
  --namespace nvidia-device-plugin \
  --create-namespace \
  --version 0.16.1

注意:如果这是一个预发布版本(例如<version>-rc.1),则只需要在helm search repo命令中传递--devel标志,以及在helm upgrade -i命令中传递--version标志。完整的发布版本将在没有这些标志的情况下列出。

3.7 配置设备插件的Helm图表

最新版本插件(v0.16.1)的Helm图表包括许多可定制的数值。

在v0.12.0之前,最常用的数值是直接映射到插件二进制文件的命令行选项的数值。从v0.12.0开始,设置这些选项的首选方法是通过ConfigMap。原始数值的主要用例是如果需要,可以覆盖ConfigMap中的选项。下面更详细地讨论了这两种方法。

可以设置的完整数值集合可以在这里找到。

通过ConfigMap向插件传递配置。 通常,我们提供一种机制,可以将多个配置文件传递给插件的Helm图表,通过节点标签选择应该应用到节点的哪个配置文件。

通过这种方式,可以使用单个图表部署每个组件,但可以将自定义配置应用于集群中不同的节点。

有两种方法可以提供用于插件的ConfigMap:

通过对预定义ConfigMap的外部引用 作为一组命名的配置文件,用于构建与图表关联的集成ConfigMap 这些可以通过图表数值config.name和config.map分别设置。在这两种情况下,值config.default可以设置为指向ConfigMap中的一个命名配置,并为尚未通过节点标签定制的节点提供默认配置(稍后详细介绍)。

3.7.1 单个配置文件示例

例如,在本地文件系统上创建一个有效的配置文件,如下所示:

cat << EOF > /tmp/dp-example-config0.yaml
version: v1
flags:
  migStrategy: "none"
  failOnInitError: true
  nvidiaDriverRoot: "/"
  plugin:
    passDeviceSpecs: false
    deviceListStrategy: envvar
    deviceIDStrategy: uuid
EOF

然后通过Helm部署设备插件(指向此配置文件并为其命名):

$ helm upgrade -i nvdp nvdp/nvidia-device-plugin \
    --version=0.16.1 \
    --namespace nvidia-device-plugin \
    --create-namespace \
    --set-file config.map.config=/tmp/dp-example-config0.yaml

在幕后,这将部署与插件关联的ConfigMap,并将dp-example-config0.yaml文件的内容放入其中,使用名称config作为其键。然后,启动插件,使得当插件上线时应用此配置。

如果不希望插件的Helm图表为您创建ConfigMap,也可以将其指向预先创建的ConfigMap,如下所示:

$ kubectl create ns nvidia-device-plugin
$ kubectl create cm -n nvidia-device-plugin nvidia-plugin-configs \
    --from-file=config=/tmp/dp-example-config0.yaml
$ helm upgrade -i nvdp nvdp/nvidia-device-plugin \
    --version=0.16.1 \
    --namespace nvidia-device-plugin \
    --create-namespace \
    --set config.name=nvidia-plugin-configs

3.7.2 多个配置文件示例

对于多个配置文件,流程类似。

创建第二个配置文件,内容如下:

cat << EOF > /tmp/dp-example-config1.yaml
version: v1
flags:
  migStrategy: "mixed" # Only change from config0.yaml
  failOnInitError: true
  nvidiaDriverRoot: "/"
  plugin:
    passDeviceSpecs: false
    deviceListStrategy: envvar
    deviceIDStrategy: uuid
EOF

然后通过Helm重新部署设备插件(指向这两个配置文件并指定默认值)。

$ helm upgrade -i nvdp nvdp/nvidia-device-plugin \
    --version=0.16.1 \
    --namespace nvidia-device-plugin \
    --create-namespace \
    --set config.default=config0 \
    --set-file config.map.config0=/tmp/dp-example-config0.yaml \
    --set-file config.map.config1=/tmp/dp-example-config1.yaml

与之前一样,如果需要,也可以使用预先创建的ConfigMap来完成:

$ kubectl create ns nvidia-device-plugin
$ kubectl create cm -n nvidia-device-plugin nvidia-plugin-configs \
    --from-file=config0=/tmp/dp-example-config0.yaml \
    --from-file=config1=/tmp/dp-example-config1.yaml
$ helm upgrade -i nvdp nvdp/nvidia-device-plugin \
    --version=0.16.1 \
    --namespace nvidia-device-plugin \
    --create-namespace \
    --set config.default=config0 \
    --set config.name=nvidia-plugin-configs

注意:如果未明确设置config.default标志,则将从配置中推断默认值,如果其中一个配置名称设置为'default',则将选择默认值。如果没有设置这两者,则除非只提供一个配置,否则部署将失败。如果只提供一个配置,它将被选择为默认值,因为没有其他选项。

使用节点标签更新每个节点的配置 通过这种设置,所有节点上的插件将默认为它们配置config0。但是,可以设置以下标签以更改应用的配置:

kubectl label nodes <node-name> –-overwrite \
    nvidia.com/device-plugin.config=<config-name>

例如,为所有安装了T4 GPU的节点应用自定义配置可能如下所示:

kubectl label node \
    --overwrite \
    --selector=nvidia.com/gpu.product=TESLA-T4 \
    nvidia.com/device-plugin.config=t4-config

注意:此标签可以在插件启动之前或之后应用,以便在节点上获得所需的配置。每当其值更改时,插件将立即更新,以开始提供所需的配置。如果设置为未知值,则将跳过重新配置。如果此标签被取消设置,则将回退到默认配置。

3.7.3 设置其他Helm图表值

如前所述,设备插件的Helm图表继续提供直接值,以设置插件的配置选项,而不使用ConfigMap。这些值应仅用于设置全局适用的选项(这些选项不应嵌入由ConfigMap提供的配置文件集),或根据需要覆盖这些选项。

这些值如下:

  migStrategy:
      the desired strategy for exposing MIG devices on GPUs that support it
      [none | single | mixed] (default "none")
  failOnInitError:
      fail the plugin if an error is encountered during initialization, otherwise block indefinitely
      (default 'true')
  compatWithCPUManager:
      run with escalated privileges to be compatible with the static CPUManager policy
      (default 'false')
  deviceListStrategy:
      the desired strategy for passing the device list to the underlying runtime
      [envvar | volume-mounts | cdi-annotations | cdi-cri] (default "envvar")
  deviceIDStrategy:
      the desired strategy for passing device IDs to the underlying runtime
      [uuid | index] (default "uuid")
  nvidiaDriverRoot:
      the root path for the NVIDIA driver installation (typical values are '/' or '/run/nvidia/driver')

注意:没有值直接映射到插件的PASS_DEVICE_SPECS配置选项。相反,提供了一个名为compatWithCPUManager的值,它充当该选项的代理。它既将插件的PASS_DEVICE_SPECS选项设置为true,又确保插件以提升的权限启动,以确保与CPUManager的适当兼容性。

除了这些自定义配置选项外,其他常被覆盖的标准Helm图表值包括:

  runtimeClassName:
      the runtimeClassName to use, for use with clusters that have multiple runtimes. (typical value is 'nvidia')

请查看values.yaml文件,以查看设备插件的完整可覆盖参数集。

设置这些选项的示例包括:

启用与CPUManager的兼容性,并请求100毫秒的CPU时间和512MB内存限制。

$ helm upgrade -i nvdp nvdp/nvidia-device-plugin \
    --version=0.16.1 \
    --namespace nvidia-device-plugin \
    --create-namespace \
    --set compatWithCPUManager=true \
    --set resources.requests.cpu=100m \
    --set resources.limits.memory=512Mi

启用与CPUManager的兼容性以及混合的migStrategy。

$ helm upgrade -i nvdp nvdp/nvidia-device-plugin \
    --version=0.16.1 \
    --namespace nvidia-device-plugin \
    --create-namespace \
    --set compatWithCPUManager=true \
    --set migStrategy=mixed

使用gpu-feature-discovery进行自动节点标签部署 从v0.12.0开始,设备插件的Helm图表集成了将gpu-feature-discovery(GFD)作为子图表进行部署的支持。可以使用GFD自动生成节点上可用GPU的标签。在后台,它利用节点特征发现来执行此标记。

要启用此功能,只需在Helm安装期间设置gfd.enabled=true。

helm upgrade -i nvdp nvdp/nvidia-device-plugin \
    --version=0.16.1 \
    --namespace nvidia-device-plugin \
    --create-namespace \
    --set gfd.enabled=true

在后台,这也将部署节点特征发现(NFD),因为它是GFD的先决条件。如果您已经在集群中部署了NFD,并且不希望在此安装中拉入它,可以通过设置nfd.enabled=false来禁用它。

除了GFD应用的标准节点标签外,当使用上述时间切片扩展部署插件时,还将包含以下标签。

nvidia.com/<resource-name>.replicas = <num-replicas>

此外,如果renameByDefault=false,nvidia.com/<resource-name>.product将被修改如下:

nvidia.com/<resource-name>.product = <product name>-SHARED

使用这些标签,用户可以选择共享GPU与非共享GPU,方式与他们传统上选择一个GPU型号而非另一个相同。也就是说,SHARED注释确保可以使用nodeSelector将Pods吸引到具有共享GPU的节点上。

由于将renameByDefault设置为true已经在资源名称中编码了该资源是共享的事实,因此无需在产品名称上添加SHARED注释。用户只需在其Pod规格中请求即可找到所需的共享资源。

注意:当使用renameByDefault=false和migStrategy=single时,MIG配置文件名称和新的SHARED注释将附加到产品名称,例如:

nvidia.com/gpu.product = A100-SXM4-40GB-MIG-1g.5gb-SHARED

3.8 以独立模式部署gpu-feature-discovery

从v0.16.1开始,设备插件的Helm图表集成了部署gpu-feature-discovery的支持。

当gpu-feature-discovery以独立方式部署时,首先设置插件的Helm仓库并按如下方式更新:

$ helm repo add nvdp https://nvidia.github.io/k8s-device-plugin
$ helm repo update

然后验证插件的最新版本(v0.16.1)是否可用(请注意,这包括GFD图表):

$ helm search repo nvdp --devel
NAME                     	  CHART VERSION  APP VERSION	DESCRIPTION
nvdp/nvidia-device-plugin	  0.16.1	 0.16.1		A Helm chart for ...

一旦这个仓库被更新,您就可以开始安装来自它的软件包,以独立模式部署gpu-feature-discovery组件。

最基本的安装命令没有任何选项,如下所示:

$ helm upgrade -i nvdp nvdp/nvidia-device-plugin \
  --version 0.16.1 \
  --namespace gpu-feature-discovery \
  --create-namespace \
  --set devicePlugin.enabled=false

禁用NFD的自动部署,并在默认命名空间中使用'mixed'的MIG策略运行。

$ helm upgrade -i nvdp nvdp/nvidia-device-plugin \
    --version=0.16.1 \
    --set allowDefaultNamespace=true \
    --set nfd.enabled=false \
    --set migStrategy=mixed \
    --set devicePlugin.enabled=false

注意:如果这是一个预发布版本(例如<version>-rc.1),则只需在helm search repo命令中传递--devel标志,以及在helm upgrade -i命令中传递--version标志。完整的发布版本将在没有这些标志的情况下列出。

3.9 通过直接URL安装Helm包进行部署

如果您不想从nvidia-device-plugin Helm仓库安装,可以直接对插件的Helm包的tarball运行helm install。下面的示例安装与上述方法相同的图表,只是它使用直接的URL指向Helm图表,而不是通过Helm仓库。

使用标志的默认值:

$ helm upgrade -i nvdp \
    --namespace nvidia-device-plugin \
    --create-namespace \
    https://nvidia.github.io/k8s-device-plugin/stable/nvidia-device-plugin-0.16.1.tgz

3.10 本地构建和运行

接下来的部分将重点介绍如何在本地构建设备插件并运行它。这纯粹是为了开发和测试,大多数用户并不需要这样做。假设您正在使用最新的发布标签(即v0.16.1),但可以轻松修改以适应任何可用的标签或分支。

使用Docker

构建

选项1,从Docker Hub拉取预构建的镜像:

$ docker pull nvcr.io/nvidia/k8s-device-plugin:v0.16.1
$ docker tag nvcr.io/nvidia/k8s-device-plugin:v0.16.1 nvcr.io/nvidia/k8s-device-plugin:devel

选项2,在不克隆仓库的情况下构建:

$ docker build \
    -t nvcr.io/nvidia/k8s-device-plugin:devel \
    -f deployments/container/Dockerfile.ubuntu \
    https://github.com/NVIDIA/k8s-device-plugin.git#v0.16.1

选项3,如果您想修改代码:

$ git clone https://github.com/NVIDIA/k8s-device-plugin.git && cd k8s-device-plugin
$ docker build \
    -t nvcr.io/nvidia/k8s-device-plugin:devel \
    -f deployments/container/Dockerfile.ubuntu \
    .

运行

不兼容CPUManager静态策略:

$ docker run \
    -it \
    --security-opt=no-new-privileges \
    --cap-drop=ALL \
    --network=none \
    -v /var/lib/kubelet/device-plugins:/var/lib/kubelet/device-plugins \
    nvcr.io/nvidia/k8s-device-plugin:devel

兼容CPUManager静态策略:

$ docker run \
    -it \
    --privileged \
    --network=none \
    -v /var/lib/kubelet/device-plugins:/var/lib/kubelet/device-plugins \
    nvcr.io/nvidia/k8s-device-plugin:devel --pass-device-specs

不使用Docker

构建

$ C_INCLUDE_PATH=/usr/local/cuda/include LIBRARY_PATH=/usr/local/cuda/lib64 go build

运行

不兼容CPUManager静态策略:

$ ./k8s-device-plugin

兼容CPUManager静态策略:

$ ./k8s-device-plugin --pass-device-specs

更改日志

查看更新日志

问题和贡献

查看贡献文档!

版本控制

在 v1.10 之前,设备插件的版本控制方案必须与 Kubernetes 的版本完全匹配。 在将设备插件提升到 beta 版后,不再需要此条件。 我们很快注意到,这种版本控制方案对用户来说非常令人困惑,因为他们仍然希望看到 每个 Kubernetes 版本的设备插件版本。

此版本控制方案适用于标记v1.8v1.9v1.10v1.11v1.12

现在,我们已更改版本控制以遵循 SEMVER。这 遵循此方案的第一个版本已被标记为 。v0.0.0

展望未来,设备插件的主要版本只会发生变化 在设备插件 API 本身发生更改后。例如,设备插件 API 的版本对应于 设备插件。如果设备插件 API 的新版本出来, 然后,设备插件会将其主要版本增加到 。v1beta1v0.x.xv2beta21.x.x

截至目前,Kubernetes 的设备插件 API >= v1.10 是 。如果你 拥有 Kubernetes 的版本>= 1.10,您可以部署任何设备插件版本>。v1beta1v0.0.0

使用设备插件升级 Kubernetes

在部署了设备插件时升级 Kubernetes 不需要您 对工作流程进行任何特定的更改。该 API 已进行版本控制,并且是 相当稳定(尽管不能保证不会中断)。起始价为 Kubernetes 版本 1.10,可以使用设备插件来执行 升级,Kubernetes 不需要您部署不同版本的 设备插件。一旦节点在升级后重新联机,您将看到 GPU 会自动重新注册自身。v0.3.0

升级设备插件本身是一项更复杂的任务。建议 耗尽 GPU 任务,因为我们无法保证 GPU 任务能够在滚动中幸存下来 升级。但是,我们会尽最大努力在升级期间保留 GPU 任务。

原文地址:GitHub - NVIDIA/k8s-device-plugin: NVIDIA device plugin for Kubernetes

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术瘾君子1573

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值