Jenkins主从集群搭建

1,154 阅读14分钟

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,如果安装有问题,可以查找其他安装方式

  1. 添加yum源。
yum install epel-release -y
yum clean all
  1. 安装yum-util。****
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
  1. 设置docker yum源。
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  1. 安装并运行Docker。
sudo yum install docker-ce
# 设置为开机启动
systemctl enable docker
systemctl start docker
  1. 检查安装结果。
docker --version
  1. 回显如下类似信息,表示Docker安装成功。
Client: Docker Engine - Community  Version:           19.03.13

docker私有仓库安装

  1. 拉取私有仓库镜像
docker pull registry
  1. 启动私有仓库容器
docker run -di --name=my_registry -p 5555:5000 registry:latest
  1. 设置开机自启动
docker container update --restart=always my_registry
  1. 测试私有镜像仓库是否搭建成功
  1. 重启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

  1. 直接联网安装JDK
yum install java-1.8.0-openjdk-devel.x86_64
  1. 配置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
  1. 让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

    1. 下载解压
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
    1. 配置M2_HOME环境变量,vim /etc/profile,最后加上:
MAVEN_HOME=/usr/local/apache-maven-3.6.1
export PATH=${MAVEN_HOME}/bin:${PATH}
    1. 让profile生效
source /etc/profile
    1. 创建maven本地仓库目录
mkdir -p /data/maven_repository
    1. 给jenkins用户授权,运行jenkins用户下载依赖包到仓库
chown -R jenkins:jenkins /data/maven_repository/
    1. 修改maven中仓库的位置
vim /usr/local/apache-maven-3.6.1/conf/settings.xml

#将仓库地址修改为如下:
<localRepository>/data/maven_repository</localRepository>
    1. 找到标签,在其中添加如下内容
<mirror>
<id>alimaven</id>
<name>alimaven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>

修改docker配置

修改docker配置文件添加执行权限

  1. jenkins用户添加可以执行docker的权限
vim /lib/systemd/system/docker.service

#找到ExecStart=/usr/bin/dockerd这一行,在此行最后添加 -G jenkins,结果如:
ExecStart=/usr/bin/dockerd -G jenkins
  1. 修改默认镜像仓库地址

有需要上传或下载镜像的服务器上,机器所在的docker环境都需要配置私有仓库地址,比如

构建服务器、应用部署服务器

# 修改daemon.json,在原有配置基础,加上如下内容
vim /etc/docker/daemon.json
# 此步用于让 docker 信任私有仓库地址
{
"insecure-registries":["122.112.155.85:5555"]
}
  1. 添加完重启docker
systemctl daemon-reload
systemctl restart docker

下载安装Jenkins

  1. 切换到jenkins用户
su jenkins
cd /home/jenkins
  1. 下载jenkins安装包
axel -n 20 http://mirrors.jenkins-ci.org/war/2.241/jenkins.war
  1. 启动jenkins,开放服务器8888端口号
java -jar jenkins.war --httpPort=8888
  1. 关闭防火墙
systemctl stop firewalld
  1. 修改jenkins配置(插件站点更新,加速联网)
vim ~/.jenkins/hudson.model.UpdateCenter.xmlXML内的url的值替换为:http://mirror.xmission.com/jenkins/updates/update-center.json
  1. 访问Jenkins

浏览器访问jenkins,地址为:http://http://120.27.194.178:8888//

  • 提示输入密码,根据页面提示查看密码的方式获取密码并登录,一般用cat命令查看
cat /home/jenkins/.jenkins/secrets/initialAdminPassword
  • 密码输入正确后提示插件的选择,可以直接忽略跳过即可看到首页
  • 修改管理员密码为123456,具体操作为点击页面左上角jenkins->people->admin->configure进行修改
  • 修改完后,跳转到登录页,输入用户名admin 密码123456即可正常登录
  1. 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管理界面核心配置介绍

重点介绍核心配置:节点管理、用户管理、角色管理、分组管理、插件管理、全局工具配置

用户管理

为方便接下来的演示,新建如下账号,开发共计两个账号,运维、测试、负责人各一个账号。

账号密码说明
java123456后端开发账号
fed123456前端
qa123456测试
ops123456运维
leader123456项目负责人

在用户管理列表中可以进行用户配置,比如设置用户密码等,也可以删除用户

角色管理

  • 之所以提到角色管理,是由于跟用户权限控制有关,在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

角色说明

角色名权限范围
adminJenkins默认的角色,最高权限
builder拥有查看job、构建job、配置job的权限
viewer拥有查看job的权限

为用户指定全局角色

项目角色管理

项目角色配置

  • 这里提到的项目指的是jenkins里的job,之所以要进行项目角色配置,是因为企业开发一般有这么一种

需求:开发人员不同、所看到的项目也不同。比如Java工程师只能看到Java的项目、WEB工程师只能

看到web的项目。接下来的配置就是为了实现此需求,单独为Java和web的账号分配不同的项目角色,

其他账号权限不变。

  • 此处要设置项目角色之前,先创建个全局角色base,指定一个overall的read权限即可。

配置说明:

  • role的值:项目的角色名
  • pattern的值:为正则表达式,表示匹配什么样名字开头的job,我们这里java和前端的项目都分为

三种环境。注意表示什么开头,在这里要写成"关键词.*"。

角色说明

角色名权限
javajava-.*表示角色java会匹配到java-开头的所有项目
webweb-.*表示角色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上,执行如下操作:

  1. 编辑备份shell脚本
vim /home/jenkins/backup.sh

在脚本中加入如下内容
sshpass -p g8d9d7AcsM1MLQRUZ31c rsync -avz /data/jenkins_backup/ jenkins@122.112.155.85:/data/jenkins_backup/
  1. 给脚本添加执行权限
chmod +x /home/jenkins/backup.sh
  1. 添加到系统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,然后超时任务被关闭