在非root用户作为Jenkinsfile代理的情况下在Docker容器中使用docker命令(以托管)

Jor*_*rdi 6 permissions jenkins docker jenkins-pipeline

作为构建管道的一部分,我有一个包含构建工具的容器,该容器用于多个项目。我的项目之一包含构建步骤,以构建和发布容器,该步骤是从build-tools容器内完成的。我的启用了docker的jenkins-slaves配置为具有jenkinsgroup中的用户docker。我使用-v挂载docker二进制文件和scoket。可以通过以下任一方式实现/复制:

  • 在构建工具的Dockerfile中添加用户(jenkins)和组(docker),并将其设置为主机UID和GID
  • 使用-u选项启动容器,提供UID和GUID(根据文档,容器中不需要存在用户和组)。

第一种策略的问题在于,在多个构建计算机上,用户名和组ID是不同的。我可以通过将所有构建机器的UID和GID更改为相同的值来解决此问题,但是docker是否不是要在没有对环境/上下文有很多依赖性的情况下独立运行的?这感觉不适合我。第二种策略在命令行上可以很好地工作,但是,似乎没有办法将UID和GID传递给Jenkinsfile中的agent命令。该args参数不支持脚本或变量,如$(id -u)

我本来不是第一个遇到此问题的人,但是,我自己,搜索机器和堆栈溢出都无法找到解决方案。我应该选择“准备好的”构建奴隶,还是有办法使第二种策略起作用?

-edit-我了解以root身份运行容器并在启动后进行切换的选项(例如,使用入口点)。但是,这将需要我的Jenkins奴隶以root身份连接,这对我来说是不可接受的。另一个找到的替代方法是所有资源的chmod777,这完全不保证不以root用户身份运行Jenkins从站的安全性。我更愿意对容器使用-u选项,但是在从Jenkinsfile中启动docker agent(docker run命令)之前,我找不到在jenkins从属服务器上确定UID和GID 的方法。

小智 2

一个简单的解决方案

实际上,我相信您的第一个解决方案想法可以使用 docker 轻松实现,而不需要以 root 身份运行任何 Jenkins 从属设备。

考虑这个命令:

docker run --rm -it -v /etc/passwd:/etc/passwd:ro -v /etc/shadow:/etc/shadow:ro -v /etc/group:/etc/group:ro debian:10 /bin/su linux-fan -c /bin/bash
Run Code Online (Sandbox Code Playgroud)

这将创建一个新容器并将用户从主机映射到容器中。然后,在该容器内,它立即掉落给用户linux-fan(仅)需要在外部系统上定义。

无论您以组root中的任何用户身份还是以docker组中的任何用户身份运行此命令都没有什么区别(请注意,关于docker组 = root 访问权限的注释非常正确!)

此外,以这种方式映射容器内的事物(已经在使用 docker 套接字这样做时......)实际上放弃了容器提供的大部分隔离。因此,明智的做法是考虑运行需要访问主机的 Docker 守护进程的命令,以便直接在主机上或在隔离程度较低的环境(如?)中运行chroot。当然,调用 Docker 的简单性可能仍然胜过这里缺乏隔离性。

替代解决方案

没有主机访问的解决方案可以轻松解决这个问题:使用 docker-in-docker 即在构建容器内运行新的 docker 守护进程而不是访问主机,将它们彼此隔离,这样主机的用户和组 ID 就无关紧要了。