因为GPU
属于特定的厂商产品,需要特定的driver
,Docker
本身并不支持GPU
。以前如果要在Docker
中使用GPU
,就需要在container
中安装主机上使用GPU
的driver
,然后把主机上的GPU
设备(例如:/dev/nvidia0
)映射到container
中。所以这样的Docker image
并不具备可移植性。
Nvidia-docker
项目就是为了解决这个问题,它让Docker image
不需要知道底层GPU
的相关信息,而是通过启动container
时mount
设备和驱动文件来实现的。
从源码编译安装nvidia-docker
(如果需要设置代理,请参考这个issue):
# go get -d github.com/NVIDIA/nvidia-docker
# cd $GOPATH/src/github.com/NVIDIA/nvidia-docker
# make install
其实从nvidia-docker
的main
函数来看:
func main() {
args := os.Args[1:]
defer exit()
assert(LoadEnvironment())
command, off, err := docker.ParseArgs(args)
assert(err)
if command != "create" && command != "run" {
if command == "version" {
fmt.Printf("NVIDIA Docker: %s\n\n", Version)
}
assert(docker.Docker(args...))
}
opt, i, err := docker.ParseArgs(args[off+1:], command)
assert(err)
off += i + 1
if (command == "create" || command == "run") && opt != "" {
vols, err := VolumesNeeded(opt)
assert(err)
if vols != nil {
var nargs []string
var err error
if Host != nil {
nargs, err = GenerateRemoteArgs(opt, vols)
} else {
assert(nvidia.LoadUVM())
assert(nvidia.Init())
nargs, err = GenerateLocalArgs(opt, vols)
nvidia.Shutdown()
}
assert(err)
args = append(args[:off], append(nargs, args[off:]...)...)
}
}
assert(docker.Docker(args...))
}
除了create
和run
命令以外,其它的命令还是由本机的docker
来处理。
此外,nvidia-docker
还提供了使用plug-in
模式(参考Internals):
$ curl -s http://localhost:3476/docker/cli --device=/dev/nvidiactl --device=/dev/nvidia-uvm --device=/dev/nvidia3 --device=/dev/nvidia2 --device=/dev/nvidia1 --device=/dev/nvidia0 --volume-driver=nvidia-docker --volume=nvidia_driver_361.48:/usr/local/nvidia:ro
$ docker run -ti --rm `curl -s http://localhost:3476/docker/cli` nvidia/cuda nvidia-smi
这种方式则无需使用nvidia-docker
,而可以直接使用docker
。然而这种方式不会检查image
和nvidia driver
是否兼容。
还有一种方式是使用Nvidia
提供的用Go
实现的package。
参考资料:
Why NVIDIA Docker。
有进一步的应用教程吗?应该如何创建容器来启动这个?
可以参考官网:https://github.com/NVIDIA/nvidia-docker/wiki。
有兩個問題想問問
1. 為什麼ndocker配vidia gpu,需要額外裝driver,其他周邊裝置如cpu、主機板。。。等卻不用?
2. Docker內的driver是吃哪邊的?(和原本編進kernel裡的或insmod有關係嘛)
好久不用docker了,因此下面的回答只是我现在的理解,不一定正确:
> 1. 為什麼ndocker配vidia gpu,需要額外裝driver,其他周邊裝置如cpu、主機板。。。等卻不用?
运行中的docker container本质上也是一个进程(process),与其它进程并无实质差异。在container中运行的进程需要透过container访问其它设备(例如,硬盘),而container则需透过操作系统访问。所以当你安装GPU时,自然需要安装相应的driver(即便在host端,不是container里)。而container不支持直接访问host端的GPU driver来访问GPU,因此需要在container内部安装GPU driver,然后把host端的GPU设备映射到container里。
> Docker內的driver是吃哪邊的?(和原本編進kernel裡的或insmod有關係嘛)
Docker container的driver透过映射的设备直接访问host端的GPU,与host端的driver没有关系。
ndocker不需要额外装driver, 在host里面装就可以了。
https://www.nvidia.com/object/docker-container.html
因為 nvidia docker 只能一次 assign 一個虛擬環境給 container,如果多個 container 則不保證其行為。誠如官方 wiki 所寫,行為如同多個 process 同時共用同一個 GPU 一般,可能會導致 Program crash 掉。於是我便一直在思考那虛擬化 GPU 到底要幹嗎?謝謝您這篇文章,解決我的疑惑。