最近在公司推行Docker Swarm集群的过程中,需要用到Jenkins来做自动化部署,Jenkins实现自动化部署有很多种方案,可以直接在jenkins页面写Job,把一些操作和脚本都通过页面设置,也可以在每个项目中直接写Pipeline脚本,但像我那么优秀,那么追求极致的程序员来说,这些方案都打动不了我那颗骚动的心,下面我会跟你们讲讲我是如何通过Pipeline脚本实现自动化部署方案的,并且实现多分支构建,还实现了所有项目共享一个Pipeline脚本。

使用Jenkins前的一些设置

为了快速搭建Jenkins,我这里使用Docker安装运行Jenkins:

$ sudo docker run -it -d \
--rm \
-u root \
-p 8080:8080 \
-v jenkins-data:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$HOME":/home \
--name jenkins jenkinsci/blueocean

初次使用jenkins,进入Jenkins页面前,需要密码验证,我们需要进入docker容器查看密码:

$ sudo docker exec -it jenkins /bin/bash
$ vi /var/jenkins_home/secrets/initialAdminPassword

Docker安装的Jenkins稍微有那么一点缺陷,shell版本跟CenOS宿主机的版本不兼容,这时我们需要进入Jenkins容器手动设置shell:

$ sudo docker exec -it jenkins /bin/bash
$ ln -sf /bin/bash /bin/sh

由于我们的Pipeline还需要在远程服务器执行任务,需要通过ssh连接,那么我们就需要在Jenkins里面生成ssh的公钥密钥:

$ sudo docker exec -it jenkins /bin/bash
$ ssh-keygen -C "root@jenkins"

在远程节点的~/.ssh/authorized_keys中添加jenkins的公钥(id_rsa.pub)

还需要安装一些必要的插件:

  1. Pipeline Maven Integration
  2. SSH Pipeline Steps

安装完插件后,还需要去全局工具那里添加maven:

这里后面Jenkinsfile有用到。

mutiBranch多分支构建

由于我们的开发是基于多分支开发,每个开发环境都对应有一条分支,所以普通的Pipeline自动化构建并不能满足现有的开发部署需求,所以我们需要使用Jenkins的mutiBranch Pipeline。

首先当然是新建一个mutiBranch多分支构建job:

接着设置分支源,分支源就是你项目的git地址,选择Jenkinsfile在项目的路径

接下来Jenkins会在分支源中扫描每个分支下的Jenkinsfile,如果该分支下有Jenkinsfile,那么就会创建一个分支Job

该job下的分支job如下:

这里需要注意的是,只有需要部署的分支,才加上Jenkinsfile,不然Jenkins会将其余分支也创建一个分支job。

通用化Pipeline脚本

到这里之前,基本就可以基于Pipeline脚本自动化部署了,但如果你是一个追求极致,不甘于平庸的程序员,你一定会想,随着项目的增多,Pipeline脚本不断增多,这会造成越来越大的维护成本,随着业务的增长,难免会在脚本中修改东西,这就会牵扯太多Pipeline脚本了,而且这些脚本基本都相同,那么对于我这么优秀的程序员,怎么会想不到这个问题呢,我第一时间就想到通用化pipeline脚本。所幸,Jenkins已经看出了我不断骚动的心了,Jenkins甩手就给我一个Shared Libraries。

Shared Libraries是什么呢?顾名思义,它就是一个共享库,它的主要作用是用于将通用的Pipeline脚本放在一个地方,其它项目可以从它那里获取到一个全局通用化的Pipeline脚本,项目之间通过不通的变量参数传递,达到通用化的目的。

接下来我们先创建一个用于存储通用Pipeline脚本的git仓库:

仓库目录不是随便乱添加了,Jenkins有一个严格的规范,下面是官方说明:

官方已经讲得很清楚了,大概意思就是vars目录用于存储通用Pipeline脚本,resources用于存储非Groovy文件。所以我这里就把Pipeline需要的构建脚本以及编排文件都集中放在这里,完全对业务工程师隐蔽,这样做的目的就是为了避免业务工程师不懂瞎几把乱改,导致出bug。

创建完git仓库后,我们还需要在jenkins的Manage Jenkins » Configure System » Global Pipeline Libraries中定义全局库:

这里的name,可以在jenkinsfile中通过以下命令引用:

@Library 'objcoding-pipeline-library'

下面我们来看通用Pipeline脚本的编写规则:

#!groovy

