首页 > 解决方案 > 写入 docker bind mount 的文件在 jenkins 主机上不可见

问题描述

更新 从我看到的日志中......

21:05:51  Running on ip-10-0-4-23.eu-west-2.compute.internal in /home/jenkins/workspace/myproj
...
... docker stuff happens here
...
21:05:54  Running on ip-10-0-4-9.eu-west-2.compute.internal in /home/jenkins/workspace/myproj

所以我假设因为主机不同(注意差异 IP)绑定挂载在第一个,而不是第二个。

有没有办法强制它保持在同一个主机/代理上?

老问题

我有一个 jenkins 管道工作,它使用一个 docker 容器来完成大部分繁重的工作。我想在 docker 容器中“做一些事情”,最终会生成一堆文件。我希望在 docker 容器退出(并被 jenkins 删除)后,这些文件在“父”代理上可用,以便我可以将它们压缩并存档或其他任何东西。

由于 jenkins 将启动 docker 并使用绑定挂载将 jenkins 工作区链接到容器内的文件夹,我原以为将文件写入 docker 容器内的该文件夹会导致文件存在于主机上,但这不会似乎工作。

ls -la块中的不Generate artifact显示file-from-build-${env.BUILD_NUMBER}.txt. 在编写/列出文件时,我已经确认pwd我在正确的目录中。

pipeline {
    agent any
    environment {
        userId = sh(script: "id -u ${USER}", returnStdout: true).trim()
    }
    stages {
        stage('Prep') {
            // do some stuff on the "any" agent
        }
        stage('Build') {
            agent {
                dockerfile {
                    filename 'Dockerfile.build'
                    additionalBuildArgs "--build-arg UID=${userId}"
                }
            }
            steps {
                sh "touch file-from-build-${env.BUILD_NUMBER}.txt"
                sh 'ls -la'
            }
        }
        stage('Generate artifact') {
            steps {
                sh "ls -la"
            }
        }
    }
}

从日志中,jenkins 使用以下命令启动 docker:

docker run -t -d -u 1001:1001 -w /home/jenkins/workspace/myproj -v /home/jenkins/workspace/myproj:/home/jenkins/workspace/myproj:rw,z -v /home/jenkins/workspace/myproj@tmp:/home/jenkins/workspace/myproj@tmp:rw,z

我的 Dockerfile.build 如果有帮助:

FROM php:7.4-alpine

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer --2

RUN apk update && apk upgrade && \
    apk add --no-cache git openssh zip

# create a jenkins user inside the docker image (so that I can put some ssh keys for use in it's home folder)
ARG UID=1001
RUN adduser -D -g jenkins -s /bin/sh -u $UID jenkins \
    && mkdir -p /home/jenkins/.ssh \
    && touch /home/jenkins/.ssh/id_rsa \
    && chown -R jenkins:jenkins /home/jenkins/.ssh \
    && chmod 700 /home/jenkins/.ssh/ \
    && chmod 600 /home/jenkins/.ssh/id_rsa
    
USER jenkins

如果这很重要,我正在 docker 容器中做繁重的工作,因为我需要安装一些我在普通 jenkins 代理上没有的工具。

标签: dockerjenkinsjenkins-pipeline

解决方案


据我了解,该reuseNode true指令是为了做你想做的事,请参阅https://www.jenkins.io/doc/book/pipeline/syntax/

在你的情况下,它会是

            agent {
                dockerfile {
                    filename 'Dockerfile.build'
                    additionalBuildArgs "--build-arg UID=${userId}"
                    reuseNode true
                }
            }

我不得不说我看到reuseNode true并不总是按预期工作,但我没有时间深入研究这个问题。


推荐阅读