持续集成作为敏捷开发重要的一步,其目的在于让产品快速迭代的同时,尽可能保持高质量。每一次代码更新,都要通过自动化测试来检测代码和功能的正确性,只有通过自动测试的代码才能进行后续的交付和部署。本文主要介绍如何将时下最流行的持续集成工具之一的Jenkins结合阿里云容器服务,实现自动测试和镜像构建推送。
接下来的演示是如何通过阿里云容器服务Jenkins实现自动测试和Docker镜像构建,实现高质量的持续集成。
具体场景:每次代码提交到GitHub上的nodejs的项目中,阿里云容器服务Jenkins都会自动触发单元测试,测试通过则继续镜像构建及推送到目标镜像仓库中,最后邮件通知结果。大致流程如下图所示:
slave-nodejs-ut是用来进行单元测试的slave节点。
slave-nodejs-image-build是用来进行build镜像和推送镜像的slave节点。
1.使用容器服务部署Jebkins
1.1 创建Jenkins编排模版
新建模版,以如下内容为基础,创建编排。
jenkins:
image: ‘registry.aliyuncs.com/acs-sample/jenkins:1.651.2-alpine’
ports:
– ‘8080:8080’
– ‘50000:50000’
volumes:
– /var/lib/docker/jenkins:/var/jenkins_home
privileged: true
restart: always
environment:
– user=1000
labels:
aliyun.scale: ‘1’
aliyun.probe.url: ‘tcp://container:8080’
aliyun.probe.initial_delay_seconds: ’10’
aliyun.routing.port_8080: jenkins
1.2 创建Jenkins应用
当然也可以直接使用阿里云提供的jenkins示例模版创建Jenkins应用。
打开容器服务提供的访问端点,就可以使用刚刚部署的jenkins应用。
Jenkins是基于Java开发的一种开源持续集成工具,监控并触发持续重复的工作,具有开源,支持多平台和插件扩展,安装简单,界面化管理等特点。Jenkins使用job来描述每一步工作,节点是用来执行项目的环境。Master节点是Jenkins job的默认执行环境,也是Jenkins应用本身的安装环境。
2.Jenkins相关介绍
2.1 master/slave
master/slave相当于server和agent的概念。master提供web接口让用户来管理job和slave,job可以运行在master本机或者被分配到slave上运行。一个master可以关联多个slave用来为不同的job或相同的job的不同配置来服务。
可以通过配置多个slave为不同项目准备单独的测试和构建环境。
2.2 配置Jenkins插件
如果代码托管在GitHub中,安装Git plugin和GitHub plugin来实现代码变更自动触发Jenkins job。
如果直接安装不成功,可以通过http://updates.jenkins-ci.org/download/plugins/手动下载 .hpi文件安装。
Tips: 本文中提到的Jenkins job和项目均指的是Jenkins一个构建单元,执行单元。
3. 使用容器服务实现自动化测试
3.1 创建slave-nodejs-ut镜像
本示例在本地创建slave-nodejs-ut镜像,然后将镜像推送到容器服务Hub。
首先在Dockerfile所在路径下执行如下命令创建镜像。
docker build –t qinyujia-test/slave-nodejs-ut .
Dockerfile如下:
# Docker-in-Docker Jenkins Slave
# See: https://github.com/tehranian/dind-jenkins-slave
# See: https://dantehranian.wordpress.com/2014/10/25/building-docker-images-within-docker-containers-via-jenkins/
# Following the best practices outlined in:
# http://jonathan.bergknoff.com/journal/building-good-docker-images
FROM evarga/jenkins-slave
ENV DEBIAN_FRONTEND noninteractive
# Adapted from: https://registry.hub.docker.com/u/jpetazzo/dind/dockerfile/
# Let’s start with some basic stuff.
RUN apt-get update -qq && apt-get install -qqy
apt-transport-https
ca-certificates
curl
lxc
iptables &&
rm -rf /var/lib/apt/lists/*
RUN echo deb https://apt.dockerproject.org/repo ubuntu-trusty main > /etc/apt/sources.list.d/docker.list &&
apt-key adv –keyserver hkp://p80.pool.sks-keyservers.net:80 –recv-keys 58118E89F3A912897C070ADBF76221572C52609D
ENV DOCKER_VERSION 1.11.1-0~trusty
# Install Docker from Docker Inc. repositories.
RUN apt-get update && apt-get install -y docker-engine=$DOCKER_VERSION && rm -rf /var/lib/apt/lists/*
ADD wrapdocker /usr/local/bin/wrapdocker
RUN chmod +x /usr/local/bin/wrapdocker
VOLUME /var/lib/docker
# Make sure that the “jenkins” user from evarga’s image is part of the “docker”
# group. Needed to access the docker daemon’s unix socket.
RUN usermod -a -G docker jenkins
# place the jenkins slave startup script into the container
ADD jenkins-slave-startup.sh /
CMD [“/jenkins-slave-startup.sh”]
# Install nodejs for demo purpose
RUN curl -sL https://deb.nodesource.com/setup | sudo bash –
RUN apt-get install -y nodejs
在容器服务主页选择镜像,新建镜像。
输入仓库名称,设置代码源为本地仓库。
通过如下指令将slave-nodejs-ut镜像推送到阿里云容器Hub。
3.2 使用编排模版创建slave-nodejs-ut容器
slave-nodejs-ut编排模版如下:
slave-nodejs-ut:
image: ‘registry.aliyuncs.com/qinyujia-test/slave-nodejs-ut’
privileged: true
restart: always
labels:
aliyun.scale: ‘1’
3.3 将slave-nodejs-ut容器配置成Jenkins的slave节点
打开Jenkins应用,进入系统设置界面,选择管理节点,新建节点,配置相应参数。如下图所示。
Note1: 标签为slave的唯一标识。
Note2: slave容器和Jenkins容器同时运行在阿里云平台上,因此填写外网访问不到的容器节点IP,隔离测试环境。
Note3: 添加Credential的时候,使用创建slave-nodejs-ut镜像的Dockerfile里的Jenkins帐户和密码。
3.4 创建项目实现自动化测试
新建Item,选择构建一个自由风格的软件项目。
填写项目名称,并选择项目运行节点,此示例填写上述准备的slave-nodejs-ut节点。默认情况下,Jenkins会使用master节点,也就是Jenkins运行主机作为项目运行节点,很可能因为缺少各种环境配置导致测试失败。即使能够执行成功,我们仍然更推荐使用slave节点来执行项目。
配置源码管理和代码分支,此示例中源代码使用GitHub管理。
配置构建触发器,此示例采用结合GitHub Webhooks & services实现自动触发项目执行。
最后在GitHub中添加Jenkins的service hook,完成自动触发实现。
在GitHub 项目主页点击settings tab,左侧菜单栏选择Webhooks & services, Add Service,下拉框中选择Jenkins(Git plugin)。
在Jenkins hook url对话框中填写${Jenkins IP}/github-webhook/, eg:
http://jenkins.cd****************.cn-beijing.alicontainer.com/github-webhook/
增加Execute shell类型的构建步骤,编写shell脚本执行测试。
本示例中的Command如下:
pwd
ls
cd chapter2
npm test
4. 使用阿里云容器服务实现自动化构建,推送镜像
本章节与章节3中相同的配置就不重复编写,重点说明需要注意的地方。
4.1 使用阿里云容器服务创建slave-nodejs-image-build容器
使用章节3中的模板和镜像,创建进行构建镜像,推送镜像的slave-nodejs-image-build容器。
4.2 将slave-nodejs-image-build容器配置成Jenkins的slave节点
打开Jenkins应用,进入系统设置界面,选择管理节点,新建节点,配置相应参数。如下图所示。
4.3 创建项目实现自动构建,推送镜像
执行job的节点配置为slave-nodejs-image-build。
如果希望每次在单元测试成功之后再执行自动构建镜像,设置如下触发器。
最后编写构建镜像和推送镜像的shell脚本。
本示例的Command如下:
cd chapter2
docker build -t registry.aliyuncs.com/qinyujia-test/nodejs-demo .
docker login -u ${yourAccount} -p ${yourPassword} registry.aliyuncs.com
docker push registry.aliyuncs.com/qinyujia-test/nodejs-demo
5. 自动重新布局应用
5.1 首次部署应用
使用编排模板,将章节4中创建的镜像部署到容器服务中,创建nodejs-demo应用。示例如下:
express:
image: ‘registry.aliyuncs.com/qinyujia-test/nodejs-demo’
expose:
– ’22’
– ‘3000’
restart: always
labels:
aliyun.routing.port_3000: express
5.2 自动重新部署
选择刚刚创建的应用nodejs-demo, 创建触发器。
在章节4.3的shell脚本中添加一行,地址即为上文创建的触发器给出的触发器链接。
curl ‘https://cs.console.aliyun.com/hook/trigger?triggerUrl=***==&secret=***’
把4.3中的示例的Command改为:
cd chapter2
docker build -t registry.aliyuncs.com/qinyujia-test/nodejs-demo .
docker login -u ${yourAccount} -p ${yourPassword} registry.aliyuncs.com
docker push registry.aliyuncs.com/qinyujia-test/nodejs-demo
curl ‘https://cs.console.aliyun.com/hook/trigger?triggerUrl=***==&secret=***’
到此,镜像推送之后,Jenkins会自动触发重新部署nodejs-demo应用。
6. 配置邮件推送结果
如果希望单元测试或者镜像构建的结果能够通过邮件推送给相关开发人员或者项目执行发起者。可以通过如下配置来实现。
首先在Jenkins主页,选择系统管理,系统设置,配置Jenkins系统管理员邮箱。
安装Extended Email Notification plugin,配置SMTP server等相关信息,并设置默认邮件接收人列表。如下图所示。
以上是Jenkins应用系统参数设置,下面是为需要用邮件推送结果的Jenkins项目进行相关配置。
在Jenkins项目中添加构建后操作步骤,选择Editable Email Notification类型,填写邮件接收人列表。
添加邮件发送触发器。
7. 总结
利用Docker镜像和Compose模版,容器服务就能快速创建自动测试和构建的环境,简化持续集成的环境搭建和扩展。容器服务提供的监控,日志,存储等功能,进一步为用户提供方便统一,功能完善的各种环境管理。