docker - Jenkins 上带有 docker 代理的易碎管道
问题描述
我们有几个作为物理机器运行的 Jenkins 代理。到目前为止,我在代理本身上运行了我的 Jenkins 管道,我现在尝试使用 Jenins docker 插件将构建和测试执行移动到 docker 容器中。
您可以在下面找到我们的 Jenkinsfile 的简化版本,它使用 gradle 来构建、测试和打包 Java Spring Boot 应用程序。
node {
stage('Preparation') {
cleanWs()
checkout scm
notifyBitbucket()
}
}
pipeline {
agent {
docker {
image "our-custom-registry.com/jenkins-build:latest"
registryUrl 'https://our-custom-registry.com'
registryCredentialsId '...'
alwaysPull true
args "-u jenkins -v /var/run/docker.sock:/var/run/docker.sock" // the pipeline itself required docker
}
}
stages {
stage('Build') {
steps {
sh './gradlew assemble classes testClasses'
}
}
stage('Test') {
parallel {
stage('Unit Tests') {
when { expression { return build_params.ENABLE_UNITTEST } }
steps {
sh './gradlew test'
junit UNIT_TEST_RESULT_DIR
}
}
stage('Integration Tests') {
when { expression { return build_params.ENABLE_INTEGRATION } }
steps {
sh './gradlew integration'
junit INTEGRATION_TEST_RESULT_DIR
}
}
}
}
stage('Finalize') {
stage('Docker Push') {
when { expression { return build_params.ENABLE_DOCKER_PUSH } }
steps {
sh './gradlew pushDockerImage'
}
}
}
}
post {
cleanup {
cleanWs()
}
always {
script {
node {
currentBuild.result = currentBuild.result ?: 'SUCCESS'
notifyBitbucket()
}
}
}
}
}
下面是我用于构建映像的 Dockerfile。如您所见,我手动创建了一个 Jenkins 用户并将其添加到 docker 组(不幸的是,GID 是 998 或 999,具体取决于 Jenkins 代理)。
FROM openjdk:8-jdk-stretch
USER root
# prerequisites:
# - a user and a group Jenkins with UID/GID=1001 exist
# - the user home is /var/jenkins
# - the user is in the docker group
# - on some agents docker has the gid 998, on some it is 999
RUN apt-get update \
&& apt-get -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common rsync tree \
&& curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - \
&& add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable" \
&& apt-get update \
&& apt-get -y install docker-ce docker-ce-cli containerd.io \
&& groupadd -g 1001 jenkins \
&& groupadd -f -g 998 docker1 \
&& groupadd -f -g 999 docker2 \
&& useradd -d "/var/jenkins" -u 1001 -g 1001 -m -s /bin/bash jenkins \
&& usermod -a -G 998 jenkins \
&& usermod -a -G 999 jenkins
USER jenkins
Jenkins 然后执行以下命令
docker run -t -d -u 1001:1001 -u jenkins -v /var/run/docker.sock:/var/run/docker.sock -w /var/jenkins/workspace/JOB_NAME -v /var/jenkins/workspace/JOB_NAME:/var/jenkins/workspace/JOB_NAME:rw,z -v /var/jenkins/workspace/JOB_NAME@tmp:/var/jenkins/workspace/JOB_NAME@tmp:rw,z -e ******** ... our-custom-registry.com/base/jenkins-build:latest cat
这条管道工作得很好......有时!然而,大多数时候,一些文件会神秘地丢失。
例如,mybuild.gradle
由包含的多个其他文件组成。在构建过程中的某个时刻,这些文件之一似乎丢失了。
+ ./gradlew pushDockerImage
FAILURE: Build failed with an exception.
* Where:
Build file '/var/****/workspace/JOB_NAME/build.gradle' line: 35
* What went wrong:
A problem occurred evaluating root project 'foo'.
> Could not read script '/var/****/workspace/JOB_NAME/build/gradle/scripts/springboot-plugin.gradle' as it does not exist.
丢失的总是一个不同的文件。
tree
我刚刚开始运行只是./gradlew
为了确保文件没有被实际删除。
有人知道这里会发生什么吗?
更新
忘记我所说的关于 docker 的一切,这是一个纯粹的 Gradle 和 Jenkins 问题。当我用普通的 Jenkins 代理替换 docker 代理时,会出现同样的问题。问题似乎是您无法在同一目录上并行运行多个 gradle 任务。
解决方案
推荐阅读
- mysql - How to sum rows with the same date from a derived table in Mysql8.0? and why GROUP BY failed?
- amazon-web-services - 从 aws lambda post 请求中获取参数
- c# - ASP.NET Core API 在 Linux 服务器上执行 bash 命令
- javascript - 嵌套多个过滤器方法javascript
- javascript - 重命名对象数组中的嵌套键JS
- c# - WebApi GET 在 Postman 中未命中,但在 chrome 中有效
- mongodb - 如何使用 API Key 使用 Mongodb Stitch API?
- c++ - 关于 std::variant 的一般问题
- php - URL 重写 (.htaccess) index.php?page=foo&lang=en 到 /en/foo
- google-chrome - 从命令行(Chrome或Firefox)全屏自动播放嵌入式视频?