Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

set PASS_DEVICE_SPECS ENV to device-plugin #690

Merged
merged 3 commits into from
Dec 27, 2024

Conversation

jingzhe6414
Copy link
Contributor

@jingzhe6414 jingzhe6414 commented Dec 6, 2024

set PASS_DEVICE_SPECS ENV to device-plugin

What type of PR is this?
/kind bug

What this PR does / why we need it:
Mitigate the issue of GPU unavailability during the pod runtime.
Which issue(s) this PR fixes:
Fixes #
#658 Containerized GPU workloads may suddenly lose access to their GPUs. This situation occurs when systemd is used to manage the cgroups of the container and it is triggered to reload any Unit files that have references to NVIDIA GPUs (e.g. with something as simple as a systemctl daemon-reload).
Special notes for your reviewer:
https://github.com/NVIDIA/gpu-operator/issues/485According to the solution provided in the k8s-nvidia-plugin, adding the PASS_DEVICE_SPECS ENV to the plugin was tested and found that not setting privileged can also mitigate the issue.
Additionally, I did not find the usage of PASS_DEVICE_SPECS in hami-device-plugin, but I did find traces of its usage in nvidia's k8s-device-plugin. This is quite puzzling as to why it would work, and I haven't found a reasonable explanation yet. If you have any insights, please let me know.
Does this PR introduce a user-facing change?: yes

…PECS=true as an environment variable.

Signed-off-by: 张 驰 <919474320@qq.com>
@archlitchi
Copy link
Collaborator

could you discuss this PR next weekly meeting?

@jingzhe6414
Copy link
Contributor Author

could you discuss this PR next weekly meeting?您能否在下次周会上讨论一下这个 PR?

ok,I'm in the WeChat group, and you can remind me during the weekly meeting.

@Nimbus318
Copy link
Contributor

Nimbus318 commented Dec 23, 2024

@jingzhe6414

感谢提交这个 PR,我花了一些时间了解了相关的上下文,以下是我对这个问题和解决方案的理解,以及改进建议:


问题背景

在容器化 GPU 工作负载中,尤其是在使用 systemd 管理 cgroup 的环境中,可能会出现以下现象:

  • GPU 容器在运行过程中突然失去对 GPU 的访问,具体表现为执行 nvidia-smi 返回 Failed to initialize NVML: Unknown Error
  • 触发条件可能是运行 systemctl daemon-reload 或类似操作
  • 重启 Pod 后 GPU 可用,但随着时间推移问题可能再次出现

问题原因

