【问题标题】:Changing the user's uid in a pre-build docker container (jenkins)在预构建的 docker 容器 (jenkins) 中更改用户的 uid
【发布时间】:2022-03-15 19:54:01
【问题描述】:

我是 docker 新手,所以如果我缺少一个相当明显的过程,我为前面的愚蠢问题道歉。

我正在使用jenkins docker 映像设置一个持续集成服务器。我做了一个docker pull jenkins,并创建了一个用户jenkins,以允许我将容器中的/var/jenkins_home 挂载到我主机的/var/jenkins_home(也属于jenkins:jenkins 用户)。

问题是容器似乎用 uid 102 定义了 jenkins 用户,但我的主机将 jenkins 用户作为 1002,所以当我运行它时,我得到:

docker run --name jenkins -u jenkins -p 8080 -v /var/jenkins_home:/var/jenkins_home jenkins
/usr/local/bin/jenkins.sh: line 25: /var/jenkins_home/copy_reference_file.log: Permission denied

我只需将主机的jenkins 用户的uid 设置为/etc/passwd 中的102,但该uid 已被sshd 占用。我认为解决方案是将容器更改为使用 uid 1002,但我不确定如何。

编辑

其实主机上的用户102是messagebus,不是sshd。

【问题讨论】:

    标签: jenkins docker jenkins-docker


    【解决方案1】:

    请看一下我刚刚上传的docker文件: https://github.com/bdruemen/jenkins-docker-uid-from-volume/blob/master/Dockerfile 。 这里的 UID 是从挂载的卷(主机目录)中提取的,带有

    stat -c '%u' <VOLUME-PATH>
    

    然后将容器用户的UID更改为与

    相同的值
    usermod -u <UID>
    

    这必须以 root 身份完成,但随后会删除 root 权限

    gosu <USERNAME> <COMMAND>
    

    一切都在 ENTRYPOINT 中完成,所以真正的 UID 在你运行之前是未知的

    docker run -d -v <HOST-DIRECTORY>:<VOLUME-PATH> ...
    

    请注意,更改 UID 后,容器中的进程可能无法再访问其他一些文件,因此您可能需要一个

    chown -R <USERNAME> <SOME-PATH>
    

    在 gosu 命令之前。

    您也可以更改 GID,请在此处查看我的答案 Jenkins in docker with access to host docker 也许您想同时更改两者以提高安全性。

    【讨论】:

    • 这似乎是迄今为止最好的答案。人们关心容器的 UID 的原因是为了与主机文件系统进行交互,所以这很棒,从挂载的卷中获取 UID 并做必要的事情。
    【解决方案2】:

    假设没有其他用户的 UID 为 1002,您可以简单地更改 /etc/passwd 中的 UID。

    然后,您需要将主机上 /var/jenkins_home 的所有权更改为 UID 1002:

    chown -R jenkins /var/jenkins_home
    

    事实上,您甚至需要主机上的jenkins 用户来执行此操作;你可以简单地运行:

    chown -R 1002 /var/jenkins_home
    

    即使本地没有可用的 UID 1002 的用户,这也可以工作。

    另一种解决方案是基于 Jenkins 映像构建您自己的 docker 映像,该映像具有类似于以下内容的 ENTRYPOINT 脚本:

    #!/bin/sh
    chown -R jenkins /var/jenkins_home 
    exec "$@"
    

    这将(递归地)chown/var/jenkins_homeinsidejenkins 用户使用的任何 UID(假设您的 Docker 包含以 root 开头,即除非图像的历史记录中有USER 指令,否则为真)。

    更新

    您可以基于 (FROM ...) jenkins 映像创建一个 映像,并使用 Dockerfile 对 /etc/passwd 文件执行必要的编辑。但这似乎付出了很多努力,却收效甚微。目前尚不清楚您为什么要在主机上创建 jenkins 用户,或者您是否确实需要访问主机上的 jenkins 主目录。

    如果您所做的只是提供数据持久性,请考虑使用数据卷容器和--volumes-from 而不是主机卷,因为这会将数据卷与您的主机隔离开,这样 UID 冲突就不会造成混淆。

    【讨论】:

    • 问题是图像使用的 uid 是 102,它是由主机获取的。如何更改容器内用户的 uid?
    【解决方案3】:

    我遇到了同样的错误,我关闭了 SELinux(在 CEntOS 上)并且它可以工作。 否则,最好使用 SEManage 命令调整 SElinux。

    【讨论】:

    • 不要关闭 SELinux,而是使用 --privileged 选项运行 docker。例如:docker run --name jenkins -d -p 8080:8080 -p 50000:50000 -v /home/jenkins:/var/jenkins_home -u 1001 --privileged jenkins
    【解决方案4】:

    理想的情况是更改 jenkins 使用的 Dockerfile 中的用户 UID 与主机使用的 UID 相同(请记住,对于非 root 用户必须这样做,如果 root 创建一个新用户并在容器给该用户)。

    • 假设用户在主机上的 UID 为 1003,用户名为 jenkins(使用 $id 获取用户和组 id)。

    添加到您的 Dockerfile

    
    # Modifies the user's UID and GID
    
    RUN groupmod -g 1003 jenkins && usermod -u 1003 -g 1003 jenkins
    
    # I use a group (docker) on my host to organize the privileges, 
    #if that's your # case add the user to this group inside the container.
    
    RUN groupadd -g 998 docker && usermod -aG docker nginx
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多