怎么把宿主机的设备交给容器用?--device 的 r/w/m 权限有什么用?容器里 mknod 出来的设备文件为什么打不开?这篇用 /dev/fuse、/dev/net/tun、/dev/loop7 实测。
默认:
/dev/fuse:不存在;O_RDONLY→ENOENT;O_WRONLY→ENOENT
/dev/net/tun:不存在;O_RDONLY→ENOENT;O_WRONLY→ENOENT
/dev/loop7:不存在;O_RDONLY→ENOENT;O_WRONLY→ENOENT
/dev/zero:crw-rw-rw- 1:5;O_RDONLY→成功;O_WRONLY→成功
--device /dev/fuse --device /dev/net/tun:
/dev/fuse:crw-rw-rw- 10:229;O_RDONLY→成功;O_WRONLY→成功
/dev/net/tun:crw-rw-rw- 10:200;O_RDONLY→成功;O_WRONLY→成功
/dev/loop7:不存在;O_RDONLY→ENOENT;O_WRONLY→ENOENT只有显式 --device 的设备才会出现在容器的 /dev 里;没指定的(如 loop7)仍然不存在。设备在容器里的路径可以改名,主次设备号不变。
--device /dev/loop7:/dev/mydisk:r(只读):
/dev/mydisk:brw-rw-rw- 7:7;O_RDONLY→成功;O_WRONLY→EPERM
/dev/loop7:不存在;O_RDONLY→ENOENT;O_WRONLY→ENOENT
--device /dev/loop7:/dev/mydisk:rw(读写,不能 mknod):
/dev/mydisk:brw-rw-rw- 7:7;O_RDONLY→成功;O_WRONLY→成功
--device /dev/zero:/dev/myzero:
/dev/myzero:crw-rw-rw- 1:5;O_RDONLY→成功;O_WRONLY→成功路径后面的 :r、:rw 是设备 cgroup 的权限:只读时,以写方式打开设备返回 EPERM。我这里只试了打开(open),没有真正读写块设备。
默认(有 MKNOD capability):mknod 退出码 0 | /tmp/myfuse:crw-r--r-- 10:229;O_RDONLY→EPERM;O_WRONLY→EPERM 加 --device-cgroup-rule 'c 10:229 rwm':mknod 退出码 0 | /tmp/myfuse:crw-r--r-- 10:229;O_RDONLY→成功;O_WRONLY→成功 加 --device-cgroup-rule 'c 10:229 r'(只读):mknod 退出码 0 | /tmp/myfuse:crw-r--r-- 10:229;O_RDONLY→成功;O_WRONLY→EPERM
默认容器有 MKNOD capability,能创建设备文件;但设备 cgroup 没有放行这个主次设备号时,open 一律 EPERM。--device-cgroup-rule 'c 10:229 rwm' 放行后才能打开。这也是为什么 --privileged 之外,想用某类设备时优先 --device。
HostConfig.Devices = [{"PathOnHost":"/dev/fuse","PathInContainer":"/dev/fuse","CgroupPermissions":"rwm"},{"PathOnHost":"/dev/loop7","PathInContainer":"/dev/mydisk","CgroupPermissions":"r"}]
HostConfig.DeviceCgroupRules = ["c 10:229 rwm"]HostConfig.Devices 记录宿主路径、容器路径和权限,DeviceCgroupRules 记录规则字符串。