jenkins
# 1、传统网站部署流程
需求》开发》测试》部署》备份》上线》测试
MAKE、ANT、MAVEN、Eclipse
jenkins部署流程
提交代码》测试代码》合并代码构建 》部署(晚上定时发布) 》回滚
Jenkins+Docker+SpringCloud持续集成流程说明
Kubernates+Docker+Jenkins持续集成架构图
大致工作流程:手动/自动构建 -> Jenkins 调度 K8S API ->动态生成 Jenkins Slave pod -> Slave pod 拉取 Git 代码/编译/打包镜像 ->推送到镜像仓库 Harbor -> Slave 工作完成,Pod 自动销毁 ->部署 到测试或生产 Kubernetes平台。(完全自动化,无需人工干预)
SonarQube代码审查
# 2、jenkins安装
yum -y install java java -version 版本8.0以上
wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins.io/redhat-stable/jenkins.repo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key yum -y install jenkins yum install xorg-x11-server-Xvfb vim /etc/sysconfig/jenkins JENKINS_USER="jenkins" JENKINS_PORT ="8080"
chown -R jenkins.jenkins /var/lib/jenkins/ chown -R jenkins.jenkins /var/log/jenkins/
java -jar /usr/lib/jenkins/jenkins.war --httpPort=8888
war包下载
https://updates.jenkins-ci.org/download/war/
# 3、基础知识
什么是持续集成(CI-Continuous integration) 持续集成是指多名开发者在开发不同功能代码的过程当中,可以频繁的将代码行合并到一起并切相互不影响工作。
什么是持续部署(CD-continuous deployment) 是基于某种工具或平台实现代码自动化的构建、测试和部署到线上环境以实现交付高质量的产品,持续部署在某种程度上代表了一个开发团队的更新迭代速率。
什么是持续交付(Continuous Delivery) 持续交付是在持续部署的基础之上,将产品交付到线上环境,因此持续交付是产品价值的一种交付,是产品价值的一种盈利的实现。
jenkins是一个开源持续集成工具 1.支持主流软件配置管理,配合实现软件配置管理,持续集成功能 2.主流的运维开发平台,兼容所有主流开发环境 3.插件市场可与海量业内主流开发工具实现集成 4.Job为配置单位与日志管理,使运维与开发人员能协同工作 5.权限管理划分不同job不同角色 6.强大的负载均衡功能,保证我们项目的可靠性
freestyle job: 1.需在页面添加模块配置项与参数完成配置 2.每个job仅能实现一个开发功能 3.无法将配置代码化,不利于Job配置迁移与版本控制 4.逻辑相对简单,无需额外学习成本
pipeline job: 匹配持续集成与持续交付的概念 1.所有模块,参数配置都可以体现为一个pipeline脚本 2.可以定义多个stage构建一个管道工作集 3.所有配置代码化,方便job配置迁移与版本控制 4.需要pipeline脚本语法基础
# 4、jenkins job构建配置
1.配置jenkins server 本地gitlab DNS 2.安装git client,curl工具依赖 3.关闭系统git http.sslVerfiy安全认证 4.添加jenkins后台 git client user与email 5.添加jenkins后台 git Credential凭据
# 4.1 jenkinx配置构建触发器
安装插件 git gitlab hook Role-based Authorization Strategy
openssl rand -hex 12
http://jenkins.ops.com/job/testproject-app/build?token=93a09ec625469417d29219c1
取消跨站请求伪造保护
高版本jenkins不能界面禁用跨站请求伪造保护。
禁用跨站请求伪造保护操作如下:
修改jenkins的配置文件。vim /etc/sysconfig/jenkins
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Dhudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true"
配置后重启jenkins。service jenkins restart
cd /var/lib/jenkins/workspace/testproject-app
ssh 192.168.200.237 "rm -rf /opt/tomcat2"
scp -r tomcat 192.168.200.237:/opt/tomcat2
ssh 192.168.200.237 "java -version"
ssh 192.168.200.237 "mkdir /opt/tomcat2/logs"
ssh 192.168.200.237 "/opt/tomcat2/bin/startup.sh start"
cd /var/lib/jenkins/workspace/testproject-app
tar czvf code.tar.gz *
scp code.tar.gz 192.168.200.212:/data/tomcat/tomcat_appdir/
ssh 192.168.200.212 "systemctl stop tomcat && rm -rf /data/tomcat/tomcat_webdir/myapp/* && cd /data/tomcat/tomcat_appdir && tar xf code.tar.gz -C /data/tomcat/tomcat_webdir/myapp/"
ssh 192.168.200.212 "systemctl start tomcat"
2
3
4
5
6
7
8
9
10
11
12
13
视图插件 build pipeline
# 5.docker安装jenkins
docker run --name jenkins -u root -p 8083:8080 -p 50000:50000 -d --restart=always -v /data/jenkins:/var/jenkins_home jenkins:2.19.3
# 6.jenkins pipeline job编写规范
pipeline基础架构 ◆所有代码包裹在pipeline{}层内 ◆stages{}层用来包含该pipeline所有stage子层 ◆stage{}层用来包含具体我们需要编写任务的steps{}子层
agent区域 ◆agent定义pipeline在哪里运行 可以使用any, none,或具体的Jenkins node主机名等 例:如果我们要特指在node1.上执行,可以写成: agent {node {label 'node1'}}
agent any
environment区域 ◆"变 量名称=变量值"定义我们的环境变量
◆可以定义全局环境变量,应用所有stages任务
◆可以定义stage环境变量,应用单独的stage任务
script区域(可选) ◆在steps内定义script{} ◆groovy脚本语言 ◆用来进行脚本逻辑运算
常用steps区域 ◆echo: 打印输出 ◆sh: 调用Linux系统shell命令 ◆git url:调用git模块进行git相关操作
pipeline {
agent {node {label 'jenkins-slave1'}}
environment {
JAVA_HOME="/opt/jdk"
}
stages {
stage("clone 代码"){
steps{
sh 'rm -rf /home/jenkins/workspace/pipeline-test2/*'
git credentialsId: 'd8106f36-80b1-4847-a93e-2b88ffa70a31', url: 'https://gitee.com/opstand/cloud.git'
}
}
stage("代码打包"){
steps{
sh 'cd /home/jenkins/workspace/pipeline-test2/ && tar zcf /opt/code.tar.gz *'
}
}
stage("代码复制"){
steps{
sh 'cp /opt/code.tar.gz /opt/tomcat8/webapps/'
}
}
stage("tomcat重启"){
steps{
sh '/opt/tomcat8/bin/shutdown.sh && sleep 10s'
sh '/opt/tomcat8/bin/startup.sh'
sh 'ps -ef|grep tomcat'
sh 'ss -tnl'
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
jenkins shell命令
#!/bin/sh
user=`whoami`
if [ $user == 'deploy' ]
then
echo "Hello, my name is $user"
else
echo "Sorry, I am not $user"
fi
ip addr
cat /etc/system-release
free -m
df -h
py_cmd=`which python`
$py_cmd --version
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
jenkins集成ansible
#!/bin/sh
ssh root@192.168.200.210 -p 2222 "cat >/tmp/1.sh<<EOF \
#!/bin/bash
ansible --version
ansible-playbook --version
cat /etc/ansible/hosts
ansible web -m command -a \"ip addr\"
EOF"
ssh root@192.168.200.210 -p 2222 "bash /tmp/1.sh"
2
3
4
5
6
7
8
9
10
11
# 7.pipline job示例
node("jenkins-slave1") {
stage("clone代码"){
sh 'rm -rf /var/lib/jenkins/workspace/pipeline-test/*'
git branch: 'develop', credentialsId: 'b0c0dd45-e628-44ad-be1c-42693fdedf6c', url: 'git@gitlab.example.com:testgroup/testproject.git'
}
stage("代码打包"){
sh 'cd /var/lib/jenkins/workspace/pipeline-test/ && tar czvf code.tar.gz *'
}
stage("代码复制"){
sh 'scp code.tar.gz 192.168.200.212:/data/tomcat/tomcat_appdir/'
}
stage("停止tomcat服务"){
sh 'ssh 192.168.200.212 "systemctl stop tomcat"'
}
stage("代码部署"){
sh 'ssh 192.168.200.212 "rm -rf /data/tomcat/tomcat_webdir/myapp/* && cd /data/tomcat/tomcat_appdir && tar xvf code.tar.gz -C /data/tomcat/tomcat_webdir/myapp/"'
}
stage("启动tomcat服务"){
sh 'ssh 192.168.200.212 "systemctl start tomcat"'
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# JenkinsFile 基础语法
// 前端项目JenkinsFile配置,后端项目配置稍有不同,后面会区分说明
pipeline {
agent any
environment {
HOST_TEST = 'root@121.41.16.183'
HOST_ONLINE = 'jenkins@39.101.219.110'
SOURCE_DIR = 'dist/*'
TARGET_DIR = '/data/www/kuaimen-yunying-front'
}
parameters {
choice(
description: '你需要选择哪个环境进行部署 ?',
name: 'env',
choices: ['测试环境', '线上环境']
)
string(name: 'update', defaultValue: '', description: '本次更新内容?')
}
triggers {
GenericTrigger(
genericVariables: [
[key: 'ref', value: '$.ref']
],
causeString: 'Triggered on $ref',
token: 'runcenter-front-q1w2e3r4t5',
tokenCredentialId: '',
printContributedVariables: true,
printPostContent: true,
silentResponse: false,
regexpFilterText: '$ref',
regexpFilterExpression: 'refs/heads/' + BRANCH_NAME
)
}
stages {
stage('获取git commit message') {
steps {
script {
env.GIT_COMMIT_MSG = sh (script: 'git log -1 --pretty=%B ${GIT_COMMIT}', returnStdout: true).trim()
}
}
}
stage('打包') {
steps {
nodejs('nodejs-12.16') {
echo '开始安装依赖'
sh 'yarn'
echo '开始打包'
sh 'yarn run build'
}
}
}
stage('部署') {
when {
expression {
params.env == '测试环境'
}
}
steps {
sshagent(credentials: ['km-test2']) {
sh "ssh -o StrictHostKeyChecking=no ${HOST_TEST} uname -a"
sh "scp -r ${SOURCE_DIR} ${HOST_TEST}:${TARGET_DIR}"
sh 'echo "部署成功~"'
}
}
}
stage('发布') {
when {
expression {
params.env == '线上环境'
}
}
steps {
sshagent(credentials: ['km-online']) {
sh "ssh -o StrictHostKeyChecking=no ${HOST_ONLINE} uname -a"
sh "scp -r ${SOURCE_DIR} ${HOST_ONLINE}:${TARGET_DIR}"
sh 'echo "发布成功~"'
}
}
}
}
post {
success {
dingtalk (
robot: '77d4c82d-3794-4583-bc7f-556902fee6b0',
type: 'MARKDOWN',
atAll: true,
title: '你有新的消息,请注意查收',
text:[
'# 运营管理系统发布通知',
'---',
'#### **所属:前端**',
"#### **构建任务:${env.BUILD_DISPLAY_NAME}**",
"#### **Git commit:${env.GIT_COMMIT_MSG}**",
"#### **本次更新内容:${params.update}**",
"#### **部署环境:${params.env}**",
'#### **构建结果:成功**'
]
)
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
- pipeline 必须在最外层
- agent 定义了在哪个环境里执行,默认any
- stages 阶段,标识构建流程的标签块,子节点是stage
- steps 执行步骤
- post 所有阶段执行完成后执行一些逻辑
- when 可以控制该阶段是否执行
- environment 环境变量,在这里定义的变量,JenkinsFile的任何地方都可以访问
- tools 项目使用到的构建工具,声明系统配置中已经定义好的工具,如maven
- parameters 定义参数,可以提供用户输入或者选择
- post 构建结束后会执行这里,有success、failure、success,本示例将在success(构建成功时)发起钉钉通知
# 8.shell自动发布脚本
自动上传war包
cd /var/jenkins_home/workspace/cjpt_222_sd/web/target
ssh 192.168.1.222 "systemctl stop tomcat && rm -f /opt/tomcat8/webapps/web.war && rm -rf /opt/tomcat8/webapps/web"
scp *.war 192.168.1.222:/opt/tomcat8/webapps/web.war
ssh 192.168.1.222 "systemctl start tomcat"
2
3
4
# 9.jenkins 设置中文显示
这里使用的方法是安装中文语言包,安装的插件名称是:Localization: Chinese (Simplified) 1.在插件管理,搜索 Localization: Chinese (Simplified),然后点击Install without restart
好记性不如烂笔头,仅用来记录
# 10.jenkins构建maven项目
一、linux的环境
jdk 、maven 、tomcat版本按照所定需求安装好
二、jenkins安装
这里就忽略了
三、jenkins所需要的插件
Deploy to container
Maven Intergration plugin
四、全局工具配置
五、创建任务
打开tomcat下conf/tomcat-users.xml,在</tomcat-users>之前增加以下配置:
<role rolename="manager"/>
<role rolename="manager-gui"/>
<role rolename="manager-script"/>
<role rolename="manager-status"/>
<user username="xxx" password="xxxx" roles="tomcat,admin-gui,admin,manager,manager-gui,manager-script"/>
2
3
4
5
6
7
8
9
10
11
之后点击构建得到以下结果就是完满成功了~
如果Jenkins报错:The username you provided is not allowed to use the text-based Tomcat Manager (error 403):
在tomcat目录修改两个文件!
webapps/manager/META-INF/context.xml
webapps/host-manager/META-INF/context.xml
将只允许本机访问的限制注释掉即可,
如果jenkins报错:
ERROR: Maven JVM terminated unexpectedly with exit code 137
1、查看内存使用情况:free -m
2、创建虚拟内存磁盘卷
mkdir /swap
dd if=/dev/zero of=/swap/swapadd bs=1024 count=2024288
3、将磁盘卷转为虚拟内存卷
mkswap /swap/swapadd
4、启用虚拟内存服务
swapon /swap/swapadd
5、再次查看内存情况
# 11.jenkins版本回滚
# 一、新建一个自由风格项目
image.png
# 二、配置参数化构建过程
添加选项参数
image.png
填入以下内容
image.png
2.添加字符参数
image.png
# 三、配置SVN
image.png
# 四、配置构建步骤
# 1. maven打包配置
选择调用顶层Maven目标,Maven版本之前已经在全局工具配置中设置过,目标中填入打包命令
image.png
# 2. 执行shell配置
此脚本为打包备份,回滚脚本
image.png
填入以下脚本
备份回滚脚本
case $Status in
Deploy)
echo "Status:$Status"
path="${WORKSPACE}/bak/${BUILD_NUMBER}" #创建每次要备份的目录
if [ -d $path ];
then
echo "The files is already exists "
else
mkdir -p $path
fi
\cp -f ${WORKSPACE}/target/*.war $path #将打包好的war包备份到相应目录,覆盖已存在的目标
echo "Completing!"
;;
Rollback)
echo "Status:$Status"
echo "Version:$Version"
cd ${WORKSPACE}/bak/$Version #进入备份目录
\cp -f *.war ${WORKSPACE}/target/ #将备份拷贝到程序打包目录中,并覆盖之前的war包
;;
*)
exit
;;
esac
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
这样发布后以后,就会备份如下
image.png
image.png
# 3. 定期删除脚本
项目备份不可能无限制备份,这样很快就会占满磁盘,所以我们必须有清除老旧备份的机制。此处配置一个脚本,每次发布都执行一次,判断备份数是否超过5个,如果超过,则删除老旧备份,只保留最新的5个。
再添加一个执行shell步骤,填入以下脚本,其中备份数量可以自行修改减小或加大
删除老旧备份脚本
ReservedNum=5 #保留文件数
FileDir=${WORKSPACE}/bak/
date=$(date "+%Y%m%d-%H%M%S")
cd $FileDir #进入备份目录
FileNum=$(ls -l | grep '^d' | wc -l) #当前有几个文件夹,即几个备份
while(( $FileNum > $ReservedNum))
do
OldFile=$(ls -rt | head -1) #获取最旧的那个备份文件夹
echo $date "Delete File:"$OldFile
rm -rf $FileDir/$OldFile
let "FileNum--"
done
2
3
4
5
6
7
8
9
10
11
12
13
14
# 五、配置发送到远程tomcat目录
image.png
其中Source files要注意配置正确,否则发送不了war包,我的jenkins该项目的workspace如下:
image.png
# 六、发布
- 回到项目主界面,点击Build with Parameters
发布选择Deploy--->开始构建,即可开始发布。
image.png
回滚选择Rollback--->输入回滚版本---->开始构建,版本号从构建历史中选择一个输入
# 12.关于execute shell
请在“Execute shell”构建步骤中添加以下行。
#!/bin/sh
现在让我解释一下为什么我们需要这行“Execute Shell”构建作业的原因。
默认情况下,Jenkins采取/bin/sh -xe
这种方式-x
将打印每一个命令。另一个选项-e
,当任何命令以非零值(当任何命令失败时)退出代码时,这会导致shell立即停止运行脚本。
所以通过添加#!/bin/sh
将让你执行没有选择。