使用Jenkins声明式pipe道为dockerfile代理设置构build参数

我正在使用声明性pipe道语法在Docker容器中执行一些CI工作。

我注意到Jenkins的Docker插件运行一个容器,使用主机中jenkins用户的用户ID和组ID(即如果jenkins用户有用户ID 100和组ID 111,它将运行pipe道创build一个容器命令docker run -u 100:111 ... )。

我有一些问题,因为容器将与一个非现有的用户运行(特别是我遇到了一些问题,用户没有一个主目录)。 所以我想创build一个Dockerfile,它将接收用户ID和组ID作为构build参数,并在容器中创build适当的jenkins用户。 Dockerfile看起来像这样:

 FROM ubuntu:trusty ARG user_id ARG group_id # Add jenkins user RUN groupadd -g ${group_id} jenkins RUN useradd jenkins -u ${user_id} -g jenkins --shell /bin/bash --create-home USER jenkins ... 

dockerfile代理具有一个additionalBuildArgs属性,所以我可以在主机上读取jenkins用户的用户ID和组ID,并将它们作为构build参考发送,但现在的问题是,似乎没有办法执行这些在指定代理之前在声明式pipe道中执行命令。 我想我的Jenkinsfile是这样的:

 // THIS WON'T WORK def user_id = sh(returnStdout: true, script: 'id -u').trim() def group_id = sh(returnStdout: true, script: 'id -g').trim() pipeline { agent { dockerfile { additionalBuildArgs "--build-arg user_id=${user_id} --build-arg group_id=${group_id}" } } stages { stage('Foo') { steps { ... } } stage('Bar') { steps { ... } } stage('Baz') { steps { .. } } ... } } 

我有什么办法可以做到这一点? 我也尝试在一个节点内包装pipe道指令,但是pipe道需要位于文件的根目录下。

我证实,试图分配user_id和group_id没有节点没有工作,因为你发现,但这工作给我分配这些值,以后访问它们:

 def user_id def group_id node { user_id = sh(returnStdout: true, script: 'id -u').trim() group_id = sh(returnStdout: true, script: 'id -g').trim() } pipeline { agent { label 'docker' } stages { stage('commit_stage') { steps { echo 'user_id' echo user_id echo 'group_id' echo group_id } } } } 

希望这些也可以在你的additionalBuildArgs语句中工作。

在一个评论中,您指出了在使用它来configurationdockerfile之前,在声明式pipe道之外找出user_id和group_id的方法最可能的一个严重缺陷:它发现user_id的从站不一定匹配它用来启动基于Docker的构build的奴隶。 我没有任何方法,同时也保持声明Jenkinsfile约束。

您可以通过使用全局代理声明来保证所有阶段的一个从属: Jenkins声明式stream水线:当只为stream水线设置代理时,哪个工作空间与阶段相关联?

但是具有相同标签的多个节点引用不能保证相同的工作空间: Jenkins声明式pipe道:什么工作空间与仅为pipe道设置代理的阶段相关联?

你也可以像这样添加一个块:

 agent { dockerfile { args '-v /etc/passwd:/etc/passwd -v /etc/group:/etc/group' } } 

这将允许容器具有正确的用户和组ID。

您也可以使用args参数来解决问题。
如pipe道语法中所述 :

docker还可以select性地接受一个args参数,该参数可能包含直接传递给docker run调用的参数。

在代理部分使用dockerfile而不是docker时,这也是可能的。

我有像你一样的问题,以下几行对我很好:

  agent { dockerfile { dir 'Docker/kubernetes-cli' args '-u 0:0' //Forces Container tu run as User Root reuseNode true } } 

如果您拥有对Jenkins的pipe理权限,则可以添加以下两个脚本批准:

 staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods execute java.lang.String staticMethod org.codehaus.groovy.runtime.ProcessGroovyMethods getText java.lang.Process 

在这个URI中: http://${jenkins_host:port}/jenkins/scriptApproval/

这将允许您以这种方式在主服务器中执行一个shell命令:

 def user = 'id -u'.execute().text node { echo "Hello World ${user}" }