You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

启用用户命名空间的Docker容器绑定挂载/proc技术问询

嘿,这个问题我之前帮不少用户排查过——在Docker启用用户命名空间的前提下,想让监控镜像正常读取主机/proc,核心要解决用户ID映射权限proc命名空间隔离这两个卡点,你说容器根进程跑在dockerd的用户命名空间映射里,这正是默认机制导致的,咱们一步步来搞定:

先搞懂问题根源

当你给dockerd开启用户命名空间后,Docker会自动创建一个专属的用户命名空间,容器内的root(uid 0)会被映射到主机上的一个非特权uid(这个范围是从/etc/subuid/etc/subgid里取的,默认是dockremap用户的100000-165535区间)。而主机/proc下的文件权限都是基于主机真实uid/gid的,容器内映射后的uid根本没权限直接读取;同时默认容器会用自己独立的proc命名空间,就算你挂载了主机/proc,也会因为命名空间隔离看不到真实的主机proc内容。

具体解决方案

1. 给容器映射的用户组添加主机/proc的访问权限

先别着急禁用用户命名空间(毕竟咱们要的就是隔离性),先调整权限:

  • 先查一下你的Docker用户映射范围,执行cat /etc/subuid,会看到类似dockremap:100000:65536的内容,这里的100000就是容器root对应的主机起始uid。
  • 给主机/proc目录添加ACL权限,允许这个uid范围读访问:
    setfacl -R -m u:100000:r-x /proc
    
    注意把100000换成你实际查到的起始uid,这条命令会递归给/proc下的所有文件和目录开放读执行权限给映射用户。

2. 让容器共享主机的PID(proc)命名空间

默认容器有自己独立的PID命名空间,要让它看到主机的真实proc,启动容器时必须加--pid=host参数,这样容器会直接使用主机的PID命名空间,proc视图也会变成主机的真实内容。

3. 正确挂载主机/proc并启动容器

结合上面两点,最终的启动命令应该是这样的(如果你的镜像需要以root运行):

docker run -d \
  --pid=host \
  -v /proc:/host/proc:ro \
  your-monitoring-image-name

如果你的镜像用非root用户运行,记得把ACL权限里的uid换成容器用户对应的主机映射uid(可以从/etc/subuid里计算:容器内uid + 起始映射uid)。

重要注意事项
  • --pid=host会让容器看到主机所有进程,虽然是监控需求必须的,但会降低一点隔离性,确认你的镜像安全再用。
  • 不要轻易用--userns=host参数禁用用户命名空间,这会直接失去你之前配置的隔离优势,除非万不得已。
  • 修改/etc/subuid//etc/subgid或者daemon.json后,必须重启dockerd才能生效:systemctl restart docker

内容的提问来源于stack exchange,提问作者THX

火山引擎 最新活动