一、CICD环境介绍与安装
1、简介
Jenkins,原名 Hudson,2011 年改为现在的名字。它是一个开源的实现持续集成的软件工具。
官方网站:https://www.jenkins.io/
2、Docker安装
Docker官网安装文档:https://docs.docker.com/engine/install/
Centos7安装
# 更新yum源
yum update
# 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加镜像
# 国外镜像
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 阿里镜像
https://mirrors.aliyun.com/docker-ce/linux/centos/gpg
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 查看源中可使用版本
yum list docker-ce --showduplicates | sort -r
# 安装指定版本
yum install docker
# 配置开机启动项
systemctl start docker
systemctl enable docker
docker version
Ubuntu安装
# 文本处理的流编辑器 -i直接修改读取的文件内容,而不是输出到终端
# sed -i 's/原字符串/新字符串/' /home/1.txt
# 下面这个是修改ubuntu的源
sudo sed -i 's/cn.archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list
# 更新
sudo apt update -y
sudo apt install curl
# 抓取docker安装脚本到一个文件中
curl -fsSL get.docker.com -o get-docker.sh
# 执行脚本,通过脚本下载 推荐设置阿里云镜像下载加速 默认管理员登陆不加sudo;有警告就忽略
sudo sh get-docker.sh --mirror Aliyun
#==========解决每次输入sudo问题===========
# 将当前用户加入到docker组,这样每次使用就不需要sudo了
sudo gpasswd -a ${USER} docker
# 更新用户组,这样才能生效
newgrp - docker
sudo service docker restart
#============加速器================
# 加速器网址:https://www.daocloud.io/mirror#accelerator-doc,可能有时会失效
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
# 查看配置文件,自己添加加速器
vi /etc/docker/daemon.json
# {"registry-mirrors": ["http://hub-mirror.c.163.com"]}
# 最后要重启
sudo systemctl restart docker.service
# 安装ssh
sudo apt install openssh-server
#===========docker-compose=============
# 在官网下载符合条件的:https://github.com/docker/compose/releases
# wget也可以使用来下载
mv /usr/local/bin/docker-compose-linux-x86_64 /usr/local/bin/docker-compose
# 放在bin目录下,在其他位置可以直接使用
sudo mv /usr/local/bin/docker-compose-linux-x86_64 /usr/local/bin/docker-compose
sudo install docker-compose-linux-x86_64 /usr/local/bin/docker-compose
docker-compose ps
3、GitLab安装使用
3.1 介绍
GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的Web服务,相当于github和Gitee代码托管平台,只是GitLab是私有的代码托管平台
官方网站:https://about.gitlab.com/
安装所需最小配置,内存至少4G,安装文档:https://gitlab.cn/install/
3.2 手动安装
Centos系统下的安装
# 安装依赖
sudo yum install -y curl policycoreutils-python openssh-server perl
sudo systemctl enable sshd
sudo systemctl start sshd
# 配置镜像
curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash
# 开始安装,这边填写你的主机地址,也可以做好域名映射的域名
sudo EXTERNAL_URL="http://192.168.44.103" yum install -y gitlab-jh
Ubuntu系统下的安装
# 安装必要软件包
sudo apt update
sudo apt upgrade
sudo apt install build-essential curl file git ca-certificates wget
# 配置极狐GitLab 软件源镜像
curl -fsSL https://packages.gitlab.cn/repository/raw/scripts/setup.sh | /bin/bash
# 执行如下命令开始安装
sudo EXTERNAL_URL="https://gitlab.example.com" apt-get install gitlab-jh
3.3 Docker安装
docker run --detach \
--hostname 192.168.44.103 \
--publish 443:443 --publish 80:80 \
--name gitlab \
--restart always \
--volume $GITLAB_HOME/config:/etc/gitlab:Z \
--volume $GITLAB_HOME/logs:/var/log/gitlab:Z \
--volume $GITLAB_HOME/data:/var/opt/gitlab:Z \
--shm-size 256m \
registry.gitlab.cn/omnibus/gitlab-jh:latest
3.4 注意事项
# gitlab常用命令
gitlab-ctl start # 启动所有 gitlab 组件
gitlab-ctl stop # 停止所有 gitlab 组件
gitlab-ctl restart # 重启所有 gitlab 组件
gitlab-ctl status # 查看服务状态
gitlab-ctl reconfigure # 启动服务
vi /etc/gitlab/gitlab.rb # 修改默认的配置文件
gitlab-ctl tail # 查看日志
如果不在安装过程中指定了自定义密码,否则将随机生成一个密码并存储在 /etc/gitlab/initial_root_password
文件中(出于安全原因,24 小时后,此文件会被第一次 gitlab-ctl reconfigure
自动删除,因此若使用随机密码登录,建议安装成功初始登录成功之后,立即修改初始密码)。使用此密码和用户名 root
登录。
安装成功后访问http://你指定的ip或域名
即可访问,如果需要修改,可以进入/etc/gitlab/gitlab.rb
进行修改,改完重启
4、JDK与Maven安装
将JDK和maven安装在Jenkins服务器
#=============================在线安装==================================
# Centos的搜索与安装
yum search java|grep jdk
yum install java-1.8.0-openjdk
# Ubuntu的搜索与安装
apt-cache search openjdk
sudo apt-get install openjdk-8-jdk -y
#==============================离线安装==================
# java下载地址:https://www.oracle.com/java/technologies/downloads/#java17
# 然后解压好
cd ~
vim ~/.bashrc #输入小写i进入insert模式
# 设置环境变量
export JAVA_HOME=/usr/local/jdk1.8.0_162
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
# 刷新
source ~/.bashrc
#==================================maven====================
# 下载安装,官网:https://maven.apache.org/
wget https://dlcdn.apache.org/maven/maven-3/3.8.6/binaries/apache-maven-3.8.6-bin.tar.gz
tar -zxvf apache-maven-3.8.6-bin.tar.gz
mv apache-maven-3.8.6 /usr/local/maven
5、Jenkins安装
官网地址:https://www.jenkins.io/,建议机器内存0.5G以上
机器要求:
256 MB 内存,建议大于 512 MB
10 GB 的硬盘空间(用于 Jenkins 和 Docker 镜像)
需要安装以下软件:
Java 8 ( JRE 或者 JDK 都可以)
Docker (导航到网站顶部的Get Docker链接以访问适合您平台的Docker下载)
下载地址:https://www.jenkins.io/zh/download/
wget http://mirrors.jenkins.io/war-stable/2.346.3/jenkins.war
# 启动
java -jar jenkins.war
# docker安装
docker pull jenkins/jenkins:lts-jdk11
# 同时安装好git
启动后访问http://ip:8080,密码默认在/home/shawn/.jenkins/secrets/initialAdminPassword
,也可以在控制看到,进入后选择推荐安装
二、Jenkins + Git + Maven 自动化部署配置
1、Jenkins拉取构建jar包
1.1 maven换源
进入maven的配置文件vim /usr/local/maven/conf/settings.xml
,找到镜像源并替换
<localRepository>${user.home}/.m2/repository</localRepository>
<pluginGroups>
<pluginGroup>org.mortbay.jetty</pluginGroup>
</pluginGroups>
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<!--This sends everything else to /public -->
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
<mirror>
<!--This is used to direct the public snapshots repo in the
profile below over to a different nexus group -->
<id>nexus-public-snapshots</id>
<mirrorOf>public-snapshots</mirrorOf>
<url>http://maven.aliyun.com/nexus/content/repositories/snapshots/</url>
</mirror>
<mirror>
<!--This is used to direct the public snapshots repo in the
profile below over to a different nexus group -->
<id>nexus-public-snapshots1</id>
<mirrorOf>public-snapshots1</mirrorOf>
<url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>
</mirror>
</mirrors>
1.2 全局配置
系统管理→全局工具配置→配置系统全局maven,注意填写自己的maven路径,然后下载好git
1.3 自动拉取构建初体验
选择新建任务→构建一个maven项目,其他暂时默认,仓库去gitlab获取链接,这里使用了http,使用不需要凭证,同时选择好自己想拉取的分支,如果报错,需要安装git
pom.xml
位置,如果项目里面有多个子项目,那需要添加前缀
1.4 构建注意事项
如果控制台报错No compiler is provided in this environment.Perhaps you are running on a "JRE rather than a JDK?
# 默认yum安装java的时候会显示安装的是openjdk1.8 实则实际上只安装了jre
yum install -y java-devel
# ubuntu正常
2、自动发布并运行
2.1 插件安装与配置
系统管理→插件管理→安装插件→publish over ssh
安装好插件好,进入系统管理→系统管理,配置好对目标服务器的ssh,设置好登录地点目录
2.2 自动发布
在原来的任务选择配置进行修改,选择构建后的操作,选择我们刚刚配置好的服务器,配置构建后出发的选项,Source files
代表要传送的文件,Remove prefix
表示去除的前缀,Remote directory
表示要创建的目录,最后是要运行的命令,构建结束后,远程服务器存在文件/home/shawn/jenkins/jenkin.jar
超时机制
输出命令时一定要注意不要让窗口卡主,不然Jenkins会认为认为一直没完成
# 工作目录为服务器配置的,我这里就是/home/shawn
nohup java -jar /home/shawn/jenkins/jenkins*.jar --server.port=8989 >mylog.log 2>&1 &
数据流重定向
数据流重定向就是将某个命令执行后应该要出现在屏幕上的数据传输到其他地方
-
标准输入(stdin):代码为0,使用<或<<;
-
标准输出(stdout):代码为1,使用>或>>;
-
标准错误输出(stderr):代码为2,使用2>或2>>
-
> 覆盖写
-
>> 追加写
2.3 自动发布前清理
在构建前进行服务器清理,在Pre Steps
的命令行下填写在构建前要运行的命令./clean.sh jenkins
,同时在目标服务器上编写脚本
#!/bin/bash
#删除历史数据
rm -rf jenkins
appname=$1
#获取传入的参数
echo "arg:$1"
#获取正在运行的jar包pid
pid=`ps -ef | grep $1 | grep 'java -jar' | awk '{printf $2}'`
echo $pid
#如果pid为空,提示一下,否则,执行kill命令
if [ -z $pid ];
#使用-z 做空值判断
then
echo "$appname not started"
else
kill -9 $pid
echo "$appname stoping...."
check=`ps -ef | grep -w $pid | grep java`
if [ -z $check ];
then
echo "$appname pid:$pid is stop"
else
echo "$appname stop failed"
fi
fi
三、自动构建触几种方式
1、触发远程构建/gitlab上改动自动构建
代码改动(提交,合并等)自动可以使用gitlab的webhook回调钩子调起Jenkins的启动任务接口,进行自动打包构建与运行
首先在构建触发器中配置接口和token
因为需要权限认证,所以需要安装一个插件Build Authorization Token Root
,安装完插件后,要访问http://192.168.249.129:8080/buildByToken/build?job=first&token=123456
即可无需认证触发构建
然后进入GitlLab或者远程代码仓库,找到Webhook选项,将调起Jenkins的启动任务接口填入,如果GitLab发现不让本地访问,调用菜单→管理员→设置→网络→出战请求→允许来自 web hooks 和服务对本地网络的请求
就可
2、定时构建
参考网站:https://crontab.guru
Jenkins cron不是标准的cron表达式
第一个 * 表示每个小时的第几分钟,取值0~59
H * * * *
H:每小时执行一次
第二颗 * 表示小时,取值0~23
* 15 * * * 表示每天下午3点
* 1 * * * 表示每天凌晨1点
第三颗 * 表示一个月的第几天,取值1~31
* 1 5 * * 表示每月5日凌晨1点
第四颗 * 表示第几月,取值1~12
* 15 5 1 * 表示每年几月执行
第五颗 * 表示一周中的第几天,取值0~7,其中0和7代表的都是周日
H * * * *
表示一小时内的任意时间
*/10 * * * *
每10分钟
H/10 * * * *
每10分钟,可能是7,17,27,起始时间hash,步长不变
45 3 * * 1-6
每个周一至周六,凌晨3点45 执行1次
45 3-5 * * 1-6
每个周一至周六,凌晨3点45 ,凌晨4点45,凌晨5点45 各执行1次
H(40-48) 3-5 * * 1-6
在40~48之间取值 其他同上
45 3-5/2 * * 1-6
每个周一至周六,凌晨3点45 ,凌晨5点45 各执行1次
45 0-6/2 * * 1-6 * * 1-6
0点开始,每间隔2小时执行一次 0:45、2:45、4:45
3、源码变更构建
使用Poll SCM 方式与Build periodically一样,会主动定期检查代码托管服务器上是否有变化,一旦发生变化执行job构建
4、所有构建方式介绍
-
快照依赖构建/Build whenever a SNAPSHOT dependency is built
- 当依赖的快照被构建时执行本job
-
触发远程构建 (例如,使用脚本)
- 远程调用本job的restapi时执行本job
-
job依赖构建/Build after other projects are built
- 当依赖的job被构建时执行本job
-
定时构建/Build periodically
- 使用cron表达式定时构建本job
-
向GitHub提交代码时触发Jenkins自动构建/GitHub hook trigger for GITScm polling
- Github-WebHook出发时构建本job
-
定期检查代码变更/Poll SCM
- 使用cron表达式定时检查代码变更,变更后构建本job
5、测试报告邮件通知
首先开启163邮箱的SMTP服务,记录下自己的授权码,比如我的SUUJPSARCHWKHWAP
,然后进入首页→系统管理→系统配置
-
首先找到Jenkins Location,填写系统管理员邮件地址(授权smtp的163邮箱)账号
-
找到Extended E-mail Notification,推荐插件安装自动安装,填写好SMTP server(smtp.163.com),端口25,创建好账户和密码(授权码),设置好默认发送邮箱,在Default Triggers里选择相应的触发条件
-
邮件通知是内置的,选择好SMTP服务器,使用SAMTP认证,这里用户名要去掉邮箱尾缀,密码还是授权码,端口25,可以测试发送,最后保存
最后在任务中进行配置设置要发送的邮箱
6、自动化部署到docker容器中
原理和前面一样,构建前清除docker,然后把构建的包发送,最后发送启动docker
FROM openjdk:11
EXPOSE 8080
WORKDIR /root
ADD jarfile/demo*.jar /root/app.jar
ENTRYPOINT ["java","-jar","/root/app.jar"]
四、Jenkins集群/并发构建
集群化构建可以有效提升构建效率,尤其是团队项目比较多或是子项目比较多的时候,可以并发在多台机器上执行构建
这里我们一模一样克隆一台jenkins机器,从机无需启动jenkins,只需要java和maven构建环境,进入系统管理→节点管理,可以看到本机就是一个主节点,然后我们新建节点,取名jenkin-01,注意标签的填写,后面流水线需要依赖这个;填好并发依赖数量,主机名
然后进入我们的任务配置,在general中勾选在必要的时候并发构建,这样就可以进行集群化构建了
五、流水线pipline
1、介绍
流水线既能作为任务的本身,也能作为Jenkinsfile
使用流水线可以让我们的任务从ui手动操作,转换为代码化,像docker的dockerfile一样,从shell命令到配置文件,更适合大型项目,可以让团队其他开发者同时参与进来,同时也可以编辑开发Jenkinswebui不能完成的更复杂的构建逻辑,作为开发者可读性也更好。
2、流水线语法
pipeline:整条流水线
agent:指定执行器
stages:所有阶段
stage:某一阶段,可有多个
steps:阶段内的每一步,可执行命令
3、简单流水线测试
首页→新建任务→选择流水线,选择最简单的脚本进行测试
post:流水线完成后可执行的任务
-
always 无论流水线或者阶段的完成状态。
-
changed 只有当流水线或者阶段完成状态与之前不同时。
-
failure 只有当流水线或者阶段状态为"failure"运行。
-
success 只有当流水线或者阶段状态为"success"运行。
-
unstable 只有当流水线或者阶段状态为"unstable"运行。例如:测试失败。
-
aborted 只有当流水线或者阶段状态为"aborted "运行。例如:手动取消。
**agent:**可以指定执行节点
-
label 指定运行job的节点标签
-
any 不指定,由Jenkins分配
pipeline {
agent {
node {
label "jenkins-01"
}
}
stages {
stage('拉取代码') {
steps {
sh """
sleep 10
"""
echo '拉取代码完成'
}
}
stage('执行构建') {
steps {
echo '执行构建完成'
}
}
}
post {
always {
echo "完成"
}
failure {
echo "失败"
}
}
}
另外全新的流水线控制ui,可重复执行某阶段代码,插件中心搜索Blue Ocean安装即可,同时流水线编码可在流水线语法页面进行在线生成
4、pipeline自动化构建示例
pipeline {
agent any
tools {
maven "maven3"
}
stages {
stage("拉取代码") {
steps {
git branch: 'main', credentialsId: 'gitlab', url: 'http://192.168.44.103/root/java-project.git'
echo '拉取成功'
}
}
stage("执行构建") {
steps {
// sh "mvn --version"
sh """
cd demo-1
mvn clean package
"""
echo '构建完成'
}
}
stage("clean test server"){
steps{
sshPublisher(publishers: [sshPublisherDesc(configName: 'testserver', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''rm -rf *
docker stop demo
docker rm demo
docker rmi demo
''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '/root')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage("发送jar包到测试服务器") {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'testserver', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/jarfile', remoteDirectorySDF: false, removePrefix: 'demo-1/target', sourceFiles: '**/demo*.jar'), sshTransfer(cleanRemote: false, excludes: '', execCommand: '''docker build -t demo .
docker run -d -p 8080:8080 --name demo demo''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '/', remoteDirectorySDF: false, removePrefix: 'demo-1/docker', sourceFiles: 'demo-1/docker/dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
echo 'jar send over!'
}
}
}
}
5、多分支job
简单来说就是一个仓库分支对应一个job,例如测试CICD和生产环境CICD
首页进入首页或者blue Ocean首页,创建多分支流水线,填写对应的git仓库,选择立刻扫描,此时如果是多模块项目,需要在配置里修改Jenkinsfile
文件位置,默认该文件需要在根目录,点击立刻扫描,jenkins就会默认去代码仓库找Jenkinsfile文件并自动替我们执行,同时也可以单独对某一个分支进行扫描构建
6、两种流水线总结
6.1 声明式流水线
好处
-
更像是在Jenkins web ui中的操作
-
可读性比较高
-
可以使用blue ocean自动生成
-
支持语法检查
坏处
- 代码逻辑能力比脚本式弱,不能完成特别复杂的任务
6.2 脚本式流水线
好处
-
更少的代码和弱规范要求
-
更灵活的自定义代码操作
-
不受约束,可以构建特别复杂的工作流和流水线
坏处
-
读写对编程要求比较高
-
比声明式流水线代码更复杂