Jenkins 管道中的 Docker 代理卷挂载未按预期工作
Posted
技术标签:
【中文标题】Jenkins 管道中的 Docker 代理卷挂载未按预期工作【英文标题】:Docker agent volume mount in Jenkins pipeline not working as expected 【发布时间】:2020-01-03 07:24:56 【问题描述】:使用卷挂载的 sn-p 会在 $JENKINS_HOME/workspace/<project-name>/?
(问号)而不是 $HOME/.m2/
下创建 maven 依赖项
请注意,settings.xml 镜像到我们的内部存储库。并且关于如何挂载的说明直接取自 jenkins.io
有人知道为什么会这样吗?
pipeline
agent
docker
image 'maven:3-alpine'
args '-v /tmp/jenkins/.m2:/root/.m2:rw,z'
stages
stage('Build')
steps
sh 'mvn clean install -s settings.xml'
这并不像独立使用 Docker 那样简单。我在 Jenkins slave 上创建了 /var/jenkins/.m2 目录,构建将在其中运行。确保新目录具有 775 权限(尽管可能不需要)并且还将所有者更改为与“/var/opt/slave/workspace/pipeline_test”的所有者相同(根据以下日志获取此路径)
$ docker login -u dcr-login -p ******** https:// nexus.corp.zenmonics.com:8449
Login Succeeded
[Pipeline]
[Pipeline] sh
+ docker inspect -f . nexus.corp.zenmonics.com:8449/maven:3-alpine
.
[Pipeline] withDockerContainer
cucj1sb3 does not seem to be running inside a container
$ docker run -t -d -u 1002:1002 -v /tmp/jenkins/.m2:/root/.m2:rw,z -w
/var/opt/slave/workspace/pipeline_test -v /var/opt/slave/workspace/pipeline_test:/var/opt/slave/workspace/pipeline_test:rw,z -v /var/opt/slave/workspace/pipeline_test@tmp:/var/opt/slave/workspace/pipeline_test@tmp:rw,z -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** nexus.corp.zenmonics.com:8449/maven:3-alpine cat
$ docker top c7282468dbb6952aadbe4bb495757e7047122b179c81516645ba23759b78c366 -eo pid,comm
Docker Hub (https://hub.docker.com/_/maven) 官方 maven 镜像的声明让我感觉卷挂载更新了
要创建预打包的存储库,请使用以下内容创建 pom.xml 您需要的依赖项并在 Dockerfile 中使用它。 /usr/share/maven/ref/settings-docker.xml 是一个设置文件 将本地存储库更改为 /usr/share/maven/ref/repository,但是 您可以使用自己的设置文件,只要它使用 /usr/share/maven/ref/repository 作为本地仓库。
【问题讨论】:
可能在管道运行期间未设置$HOME
,导致-v /.m2:/root/.m2
,其中docker run
上下文中的/
设置为jenkins 工作区目录。我会使用命名卷而不是像那样绑定安装目录。
您好 masseyb,我已更新以添加更多详细信息。我们在运行 Docker 的 Jenkins slave 上运行构建。我们在 Jenkins master 上没有 Docker,master 的作用只是克隆存储库并根据其调度算法将其远程到适当的 slave。如果您注意到上面发布的新日志,则以 /var/opt/slaves 开头的其他卷挂载路径位于从属计算机上。
【参考方案1】:
正如 @masseyb 在 cmets 中提到的,Jenkins 将 $HOME
视为当前的构建上下文。
有两种解决方法:
a) 使用 Jenkins 插件设置 Env 变量
您可以在 Jenkins 中使用Envinject Plugin 设置环境变量。
b) 指定绝对路径而不是$HOME/.m2
您可以为.m2
指定绝对路径,例如:
pipeline
agent
docker
image 'maven:3-alpine'
args '-v /home/samir-shail/.m2:/root/.m2'
stages
stage('Build')
steps
sh 'mvn -B'
注意:请检查 Jenkins 是否有权访问您的 $HOME/.m2/
目录。
【讨论】:
更新了原始票,如果有帮助,还可以查看上面为 masseyb 添加的评论。这不是很明显的设置,因此具有挑战性。可能我会尝试使用体积映射而不是 masseyb 建议的绑定映射,但我记得之前做过,但没有奏效。【参考方案2】:https://jenkins.io/doc/book/pipeline/docker/ 上的文档在卷安装方面具有误导性和浪费时间。
创建 Docker 容器时,它使用用户 1002 和组 1002 创建。用户 1002 无权访问 /root/.m2,只能访问注入到容器中的工作目录。
Dockerfile
FROM maven:3-alpine
COPY --chown=1002:1002 repository/ /usr/share/maven/ref/repository/
RUN chmod -R 775 /usr/share/maven/ref/repository
COPY settings.xml /usr/share/maven/ref/
Settings.xml
<localRepository>/usr/share/maven/ref/repository</localRepository>
Docker 命令
docker build -t <server>:<port>/<image-name>:<image-tag> .
docker push <server>:<port>/<image-name>:<image-tag>
docker volume create maven-repo
Jenkinsfile
pipeline
agent('linux2')
docker
label '<slave-label-here>'
image '<image-name>:<image-tag>'
registryUrl 'https://<server>:<port>'
registryCredentialsId '<jenkins-credentials-for-docker-login>'
args '-v maven-repo:/usr/share/maven/ref/repository/'
parameters
booleanParam(name: 'SONAR', defaultValue: false, description: 'Select this option to run SONAR Analysis')
stages
stage('Build')
steps
sh 'mvn clean install -s /usr/share/maven/ref/settings.xml -f pom.xml'
【讨论】:
以上是关于Jenkins 管道中的 Docker 代理卷挂载未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章
使用 Jenkins 中的 Kubernetes 插件未进行卷挂载
来自 AWS ECR 的 Jenkins 管道 Docker 代理