Jenkins CI&CD 自动化发布项目实战(上篇)
作者 | 刘畅 |
时间 | 2020-11-28 |
实验环境
centos7.5
主机名 | ip | 服务配置 | 软件 |
gitlab | 172.16.1.71 | 2核/4G/60G | docker、gitlab |
jenkins-master | 172.16.1.72 | 2核/4G/60G | docker、jdk、maven、jenkins |
jenkins-slave01 | 172.16.1.73 | 2核/2G/60G | jdk、maven、ansible |
java-web01 | 172.16.1.74 | 2核/2G/60G | jdk、tomcat |
java-web02 | 172.16.1.75 | 2核/2G/60G | jdk、tomcat |
说明:本文docker、gitlab的安装就不赘述了,可以参考其它专题文档。
创建一个gitlab项目,项目内容具体如下:
master分支:
dev分支:
目录
5.4 分布式构建(master/slave) 28
6 jenkins 发布单台java web项目 41
6.3 在jenkins中设置java-mall项目 42
6.4 Build with Parameters 45
7 jenkins集成Ansible发布多台java web服务器 48
7.2 在jenkins中配置java-mall项目 49
7.3 配置playbook(java-mall.yml)文件 52
7.4 Build with Parameters 53
1 CICD概述
(1) 持续集成(Continuous Integration,CI)
代码合并、部署、自动化测试都在一起,不断地执行这个过程,并对结果反馈。
(2) 持续交付(Continuous Delivery,CD)
是一种软件工程方法,让软件的产出过程在一个短周期内完成,以保障软件可
以稳定、持续的保持在随时可以发布的状态。与持续集成相比,持续交付偏重
点在于可交付的产物。
(3) 持续部署(Continuous Deployment,CD)
通过自动化部署的手段将软件频繁的交付,部署到期望的环境。
2 Jenkins介绍
2.1 什么是Jenkins
Jenkins是一款开源 CI&CD 系统,用于自动化各种任务,包括构建、测试和部署。
2.2 Jenkins vs Gitlab
Jenkins | Gitlab CI/CD |
开源 | 开源 |
专注CI/CD | 无缝集成,内置功能 |
支持分布式构建 | 支持分布式构建 |
提供API | 提供API |
插件丰富 | 市场小众化 |
使用简单 |
|
市场大众化 |
|
3 Jenkins部署
3.1 tomcat安装
1 部署jdk和maven
# tar -xzf jdk-8u45-linux-x64.tar.gz
# mv jdk1.8.0_45/ /usr/local/jdk/
# tar -xzf apache-maven-3.5.0-bin.tar.gz
# mv apache-maven-3.5.0/ /usr/local/maven/
# cat >>/etc/profile<< EOF
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=\$JAVA_HOME/lib/tools.jar:\$JAVA_HOME/jre/lib/rt.jar
export PATH=\$JAVA_HOME/bin:/usr/local/maven/bin:\$PATH
EOF
# source /etc/profile
# java -version
2 部署tomcat
# tar -xzf apache-tomcat-8.5.59.tar.gz
# mv apache-tomcat-8.5.59/ /usr/local/tomcat/
# cd /usr/local/tomcat/webapps/
# rm -rf *
3 部署Jenkins war包
# pwd
/usr/local/tomcat/webapps
# wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/war-stable/2.249.3/jenkins.war
# mv jenkins.war ROOT.war
4 启动tomcat
# /usr/local/tomcat/bin/startup.sh
5在浏览器中访问Jenkins进行安装
(1) http://172.16.1.72:8080/
(2) 解锁jenkins
(3) 跳过插件安装
(4) 创建管理员账户
(5) 实例配置
(6) 开始使用
6 设置插件安装地址
(1) Manage(URL)
http://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
提示:
Submit -> Check now后会在Jenkins家目录/root/.jenkins/目录下生成一个updates目录。
(2) 修改下载插件的真实配置文件
# cd /root/.jenkins/updates/
# sed -i.bak 's/https:\/\/updates.jenkins.io\/download/http:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json
# sed -i.bak 's/http:\/\/www.google.com/http:\/\/www.baidu.com/g' default.json
提示:
如果啊修改错误可以尝试删除/root/.jenkins/updates/目录后执行Submit -> Check now操作或
直接执行Submit -> Check now操作,那么初始的/root/.jenkins/updates/default.json文件就会
还原回来了。
(3) 重启jenkins
http://172.16.1.72:8080/restart
到此jenkins tomcat方式就安装完成了,jenkins插件下载速度也会很快。
(4) 补充说明
tomcat+jenkins.war包方式安装的jenkins家目录为/root/.jenkins/,如果升级jenkins,只需要替换
/usr/local/tomcat/webapps/目录下的jenkins war包即可,且jenkins家目录下的数据不会丢失。
3.2 Docker安装
1 部署jdk和maven
# tar -xzf jdk-8u45-linux-x64.tar.gz
# mv jdk1.8.0_45/ /usr/local/jdk/
# tar -xzf apache-maven-3.5.0-bin.tar.gz
# mv apache-maven-3.5.0/ /usr/local/maven/
2 安装
# docker run -d --name jenkins -p 8080:8080 -p 50000:50000 -u root \
-v /opt/jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
-v /usr/local/maven:/usr/local/maven \
-v /usr/local/jdk:/usr/local/jdk \
-v /etc/localtime:/etc/localtime \
--restart=always \
--name jenkins jenkins/jenkins:lts
提示:
jenkins家目录为:/opt/jenkins_home
8080:代表jenkins http访问端口
50000:代表jenkins和分布式主机通信端口
3 在浏览器中访问Jenkins进行安装
(1) http://172.16.1.72:8080/
(2) 解锁jenkins
(3) 不安装任何插件
(4) 创建管理员账户
(5) 实例配置
(6) 开始使用
4 Jenkins基本配置
4.1 让Jenkins UI变好看点
jenkins主题网站:http://afonsof.com/jenkins-material-theme/
1 选择light-green为主题颜色
2 主题URL路径:https://cdn.rawgit.com/afonsof/jenkins-material-theme/gh-pages/dist/material-cyan.css
3 Manage Jenkins -> Manage Plugins -> 搜索Simple Theme插件并安装
4-7 Manage Jenkins -> Configuration System -> Theme(Theme elements -> CSS URL -> 粘贴步骤2中
的URL) -> save
8 添加样式后的jenkins页面
补充:
如果由于网络问题,导致无法加载样式url,可以采用直接粘贴css样式表的方式"Extra CSS"
样式一:
样式二:
4.2 Jenkins插件安装
1 修改jenkins插件源为清华源
# cd /opt/jenkins_home/updates/
# sed -i 's/https:\/\/updates.jenkins.io\/download/https:\/\/mirrors.tuna.tsinghua.edu.cn\/jenkins/g' default.json && \
# sed -i 's/http:\/\/www.google.com/https:\/\/www.baidu.com/g' default.json
重启jenkins,使配置生效
http://172.16.1.72:8080/restart
2 常用插件
插件名称 | 描述 |
Pulish Over SSH | 通过SSH发送构建的程序到远程服务器 |
SSH plugin | 在远程服务器执行Shell命令 |
Subversion Plug-in | SVN管理 |
Extended Choice Parameter Plug-In | 参数化构建 |
Git plugin | Git管理 |
Git Parameter Plug-In | Git参数化构建 |
Role-based Authorization Strategy | 用户项目权限控制 |
Email Extension Plugin | 邮件通知扩展功能(定义内容格式等) |
Dingding Plugin | 钉钉通知 |
Maven Integration plugin | Maven环境深度集成 |
Locale plugin Chinese (Simplified) | 中文支持 |
Bluce Ocean | 全新的Jenkins用户界面 |
3 在线安装
Manage Jenkins -> Manage Plugins -> available plugin
4 离线安装
Manage Jenkins -> Manage Plugins -> advanced -> Upload plugin
离线插件包推荐下载点:
https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/
补充:
可以将联网的jenkins已安装的插件从/root/.jenkins/plugins/目录中拷贝出来后拷贝到不能连接互联
网下载插件的jenkins /root/.jenkins/plugins/目录下也可。
4.3 Jenkins设置中文
安装Chinese (Simplified)插件,然后重启jenkins即可。
Locale plugin中文插件可以不装(zh_cn)。
4.4 设置maven源
maven国内源:https://maven.aliyun.com/mvn/guide
在<mirrors></mirrors>标签中添加 mirror 子节点。
# vim /usr/local/maven/conf/settings.xml
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
说明:
配置好maven源后立即生效,不需要重启jenkins服务。
5 Jenkins核心功能应用
5.1 项目管理
1 创建自由风格的java-demo项目
新建Item
2 丢弃旧的构建(Discard old builds)
3 参数化构建(Choice Parameter 多参数单选)
(1) 配置
1) Choice Parameter参数设置
2) 构建shell脚本设置
(2) Build with Parameters
(3) 查看构建控制台输出日志
4 参数化构建(String Parameter单参数单选)
(1) 配置
1) String Parameter参数设置
2) 构建shell脚本设置
(2) Build with Parameters
(3) 查看构建控制台输出日志
5 Git地址配置(Git插件)
(1) 安装Git插件
(2) 配置
1) String Parameter参数设置
2) 源码管理设置
3) 构建shell脚本设置
pwd
ls
echo $branch
echo $BUILD_NUMBER
# 构建序号
echo $JOB_NAME
# 项目名
echo $WORKSPACE
# 工作目录
(3) Build with Parameters
(4) 查看控制台输出
6 自动执行项目(构建触发器)
(1) 周期性进行项目构建(Build periodically)
这个是到指定的时间必须触发构建任务。
(2) 定时检查源码变更(Poll SCM)
定时检查源码变更,如果有更新就checkout最新code下来,然后执行构建动作。
5.2 用户与权限管理
0 实验背景
(1) 创建两个用户
user-A
user-B
Manage Jenkins -> Manage Users
(2) 创建两个项目
A-project
B-project
(3) 赋权规则
user-A用户登录后只能看到A-project项目
user-B用户登录后只能看到B-project项目
1 安装插件(Role-based Authorization Strategy)
2 开启插件
Manage Jenkins -> Configure Global Security -> 授权策略
3 创建角色
Manage Jenkins -> Manage and Assign Roles -> Manage Roles
(1) 创建全局用户角色权限
全局角色:
控制对Jenkins配置和项目操作,默认admin管理员权限,角色给一个Read权限,可以读取所有
项目。
(2) 创建项目角色权限
项目角色:
针对项目操作,使用正则表达式匹配项目名称,例如A-.*,匹配以A-开通的项目。
4 为用户赋于角色
Manage Jenkins -> Manage and Assign Roles -> Assign Roles
(1) 赋予用户全局用户角色权限
(2) 赋予用户项目角色权限
5 用户登录测试
(1) user-A用户
(2) user-B用户
5.3 参数化扩展(master机器)
1 说明
(1) 在实际环境中, 往往有很多项目,特别是微服务架构,如果每个服务都创建一个item,势必给运维增加很大工作量,因此可以通过Jenkins的参数化构建, 人工交互确认发布的环境配置、预期状态等。
(2) 一个Pipeline脚本适配多项目关键在于将差异化部分使用参数化构建交互选择。
(3) Git Parameter插件
自动获取当前Git地址所有分支(和Git插件一起使用),并提供下拉框可选(单选)。
(4) Extended Choice Parameter插件
功能强大,支持单选、多选,读取文件作为值,支持Groovy脚本。
2 Git Parameter插件
(1) 安装插件
(2) 配置
1) Git参数设置
2) 源码管理
3) 构建shell脚本设置
(3) Build with Parameters
(4) 控制台输出日志查看
3 Extended Choice Parameter插件
(1) 安装插件
(2) 配置
1) 构建shell配置
2) Extended Choice Parameter参数配置
(3) Build with Parameters
(4) 控制台输出
(5) 补充:Choose Source for Value使用Property File代替value
在172.16.1.172节点上执行下面一条命令,添加主机ip清单,只要按格式更新该文件,jenkins就
能读取到服务器ip。
# echo "hosts=172.16.1.71,172.16.1.72,172.16.1.73,172.16.1.74" >/opt/jenkins_home/server.list
设置完成后,效果同上面实验相同。
5.4 分布式构建(master/slave)
1 在172.16.1.73节点上部署jdk、maven
# tar -xzf jdk-8u45-linux-x64.tar.gz
# mv jdk1.8.0_45/ /usr/local/jdk/
# tar -xzf apache-maven-3.5.0-bin.tar.gz
# mv apache-maven-3.5.0/ /usr/local/maven/
# cat >>/etc/profile<< EOF
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=\$JAVA_HOME/lib/tools.jar:\$JAVA_HOME/jre/lib/rt.jar
export PATH=\$JAVA_HOME/bin:/usr/local/maven/bin:\$PATH
EOF
# source /etc/profile
修改maven的源路径
# vim /usr/local/maven/conf/settings.xml
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
2 将172.16.1.73节点作为172.16.1.72 jenkins的分布式节点
(1) Manage Jenkins -> Manage Nodes and Clouds -> 新建节点
1) 节点名称
2) 节点参数配置
(2) 在172.16.1.73节点上按如下步骤注册agent
# mkdir -p /opt/jenkins_home
# cd /opt/jenkins_home
# wget http://172.16.1.72:8080/jnlpJars/agent.jar
# nohup java -jar agent.jar -jnlpUrl http://172.16.1.72:8080/computer/jenkins-slave01/slave-agent.jnlp -secret 6ed1fe56905852442527709616b0ebd53e7594e93e9ceb8791c56111d4850b01 -workDir "/opt/jenkins_home" &>slave.log &
# 可以将该启动命令加入到开机自启动中
(3) 添加完成
3 在项目中指定使用哪台slave处理代码构建操作
说明:
从节点配置参数中的"名称"或"标签"都可以作为标签表达式来使用,推荐使用"名称"。
# 发布java-demo项目时,项目在172.16.1.73节点上执行
5.5 配置web服务器
1 在172.16.1.74/75节点上安装jdk、tomcat
# tar -xzf jdk-8u45-linux-x64.tar.gz
# mv jdk1.8.0_45/ /usr/local/jdk/
# tar -xzf apache-tomcat-8.5.59.tar.gz
# mv apache-tomcat-8.5.59/ /usr/local/tomcat/
# rm -rf /usr/local/tomcat/webapps/*
# cat >>/etc/profile<< EOF
export JAVA_HOME=/usr/local/jdk
export CLASSPATH=\$JAVA_HOME/lib/tools.jar:\$JAVA_HOME/jre/lib/rt.jar
export PATH=\$JAVA_HOME/bin:\$PATH
EOF
# source /etc/profile
5.6 拷贝构建文件到远程服务器
1 安装Publish Over SSH插件
该插件是基于SSH发送文件并在远程服务器上执行命令。
2 配置SSH密钥对,实现免交互认证
在172.16.1.72节点上操作(在哪个主机上生成密钥对没有关系)
(1) 生成密钥对
# ssh-keygen
(2) 将id_rsa.pub公钥内容添加到目标服务器
# ssh-copy-id [email protected]
# ssh-copy-id [email protected]
(3) 将id_rsa私钥保存到插件配置里并添加远程主机
# cat /root/.ssh/id_rsa
Manage Jenkins -> Configure System -> Publish over SSH
3 java-demo项目配置
"Execute shell"的shell命令是在构建节点(172.16.1.73)上执行的。
ip addr
echo $JOB_NAME
# 项目名
echo $branch
pwd
echo $WORKSPACE
# 工作目录
ls
echo $BUILD_NUMBER
# 构建序号
构建
Source files # 传输的源文件,相对路径
Remove prefix # 去除拷贝的源文件上级目录
Remote directory # 拷贝到远程服务器的目录,与SSH配置的Remote Directory拼接,例如 # 这里写tmp/test,最终目标目标是/tmp/test
Exec command # 在远程服务器执行的Shell脚本
4 Build with Parameters
5 查看控制台输出
7 查看目标主机
5.7 在远程服务器执行shell命令
1 安装ssh插件
2 配置SSH密钥对,实现免交互认证
在172.16.1.72节点上操作(在哪个主机上生成密钥对没有关系)
(1) 生成密钥对
# ssh-keygen
(2) 将id_rsa.pub公钥内容添加到目标服务器
# ssh-copy-id [email protected]
# ssh-copy-id [email protected]
(3) 将id_rsa私钥保存到jenkins凭据里,并添加远程主机
# cat /root/.ssh/id_rsa
Manage Jenkins -> Configure System -> SSH remote hosts
3 java-demo项目配置
构建
4 Build with Parameters
5 查看控制台输出
6 jenkins 发布单台java web项目
6.1 发布流程
1 分布式构建
2 Git参数化
3 配置Git地址
4 配置触发器
5 代码编译构建
6 拷贝构建文件到远程Web服务器(备份旧代码)
7 修改代码,验证测试
6.2 将实验代码上传到gitlab上
1 在java-project群组下创建名为java-mall的项目
2 在172.16.1.72节点上将代码上传到java-mall项目下
# unzip tomcat-java-demo-master.zip
# cd tomcat-java-demo-master/
# git config --global user.name "Administrator"
# git config --global user.email "[email protected]"
# git init
# git remote add origin http://172.16.1.71/java-project/java-mall.git
# git add .
# git commit -m "all"
# git push -u origin master
6.3 在jenkins中设置java-mall项目
1 创建自由风格的java-mall项目
2 Discard old builds
3 This project is parameterized
4 限制项目的运行节点
5 源码管理
6 构建触发器
7 构建
mvn clean package -Dmaven.test.skip=true
ls
ls target
#!/bin/bash
# 备份已部署的程序
tomcat=/usr/local/tomcat/webapps
BACKUP_DIR=/data/backup
[ ! -d $BACKUP_DIR ] && mkdir -p $BACKUP_DIR
[ -f $tomcat/*.war ] && mv $tomcat/*.war $BACKUP_DIR/$(date +"%F_%T")_ROOT.war
# 部署新程序并重启Tomcat
[ -d $tomcat/ROOT ] && rm -rf $tomcat/ROOT
mv /tmp/$JOB_NAME/*.war $tomcat/ROOT.war
pid=$(ps -ef |grep $tomcat |egrep -v 'grep' |awk '{print $2}')
[ -n "$pid" ] && kill -9 $pid
export JAVA_HOME=/usr/local/jdk
/usr/local/tomcat/bin/startup.sh
6.4 Build with Parameters
6.5 查看控制台输出
6.6 测试
1 在浏览器中输入"http://172.16.1.74:8080/" URL地址即可访问发布的网站
2 修改gitlab中java-mall项目首页html代码,间隔一分钟后,jenkins发现gitlab上的代码发生了
改变,自动执行项目代码的构建发布过程。
7 jenkins集成Ansible发布多台java web服务器
7.1 部署Ansible
在jenkins-slave01(172.16.1.73)节点上操作
1 安装ansible
# yum install ansible -y
# ansible --version
ansible 2.9.15
2 配置ansible免交互密钥连接java-web01/web02服务器
(1) 配置ansible配置文件
# vim /etc/ansible/ansible.cfg
host_key_checking = False
log_path = /var/log/ansible.log
(2) 生成密钥对
在172.16.1.72节点上操作,在哪个主机上生成密钥对没有关系)
# ssh-keygen
(3) 将id_rsa.pub公钥内容添加到目标服务器
# ssh-copy-id [email protected]
# ssh-copy-id [email protected]
(4) 将id_rsa私钥保存到全局凭中
# cat /root/.ssh/id_rsa
Manage Jenkins -> Manage Credentials ->凭据
3 安装ansible插件
7.2 在jenkins中配置java-mall项目
1 Discard old builds
2 This project is parameterized
3 限制项目的运行节点
4 源码管理
5 构建
6 构建
7.3 配置playbook(java-mall.yml)文件
在172.16.1.73节点上操作
# cat /opt/jenkins_home/java-mall.yml
- hosts: "{{ HostGroups }}"
gather_facts: no
tasks:
- name: 在远程服务器上创建项目目录
file:
dest: /tmp/{{ JobName }}
state: directory
- name: 推送部署包到远程服务器
copy: src="{{ item }}" dest=/tmp/{{ JobName }}
with_fileglob:
- "{{ workspace }}/target/*.war"
部署新程序并重启Tomcat
shell: |
# 备份已部署的程序
tomcat=/usr/local/tomcat/webapps
BACKUP_DIR=/data/backup
[ ! -d $BACKUP_DIR ] && mkdir -p $BACKUP_DIR
[ -f $tomcat/*.war ] && mv $tomcat/*.war $BACKUP_DIR/$(date +"%F_%T")_ROOT.war
部署新程序并重启Tomcat
[ -d $tomcat/ROOT ] && rm -rf $tomcat/ROOT
mv /tmp/{{ JobName }}/*.war $tomcat/ROOT.war
pid=$(ps -ef |grep $tomcat |egrep -v 'grep' |awk '{print $2}')
[ -n "$pid" ] && kill -9 $pid
export JAVA_HOME=/usr/local/jdk
nohup /usr/local/tomcat/bin/startup.sh &
7.4 Build with Parameters
7.5 查看控制台输出
8 补充
8.1 上线流程
8.2 Ansible介绍
Ansible是一个自动化运维工具,基于Python开发,可以实现批量系统配置、
批量软件部署、批量执行命令等功能。
Inventory # 主机清单,根据服务器角色进行分组管理。
Playbook # 描述希望在远程服务器做哪些事的文件,采用YAML格式。