我正在与docker和jenkins合作,我正在尝试做两项主要任务:
- 使用jenkins控制和管理docker映像和容器(运行/启动/停止)
- 在docker镜像中设置一个开发环境,然后使用jenkins构建并测试容器中的应用程序
当我在网上冲浪时,我发现了许多解决方案:
- 将jenkins作为容器运行,并将其与其他容器链接
- 将jenkins作为服务运行,并使用提供的jenkins插件来支持docker
- 在包含开发环境的容器中运行jenkins
所以我的问题是什么是最好的解决方案,或者你可以建议其他方法。
我又听到一个关于在容器中运行容器的问题。这是一个好的做法还是最好避免?
将Jenkins作为容器化服务运行并不是一项困难的任务。有很多图片可以让你做到这一点。我只花了几分钟的时间就让Jenkins 2.0-beta-1在一个容器中运行,从源代码进行编译(图片可以在这里找到)。特别的是,我喜欢这种方法,你只需要确保使用数据卷或数据容器作为jenkins_home
来保持你的数据。
当你想在容器中使用这个Jenkins来构建和管理容器时,事情会变得有点棘手。为了实现这一点,您需要在docker中实现一个名为docker的东西,因为您需要在Jenkins容器中提供一个docker守护进程和客户端。
有一个很好的教程解释了如何做到这一点:Docker in Docker with Jenkins and Supervisord。
基本上,您将需要使用类似supervisord的东西使两个进程(Jenkins和Docker)在容器中运行。它是可行的,并宣称具有良好的隔离等……但可能真的很棘手,因为docker守护进程本身有一些依赖项,这些依赖项也需要存在于容器中。因此,仅仅使用supervisord并同时运行这两个过程是不够的,您需要利用DIND项目本身来使其工作。。。并且您需要在特权模式下运行容器。。。你需要处理一些奇怪的DNS问题。。。
就我个人而言,让一些简单的事情发挥作用听起来太多了,在一个容器内运行两个服务似乎打破了docker的良好做法和关注点分离原则,这是我想避免的。
当我读到这篇文章时,我的观点变得更加强烈:在Docker中为您的CI或测试环境使用Docker?三思而后行。值得一提的是,这最后一篇文章是来自DIND作者本人,因此他值得关注。
我的最终解决方案是:将Jenkins作为一个容器化服务运行,是的,但将docker守护进程视为底层服务器供应的一部分,即使因为您的docker缓存和映像是您可能想要持久化的数据,并且它们完全由守护进程拥有和控制。
有了这个设置,您所需要做的就是在Jenkins映像中安装docker守护进程套接字(它也需要docker客户端,但不需要服务):
$ docker run -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock -v local/folder/with/jenkins_home:/var/jenkins_home namespace/my-jenkins-image
或者用docker编写volumes
指令:
---
version: '2'
services:
jenkins:
image: namespace/my-jenkins-image
ports:
- '8080:8080'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- local/folder/with/jenkins_home:/var/jenkins_home
# other services ...