基于Jenkins实现项目部署

Jenkins 有很多中创建任务的方式,这里,我只测试了常用的三种方式,来实现简单的自动化部署,分别是 Freestyle、Pipeline、Open Blue Ocean。

假设,我们有一个项目,放在 Git 上维护,部署在 slave-web-1、slave-web-2 两台服务器上,基于 Jenkins , 来实现自动化部署。

服务器信息说明:

域名 IP 作用
master 192.168.1.1 部署 jenkinsmaven 服务
slave-web-1 192.168.1.2 业务部署服务器
slave-web-2 192.168.1.3 业务部署服务器
scm 172.31.2.189 git 等项目仓库服务器

下面,我们用三种不同的方式来实现自动化部署。

1、自由风格(Freestyle)

首先,进入新建任务页,填写项目名称,选择 “Freestyle project”,点击 “确定”,进入构建配置页面。

jenkins-freestyle-1

然后,在 “源码管理” 区域,填写项目在 Git 的信息。(需要 Jenkins 服务器拥有从 Git 服务拉取项目的权限)

jenkins-freestyle-2

下一步,在 “构建” 区域,可以编写项目构建的脚步。例如:mvn clean package。(这里的项目是一个静态脚本项目,构建操作是将项目打包)

jenkins-freestyle-3

最后,选择 “Send files or execute commands over SSH”,点击 “Add Server”,配置部署节点 “SSH Server” 信息。多少部署节点就对应多少配置信息。

