【问题标题】:Jenkins + Docker: How to control docker user when using Image.inside commandJenkins + Docker:使用 Image.inside 命令时如何控制 docker 用户
【发布时间】:2023-03-27 13:46:02
【问题描述】:

尊敬的 Stackoverflow 社区,

我正在尝试使用 docker 映像作为构建过程的容器来设置 Jenkins CI 管道。我正在定义一个 Jenkinsfile 以将构建管道作为代码。我正在做这样的事情:

node {
  docker.withRegistry('http://my.registry.com', 'docker-credentials') {     
      def buildimage = docker.image('buildimage:latest');
      buildimage.pull();
      buildimage.inside("")
      {
        stage('Checkout sources') {
          git url: '...', credentialsId: '...'
        }

        stage('Run Build and Publish') {
            sh "..."
        }
      }
  }
}

不幸的是,我偶然发现了 Docker 管道插件的奇怪行为。在构建输出中,我可以看到 Image.inside(...) 命令使用

触发容器
docker run -t -d -u 1000:1000 ...

这使我的构建失败,因为在 Dockerfile 中定义的用户没有 UID 1000 ...实际上是另一个用户。我什至尝试在 Jenkinsfile 中指定应该使用哪个用户

node {
  docker.withRegistry('http://my.registry.com', 'docker-credentials') {     
      def buildimage = docker.image('buildimage:latest');
      buildimage.pull();
      buildimage.inside("-u otheruser:othergroup")
      {
        stage('Checkout sources') {
          git url: '...', credentialsId: '...'
        }

        stage('Run Build and Publish') {
            sh "..."
        }
      }
  }
}

但这会导致生成的 docker run 命令中出现重复的 -u 开关

docker run -t -d -u 1000:1000 -u otheruser:othergroup ...

显然只有第一个 -u 被应用,因为我的构建仍然失败。我还使用 whoami 进行了调试以验证我的假设。

所以我的问题是:我怎样才能改变这种行为?有没有可以关闭 -u 1000:1000 的开关?这甚至是一个错误吗?我实际上喜欢使用 Docker 插件,因为它简化了使用自己的 docker 注册表和在 Jenkins 中维护的凭据。但是,如果 Docker 插件不可用,还有其他简单的方法可以实现我的目标吗?

提前感谢您的宝贵时间

【问题讨论】:

    标签: docker jenkins jenkins-pipeline


    【解决方案1】:

    我发现您实际上可以通过添加args 来更改用户,如下所示。尽管 -u 1000:1000 仍将存在于 docker run 中,但在 1000:1000 之后您将额外添加一个 -u [您的用户]。 Docker 将实际使用最新的 -u 参数

    agent {
      docker {
        image 'your image'
        args '-u root --privileged'
      }
    }
    

    【讨论】:

    • 这段代码是对的,不过@z0beat的回答也对,对我帮助很大
    • running docker start -u 1:1 -u 2:2 ... 在本地执行时设置用户 2。但是当开始使用 Jenkins 时,它似乎不起作用。为什么?
    • 我和@Datz 有同样的问题,我用 -u 设置了用户,但没有执行任何操作 -u root 可以工作
    • 我遇到了这个问题并通过使用my_image.inside('-u root:root') 解决了它,然后在我的sh 命令中切换到我需要运行命令的用户(即'su - my_user')跨度>
    【解决方案2】:

    如您所见,herehere 是硬编码的,即附加运行 Jenkins 的用户的 uid 和 gid(在您的情况下,是在官方 docker 映像中创建的 Jenkins 用户)。

    您可以更改在 Jenkins 映像中运行进程的用户,将 --user(或 -u)参数传递给 docker run 命令。也许这可以最大限度地减少您的问题。

    已编辑

    我怎样才能改变这种行为?有没有可以关闭 -u 1000:1000 的开关?

    您无法在实际版本中更改此行为,因为 whoami 是硬编码的。

    这甚至是一个错误吗?

    this 的拉取请求中似乎他们正在处理它。

    但是,如果 Docker 插件不可用,还有其他简单的方法可以实现我的目标吗?

    Jenkins 附带的新管道插件版本也使用 docker-workflow-plugin 来运行容器。我不知道另一个插件可以以简单的方式运行它。要解决此问题,您可以以 root 身份运行 Jenkins,但这是一个非常丑陋的解决方案。

    【讨论】:

    • 对不起,但这不能回答我的问题。使用 -u 运行的提示没有帮助,因为它不像问题中所述的那样工作。
    • 我想回答你的问题,确保你的 Dockerfile 在容器中创建一个用户,其 UID 和 GID 与最终将运行管道的 jenkins 用户(或其他一些非特权用户)匹配:stackoverflow.com/questions/62958484/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 2018-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多