一尘不染

Jenkins + Docker:使用Image.inside命令时如何控制Docker用户

jenkins

尊敬的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插件,因为它通过Jenkins中维护的凭据简化了自己的Docker注册表的使用。但是,如果无法使用Docker插件,还有另一种简单的方法可以实现我的目标吗?

预先感谢您的时间


阅读 955

收藏
2020-07-25

共1个答案

一尘不染

正如您在此处此处所看到的那样,对运行Jenkins的用户的uid和gid进行了硬编码(在您的情况下,是在官方docker映像内创建的Jenkins用户)。

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

已编辑

我该如何改变这种行为?有没有可以关闭-u 1000:1000的开关?

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

这甚至是错误吗?

这个拉取请求中,似乎他们正在努力。

但是,如果无法使用Docker插件,还有另一种简单的方法可以实现我的目标吗?

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

2020-07-25