【问题标题】:Trying to push image to DockerHub in containerized Jenkins尝试在容器化的 Jenkins 中将图像推送到 DockerHub
【发布时间】:2021-12-03 17:52:52
【问题描述】:

我正在容器中运行的 Jenkins 中设置 CI 管道。我正在使用官方的 jenkins/jenkins:latest docker image,没有任何修改。在 Jenkins 本身上,我安装了 docker 插件,并在全局工具配置中添加了 docker 安装,并在管道工具部分添加了 dockerTool。

我使用以下命令创建了容器:

docker run -d -u root -p 8080:8080 -p 50000:50000 -v /var/run/docker.sock:/var/run/docker.sock -v jenkins_home:/var/jenkins_home jenkins/jenkins:latest

我安装了 docker.sock 以使用主机上的部分 docker 来构建映像。 这是 Jenkinsfile 的一部分,但失败了:

stage('PUSH') {
        steps {
            script {
                dockerImage = docker.build 'mygithub/spring-petclinic:latest'
                docker.withRegistry( '', 'dockerHubCreds' ) {
                  dockerImage.push()
                }
            }
        }
    }

镜像构建成功。仅当我尝试将图像推送到 DockerHub 时,构建才会失败。它说没有这样的文件/目录称为 Docker,但上一步实际上打印了 docker build 命令。

我在下面提供了日志。

+ docker build -t qeqoos/spring-petclinic:latest .
Sending build context to Docker daemon  63.25MB

Step 1/4 : FROM openjdk:8-jre-alpine3.9
 ---> f7a292bbb70c
Step 2/4 : COPY target/spring-petclinic-2.5.0-SNAPSHOT.jar /usr/bin/spring-petclinic.jar
 ---> ced11038c9dd
Step 3/4 : EXPOSE 80
 ---> Running in f222a20aad19
Removing intermediate container f222a20aad19
 ---> 3cd6a16e7890
Step 4/4 : ENTRYPOINT ["java", "-jar", "/usr/bin/spring-petclinic.jar", "--server.port=80"]
 ---> Running in 0a392d01e56b
Removing intermediate container 0a392d01e56b
 ---> 9afe8b544a7b
Successfully built 9afe8b544a7b
Successfully tagged qeqoos/spring-petclinic:latest
[Pipeline] withEnv
[Pipeline] {
[Pipeline] withDockerRegistry
$ docker login -u qeqoos -p ******** https://index.docker.io/v1/
[Pipeline] // withDockerRegistry
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
java.io.IOException: error=2, No such file or directory
    at java.base/java.lang.ProcessImpl.forkAndExec(Native Method)
    at java.base/java.lang.ProcessImpl.<init>(ProcessImpl.java:340)
    at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:271)
    at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1107)
Caused: java.io.IOException: Cannot run program "docker": error=2, No such file or directory
    at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1128)
    at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1071)
    at hudson.Proc$LocalProc.<init>(Proc.java:252)
    at hudson.Proc$LocalProc.<init>(Proc.java:221)
    at hudson.Launcher$LocalLauncher.launch(Launcher.java:995)
    at hudson.Launcher$ProcStarter.start(Launcher.java:507)
    at hudson.Launcher$ProcStarter.join(Launcher.java:518)
    at org.jenkinsci.plugins.docker.commons.impl.RegistryKeyMaterialFactory.materialize(RegistryKeyMaterialFactory.java:101)
    at org.jenkinsci.plugins.docker.workflow.AbstractEndpointStepExecution2.doStart(AbstractEndpointStepExecution2.java:53)
    at org.jenkinsci.plugins.workflow.steps.GeneralNonBlockingStepExecution.lambda$run$0(GeneralNonBlockingStepExecution.java:77)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:829)
Finished: FAILURE

对于容器中的 Jenkins,有没有更好的方法,或者有什么建议如何让 Jenkins 推送图像?谢谢。

【问题讨论】:

    标签: docker jenkins-pipeline


    【解决方案1】:

    jenkins/jenkins:latest 默认不会有docker client 二进制文件,你只需将unix socket 挂载到容器中,这肯定是不够的。

    我认为输出中的command 只是打印出来:它计划使用的 docker 命令是什么,并不意味着它已经运行它。

    所以,对你来说,你需要在jenkins容器中安装docker客户端:

    • 要么使用绑定挂载:
    docker run -v `which docker`:/usr/bin/docker ......
    
    • 或者,如果宿主机的docker客户端不适合容器环境,直接从here下载预构建的docker client,将docker二进制复制到容器中。

    【讨论】:

    • 很好,我尝试了第一个建议,它奏效了。我还尝试使用 jenkins 和 docker 创建图像,效果也很好,但是图像从 460MB 变成了 1GB(哎呀)。只是想知道,将客户端和套接字从主机绑定到 docker 容器是一种好习惯吗?
    • 如果你使用预编译二进制(第二种方案),你只需要一个文件docker,它只有50M。 Bind sockets,对于您的场景,这是常见的方式。 Bind docker executable on host to container:取决于你的场景,如果你改变容器的基础镜像,它可能会崩溃,比如将容器更改为基于alpine,但如果你的情况没问题,那就没关系。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    相关资源
    最近更新 更多