Jenkins主从集群搭建
jenkins支持主从模式,这将会把构建任务分发到多个从节点去执行,这样就可以支撑起多个项目的大量
构建任务,提升构建效率。同时,你可以提供多种环境(如:开发环境、生产环境)来对同一个项目进
行测试和构建。jenkins的部署方式主要有三种:服务器直接运行war、服务器通过 yum命令下载
jenkins安装包进行安装运行、docker容器运行。
环境说明
- centos7
- jdk1.8
- maven3.6.1
- git1.8.3
- jenkins2.241
- docker18.06.1-ce
- Master主机IP:120.27.194.178
- Slave从机IP:47.110.58.254
- Slave从机IP:124.221.73.149
- 备份机及Docker私有仓库机器IP:122.112.155.85
docker私有仓库安装
登录到私有仓库服务器,要安装docker私有仓库前必须先安装docker环境
docker环境安装
我这里用的是华为云,可能不适用于其他的ecs,如果安装有问题,可以查找其他安装方式
- 添加yum源。
yum install epel-release -y
yum clean all
- 安装yum-util。****
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
- 设置docker yum源。
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- 安装并运行Docker。
sudo yum install docker-ce
# 设置为开机启动
systemctl enable docker
systemctl start docker
- 检查安装结果。
docker --version
- 回显如下类似信息,表示Docker安装成功。
Client: Docker Engine - Community Version: 19.03.13
docker私有仓库安装
- 拉取私有仓库镜像
docker pull registry
- 启动私有仓库容器
docker run -di --name=my_registry -p 5555:5000 registry:latest
- 设置开机自启动
docker container update --restart=always my_registry
- 测试私有镜像仓库是否搭建成功
-
- 打开浏览器 输入地址http://122.112.155.85:5555/v2/_catalog
- 看到{"repositories":[]} 表示私有仓库搭建成功
- 重启docker服务
systemctl restart docker
docker start my_registry
- 新建jenkins用户
useradd jenkins --home-dir /home/jenkins --shell /bin/bash
passwd jenkins # 设置密码为12345678
- 新建jenkins备份目录
mkdir -p /data/jenkins_backup
chown -R jenkins:jenkins /data/jenkins_backup
- 安装rsync
yum install rsync
安装Master
登录master服务器
基础环境准备(root用户执行命令)
安装JDK
- 直接联网安装JDK
yum install java-1.8.0-openjdk-devel.x86_64
- 配置JAVA_HOME环境变量,vim /etc/profile,最后加上:
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.252.b09-2.el7_8.x86_64
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
- 让profile生效
source /etc/profile
安装git
yum install -y git
安装sshpass
yum install sshpass
安装wget
yum install wget
多线程下载工具axel安装
yum install axel -y
新建jenkins用户
useradd jenkins --home-dir /home/jenkins --shell /bin/bash
passwd jenkins # 设置密码为12345678
创建项目测试时会用到的日志目录
mkdir -p /data/logs/mall
chown jenkins:jenkins /data/logs/mall
下载安装maven
-
- 下载解压
axel -n 20 https://archive.apache.org/dist/maven/maven-3/3.6.1/binaries/apache-maven-3.6.1-bin.tar.gz
tar zxvf apache-maven-3.6.1-bin.tar.gz
-
- 配置M2_HOME环境变量,vim /etc/profile,最后加上:
MAVEN_HOME=/usr/local/apache-maven-3.6.1
export PATH=${MAVEN_HOME}/bin:${PATH}
-
- 让profile生效
source /etc/profile
-
- 创建maven本地仓库目录
mkdir -p /data/maven_repository
-
- 给jenkins用户授权,运行jenkins用户下载依赖包到仓库
chown -R jenkins:jenkins /data/maven_repository/
-
- 修改maven中仓库的位置
vim /usr/local/apache-maven-3.6.1/conf/settings.xml
#将仓库地址修改为如下:
<localRepository>/data/maven_repository</localRepository>
-
- 找到标签,在其中添加如下内容
<mirror>
<id>alimaven</id>
<name>alimaven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
修改docker配置
修改docker配置文件添加执行权限
- jenkins用户添加可以执行docker的权限
vim /lib/systemd/system/docker.service
#找到ExecStart=/usr/bin/dockerd这一行,在此行最后添加 -G jenkins,结果如:
ExecStart=/usr/bin/dockerd -G jenkins
- 修改默认镜像仓库地址
有需要上传或下载镜像的服务器上,机器所在的docker环境都需要配置私有仓库地址,比如
构建服务器、应用部署服务器
# 修改daemon.json,在原有配置基础,加上如下内容
vim /etc/docker/daemon.json
# 此步用于让 docker 信任私有仓库地址
{
"insecure-registries":["122.112.155.85:5555"]
}
- 添加完重启docker
systemctl daemon-reload
systemctl restart docker
下载安装Jenkins
- 切换到jenkins用户
su jenkins
cd /home/jenkins
- 下载jenkins安装包
axel -n 20 http://mirrors.jenkins-ci.org/war/2.241/jenkins.war
- 启动jenkins,开放服务器8888端口号
java -jar jenkins.war --httpPort=8888
- 关闭防火墙
systemctl stop firewalld
- 修改jenkins配置(插件站点更新,加速联网)
vim ~/.jenkins/hudson.model.UpdateCenter.xml
将XML内的url的值替换为:http://mirror.xmission.com/jenkins/updates/update-center.json
- 访问Jenkins
浏览器访问jenkins,地址为:http://http://120.27.194.178:8888//
- 提示输入密码,根据页面提示查看密码的方式获取密码并登录,一般用cat命令查看
cat /home/jenkins/.jenkins/secrets/initialAdminPassword
- 密码输入正确后提示插件的选择,可以直接忽略跳过即可看到首页
- 修改管理员密码为123456,具体操作为点击页面左上角jenkins->people->admin->configure进行修改
- 修改完后,跳转到登录页,输入用户名admin 密码123456即可正常登录
- Jenkins开机自启动
- 创建jenkins新的工作目录
#切换回root账号
mkdir /data/jenkins_data
chown -R jenkins:jenkins /data/jenkins_data
- 切换到jenkins用户
su jenkins
- 在/home/jenkins下新建脚本:vim jenkins.sh
#!/bin/bash
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.171-8.b10.el6_9.x86_64
export JENKINS_SERVER_PATH=/home/jenkins
export JENKINS_HOME=/data/jenkins_data
cd ${JENKINS_SERVER_PATH}
nohup java -jar jenkins.war --httpPort=8888 >jenkins.log 2>&1 &
以上内容编辑后保存退出
- 添加脚本执行权限
chmod +x jenkins.sh
- 退出到root用户下
exit
- 设置开机执行:vim /etc/rc.d/rc.local,在最后添加如下启动命令:
su jenkins -c "/home/jenkins/jenkins.sh"
此命令可尝试下执行是否能成功,再访问jenkins,发现jenkins首页一直在加载
- 加速加载插件列表,修改配置
vim /data/jenkins_data/hudson.model.UpdateCenter.xml
在以上文件中替换url内的值为:http://mirror.xmission.com/jenkins/updates/update-cen
ter.json
再次执行刚执行的启动jenkins的命令,发现能正常启动,不用做其他配置,继续执行下面命令
- 添加执行权限
chmod +x /etc/rc.d/rc.local
- 重启服务器
- 重启完再次访问jenkins,发现启动成功,此时由于工作目录已还,再次登录修改密码即可
安装slave
slave无需再次安装jenkins,保证主机从机能够连通
登录到从机器安装环境
新建jenkins用户
useradd jenkins --home-dir /home/jenkins --shell /bin/bash
passwd jenkins # 设置密码为12345678
wget、axel、sshpass、jdk、git、maven、创建项目测试时会用到的日志目录、docker的安装、
docker私有仓库的配置等步骤参考前文
配置ssh免密登录
免密登录指的是master可以不用密码直接登录到slave
登录到主机器,切换到jenkins用户,进入jenkins目录,生成sshkey,执行下面命令后一直回车完成即可
ssh-keygen
拷贝主机的公钥文件到从机器,执行命令后输入从机jenkins用户密码即可
# 进入到.ssh目录
cd /home/jenkins/.ssh
#将公钥拷贝到从机上
cat id_rsa.pub >> authorized_keys
scp authorized_keys jenkins@47.110.58.254:/home/jenkins/.ssh
注意,备份服务器也需要公钥文件:
scp authorized_keys jenkins@122.112.155.85:/home/jenkins/.ssh
登录jenkins,安装ssh插件
新建节点
- 上图中点击create后,配置信息
- 说明:
-
- of executors:并发构建数量
- Remote Root Directory:从节点的工作目录
- Labels:标签名,当job配置节点关联时会用到标签名,比如新建普通job时,配置job里可通过“Restrict where this project can be run”来填写标签,标签可用于分组,一个标签可以对应个node
- Usage:常选择“尽可能多的使用此节点
添加私钥
点击上图中Credentials下的add按钮,弹出以下页面,添加凭证
图中添加的私钥来自于我们在主机器上生成的两个文件之一,具体查看方式为:
cat /home/jenkins/.ssh/id_rsa
选择证书,然后保存
保存后如果启动失败的时候遇到以下问题
[04/10/22 16:49:21] [SSH] Opening SSH connection to 47.110.58.254:22.
ERROR: Server rejected the 1 private key(s) for jenkins (credentialId:7265ff8a-1515-4745-a174-e6f550630818/method:publickey)
[04/10/22 16:49:21] [SSH] Authentication failed.
hudson.AbortException: Authentication failed.
at hudson.plugins.sshslaves.SSHLauncher.openConnection(SSHLauncher.java:1143)
at hudson.plugins.sshslaves.SSHLauncher$2.call(SSHLauncher.java:648)
at hudson.plugins.sshslaves.SSHLauncher$2.call(SSHLauncher.java:642)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:701)
[04/10/22 16:49:21] [SSH] Connection closed.
[04/10/22 16:49:21] Launch failed - cleaning up connection
是因为SSH不希望用户组对home目录和~/.ssh目录及其下文件有写的权限。更改权限即可
chmod g-w authorized_keys
测试slave可用性
安装pipeline插件
创建pipeline方式的测试job
首页点击new item打开以下页面
job配置
pipeline {
agent {
label "jenkins-slave"
}
stages {
stage('Hello') {
steps {
echo 'Hello World'
}
}
}
}
构建JOB
查看运行状态
从上图可以看到,由于我们脚本配置了jenkins-slave,所以,最终执行任务实在jenkins-slave1节点机
器上执行的
我这里只安装了一个从节点,另一个从节点的安装步骤和上面一样,推荐新建node的时候,复制第一个的信息,改动host即可
主从节点列表
jenkins管理界面核心配置介绍
重点介绍核心配置:节点管理、用户管理、角色管理、分组管理、插件管理、全局工具配置
用户管理
为方便接下来的演示,新建如下账号,开发共计两个账号,运维、测试、负责人各一个账号。
| 账号 | 密码 | 说明 |
|---|---|---|
| java | 123456 | 后端开发账号 |
| fed | 123456 | 前端 |
| qa | 123456 | 测试 |
| ops | 123456 | 运维 |
| leader | 123456 | 项目负责人 |
在用户管理列表中可以进行用户配置,比如设置用户密码等,也可以删除用户
角色管理
- 之所以提到角色管理,是由于跟用户权限控制有关,在jenkins中控制用户权限需要选择安全策
略,比如有:安全矩阵策略、项目矩阵策略、基于角色的策略等,而企业最常用的就是基于角色的
策略,本文也是以角色管理为主。
- 在jenkins中角色管理分为两种:一种是全局角色,此角色与具体的job无关,是一种全局权限的控
制,比如控制用户能不能查看job,能不能配置job;还有一种是项目角色,此角色与具体job有
关,可以精细化控制到用户具体能拥有哪些job的哪些权限。但是特殊说明的是:如果想要配置角
色管理,必须安装插件才行
安装插件
插件名:Role-based Authorization Strategy
选择安全管理策略
Manage Jenkins -> Security - > Configure Global Security
权限配置需求
| 账号 | 岗位 | 查看job | 点击构建job | 取消构建job | 配置job |
|---|---|---|---|---|---|
| java | 研发 | 是 | 是 | 是 | 是 |
| fed | 研发 | 是 | 是 | 是 | 是 |
| qa | 测试 | 是 | 是 | 是 | 是 |
| ops | 运维 | 是 | 是 | 是 | 是 |
| leader | 负责人 | 是 | 否 | 否 | 否 |
以上是粗粒度权限控制要求:
- Java视图里能够操作所有项目
- Web视图里能够操作所有项目
- 运维和测试视图里能够操作所有项目
- 负责人视图里能看到所有项目
下面是细细力度权限控制要求(主要针对研发人员):
- Java视图里只能操作Java相关的项目
- Web视图里只能操作web相关的项目
- 运维和测试视图里能够操作所有项目
- 负责人视图里能看到所有项目
全局角色管理
新建演示用job
均基于pipline的helloword进行创建,java的开发测试生产各一个,web的开发测试生产各一个
选择角色管理
点击全局角色并配置
新增两个角色分别为builder和viewer
角色说明
| 角色名 | 权限范围 |
|---|---|
| admin | Jenkins默认的角色,最高权限 |
| builder | 拥有查看job、构建job、配置job的权限 |
| viewer | 拥有查看job的权限 |
为用户指定全局角色
项目角色管理
项目角色配置
- 这里提到的项目指的是jenkins里的job,之所以要进行项目角色配置,是因为企业开发一般有这么一种
需求:开发人员不同、所看到的项目也不同。比如Java工程师只能看到Java的项目、WEB工程师只能
看到web的项目。接下来的配置就是为了实现此需求,单独为Java和web的账号分配不同的项目角色,
其他账号权限不变。
- 此处要设置项目角色之前,先创建个全局角色base,指定一个overall的read权限即可。
配置说明:
- role的值:项目的角色名
- pattern的值:为正则表达式,表示匹配什么样名字开头的job,我们这里java和前端的项目都分为
三种环境。注意表示什么开头,在这里要写成"关键词.*"。
角色说明
| 角色名 | 权限 |
|---|---|
| java | java-.*表示角色java会匹配到java-开头的所有项目 |
| web | web-.*表示角色web会匹配到所以web-开头的项目 |
| viewer | 拥有查看job的权限 |
调整角色及分配角色
分组管理
根据测试job列表,我们发现,如果是非开发的账号,比如测试、运维、负责人都可以查看到所有job,
job如果太多则列表显示过长,所以可对job进行分组管理
点击新建分组
配置Java分组内的job
插件管理
jenkins提供了丰富多样的插件,能够满足几乎所有企业持续集成过程中的需求。根据前文操作,我们实
际上已经用过插件管理:比如安装主从时用到的pipeline插件、角色管理使用的Role-based
Authorization Strategy插件。
插件镜像地址更新
我们在前文安装jenkins时已经修改过,目的是加速插件下载,实际上可选的镜像地址有很多,如下:
也可参见官方网站提供的可用镜像地址:mirrors.jenkins-ci.org/status.html
镜像地址更换
方式1:可采用之前安装jenkins时修改~/.jenkins/hudson.model.UpdateCenter.xml中url值的方式
方式2:可进入到web-ui界面的Manage Plugins->Advanced -> Update Site进行修改
重启Jenkins
这里是个小技巧,具体为在页面重启jenkins的方式,在jenkins地址后加上/restart即可,比如在本课
程中具体的重启地址可以为:http://192.168.200.200:8888/restart
全局工具配置
非pipeline的Java项目如果要构建成功,全局工具的环境需要配置好
- 配置入口:Manage Jenkins->Global Tool Configuration
- 配置方式:指定服务器上已经安装好的服务位置(不需要勾选自动安装)
- 配置前提:服务器已经安装好jdk1.8、maven3.6.1、git1.8.3.1
- 配置内容如图
Jenkins原理分析-jenkins如何存储数据
- 在jenkins中,所有的数据默认都以文件形式存储在$JENKINS_HOME目录下。
- 占用空间最大的目录就是jobs目录和workspace目录
- jobs目录:项目在jenkins上的配置、构建日志、构建结果等所在目录
- workspace目录:项目在jenkins上配置的源码仓库地址下载下的源码所在目录,比如Java中maven的
- 构建操作在此目录下进行
目录存放位置说明
| 目录 | 存放位置 |
|---|---|
| jobs目录 | 对应master的/data/jenkins_data/jobs目录 |
| workspace目录 | 对应master的/data/jenkins_data/workspace目录或者对应node节点的/home/jenkins/workspace目录 |
为方便介绍目录结构信息,我们要新建一个普通的非pipeline的job。注意新建项目前workspace目录还
不存在。
Jenkins Job备份恢复
备份需求
- 只备份重要的信息,保证恢复时除了构建历史,重要配置和job都在,排除掉build目录
- 备份要周期性的执行,保证至少每天备份一次
- 备份不仅仅要存放到Master,还要同步备份到备份服务器上
备份实现
- thin backup插件实现备份到Master机器
- Rsync实现备份到备份服务器
备份配置
插件设置备份内容
- 创建备份目标目录
mkdir /data/jenkins_backup
chown -R jenkins:jenkins /data/jenkins_backup
- 安装Thin Backup插件
- 开始备份配置
找到备份管理页面Manage Jenkins->ThinBackUp,进入后选择Settings进行配置
- 如上配置好了每天14:15执行一次,构建的最大备份文件个数为-1表示不限制,备份中排除了build的结果,
- 图中特殊配置了备份时需要将凭证目录secrets下的所有文件进行备份,通过正则表达式:
^(secrets|.*)$
点击保存后,等待时间到14:15过后,我们查看master上的/data/jenkins_backup目录
发现备份到点已经执行完毕,那么改目录下备份的内容是否是正确的内容,查看生成的备份目录
由生成的备份目录发现,用户、插件、节点、JOB等核心的配置文件目录都已经备份完毕
rsync增量同步备份文件
使用rsync命令可以实现在每天jenkins完毕后,将当天新增的同步内容,增量同步到备份服务器上
在master上切换到jenkins用户,执行rsync备份命令
特殊说明:执行sshpass命令前先在构建服务器上执行一次rsync命令(仅需一次即可),只有这
次执行通过后,后续再执行sshpass带密码才可使用。后续再执行sshpass前都无需单独再执行
rsync命令。
sshpass -p g8d9d7AcsM1MLQRUZ31c rsync -avz /data/jenkins_backup/ jenkins@122.112.155.85:/data/jenkins_backup/
执行完成后,看到如下内容
登录到备份服务器,切换到Jenkins用户查看,发现已经同步成功
脚本自动执行同步
将rsync做成脚本自动执行,比如jenkins配置的是每天14:10执行同步,那么rsync可以在每天14:30
再自动执行
登录到master上,执行如下操作:
- 编辑备份shell脚本
vim /home/jenkins/backup.sh
在脚本中加入如下内容
sshpass -p g8d9d7AcsM1MLQRUZ31c rsync -avz /data/jenkins_backup/ jenkins@122.112.155.85:/data/jenkins_backup/
- 给脚本添加执行权限
chmod +x /home/jenkins/backup.sh
- 添加到系统crontab文件中,切换到root用户
vim /etc/crontab
在最后行添加如下内容
33 22 * * * jenkins /bin/bash /home/jenkins/backup.sh &>/dev/null
保存完后,重启contab
systemctl restart crond.service
等待到14:30后,查看备份服务器的备份目录,查看同步的结果
恢复备份文件
为了演示恢复备份文件的效果,我们可以假设jenkins数据全丢了,现在什么配置都没有了。为了实现这
个效果我们决定切换jenkins工作目录到一个空目录下,然后重启jenkins,这样jenkins等同于一个全新
的jenkins,就相当于数据全丢了。
- jenkins没有切换到空工作目录前:有上文所述的5个测试用户,角色配置,7个测试job,还有备份
设置
- 登录到master开始切换
新建一个空的工作目录并授权:
mkdir /data/jenkins_data_temp
chown -R jenkins:jenkins /data/jenkins_data_temp
- 切换到jenkins用户,修改jenkins启动脚本
cd /home/jenkins/
su jenkins
vim /home/jenkins/jenkins.sh
- 修改JENKINS_HOME的值为/data/jenkins_data_temp,并保存脚本
export JENKINS_HOME=/data/jenkins_data_temp
- 切换到root用户,杀掉启动中的jenkins进程,然后启动jenkins
exit
su jenkins -c "/home/jenkins/jenkins.sh"
- 访问jenkins
发现jenkins首页变成最初的初始化页面了,我们按照步骤先登录然后设置admin密码为123456
- 此时的jenkins已经是全新的无任何配置的jenkins了,我们需要更换镜像中心地址,然后下载
thinbackup插件
- 插件安装完毕后,重启jenkins ,然后登录找到ThinBackup的配置,点击Settings,配置备份目录,然
后恢复的时候就能从备份目录中,找到之前备份的那些文件了
- 选择要恢复的备份文件,选择最新的备份文件,点击开始恢复
恢复过程页面是不会有恢复完成提示的,等待几分钟后,执行jenkins的重启链接即可,再次登录发现所有的配置都恢复回来了
简单的demo搭建
先直接在主机上搭建一个流水线
新建一个主机node
添加主机凭证,为账号密码登录
添加git凭证,输入账号密码
配置全局工具
新建一个Pipeline项目
Pipeline语法可以使用参数化配置
编写pipeline语法
这里我就简单的打一个jar包,然后通过java -jar的方式运行,里面的sh脚本是我已经在服务器上编写好的
pipeline {
agent {
node {
label 'jenkins-master'
}
}
options {
//保持构建的最大个数
buildDiscarder(logRotator(numToKeepStr:'20'))
}
tools {
//需要在jenkins配置maven环境,名称为maven3.6.1
maven 'maven-3.6.1'
}
stages {
stage('GitPull') {
steps {
git branch: '${BRANCH}', credentialsId: '935abf63-ec31-469d-983b-88f9fc75b6c1', url: '${URL}'
}
}
stage('Build') {
steps {
sh "mvn clean package"
}
}
stage('Deploy') {
steps {
sh "mv /home/jenkins/workspace/aaa/qnvip-data-overview-web/target/qnvip-data-overview-oauth-web.jar /root"
sh "cd /root && sh stop-web.sh"
sh "cd /root && sh start-web.sh"
}
}
}
}
sh脚本
首先在创建好./logs/consoleMsg-web.log目录以及文件
#! /bin/bash
#注意:必须有&让其后台执行,否则没有pid生成 jar包路径为绝对路径
nohup java -jar qnvip-data-overview-oauth-web.jar > logs/consoleMsg-web.log 2>&1 &
# 将jar包启动对应的pid写入文件中,为停止时提供pid
echo $! > logs/pid-web.txt
同样的创建好./logs/pid-web.txt 目录以及文件,将pid输出到这个文件中
#! /bin/bash
PID=$(cat logs/pid-web.txt)
kill -9 $PID
最后根据参数构建脚本运行
这里提示下,java -jar 要以后台的方式启动,不然就算项目运行成功了,也会一直pending,然后超时任务被关闭