def getServer() {
def remote = [:]
remote.name = 'manager node'
remote.user = 'dev'
remote.host = "${REMOTE_HOST}"
remote.port = 22
remote.identityFile = '/root/.ssh/id_rsa'
remote.allowAnyHosts = true
return remote
} def call(Map map) { pipeline {
agent any environment {
REMOTE_HOST = "${map.REMOTE_HOST}"
REPO_URL = "${map.REPO_URL}"
BRANCH_NAME = "${map.BRANCH_NAME}"
STACK_NAME = "${map.STACK_NAME}"
COMPOSE_FILE_NAME = "docker-compose-" + "${map.STACK_NAME}" + "-" + "${map.BRANCH_NAME}" + ".yml"
} stages {
stage('获取代码') {
steps {
git([url: "${REPO_URL}", branch: "${BRANCH_NAME}"])
}
} stage('编译代码') {
steps {
withMaven(maven: 'maven 3.6') {
sh "mvn -U -am clean package -DskipTests"
}
}
} stage('构建镜像') {
steps {
sh "wget -O build.sh https://git.x-vipay.com/docker/jenkins-pipeline-library/raw/master/resources/shell/build.sh"
sh "sh build.sh ${BRANCH_NAME} "
}
} stage('init-server') {
steps {
script {
server = getServer()
}
}
} stage('执行发版') {
steps {
writeFile file: 'deploy.sh', text: "wget -O ${COMPOSE_FILE_NAME} " +
" https://git.x-vipay.com/docker/jenkins-pipeline-library/raw/master/resources/docker-compose/${COMPOSE_FILE_NAME} \n" +
"sudo docker stack deploy -c ${COMPOSE_FILE_NAME} ${STACK_NAME}"
sshScript remote: server, script: "deploy.sh"
}
}
}
}
}
  1. 由于我们需要在远程服务器执行任务,所以定义一个远程服务器的信息其中remote.identityFile就是我们上面在容器生成的密钥的地址;
  2. 定义一个call()方法,这个方法用于在各个项目的Jenkinsfile中调用,注意一定得叫call;
  3. 在call()方法中定义一个pipeline;
  4. environment参数即是可变通用参数,通过传递参数Map来给定值,该Map是从各个项目中定义的传参;
  5. 接下来就是一顿步骤操作啦,“编译代码”这步骤需要填写上面我们在全局工具类设置的maven,“构建镜像”的构建脚本巧妙地利用wget从本远程仓库中拉取下来,”执行发版“的编排文件也是这么做,“init-server”步骤主要是初始化一个server对象,供“执行发版使用”。

从脚本看出来Jenkins将来要推崇的一种思维:配置即代码。

写完通用Pipeline脚本后,接下来我们就需要在各个项目的需要自动化部署的分支的根目录下新建一个Jenkinsfile脚本了:

接下来我来解释一下Jenkinsfile内容:

#!groovy

// 在多分支构建下,严格规定Jenkinsfile只存在可以发版的分支上

// 引用在jenkins已经全局定义好的library
library 'objcoding-pipeline-library'
def map = [:] // 远程管理节点地址(用于执行发版)
map.put('REMOTE_HOST','xxx.xx.xx.xxx')
// 项目gitlab代码地址
map.put('REPO_URL','https://github.com/objcoding/docker-jenkins-pipeline-sample.git')
// 分支名称
map.put('BRANCH_NAME','master')
// 服务栈名称
map.put('STACK_NAME','vipay') // 调用library中var目录下的build.groovy脚本
build(map)
  1. 通过library 'objcoding-pipeline-library'引用我们在Jenkins定义的全局库,定义一个map参数;
  2. 接下来就是将项目具体的参数保存到map中,调用build()方法传递给通用Pipeline脚本。

Shared Libraries共享库极大地提升了Pipeline脚本的通用性,避免了脚本过多带来的问题,也符合了一个优秀程序员的审美观,如果你是一个有追求的程序员,你一定会爱上它。

更多精彩文章请关注作者维护的公众号「后端进阶」,这是一个专注后端相关技术的公众号。

关注公众号并回复「后端」免费领取后端相关电子书籍。

欢迎分享,转载请保留出处。

