以非root用户身份运行Docker或以root用户身份在Tomcat上运行Jenkins

5
我正在尝试使用docker-maven插件构建docker镜像,并计划使用jenkins执行mvn命令。我已经将jenkins.war部署在tomcat实例上,而不是独立应用程序中,该实例作为非root用户运行。
问题在于docker需要以root用户身份运行,因此maven命令需要以root用户身份运行,因此jenkins/tomcat需要以root用户身份运行,这不是一个好的做法(尽管我的非root用户也是sudoer,所以我猜不会有太大的影响)。
因此,最终,我看到两个解决方案:要么将docker作为非root用户运行(并需要帮助如何做到这一点),要么需要以root身份运行jenkins(并不确定如何实现,即使我更改了环境变量/配置,它仍然没有切换到root)。
对于选择哪种解决方案以及如何实现它,您有什么建议吗?
3个回答

4
问题在于docker需要以root用户运行,因此maven命令需要以root用户运行,
不,可以使用-u (--user)参数来运行docker run,以便在容器内使用非root用户。
要么以非root用户身份运行docker, 您的用户(在主机上)需要是docker组的一部分。然后您可以使用该用户运行docker服务。
正如评论中所述,这并不是非常安全的。
请参见: 那最后一个链接得出以下发现:
- 如果容器内部的进程正在执行已知的 uid,则可以简单地限制对主机系统的访问,以使来自容器的 uid 具有受限访问权限。 - 更好的解决方案是使用--user(也可以使用用户名,但请记住,这只是提供主机用户名系统中的 uid 的友好方式)启动具有已知 uid 的容器,然后限制在主机上您决定容器将运行的 uid 的访问权限。 - 由于 uid 和用户名(以及 gid 和组名)从容器映射到主机的方式,指定容器化进程运行的用户可以使进程在容器内部和外部看起来属于不同的用户。
关于最后一点,现在你有user namespace (userns) remapping(自 Docker 1.10 起,但我建议使用 17.06,因为 issue 33844)。

作为“docker”组的成员确实可以访问docker命令,但实际上这等同于将用户设置为root(请参见我的回答)。我想,如果涉及的用户已经是sudoer(根据OP),那么这一切都无关紧要了,但我反对将“docker”组作为快速修复方案。 - Ryan
@Ryan 这两个问题是不同的。无论是否在docker组中,您仍然可以使用-u参数运行,确保容器内的用户不是root。第二个问题确实存在(https://github.com/chrisfosterelli/dockerrootplease,https://medium.com/@mccode/understanding-how-uid-and-gid-work-in-docker-containers-c37a01d01cf#ce09)。最后一个链接包含建议。 - VonC
@Ryan 我已经编辑了答案,提出了一些替代方案。 - VonC
谢谢。我想这已经是最好的了。--user选项很好,但它只能保护主机免受构建不良容器的影响。它不能保护主机免受本地用户任意执行docker命令的影响(他们可以选择不使用它),而这正是他的Jenkins守护程序所需要的。 - Ryan

2

我也卡在了如何设置 Docker 构建服务器上。

目前我看到的基本情况如下...

  • Docker 命令需要 root 权限

    • 这是因为如果可以运行任意的 Docker 命令,您就拥有与主机上的 root 相同的权限。(您可以构建一个以 root 身份在内部运行的容器,并将其文件系统挂载到主机上的任何位置,从而允许任何 root 操作。)
  • "docker" 组是个大谎言,在我看来它实际上等同于将成员设为 root。

  • 我唯一能想到的为非 root 用户提供安全性保障的方式是构建自定义 bash 脚本来启动非常特定的 Docker 命令,然后 仔细审计 这些命令的安全影响,然后将这些脚本添加到 sudoers 文件中(授予非 root 用户无需密码即可进行 sudo)。

在我们将 Docker 集成到开发流程中的世界中(例如将 Docker 命令放入 Maven 构建中或允许开发人员对 Docker 构建服务器的构建定义进行任意更改),我不知道如何保证安全性。


0

经过大量的搜索和研究,我在上周解决了这个问题。

我发现要以非 root 用户运行 maven docker 容器,需要传递用户标志,例如 -u 1000。

但是为了使其正常工作,用户需要在镜像的 /passwd 目录中。为了解决这个问题,您可以将主机(Jenkins)/etc/passwd 目录添加到 docker 镜像中,并使用非 root 用户。

从您的系统命令参数在 docker run 容器中添加以下内容,以挂载正确的卷到 mvn 镜像中,以允许主机非 root 用户映射到 maven 容器内。

-v /share:/share -v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro -v "$HOME/.m2":/var/maven/.m2:z -w /usr/src/mymaven -e MAVEN_CONFIG=/var/maven/.m2 -e MAVEN_OPTS="-Duser.home=/var/maven"

我知道这可能不是最详细的答案,但它应该可以以非 root 用户身份运行 mvn 容器,特别是用于运行 otj-embedded-pg 进行集成测试,在本地测试通过但在 Jenkins 服务器上失败的情况下。

请查看此链接OTJ_EMBEDDED_RUN_IN_CI_SERVER

正如该帖子上的大多数发帖人建议创建新图像,其实并不需要这样做,您可以使用上面列出的命令运行最新的Maven Docker镜像,它会按照预期工作。

希望这能帮助那些可能遇到此问题并节省几个小时工作的人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接