本文讲的是Jenkins与Docker的持续集成实践【编者的话】持续集成(CI/CD)是一种软件开发实践。用于帮助团队成员频繁、快速的集成,测试他们的工作成果,以尽快发现集成错误。 更频繁、更早的集成意味着更早的发现问题。通过持续集成,及时发现和解决代码故障,提高代码质量,减少故障处理成本等等。【3 天烧脑式基于Docker的CI/CD实战训练营 | 北京站】本次培训围绕基于Docker的CI/CD实战展开,具体内容包括:持续集成与持续交付(CI/CD)概览;持续集成系统介绍;客户端与服务端的 CI/CD 实践;开发流程中引入 CI、CD;Gitlab 和 CI、CD 工具;Gitlab CI、Drone 的使用以及实践经验分享等。常见持续集成工具
目前持续集成的生态越来越完善,工具也有很多,开源的或商业的。如:
- 最最流行的,也是使用最多的Jenkins
- 有着持续集成DNA的ThoughtWorks GO。理念:"Deployment as pipeline" (华为容器平台应该是基于GO做的二次开发实现)
- Atlassian工具链之一的Bamboo
- 与Gitlab紧密集成的Gitlab CI
- 专为开源打造的Travis CI,与Github紧密集成
- 使用Python语言实现的Buildbot,相信Pythoner看到会喜欢
我们的选型是Jenkins,所以我们来看下Jenkins。Jenkins
Jenkins特点
- Jenkins是开源的应用最广泛的持续集成工具,支持CI, CD;
- Jenkins有很多插件,而且用户也可以自定义插件,可扩展性非常强;
- Jenkins对Docker支持非常好,有一套完善的Docker插件;
- Jenkins 2.0开始支持Pipeline,一个非常强大的插件,使用基于Groovy的DSL,支持CI/CD流水线;
- Jenkins基于Java语言开发;
Jenkins几个概念
- Master是Jenkins安装和运行的地方,它负责解析job脚本,处理任务,调度计算资源;
- Agent 负责处理从Master分发的任务;
- Executor就是执行任务的计算资源,它可以在Master或者Agent上运行。多个Executor也可以合作执行一些任务;
- job 任务,用来定义具体的构建过程;
- Groovy是一种基于JVM(Java虚拟机)的敏捷开发语言,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy代码能够与Java代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy可以使用其他Java语言编写的库。Jenkins用Groovy作为DSL;
- Pipeline 流水线即代码(Pipeline as Code),通过编码而非配置持续集成/持续交付(CI/CD)运行工具的方式定义部署。流水线使得部署是可重现、可重复的;
流水线包括节点(Node)、阶段(Stage)和步骤(Step)。
流水线执行在节点上。节点是Jenkins安装的一部分。流水线通常包含多个阶段。一个阶段包含多个步骤。流水线上手指南可以查看到更多的内容。
-
node在Pipeline中的context中,node是job运行的地方。 node会给job创建一个工作空间。工作空间就是一个文件目录,这是为了避免跟资源相关的处理互相产生影响。工作空间是node创建的,在node里的所有step都执行完毕后会自动删除。
-
stage阶段,stage是一个任务执行过程的独立的并且唯一的逻辑块,Pipeline定义在语法上就是由一系列的stage组成的。 每一个stage逻辑都包含一个或多个step。
-
step步骤,一个step是整个流程中的一系列事情中的一个独立的任务,step是用来告诉Jenkins如何做。
- Jenkinfile Jenkins支持创建流水线。它使用一种基于Groovy的流水线领域特定语言(Pipeline DSL)的简单脚。而这些脚本,通常名字叫Jenkinsfile。它定义了一些根据指定参数执行简单或复杂的任务的步骤。流水线创建好后,可以用来构建代码,或者编排从代码提交到交付过程中所需的工作。Jenkins中的Jenkinsfile有点类似Docker中的Dockfile的感觉
Jenkins 部署
Jenkins组件其实非常少,安装部署也非常简单。 Jenkins按角色就两类: master节点和slave节点。master安装完成后,在控制台中添加节点即可。下面以Dcoker的部署方式为例说一下Jenkins的部署:Master节点查看 docker hub 中 jenkins 的 image[root@k3128v /home/huomingming]# docker search jenkinsNAME DESCRIPTION STARS OFFICIAL AUTOMATEDjenkins Official Jenkins Docker image 2600 [OK] stephenreed/jenkins-java8-maven-git Automated build that provides a continuous... 53
可以看到第一个是官方提供的,所以我们选择这个即可。拉取jenkins imagedocker pull jenkins
启动Jenkins容器Jenkins没有数据库,所有数据都是存放在文件中的,首先在本地创建Jenkins数据目录,用于保存Jenkins的数据 这个目录需要定期的备份,用于容灾(当前Jenkins容器所在节点由于不可抗因素无法使用时,可以在新机器上使用备份的数据启动新的jenkins master节点)。sudo mkdir /var/jenkins
sudo chown 1000:1000 /var/jenkins
sudo docker run -p 8080:8080 -p 50000:50000 -v /var/jenkins:/var/jenkins_home --name my_jenkins -d jenkins
这样Jenkins就成功跑起来了。可以直接通过机器的8080端口访问Jenkins,本地的/var/jenkins就相当于容器里Jenkins用户的用户主目录,所以要保证该目录的权限为uid为j1000的用户目录。配置Jenkins启动完 jenkins master 后,在浏览器中数据输入 http://jenkins_master_ip:8080 登录Jenkins控制台进行接下来的安装和配置。 具体图就不贴出来了。查看Jenkins的版本java -jar /usr/share/jenkins/jenkins.war --version
slave 节点安装Java JDKyun install java-1.8.0-openjdk
创建Jenkins用户$ useradd -m jenkins -d /home/jenkins$ passwd jenkins
创建工作目录mkdir /data/jenkinschown jenkins.jenkins /data/jenkins
添加Jenkins用户到Docker用户组sudo usermod -a -G docker jenkins
配置SSH互信,Master免密码登陆SlaveMaster有多种管理Slave的方式,我们选择SSH方式在Master节点中,切换到Jenkins用户ssh-keygen -t rsa创建秘钥对把公钥拷贝到Slave节点scp ~/.ssh/id_rsa.pub jenkins@slave_ip:~/.ssh/authorized_keys
确保在scp前,slave节点根目录下.ssh目录已存在chmod 700 authorized_keys
使用Jenkins来构建Docker是需要安装插件的。那我们需要安装哪些插件呢?Jenkins有哪些Docker的Plugins
是非常丰富的,但并不是我们都能用的上,所以需要根据你使用的环境和平台来选择适合自己的Plugin安装就可以了。 每个Plugin都需要适配 Jenkins的版本,且每个Plugin也需要依赖一些其它Plugin,上面都已经做了标注,需要配套来用。这里介绍几个常用的Docker插件:Docker Commons Plugin其基本功能:
- API for managing Docker image and container fingerprints
- Credentials and location of Docker Registry
- Credentials and location of Docker Daemon (aka Docker Remote API)
- ToolInstallation for Docker CLI clients
- DockerImageExtractor extension point to get Docker image relations from jobs
- Simple UI referring related image fingerprints in Docker builds
Docker Plugins,该插件是将Docker作为Jenkins的slave来使用,来在Docker容器种完成项目的build,build完成后该容器slave容器就会被销毁。所有的工作都是在slave容器内完成。docker-build-step
该插件在 build 过程种增加了对 Docker 命令的支持。Docker Pipeline Plugin,基于Docker Commons Plugin实现的一些上层的基于Docker的Pipeline编排。Docker Hub Notification Trigger Plugin,该插件提供了当Registry中的image发生变化时触发build新镜像的功能。CloudBees Docker Build and Publish,该插件提供了通过Dockerfile来构建项目并将生成的镜像上传到镜像仓库的功能。CloudBees Docker Custom Build Environment,This plugin allows the definition of a build environment for a job using a Docker container。该插件适用于 “自由风格的软件项目”,如图:
CloudBees Docker Traceability,用于追踪通过Jenkins启停的容器的事件。Kubernetes, This plugin allows Jenkins agents to be dynamically provisioned on a Kubernetes cluster. The aim of the Kubernetes plugin is to be able to use a Kubernetes cluster to dynamically provision a Jenkins agent (using Kubernetes scheduling mechanisms to optimize the loads), run a single build, then tear-down that slave.与Kubernetes结合,通过Kubernetes提供Jenkins的 slave 节点。利用Kubernetes的调度功能提供快速的启停 slave 节点执行 build 等任务。目前是0.11版本,稳定性有待验证。Jenkins有没有API?
因为,我们不是直接在Jenkins的Dashbord来操作, 而是集成到现有平台,所以我们需要使用它的API。Jenkins的Remote API以REST的形式进行提供。例如,我们搭建的Jenkins站点为http://myjenkins.com:8080。那么,访问http://myjenkins.com:8080/api 即可查看到该站点所有可用的API。查询操作
执行一些动作
例如,我要创建一个 job,名字为 my_job,my_job的配置文件:<?xml version='1.0' encoding='UTF-8'?><project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers class="vector"/>
<concurrentBuild>false</concurrentBuild>
<builders/>
<publishers/>
<buildWrappers/></project>
调用API创建 my_job:curl -X POST http://www.xxx.xxx/jenkins/createItem?name=my_job --user uname:pass --data-binary "my_job_config.xml" -H "Content-Type: application/xml"
然后,你就可以在Jenkins Dashboard上看到这个job了。它的管理页面为http://myjenkins.com:8080/job/my_job。那么我们访问 /my_job/api/ 即可查看到该job可用的API。更多的API介绍可以参考Jenkins的官方wiki,这里只是个引子,在此就不过多进行介绍。总结
该篇文章主要是介绍了Jenkins和Docker的持续集成的实现部分,后续还有关于Jenkins的压测、性能扩展、高可用等,还需要持续深入的介绍。本文转载自公众号:HULK一线技术杂谈,ID:hulktalk,作者:ADDOPS团队霍明明。
原文发布时间为:2017-08-16
本文作者:霍明明
本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。
原文标题:Jenkins与Docker的持续集成实践