解决WSL2中非root用户无法使用Docker GPU支持的问题

本人遇到问题后,通过deepseek+大量尝试才解决。这篇blog也是让deepseek总结了解决过程写出来的,供遇到相似问题的人参考。

问题背景

最近在Windows 11的WSL2(Ubuntu 24.04)中配置Docker的GPU支持时,遇到了一个棘手的问题:使用sudo运行带有--gpus all参数的容器时一切正常,但当尝试以普通用户身份(已加入docker用户组)运行相同的命令时,却出现了如下错误:

$ docker run --rm --gpus all --privileged=true nvidia/cuda:12.8.1-cudnn-runtime-ubuntu24.04 nvidia-smi

docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error running prestart hook #0: exit status 1, stdout: , stderr: Auto-detected mode as 'legacy'
nvidia-container-cli: mount error: failed to add device rules: unable to find any existing device filters attached to the cgroup: bpf_prog_query(BPF_CGROUP_DEVICE) failed: operation not permitted: unknown

环境说明

​​宿主机系统​​:Windows 11 专业版 24H2 (OS版本 26100.4351)
​​WSL版本​​:WSL 2
​​Linux发行版​​:Ubuntu 24.04.2 LTS
​​Docker版本​​:Docker Engine 26.1.1
​​NVIDIA驱动版本​​:572.61 (CUDA 12.8)

问题原因

经过深入排查,发现问题的根源在于WSL2的特殊架构:

WSL2没有传统的Linux设备节点(如/dev/nvidia*),而是通过特殊的接口与Windows主机上的NVIDIA驱动通信。
在WSL2中,NVIDIA Container Toolkit尝试通过cgroups的BPF设备过滤器来管理GPU设备访问权限,但在非特权用户模式下,该操作会被内核拒绝(operation not permitted)。

解决方案

通过禁用NVIDIA Container Toolkit中的cgroups功能,我们可以避免这个权限问题。具体步骤如下:

步骤1:编辑配置文件

打开NVIDIA Container Toolkit的配置文件:

sudo nano /etc/nvidia-container-runtime/config.toml

步骤2:修改配置

在文件中找到[nvidia-container-cli]部分,如果没有则新建。在该部分下添加或修改以下设置:

[nvidia-container-cli]
no-cgroups = true

步骤3:保存并重启Docker服务

保存文件后,重启Docker服务使配置生效:

sudo systemctl restart docker

(在WSL中,通常docker服务是通过systemd运行的,但WSL默认不启动systemd。如果您的WSL已经配置了systemd,则使用sudo systemctl restart docker。如果没有,则需要在Windows端重启Docker Desktop,或者重启WSL)

步骤4:验证解决方案

重新运行测试命令:

docker run --rm --gpus all nvidia/cuda:12.8.1-cudnn-runtime-ubuntu24.04 nvidia-smi

现在应该能够成功输出GPU信息,而不需要sudo。

技术原理

为什么这个设置能够解决问题?

no-cgroups=true告诉NVIDIA运行时不要尝试通过cgroups来控制设备访问权限。
在WSL2环境中,由于没有传统的Linux设备节点,NVIDIA驱动通过WSL的特殊接口(位于/usr/lib/wsl/lib)访问,因此不需要cgroups管理。
禁用cgroups后,容器直接使用宿主机的NVIDIA环境,绕过了BPF权限检查。

补充建议

为了使配置更完善,还可以考虑添加以下设置(非必需,但可增强稳定性):

[nvidia-container-cli]
root = "/run/nvidia/driver"  # 指定驱动根目录
load-kmods = false           # WSL不需要加载内核模块
ldconfig = "@/sbin/ldconfig" # 确保正确的库路径

总结

在WSL2环境中,由于架构差异,传统的cgroups设备管理方式可能导致权限问题。通过禁用NVIDIA Container Toolkit的cgroups功能,我们可以顺利解决非root用户无法使用GPU的问题。

这个方法经过测试适用于Windows 11 24H2 + WSL2 Ubuntu 24.04的环境。如果您使用其他WSL发行版,也可以尝试此方案。

希望这篇教程能帮助遇到相同问题的开发者。如果你有更好的解决方案或任何疑问,欢迎在评论区交流!

注意事项

  1. 本文假设读者已经正确安装了WSL2、Docker和NVIDIA驱动,并且已将用户加入docker用户组。
  2. 修改配置文件时请注意备份原始文件,以便在出现问题时可以恢复。
  3. 本解决方案仅适用于WSL2环境,标准Linux环境可能需要不同的配置。

如果你在使用过程中遇到其他问题,建议参考NVIDIA官方文档:https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/index.html

祝你在WSL2的Docker容器中愉快地使用GPU加速!

Logo

分享最新的 NVIDIA AI Software 资源以及活动/会议信息,精选收录AI相关技术内容,欢迎大家加入社区并参与讨论。

更多推荐