这里基于jenkins、gitee、ansible、bsdiff,mvn,springboot jar,md5sum讲解
大致流程是jenkins生成jar包,ansible进行二进制增量传输,最终检查checksum、部署、重启项目
准备:
所有centos服务器创建jenkins用户:
useradd -G jenkins jenkins
1、yum Jenkins安装、配置、启动:
yum install jenkins
service jenkins start/stop/restart
2、ansible安装、配置
yum install ansible
配置ansible ssh可信host、登入各从服务器的jenkins用户生成public key,保存到jenkins主机的~/.ssh/authorized_keys下,测试,保证可以用jenkins用户免密ssh
vi /etc/ansible/hosts
# add
[Self]
self ip
[Client]
child1 ip
child2 ip
child3 ip ansible_ssh_port=60000 # ssh use port 60000
vi /etc/ansible/ansible.cfg
# replace
remote_user=jenkins
3、安装jenkins插件
安装ansible plugin支持ansible配置,安装gitee plugin支持gitee的scm,在jenkins中配置好gitee,保证代码可以拉取,在全局工具配置中添加maven、ansible等工具,支持pipline使用这些命令,所有安装完成后重启jenkins。
4、创建jenkins pipline项目
pipline的核心配置如下
这个配置如果正常就会fetch git repo,并自动执行该git项目下的Jenkinsfile文件,接下来看看jenkinsfile的编写
#!groovy
node {
stage('checkout') {
checkout([$class: 'GitSCM', branches: [[name: 'origin/develop']], doGenerateSubmoduleConfigurations: false, extensions: [[$class: 'CloneOption', depth: 0, noTags: false, reference: '', shallow: false, timeout: 60]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'credentialsId', name: 'origin', refspec: '+refs/heads/*:refs/remotes/origin/*', url: 'git@gitaddress:/opt/repos/ishikang/jinan']]])
}
//定义mvn环境
def mvnHome = tool 'MVN3'
env.PATH = "${mvnHome}/bin:${env.PATH}"
def ansibleHome = tool 'ANSIBLE-PLAYBOOK'
env.PATH = "${ansibleHome}:${env.PATH}"
def name = 'sssdfsd'
def suffix = 'jar'
def ansbileFile = 'ansible.yml'
def devopsPath = "/devroot/devops/.build/"
stage('enter project dir') {
dir(name) {
stage('package') {
sh "mvn clean package"
}
stage('create diff and move') {
dir('target') {
sh "mv *.${suffix} ${name}.${suffix}"
if(fileExists("${devopsPath}${name}.${suffix}")) {
// create patch
sh "${devopsPath}bsdiff ${devopsPath}${name}.${suffix} ${name}.${suffix} ${name}.${suffix}.patch"
sh "mv ${name}.${suffix}.patch ${devopsPath}"
}
sh "md5sum ${name}.${suffix} > ${name}.${suffix}.checksum"
sh "mv ${name}.${suffix} ${devopsPath}"
sh "mv ${name}.${suffix}.checksum ${devopsPath}"
}
}
stage('deploy') {
sh "ansible-playbook ${ansbileFile}"
}
stage('clean and send mail') {
sh "mvn clean"
emailext body: '''$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS:
Check console output at $BUILD_URL to view the results.''', subject: '$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!', to: 'mailaddress@163.com'
}
}
}
}
这是一个groovy文件,文件首先checkout一个项目,这个语法的导出可以在http://admin.berrybit.cn/job/berrybit-manager/pipeline-syntax/中找checkout找到配置方法并导出语句,这里定义的mvn和ansible是在jenkins中配置的,这里还用到了bsdiff命令,创建了一个一个差量包,用来降低更新包的大小,部署的代码在ansible-playbook ${ansbileFile}这一句,这个ansbileFile文件是在开头拉取的那个项目里的一个absible部署文件。接着看ansible的部署文件,这里的项目文件路径都不一样,只是例子。
- hosts: 106.75.49.211
tasks:
- name: judge a file or dir is exits
shell: ls /devroot/devops/example.jar
ignore_errors: True
register: result
- name: "ssh copy patch jar!"
copy: src=/root/devops/.build/example.jar.patch dest=/devroot/devops/example.jar.patch mode=0700
when: result|succeeded
- name: "ssh copy jar checksum!"
copy: src=/root/devops/.build/example.jar.checksum dest=/devroot/devops/example.jar.checksum mode=0400
when: result is succeeded
- name: patch the file
command: ./bspatch example.jar example.jar example.jar.patch
args:
chdir: /devroot/devops
when: result is succeeded
- name: check target file is ok
command: md5sum -c example.jar.checksum
ignore_errors: True
register: checksum
args:
chdir: /devroot/devops
when: result is succeeded
- name: "copy jar!"
copy: src=/root/devops/.build/example.jar dest=/devroot/devops/example.jar mode=0700
when: result is failed
- name: "copy jar when checksum error!"
copy: src=/root/devops/.build/example.jar dest=/devroot/devops/example.jar mode=0700
when: checksum is failed
- name: move to back
command: mv /targetroot/example-target.jar /targetroot/example-target.jar.back
- name: "replace jar!"
command: \cp -rf /devroot/devops/example.jar /targetroot/example-target.jar
- name: restart jar
command: ./springboot.sh restart example-target.jar
args:
chdir: /targetroot
这里是一些常规流程,包括判断文件是否存在、增量包的合并,checksum的检查等,总之,首先要保证最终的部署文件的checksum和编译出来的文件一样,springboot.sh是一个jar包部署脚本可以直接写nohup java -jar example-target.jar &,注意这里的nohup是一定要的,否则ansible执行结束后,这个启动的进程会被杀死。
到此一个基于jenkins的自动化部署的基本流程大致完成,还可以在jenkins配置gitee的webhook,进行触发部署。