SSH Server 配置:

  • Name: 部署节点IP或Host(配置Host,需要在 Jenkins 服务器上配置 Host 信息)
  • Source files: 需要发送的源文件地址,该地址是相对路径(相对于 {jenkins_home}/workspace/{JOB_NAME}
  • Remove prefix: 排除的目录或文件
  • Remote directory: 源文件在远程节点存放的相对目录(相对于 “节点管理” 中 “远程工作目录” 的路径,详细请看 持续集成工具 — Jenkins
  • Exec command: 在远程部署节点需要执行的脚本命令(可是解压项目、停止服务,重启服务等操作)

这样,执行任务构建操作(或者在 Open Blue Ocean 界面执行运行操作),就可以将项目发送到部署节点。

jenkins-freestyle-4

2、流水线(Pipeline)

相对于 FreestylePipeline 更加灵活,尤其是有很多部署节点时,Pipeline 更加适用。使用 Pipeline,需要先了解 Pipeline 的语法,可以看 Pipeline SyntaxPipeline 入门

首先,进入新建任务页,填写项目名称,选择 “Pipeline”,点击 “确定”,进入构建配置页面。

jenkins-pipeline-1

根据需要,可以选择构建触发器。

然后,编写 Pipeline 脚本。

jenkins-pipeline-2

Pipeline 脚本分 Declarative PipelineScripted Pipeline。这里采用的是 Scripted Pipeline

1
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
node('master') {
def mvnHome
def jdkHome
def workspace = pwd()

def clusterNodes="web-1,web-2,web-3,web-4"
def clusterNodesArray = clusterNodes.split(",")

stage('Ready') {
mvnHome = tool 'MAVEN_HOME'
jdkHome = tool 'JAVA_HOME'

echo "------------------------------------------"
sh "'${mvnHome}/bin/mvn' -v"

echo "------------------------------------------"
sh "'${jdkHome}/bin/java' -version"

echo "------------------------------------------"
echo "current path: ${workspace}"

echo "------------------------------------------"
echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}"
echo "BUILD_DISPLAY_NAME: ${env.BUILD_DISPLAY_NAME}"
echo "JOB_NAME: ${env.JOB_NAME}"
echo "NODE_LABELS: ${env.NODE_LABELS}"
echo "WORKSPACE: ${env.WORKSPACE}"
echo "JOB_URL: ${env.JOB_URL}"
echo "BRANCH_NAME: ${env.BRANCH_NAME}"

timeout(time: 60, unit: 'SECONDS') {
input message: "this action will stop service, are you sure you want to execute?", ok: "yes"
}

}

stage('Build') {
git 'git@scm-git:/home/git/repo/spring-boot-test.git'

sh "'${mvnHome}/bin/mvn' -DshipTests clean package"
echo "build number: ${currentBuild.number}"
echo "build result: ${currentBuild.result}"
echo "build currentResult: ${currentBuild.currentResult}"
echo "build displayName: ${currentBuild.displayName}"

sh "cd ${env.WORKSPACE} && true"

if (currentBuild.currentResult == 'SUCCESS') {
echo "BUILD SUCCESS"

}else {
echo "BUILD FAILED"
}
}

stage('Deploy') {
timeout(time: 60, unit: 'SECONDS') {
for (slave in clusterNodesArray) {
echo "publish project to ${slave}"
sh """
scp -r target/spring-boot-test.tar.gz user@${slave}:/work/app/jenkins/upload

ssh user@${slave} "service tomcat stop && cd /work/app/auto-deploy && sh +x ./bin/service-dubbo-common.sh"
"""
}
}

echo "all slave node are deployed."
}

stage('Verify') {
echo "verify service."
for (slave in clusterNodesArray) {
timeout(time: 5, unit: 'SECONDS') {//超时设置
echo "verify ${slave} url"
}
}
}
}

脚本说明:

  • 第一步(Ready):构建准备工作,查看构建环境,让操作者进行操作任务,防止误操作。
  • 第二步(Build):构建项目,通过 git 获取最新项目,通过 maven 打包构建。
  • 第三步(Deploy):遍历所有节点,将打包项目发布到所有节点,并执行相关命令。
  • 第四部(Verify):验证所有节点服务。

3、Open Blue Ocean

BlueOcean 重新考虑了 Jenkins 的用户体验。BlueOceanJenkins Pipeline 设计,但仍然兼容自由式工作,减少了团队成员的混乱,增加了清晰度。

我们模仿 Pipeline 构建项目的方式,来创建一个 BlueOcean 任务。

首先,在 BlueOcean 界面,点击 “创建流水线”,进入构建页面。选择代码仓库,并填写相关信息(可能会生成一个认证key,需要将 key 加到 代码仓库服务器上)。

jenkins-blueocean-1

进入 Pipeline 构建页面,默认会有一个 Start 阶段,在这里,可以配置 Pipeline 的全局变量和参数。

jenkins-blueocean-2

点击 Start 后面的 “+”,可以添加阶段。填写阶段名称,然后添加该阶段包含的步骤,步骤类型有很多种,根据需要进行选择。

jenkins-blueocean-3

例如,我们选择 “Shell Script” 类型。

jenkins-blueocean-4

jenkins-blueocean-5

添加完所有阶段后,最终图形如下:

jenkins-blueocean-6

以上三种方式,更倾向于采用 PipelineBlueOcean 虽然方便、简介,但是还需要完善。

4、运行

BlueOcean 主界面或任务列表界面,都可以运行任务。

例如:在 BlueOcean 界面运行任务,可以查看详细的信息输出。

jenkins-run-1

如果执行失败,会终止运行,并提示错误信息。

jenkins-blueocean-6

也可以直接在任务列表点击 “构建” 来运行。在 “Stage View” 可以查看每一阶段的执行时间和结果。

jenkins-blueocean-6

除此之外,还有许多其它高级应用,在今后的使用过程中,逐步学习。

5、注意事项

5.1、从节点环境变量问题

使用 ssh 启动 Tomcat 项目时,可能会遇到下面错误信息。

1
2
3
Neither the JAVA_HOME nor the JRE_HOME environment variable is defined

At least one of these environment variable is needed to run this program

这个错误是因为环境变量是通过 /etc/profile 配置的原因导致。

1
2
3
/etc/profile: 此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行。并从/etc/profile.d目录的配置文件中搜集shell的设置

/etc/bashrc: 为每一个运行bash shell的用户执行此文件。当bash shell被打开时,该文件被读取(即每次新开一个终端,都会执行bashrc)

查看 /etc/bashrc 代码,发现它会引用 /etc/profile.d/ 下的所有 .sh 文件。所以,解决这个问题有两种方式:

  • 1、将环境变量配置到 /etc/bashrc
  • 2、将环境变量配置到 /etc/profile.d/ 下(推荐)

注意:
如果是服务自启动脚本,通过 rc.local 调用 shell,也会出现无法找到环境变量的错误,因为系统的任何一个用户都没有登录过,这种情况下,可以在 rc.local 调用 shell 前,加载用户环境变量 source /etc/profile

5.2、进程问题

通过 SSH 远程运行从节点脚本时,远程会话结束以后会把 SSH 下的所有子进程干掉。这时,就可能出现 Tomcat 启动成功了,过一会进程消失了,但是在节点服务器运行脚本又不会消失的现象。

有两种解决方法:

1、在脚本中加入 nohup 来执行关键命令;

1
nohup ${TOMCAT_HOME}/bin/startup.sh > /dev/null 2>&1 &

2、在 Jenkins 的节点管理中增加变量。

1
2
key=BUILD_ID
value=DONTKILLME

参考:

文章作者: OneRain
文章链接: https://kiswo.com/2018/04/12/tools/auto/jenkins-note2/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 OneRain's Blog