基于 Jenkins Pipeline 自动化部署的更多相关文章

  1. [转]基于AWS的自动化部署实践

    作者 徐桂林 发布于 2014年1月22日 -------------------------------------------------------------------- 1. 背景 在过去 ...

  2. 基于AWS的自动化部署实践

    过年前,我给InfoQ写了篇文章详细介绍我们团队在过去4年基于AWS的自动化部署实践.文章包括了:为什么选择AWS.AWS上自动化部署的优势和挑战.我们的解决方案,以及和AWS DevOps方案(Op ...

  3. gitlab与jenkins的自动化部署(通过webhook与ansilble)

    gitlab与jenkins的自动化部署(通过webhook与ansilble) 1.部署介绍 gitlab服务器:192.168.1.49:80jenkins服务器:192.168.1.49:818 ...

  4. 搭建jenkins实现自动化部署

    搭建jenkins实现自动化部署 一.安装jenkins 1.添加yum repos,然后安装 sudo wget -O /etc/yum.repos.d/jenkins.repo https://p ...

  5. CentOS下Docker与.netcore(四)之 三剑客之一Docker-machine+jenkins简单自动化部署

    CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客 ...

  6. 基于【SpringBoot】的微服务【Jenkins】自动化部署

    最近,也是抽空整理了一些在工作中积累的经验,通过博客记录下来分享给大家,希望能对大家有所帮助: 一.关于自动化部署 关于自动化部署的优点,我就不在这里赘述了:只要想想手工打包.上传.部署.重启的种种, ...

  7. 基于Jenkins Pipeline的ASP.NET Core持续集成实践

    最近在公司实践持续集成,使用到了Jenkins的Pipeline来提高团队基于ASP.NET Core API服务的集成与部署效率,因此这里总结一下. 一.关于持续集成与Jenkins Pipelin ...

  8. Linux文档整理之【Jenkins+Docker自动化部署.Net Core】

    这次整理的文档是Jenkins+Docker实现自动化部署,很早之前就写的,今天有时间就搬到博客园做个记录. Jenkins是基于Java开发的一种持续集成工具,主要用于持续.自动的构建/测试软件等相 ...

  9. SpringBoot项目 使用Jenkins进行自动化部署 (gitLab管理项目)_

    1.部署服务器创建好对应文件夹和启动脚本 创建文件夹 mkdir /wdcloud/app/rps/rps-module-category 创建启动脚本 cd /wdcloud/app/rps/rps ...

随机推荐

  1. 2019 中国.NET 开发者峰会正式启动

    2014年微软组织并成立.NET基金会,微软在成为主要的开源参与者的道路上又前进了一步.2014年以来已经有众多知名公司加入.NET基金会,Google,微软,AWS三大云厂商已经齐聚.NET基金会, ...

  2. 分库分表(3) ---SpringBoot + ShardingSphere 实现读写分离

    分库分表(3)---ShardingSphere实现读写分离 有关ShardingSphere概念前面写了两篇博客: 1.分库分表(1) --- 理论 2. 分库分表(2) --- ShardingS ...

  3. Java匹马行天下之教你用学汉语式方法学编程语言

    Java匹马行天下之教你用学汉语式方法学编程语言 前言: 前段时间接连更新了带小白从入门到了解的几篇博客: <Java匹马行天下之编程常识知多少> <Java匹马行天下之走进编程的殿 ...

  4. python编程基础之三十六

    文件处理:文件处理包括读文件,写文件 读文件: 1.打开文件 2.读取文件 3.关闭文件 写文件: 1.打开文件 2.写如文件 3.关闭文件 无论是读取文件还是写文件都时需要打开文件,和关闭文件 打开 ...

  5. InfluxDB从原理到实战 - InfluxDB常用的基础操作

    0x00 基础操作介绍 在本文中将介绍InfluxDB常用的基础操作,帮助读者建立对InfluxDB的感性认识,快速的动手玩起来,持续查询(Continuous Queies).Group by.Se ...

  6. vim 的初始配置

    我是一个vim爱好者,项目开发过程中,大量地使用vim作为编辑工具. 今天刚开箱了一台新的 CentOS7, 现将Vim安装后的一些基本配置作一下记录. 使用配置模板 vim安装完之后,大多数配置都是 ...

  7. JVM垃圾回收(下)

    接着上一篇,介绍完了 JVM 中识别需要回收的垃圾对象之后,这一篇我们来说说 JVM 是如何进行垃圾回收. 首先要在这里介绍一下80/20 法则: 约仅有20%的变因操纵着80%的局面.也就是说:所有 ...

  8. cocos2d-x 3.2,Label,Action,Listener,Menu Item等简单用法

    转载自:http://blog.csdn.net/pleasecallmewhy/article/details/34931021 创建菜单(Menu Item) // 创建菜单 auto menuI ...

  9. jmeter-控制业务比例

    方式一: 多线程组 缺点:由于各事务相应时间一般不一致,故只能粗略的控制业务占比 实例:待补充

  10. 使用FastReport报表工具生成标签打印文档

    在我们实际开发报表的时候,我们需要按一定的业务规则组织好报表的模板设计,让报表尽可能的贴近实际的需求,在之前的随笔中<使用FastReport报表工具生成报表PDF文档>介绍了FastRe ...