使用Jenkins Pipeline插件和Docker打造容器化构建环境


Docker和Jenkins像DevOps界的巧克力和花生酱那样,它们的组合产生了无数的机会,固然也产生了不少难题,笔者将说起这两个方面。node

本文中,我假定读者已经熟悉Jenkins和Docker,我将把焦点放在特定的配置上而不是把笔墨花费在许多博文已经介绍过的入门概念上。git

 

 设定目标github

 

我所要达成的目标其实很是简单:在一个容器中搭建Jenkins主节点,而且在多个主机上搭建多个JNLP代理容器。这些代理节点能够运行在不一样的AWS VPC或者ECS上。docker

个人目标是获得一个能在任何主机上部署的通用配置,而每一个项目分别定义各自的构建环境。这样各个开发团队就能够掌控这份配置,而不用经由Jenkins的构建团队。我会尽可能避免构建一个特定工具集的代理节点。容器技术能实现这样的构建环境,可是要真正把每一个细节都作好绝对是一个挑战。安全

为了实现这个目标,我还使用了Jenkins Pipeline / Workflow插件。这个插件让你能很是优雅地使用DSL语言描述构建过程,例如这样简单地定义:架构

```js
node('test-agent') {
    stage "Container Prep"
    // do the thing in the container
    docker.image('maven:3.3.3-jdk-8').inside {
        // get the codez
        stage 'Checkout'
        git url: 'https://github.com/damnhandy/Handy-URI-Templates.git'
        stage 'Build'
        // Do the build
        sh "./mvnw clean install"
    }
}
```
socket

这个pipeline会在一个名为"test-agent"的Jenkins代理上执行,它会基于“maven”3.3.3-jdk-8”镜像构建一个容器。这个pipeline在物理节点上能正常运行,可是在容器中运行则会报错。maven

 

运行在Docker中的Dockeride

 

在容器中运行Jenkins的主或从节点,可能有人会觉得我须要特权模式来使用"Docker in Docker",可是我并无,Jérôme Petazzoni发表了一篇文章[《用Docker-in-Docker来构建持续集成环境?请三思》](https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/),你应该参考一下这篇文章。工具

若是你还在使用wrapdocker的脚本,你应该问问本身为何,由于这样用起来更简单:

```sh
docker run -v ${JENKINS_HOME}:/var/jenkins_home \
     -v /var/run/docker.sock:/var/run/docker.sock \
     -p 8080:8080 -p 50000:50000 \
     index.csphere.cn/microimages/jenkins
```

这个命令会启动Jenkins而且能够拥有全部的容器操做功能,因此并不须要特权模式来启动容器,也不须要"Docker-in-Docker"模式。

有个地方须要注意:在这里你不能用官方的Jenkins镜像,由于jenkins用户须要属于docker用户组,这样才能使用socket,从而能在容器中的Jenkins调用docker,最终实现经过Jenkins构建和运行其余容器。

 

 Jenkins JNLP代理容器

 

在“系统管理”=>“管理节点”页面,点击“新建节点”,能够添加slave:

Jenkins从节点的启动方式与主节点相似,它也须要链接docker的socket接口,你能够这样启动:

```sh
docker run -v ${JENKINS_HOME}:/var/jenkins_home \
    -v /var/run/docker.sock:/var/run/docker.sock \
    --name=jenkins-slave \
    -d index.csphere.cn/microimages/jenkins-slave \
    -url
http://jenkins-master:8080/ \
a0a1b92971030d5f5dd69bd972c6cd899f705ddd3699ca3c5e92f937d860be7e \
test-agent
```

与Jenkins主节点同样,你须要确保jenkins用户有权限访问docker socket接口,我使用的是Jenkins jnlp从节点容器,这样,这个slave容器就能够执行构建操做了,注意secret参数须要从master上的某个slave里查看。

 

 准备就绪,开始构建

 

在容器中开始一个构建过程不难,问题是你必需让这个代理容器绑定一个宿主机上的路径<code>${JENKINS_HOME}:/var/jenkins_home</code>,并且被构建的容器也须要这个目录的访问权限。

```sh
docker run -t -d -u 1000:1000 -w /var/jenkins_home/workspace/uri-templates-in-docker \
-v /var/jenkins_home/workspace/uri-templates-in-docker:/var/jenkins_home/workspace/uri-templates-in-docker:rw \
-e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** \
-e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** -e ******** \
maven:3.3.3-jdk-8 cat
```

这个容器会把宿主机上的 /var/jenkins_home/workspace/uri-templates-in-docker目录挂载到容器化环境以供Maven使用,而且会把这个路径设置成当前工做路径,这些在物理机上都能正常运行,可是要在容器中执行,我须要尝试这样作:

这样明显不行,由于我把docker socket端口映射到了Jenkins代理容器上,挂载到Jenkins agent容器的全部卷实际上都是引用宿主上的路径,假定宿主上的<code>${JENKINS_HOME}</code>是<code> /opt/jenkins_home</code>,如下的命令应该生效:


```sh
docker run -t -d -u 1000:1000 -w /opt/jenkins_home/workspace/uri-templates-in-docker \
-v /opt/jenkins_home:/var/jenkins_home/workspace/uri-templates-in-docker:rw \
-e ********
maven:3.3.3-jdk-8 cat
```

 

总结

 

把构建环境容器化是一个很是好的主意,这样节省了不少时间。

注意,这份代码可能不正正知足你的需求,可是起码是一个demo,我但愿本文能帮助更多人用上Jenkins的容器来构建应用。

 

关于希云cSphere


希云cSphere是一个高度集成、功能强大的Docker私有云平台和类PaaS解决方案,其架构设计借鉴了VMWare vSphere的思想。系统健壮性比肩VMWare这样的商业产品,产品通过一年多十多个版本的迭代更新,在内部更是经历了1000次以上的破坏性测试,目前已经在金融、制造、游戏、安全、电商、教育等多个领域落地。

cSphere的亮点:

- 平台适应应用,不须要应用适应平台。
- 多应用架构多场景支持,希云承诺不管是5年前的应用、如今的甚至5年后的应用架构均可以在希云上完美支持
- 搬迁现有业务,代码、架构无需任何修改
- 希云产品以自研发为主,抛弃了“拼凑”模式,有力保证了工程质量
- 真正企业级的PaaS,可知足高复杂项目需求

欢迎联系咱们:

- 电话  400-686-1560
- 邮箱 
docker@csphere.cn

相关文章
相关标签/搜索