看了前面几个相关的 Issue 和 NVIDIA 官方 Issue(NVIDIA/gpu-operator#485),比较核心的原因应该是:

  1. 符号链接(symlinks)缺失
    • K8s 的容器运行时(如 runc)需要设备节点的符号链接(如 /dev/char 下的链接)来正确注入设备
    • 如果这些链接在系统中不存在或者未被正确维护(例如 NVIDIA 驱动未生成这些链接),容器中的 GPU 设备可能无法被正确识别和访问
    • 这一点在 plugin.apiDeviceSpecs 明确传递了设备的 ContainerPathHostPath,以确保 kubelet 和容器运行时能够准确找到设备节点,来弥补了符号链接缺失或不稳定的情况
  2. systemd 的 cgroup 管理影响
    • systemd 重新加载(daemon-reload)单元文件时,可能会对设备节点的状态产生干扰,尤其是在符号链接缺失或不稳定的情况下
    • 如果 kubelet 或 dp 无法确保 GPU 设备的完整性(例如通过显式描述所有设备路径),可能导致容器无法继续使用分配的 GPU

解决方案:为啥 PASS_DEVICE_SPECS=true 有效?

通过设置 PASS_DEVICE_SPECS=true,这个在 HAMi 源码NVIDIA 的 k8s-device-plugin 源码实现 是类似的:

  • 设备路径的显式传递
    • 启用 PASS_DEVICE_SPECS=true 后,dp 会在 Allocate() 阶段直接传递 GPU 的完整设备路径(如 /dev/nvidia0/dev/nvidiactl),即使符号链接(如 /dev/char)缺失,也能确保设备正确挂载到容器中
  • 避免符号链接依赖
    • 在某些环境(特别是 systemd 管理的 cgroup 环境)中,符号链接可能未生成或在 daemon-reload 后丢失,导致设备不可用
    • 通过直接传递设备路径,PASS_DEVICE_SPECS=true 避免了对符号链接的依赖,解决了这一问题

然后关于,你没找到对应的变量,但是莫名其妙生效了,是因为这些 config 的 Flag 是通过 nvidia 的库(github.com/NVIDIA/k8s-device-plugin/api/config/v1)定义的,而不是在我们自己的仓库里声明的


改进建议

这个 PR 的改动基本照搬了 NVIDIA 的 dp 中 compatWithCPUManager 的实现,NVIDIA 是同时绑定了两项配置:

  1. 启用 PASS_DEVICE_SPECS=true
  2. 将 dp 以特权模式(privileged: true)运行(#edited:我看你提 PR 的时候 hami-device-plugin 还没有特权,刚刚看 latest 的 helm 里面又给了,那看起来下面的限制提权啥的就没啥意义了,有点奇怪)

NVIDIA 的 dp 这么做是为了在为 K8s 启用 CPUManager 功能时提供完整的 GPU 资源支持,但在 HAMi 中也用 compatWithCPUManager 这个不太准确,所以我感觉有俩可以改进的:

  1. 修改配置项命名为 passDeviceSpecsEnabled,更准确地描述其功能
  2. 在 Helm 的 Values 中 passDeviceSpecsEnabled 所在地方加上简单的注释对这个配置的描述,帮助用户理解该配置的背景和用途,甚至可以把这个 PR 链接放进去辅助理解

再次感谢你的贡献,希望这些建议能帮助进一步优化这个 PR!

@jingzhe6414
Copy link
Contributor Author

@jingzhe6414

感谢提交这个 PR,我花了一些时间了解了相关的上下文,以下是我对这个问题和解决方案的理解,以及改进建议:

问题背景

在容器化 GPU 工作负载中,尤其是在使用 systemd 管理 cgroup 的环境中,可能会出现以下现象:

  • GPU 容器在运行过程中突然失去对 GPU 的访问,具体表现为执行 nvidia-smi 返回 Failed to initialize NVML: Unknown Error
  • 触发条件可能是运行 systemctl daemon-reload 或类似操作
  • 重启 Pod 后 GPU 可用,但随着时间推移问题可能再次出现

问题原因

看了前面几个相关的 Issue 和 NVIDIA 官方 Issue(NVIDIA/gpu-operator#485),比较核心的原因应该是:

  1. 符号链接(symlinks)缺失

    • K8s 的容器运行时(如 runc)需要设备节点的符号链接(如 /dev/char 下的链接)来正确注入设备
    • 如果这些链接在系统中不存在或者未被正确维护(例如 NVIDIA 驱动未生成这些链接),容器中的 GPU 设备可能无法被正确识别和访问
    • 这一点在 plugin.apiDeviceSpecs 明确传递了设备的 ContainerPathHostPath,以确保 kubelet 和容器运行时能够准确找到设备节点,来弥补了符号链接缺失或不稳定的情况
  2. systemd 的 cgroup 管理影响

    • systemd 重新加载(daemon-reload)单元文件时,可能会对设备节点的状态产生干扰,尤其是在符号链接缺失或不稳定的情况下
    • 如果 kubelet 或 dp 无法确保 GPU 设备的完整性(例如通过显式描述所有设备路径),可能导致容器无法继续使用分配的 GPU

解决方案:为啥 PASS_DEVICE_SPECS=true 有效?

通过设置 PASS_DEVICE_SPECS=true,这个在 HAMi 源码NVIDIA 的 k8s-device-plugin 源码实现 是类似的:

  • 设备路径的显式传递

    • 启用 PASS_DEVICE_SPECS=true 后,dp 会在 Allocate() 阶段直接传递 GPU 的完整设备路径(如 /dev/nvidia0/dev/nvidiactl),即使符号链接(如 /dev/char)缺失,也能确保设备正确挂载到容器中
  • 避免符号链接依赖

    • 在某些环境(特别是 systemd 管理的 cgroup 环境)中,符号链接可能未生成或在 daemon-reload 后丢失,导致设备不可用
    • 通过直接传递设备路径,PASS_DEVICE_SPECS=true 避免了对符号链接的依赖,解决了这一问题

然后关于,你没找到对应的变量,但是莫名其妙生效了,是因为这些 config 的 Flag 是通过 nvidia 的库(github.com/NVIDIA/k8s-device-plugin/api/config/v1)定义的,而不是在我们自己的仓库里声明的

改进建议

这个 PR 的改动基本照搬了 NVIDIA 的 dp 中 compatWithCPUManager 的实现,NVIDIA 是同时绑定了两项配置:

  1. 启用 PASS_DEVICE_SPECS=true
  2. 将 dp 以特权模式(privileged: true)运行(#edited:我看你提 PR 的时候 hami-device-plugin 还没有特权,刚刚看 latest 的 helm 里面又给了,那看起来下面的限制提权啥的就没啥意义了,有点奇怪)

NVIDIA 的 dp 这么做是为了在为 K8s 启用 CPUManager 功能时提供完整的 GPU 资源支持,但在 HAMi 中也用 compatWithCPUManager 这个不太准确,所以我感觉有俩可以改进的:

  1. 修改配置项命名为 passDeviceSpecsEnabled,更准确地描述其功能
  2. 在 Helm 的 Values 中 passDeviceSpecsEnabled 所在地方加上简单的注释对这个配置的描述,帮助用户理解该配置的背景和用途,甚至可以把这个 PR 链接放进去辅助理解

再次感谢你的贡献,希望这些建议能帮助进一步优化这个 PR!

感谢回复,既然设置这个变量有效是否可以考虑把默认值设为true?

@Nimbus318
Copy link
Contributor

@jingzhe6414 确实,我也觉得可以默认开启

主要是我看最新的 helm 已经有特权了,默认开启应该是没啥额外风险

而且虽然 NVIDIA 的 compatWithCPUManager 默认是 null,但那是针对特定场景的配置

所以我目前看起来 PASS_DEVICE_SPECS=true 是一个更稳定通用的方案

jingzhe6414 and others added 2 commits December 24, 2024 11:36
…_SPECS ENV to passDeviceSpecsEnabled, and set the default value to true.

Signed-off-by: 张 驰 <919474320@qq.com>
@archlitchi archlitchi merged commit 7527b2b into Project-HAMi:master Dec 27, 2024
5 checks passed
@wawa0210 wawa0210 added the kind/bug Something isn't working label Dec 31, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
kind/bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants