使用Docker Jenkins容器流水线构建Docker镜像时找不到Docker

38

我有一个运行在Docker容器中的Jenkins,现在我想使用流水线构建一个Docker镜像,但是Jenkins容器总是提示找不到Docker。

[simple-tdd-pipeline] Running shell script
+ docker build -t simple-tdd .
/var/jenkins_home/workspace/simple-tdd-pipeline@tmp/durable-
ebc35179/script.sh: 2: /var/jenkins_home/workspace/simple-tdd-
pipeline@tmp/durable-ebc35179/script.sh: docker: not found

以下是我如何运行Jenkins镜像的步骤:

docker run --name myjenkins -p 8080:8080 -p 50000:50000 -v 
/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock 
jenkins

以下是Jenkins镜像的DockerFile: https://github.com/jenkinsci/docker/blob/9f29488b77c2005bbbc5c936d47e697689f8ef6e/Dockerfile

8个回答

26

你需要安装Docker客户端,可以在Dockerfile文件中加入以下代码:

RUN curl -fsSLO https://get.docker.com/builds/Linux/x86_64/docker-17.04.0-ce.tgz \
  && tar xzvf docker-17.04.0-ce.tgz \
  && mv docker/docker /usr/local/bin \
  && rm -r docker docker-17.04.0-ce.tgz

来源


1
我添加了上述脚本并构建了dockerfile,但是出现以下错误:curl: (23) 写入失败 (0 != 16384) - kitko112
1
现在我可以运行该命令,只需在curl命令之前将用户更改为root。用户root。 - kitko112
是的。或者在重新定义用户的那一行前添加命令。 - Robert

22

在您的Jenkins界面中,转到"管理Jenkins/全局工具配置"

然后向下滚动到Docker安装并单击"添加Docker"。给它一个名称,比如"myDocker"

确保选中"自动安装"复选框。单击"添加安装程序"并选择"从docker.com下载"。在Docker版本中保留"latest"。确保单击保存。

enter image description here

在您的Jenkinsfile中,在运行任何docker命令之前,请添加以下阶段:
 stage('Initialize'){
        def dockerHome = tool 'myDocker'
        env.PATH = "${dockerHome}/bin:${env.PATH}"
    }

1
这种方法需要额外的配置吗?我也做了同样的事情,并能够运行简单的命令,如 docker -v,但当涉及到 docker build 时,我得到了 Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?... 有什么建议吗? - ChernikovP
@ChernikovP 我也遇到了同样的错误。你解决了吗? - khushboo29
@ChernikovP,@khushboo29,您需要将jenkins添加到组docker中,可以使用以下命令:sudo usermod -a -G docker jenkins - Guilherme Abacherli
它可以工作了,我必须将代码添加到stage>steps>scripts中才能运行。 - D4ITON

14

编辑:2018年5月

正如Guillaume Husta所指出的,这篇jpetazzo博客文章反对使用这种技术:

本文的早期版本建议从主机向容器中挂载绑定docker二进制文件。由于Docker Engine不再作为(几乎)静态库分发,因此这种方法已经不可靠。

Docker客户端应该安装在容器内,如此处所述。此外,jenkins用户应该加入docker组,可以执行以下命令:

$ docker exec -it -u root my-jenkins /bin/bash
# usermod -aG docker jenkins

最后重启 my-jenkins 容器即可。

原始回答:

您可以像@Adrian Mouat博客文章中所示一样使用主机的docker引擎

 docker run -d \
   --name my-jenkins \
   -v /var/jenkins_home:~/.jenkins \
   -v /var/run/docker.sock:/var/run/docker.sock \
   -p 8080:8080 jenkins

这样可以避免在主机和 Jenkins 容器上有多个 Docker 引擎版本。


1
最佳的卷映射是 -v /usr/local/bin:/user/bin,否则会导致错误提示:docker: Error response from daemon: Mounts denied: EOF. - Folyd
1
仍然建议使用吗?请参阅此说明:本文的早期版本建议将Docker二进制文件从主机绑定到容器中。这已不再可靠,因为Docker引擎不再作为(几乎)静态库分发。来源:https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/ - Guillaume Husta
@Guillaume Husta,你可能是对的,如果Docker使用系统库,它可能是不安全的。然而,我已经在一个coreos主机上使用这个绑定,在jenkins debian镜像中使用了1年,现在已经在30多个docker镜像中使用了... 在docker build过程中没有看到任何冲突或问题。 - François Maturel
好的,感谢您的反馈。就像您所说的那样,这将取决于上下文。 - Guillaume Husta
我认为原始答案仍然有效,因为这种使用卷挂载暴露主机的Docker二进制文件的方式正是Red Hat的Openshift容器平台v3.11(LTS)在Docker构建策略下所做的(您可以清楚地看到服务帐户创建的Volume Mounts中列出了/var/run/docker.sock),因此我希望这能缓解一些关于稳定性的担忧 ;) - mirekphd

8
问题出在您的Jenkins上,它无法使用docker引擎,即使您从插件管理器安装了docker也不行。通过研究,我发现有一些替代方法可以解决这个问题:
1:使用预先安装了docker的docker镜像(例如getintodevops/jenkins-withdocker:lts)来构建镜像。
2:从jenkins/jenkins构建镜像,并将卷挂载到主机上,然后通过创建另一个具有相同卷并执行bash命令来安装docker或使用Robert的建议来自己安装docker。
docker run -p 8080:8080 -p 50000:50000 -v $HOME/.jenkins/:/var/jenkins_home 
-v /var/run/docker.sock:/var/run/docker.sock jenkins/jenkins:latest

或 3:最简单的方法是将您主机上已安装的Docker路径添加到Jenkins容器中,方法如下:-v $(which docker):/usr/bin/docker

您的Docker命令应该像这样:

docker run \
--name jenkins --rm \
-u root -p 8080:8080 -p 50000:50000 \
-v $(which docker):/usr/bin/docker\
-v $HOME/.jenkins/:/var/jenkins_home 
-v /var/run/docker.sock:/var/run/docker.sock \
jenkins/jenkins:latest

[Source]https://forums.docker.com/t/docker-not-found-in-jenkins-pipeline/31683

额外选项:如果您只想使用单个Jenkins服务器,则没有意义,但始终可以使用映像安装类似于Ubuntu的操作系统,并从那里安装jenkins .war文件。


2
docker run -d \
--group-add docker \
-v $(pwd)/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v $(which docker):/usr/bin/docker \
-p 8080:8080 -p 50000:50000 \
jenkins/jenkins:lts

只需在运行docker时添加选项--group-add docker即可。最初的回答。

3
使用上述方法时出现了以下错误:docker: Error response from daemon: Unable to find group docker. - madhu131313

1

这一部分帮助我在Jenkins容器中安装Docker:https://www.jenkins.io/doc/book/installing/docker/#downloading-and-running-jenkins-in-docker。文档中提到了以下内容。

推荐使用的Docker镜像是官方的jenkins/jenkins镜像(来自Docker Hub存储库)。此镜像包含当前的长期支持(LTS)版本的Jenkins(即生产就绪)。但是,此镜像没有docker CLI,并且不捆绑经常使用的Blue Ocean插件和功能。这意味着,如果您想要使用Jenkins和Docker的全部功能,则可能需要通过以下描述的安装过程进行安装。


1
版本固定是建议用于可重复构建的。不要盲目地用隐式的:latest替换。 - OneCricketeer
已注意,感谢指出。已编辑答案。 - Prabhatika Vij

1
将Docker路径添加到卷中的容器中,例如:-v $(which docker):/usr/bin/docker
 docker run -d \
   --name my-jenkins \
   -v $(which docker):/usr/bin/docker \
   -v /var/jenkins_home:~/.jenkins \
   -v /var/run/docker.sock:/var/run/docker.sock \
   -p 8080:8080 jenkins

0

我遇到了同样的问题。我的Jenkins服务器中找不到Docker。因此,为了解决这个问题,我们需要安装Docker以及Jenkins镜像。

可行的代码:

1.Create one docker file named as "DockerfileJenkins"
2. Create docker-compose file for Jenkins Server.
3. Run the docker-compose file. 

DockerfileJenkins

FROM jenkins/jenkins

USER root

# see https://docs.docker.com/compose/install/
RUN curl -L \
  "https://github.com/docker/compose/releases/download/1.25.3/docker-compose-$(uname -s)-$(uname -m)" \
  -o /usr/local/bin/docker-compose \
  && chmod +x /usr/local/bin/docker-compose

RUN curl -fsSL https://get.docker.com | sh


USER jenkins

docker-compose:

version: '2'
services:

  jenkins:
    build:
      context: .
      dockerfile: DockerfileJenkins
    hostname: jenkins
    container_name: jenkins
    restart: always
    privileged: true
    user: root
    ports:
      - 8083:8080
      - 50003:50000

    volumes:
      - ~/jenkins_data:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接