随着敏捷软件开发方法论的普及,越来越多的原来由开发者完成的重复性工作都自动化让机器来执行了,对于一个开发团队来说,如果没有自动化的pipeline,开发人员的痛苦相信大家都深有体会,随着.NET Core 2.0 的发布,在.NET Core平台上的所有开发工具都跨平台化了,这也给团队在Linux环境上部署持续集成(CI),持续发布(CD)工作带来方便,整套环境对团队的开发效率的提升可以说是指数级别的,以下以 Ubuntu 16.0.4 服务器为例,演示CI CD搭建兽如何搭建整个环境,当你征服了手动搭建过程后,就可以借助 ansible docker 等工具将这一过程自动化,后续文章将演示这一自动化搭建的过程。
一,服务器环境的准备
- 因为家里的文件服务器是 Ubuntu 16.0.4 Server 版,为了方便,就选这个作为服务器了。
- 按照 .NET Core 2.0 SDK安装指南 安装.NET Core SDK,.NET Core 项目需要 dotnet 工具来编译,发布,测试项目。
- 按照 Docker官方安装指南安装 docker 服务。
- 通过
sudo apt install nginx
安装 Nginx 服务器,后面会用到该服务来反向代理内部所有的服务,这样 HTTPS 的问题都交给 Nginx 来解决。
二,安装并配置Jenkins CD 服务
目前比较流行的CD工具有 Jenkins 和 GoCD,此处我们选择Jinkins,当然 Jenkins 服务可以使用docker来运行,但考虑到简单性,我们此处直接安装为本地服务运行。
参照官方安装指南安装 Jenkins 服务, 默认服务端口为:8080,为了服务的安全性,我们在服务器上安装了nginx 服务通过 https
反向代理 Jenkins 服务,最后的服务地址为:https://home.freemanke.com:28080,当然如果你的服务器主机是云主机有固定IP可以直接使用443端口,我的服务器在家里,通过DDNS暴露到外网,而家里的路由器又把443和80端口占用了,所以服务需要用其他端口(28080等)来服务,SSL证书可以通过腾讯云SSL证书服务申请个人免费证书(当然前提是你要有一个你自己的域名),有效期一年。
Nginx 反向代理配置如下:
####################################################################
## jenkins service - https://home.freemanke.com:28080
server {
listen 28080;
server_name home.freemanke.com;
ssl on;
ssl_certificate /home/freeman/ssl/home.freemanke.com.crt;
ssl_certificate_key /home/freeman/ssl/home.freemanke.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_redirect default;
}
}
搭建完成后访问服务地址https://home.freemanke.com:28080
默认安装完成是朴素的默认theme,我们可以参照 jenkins-material-theme 来自定义界面,此处我选择了绿色的 Material
主题。
安装完成后的配置步骤比较多,不一一列举,根据每个人团队的需要不同而不同,一下列举本次用到插件和配置
- Bitbucket Plugin 因为我使用的git库是 https://bitbucket.org/,所以需要安装 Bitbucket Plugin 来支持 Webhook,当git又提交时,bitbucket通过 Webhook 功能发送请求到 Jenkins 服务器,服务器将实时触发指定 pipeline 的构建,这样才能具有持续构建的能力。
- Email,Slack 扩展,将pipeline通过 Email 或 Slack 通知到开发者,实时反馈构建的过程和结果。
三,安装 docker registry 本地服务
Pipeline的每次成功构建,都将产生一个软件的新的可发性版本,如果我们使用文件存储,我们后续的部署起来非常繁琐,此处我们使用 docker 来部署服务,所以需要一个 docker registry 服务来保存托管这些新的镜像,官方的速度太慢,所以需要本地服务,此处直接使用 docker 来启动服务,脚本如下。
docker stop registry
docker rm -f registry
docker run \
--detach \
--name registry \
--publish 5000:5000 \
--volume /home/freeman/docker-registry:/var/lib/registry \
registry:2.6.2
同样我们需要通过 Nginx 反向代理服务,最后的服务地址为https://home.freemanke.com:25000/v2/_catalog,反向代理配置如下,注意此处的配置client_max_body_size 1000M;
因为 image 包都很大,而默认的 body size 为 2M,无法提交大的 Image 文件。
####################################################################
## docker-registry service - https://home.freemanke.com:25000
server {
listen 25000;
server_name home.freemanke.com;
ssl on;
ssl_certificate /home/freeman/ssl/home.freemanke.com.crt;
ssl_certificate_key /home/freeman/ssl/home.freemanke.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
ssl_prefer_server_ciphers on;
client_max_body_size 1000M;
location / {
proxy_pass http://127.0.0.1:5000/;
proxy_redirect default;
}
}
四,准备项目和 Pipeline
此处以我最近正在做的项目为例,项目的产出物是一个web站点和一个windows平台的winform客户端,此处先为 web 站点的开发构建准备一个自动化的CI CD Pipeline。
配置过程如下
- 在 Jenkins 服务上新建一个 pipeline 名为 telemetry
- 将项目的git地址添加到git源,并配置好授权信息
- 在项目的根目录下创建 Jenkinsfile,此处是 Pipeline as Code 的关键,如果你直接在 Jenkins 上配置构建脚本的话,你将无法跟踪到脚本的任何改动,如果我们使用文件作为配置,并放入到git管理中,我们每一个开发者都能实时修改并跟踪 pipeline 配置变化。此处的脚本内容如下,具体的内容定义请参见官方文档,此处的主要流程是:
- 恢复nuget包应用
- 构建解决方案
- 运行测试
- 发布 web 项目到指定环境,此处为 ubuntu.16.10-x64 环境
- 构建 docker 镜像
- 推送 docker 镜像到 docker registry
- 在 dev 环境上部署最新的代码版本
#!/usr/bin/env groovy
pipeline {
agent any
stages {
stage('build-test') {
steps {
sh 'dotnet restore ./src/Telemetry.sln'
sh 'dotnet build ./src/Telemetry.sln'
sh 'dotnet test --no-build --no-restore ./src/Telemetry.Data.Tests/'
}
}
stage('build-push-image') {
steps {
sh 'dotnet publish ./src/Telemetry.Web/Telemetry.Web.csproj -c Release -r ubuntu.16.10-x64 -o ./bin/publish'
sh 'dotnet publish ./src/Telemetry.Web/Telemetry.Web.csproj -c Release -r win7-x86 -o ./bin/win7/publish'
sh 'docker build -t home.freemanke.com:25000/freemanke/telemetry:${BUILD_NUMBER} ./src/Telemetry.Web/'
sh 'docker push home.freemanke.com:25000/freemanke/telemetry:${BUILD_NUMBER}'
}
}
stage('deploy-dev') {
steps {
sh 'docker stop telemetry || true && docker rm -f telemetry || true'
sh 'docker run -d --name telemetry -p 45000:45000 home.freemanke.com:25000/freemanke/telemetry:${BUILD_NUMBER}'
}
}
}
}
五,验证 Pipeline
git上的每次提交都自动触发 pipeline 的一次构建,构建结果如下
对于每次的构建,我们可以跟踪 Console 的输出来定位是否有问题发生,一个典型的 Console 输出结果如下图,我们可以很清晰的跟踪到每一个步骤的执行情况。
自动构建发布如果成功完成,将直接将最新的代码部署到dev环境中,下图是本站点的dev环境访问截图。
后续文章将把此次的手动搭建工作通过 ansible 和 docker 等辅助工具自动化,敬请期待!