Jenkins作业项目配置
# Freestyle项目配置
此处将举例如何配置一个Freestyle类型作业,并获取Gitlab的代码进行触发构建、手动构建。
# 创建Freestyle项目
在Jenkins主页面中,点击左侧菜单栏的新建任务来打开作业创建页面,输入作业名称,并选择**"构建一个自由风格的软件项目"**进行创建。
作业名称需要有意义有规则,以便于后面的权限管理,因为Jenkins权限是针对文件名进行正则表达式匹配的。
我们可以根据
[项目名]-[微服务名]-[发布环境]
方式来规划,例如:azubot-receiver-pro
、azubot-receiver-dev
、azubot-trasmitter-test
等
# 通用配置
作业创建完毕后,可以从首页或我的视图页面中查看,单击对应作业的名称即可进行配置。
作业页面中可以修改作业名称、手动构建、删除工程、配置等,我们单击配置打开Freestyle作业的配置页面。
通常配置中的GitLab Connection用于选择我们配置的GitLab连接,安装了GitLab插件才会出现。Use alternative credential可以指定GitLab连接的备用凭证。
通常配置中的Throttle builds用于限制构建速率,表示每个时间单位最大能构建几次,例如下图中表示每分钟最多能构建1次。
如果勾选Allow user triggered builds to skip the rate limit则表示手动构建不会受速率限制,但它仍会计入构建限速的已构建次数中。
通常配置中的丢弃旧的构建用于设置如何处理历史构建数据。作业构建会产生大量文件、占用大量空间,因此一般都会配置该选项,以实现历史构建数据的按时按量清理。
另外Jenkins规定必须保存最后一次成功构建的数据,因此填0是非法的。
通常配置中的参数化构建过程用于定义用户执行构建时需要传递给环境变量的值、或需要上传的文件。
环境变量可以指定默认值,它能在构建命令中使用。上传的文件会被上传到工作空间中,也能在构建命令中使用。
通常配置中的在必要的时候并发构建用于决定是否允许并发执行该Job,可以根据实际需求和情况来决定。
# 源码管理
此处以Git为例,因此Jenkins服务器需要安装Git命令,且Jenkins中需要安装Git插件。
此处假设使用SSH作为认证方式,首先在Jenkins服务器中通过命令行新建一个SSH密钥对。
其他验证方式也行,Gitlab账号密码、API Token等等。
# 新建密钥对
ssh-keygen -t rsa
# 查看公钥命令,默认存放在以下位置
cat /root/.ssh/id_rsa.pub
# 查看私钥命令,默认存放在以下位置
cat /root/.ssh/id_rsa
2
3
4
5
6
然后将公钥添加到GitLab的SSH密钥中,可以不指定到期时间,表示永不过期。
然后我们在Freestyle源码管理下选择Git,输入仓库SSH克隆URL,先暂时忽视报错,因为我们还没有配置凭证。然后我们单击添加来配置凭证。
如果已经配置了仓库可用的凭证,也可以选用现有的凭证,可以在凭证配置中增删改查凭证。
在新增凭证中选择SSH类型,然后输入描述和用户名(都会被用于下拉列表的展示)。
然后将刚刚生成的SSH私钥,复制到Private Key中。如果在生成SSH密钥对时指定了Passphrase,则将其填写到Passphrase,如果没有则留空。最后单击添加即可。
凭证添加完后,选择刚刚新增的凭证,看到没有报错就是能够正常拉取源代码了,然后修改一下作业使用的分支名即可。
# 构建触发器
此处以GitLab Webhook为例,需要在Jenkins上安装Gitlab插件,并配置GitLab API。
Jenkins中可以通过GitLab API来操作GitLab中的项目,例如自动配置Webhooks、自动化GitLab的管理任务,例如检查和操作GitLab中的合并请求,自动运行测试并在测试通过后批准合并请求。
# 在GitLab中配置令牌
先在GitLab的访问令牌页面中,单击添加新令牌。
# 输入令牌名称、到期时间(最长1年),然后勾选API权限,最后创建即可。
另外令牌最长只能有一年有效期,如果想要长期有效的凭证,可以使用SSH密钥验证方式。
# 创建完成后,复制提示中的访问令牌,用于Jenkins中配置连接使用。
# 在Jenkins配置中GitLab连接
在Jenkins后台的系统管理
->系统配置
中,找到GitLab配置部分,输入连接名称、GitLab地址,然后单击添加凭证。
需要在Jenkins上安装Gitlab插件。
在新增凭证页面中类型选择GitLab API Token
,API token输入刚刚保存的GitLab令牌,ID可以留空,描述会用于下拉列表的展示建议填写,然后单击添加。
最后选择刚刚添加的凭证保存即可,也可以先单击右侧的Test Connection进行测试。
如果有多个GitLab连接,可以单击新增继续配置新的GitLab连接。
# Freestyle中配置构建触发器
在构建触发器下勾选Build when a change is pushed to GitLab,另外后面跟的URL也需要保存,用于在GitLab中添加Webhook。
展开高级,勾选Filter branches by name可以指定分支,否则任何分支的操作都会触发构建。然后单击Generate生成一个密钥并复制,用于在GitLab上配置WebHook。然后我们先保存配置。
除了
Filter branches by name
外也可以在gitlab的webhook配置中限定分支。
# 在GitLab仓库中配置WebHook
需要先使用管理员账号在配置中心的网络里,搜索"出站请求",然后勾选允许来自 webhooks 和集成对本地网络的请求,然后单击保存更改。
然后在项目仓库里打开Webhooks界面,单击添加新的webhook。
URL和Secret令牌输入Jenkins中保存的URL和Secret,名称不限,最后勾选推送事件,可以指定是推送所有分支的事件还是指定分支的事件。最后保存即可。
添加完后,我们可以测试推送事件。
提示框弹出请求正常,且Jenkins上有构建记录说明能够正常触发。
# 构建环境
推荐安装插件:Workspace Cleanup(构建前清理工作空间)、Build Timeout(构建超时时间)、Timestamper(构建控制台输出时间)。
构建环境下的Delete workspace before build starts用于在构建前清理工作空间。**Use secret text(s) or file(s)**用于指定机密文本或文件。Terminate a build if it's stuck用于指定构建超时时间。在构建日志中添加时间戳前缀则顾名思义用于添加时间戳。
# 构建步骤
构建步骤主要用于应用的编译代码、运行测试、打包等操作。
我们添加一条执行shell步骤并保存,通过命令看看工作目录路径的文件。
返回到项目页面,单击立即构建,然后刷新下页面,单击构建历史中刚刚生成的构建记录。
然后单击控制台输出查看构建的过程,可以看到工作空间在JENKINS_HOME下的workspace/中,且会拉取源代码库中的文件到工作目录下。
# 构建后操作
构建后步骤主要用于应用程序的发布、通知、触发其他项目等。
推荐安装的插件:Publish Over SSH(通过SSH上传产品并执行命令)
例如添加构建后操作Delete workspace when build is done在构建完成后删除工作空间目录。
# PipeLine项目配置
# 创建Pipeline项目
在Jenkins主页面中,点击左侧菜单栏的新建任务来打开作业创建页面,输入作业名称,并选择**"流水线"**进行创建。
# 通用配置
通常配置中的Preserve stashes from completed builds用于在构建完成后保留存储的临时文件(stash),可以指定保存最近几次构建版本的文件。
在流水线的某些步骤中如果需要共享某些数据,就可以使用
stash
命令将文件临时存储起来,然后在流水线的其他部分通过unstash
命令获取这些文件。保留这些文件可以避免重复下载或生成数据,在需要多次运行的流水线中非常有用。
通常配置中的当master重启后,不允许恢复流水线用于确保Jenkins主节点重启后,流水线不会中断位置恢复运行。而是只能重新开始运行,以确保构建结果稳定可靠。
通常配置中的不允许并发构建用于禁止流水线作业的并发执行。流水线项目与Freestyle项目相反,默认是允许并发构建的,因此在某些不能并发构建的项目中,就需要明确禁止并发构建。
如果勾选Abort previous builds参数,则触发构建时会通过终止之前的构建作业,来确保不会并发构建。
通常配置中的流水线效率、持久保存设置覆盖用于覆盖默认的流水线效率和日志持久化设置,通过调整持久化设置,可以在性能和可靠性之间取得平衡。
它有以下选项:
Performance-optimized: much faster(性能模式,性能优化,速度更快):在该模式下,流水线的执行日志仅保存在内存中,但在Jenkins出错或重启后无法恢复执行。这种模式没有持久性,对性能的影响最小。
Less durability, a bit faster(平衡模式,持久性更低,速度更快):在该模式下,流水线的执行日志会保存到磁盘上,但不会很频繁,因此并不保证Jenkins出错或重启后能够恢复执行。这种模式提供了一定程度的持久性,对性能的影响较小。
Maximum durability but slowest(可靠模式,持久性最高,但速度最慢):该模式是全局配置中配置的默认模式,在该模式下,流水线的执行日志会频繁保存到磁盘上,可以在Jenkins出错或重启后恢复执行。这种模式提供了最高的持久性,对性能的影响较大。
# Pipeline语法
# Groovy语言介绍
Jenkins流水线脚本依赖于Groovy语言,它是一种面向对象的编程语言,基于Java平台开发。Groovy在Jenkins中用于编写流水线脚本(Jenkinsfile),来定义自动化构建、测试和部署流程。
# Groovy沙盒介绍
Groovy沙盒是Jenkins提供的一个安全机制,用于在运行Groovy脚本时保护Jenkins实例不受恶意代码的攻击。启用沙盒模式后,只有经过批准的代码才可以运行。用户可以通过Jenkins的安全管理界面审核和批准代码。
# Pipeline语句基本结构
在Pipeline语句中必须包含agent、stages、stage、steps,因此这些语句也是Pipeline的基本组成部分。
// 流水线区域
pipeline {
// 指定流水线的全局agent,定义在哪个节点上运行,值可以为any、none或节点标签。
agent any
// 阶段主区域,其中包含一个或多个阶段。
stages {
// 阶段区域,其中包含一个或多个步骤。
stage('Stage Name') {
// 步骤阶段,其中包含步骤语句。
steps {
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# agent说明
any
:表示在任何可用的节点上运行。none
:表示不指定全局节点,需要在每个stage区域中分别指定自己的agent语句。'节点标签'
:通过标签指定节点,同时还可以指定工作空间。agent { // 指定节点的标签 label 'NodeLabelName' // 可选,指定节点的工作空间 customWorkspace '/data/workspace/' }
1
2
3
4
5
6
# 常用Pipeline语句
# environment
定义构建过程中的环境变量,作用域取决于定义的位置。另外它的值还可以通过credentials()
方法获取预定义的凭证。
pipeline {
agent any
// 全局变量
environment {
ENV_NAME1 = 'VALUE1'
ENV_NAME2 = 'VALUE2'
}
stages {
stage('Stage Name') {
// 局部变量
environment {
// 获取预定义的凭证作为变量的值
ENV_NAME3 = credentials('my-prefined-secret-text')
}
steps {
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# options
配置流水线的运行选项, 流水线内置许多这样的选项,同时插件也能够提供,比如timestamps。
pipeline {
agent any
// 配置选项,多个用换行隔开
options {
// 设置最多保存多少次的构建记录
buildDiscarder(logRotator(numToKeepStr: '1'))
// 设置流水线运行的超时时间
timeout(time: 1, unit: 'HOURS')
// 禁用并发构建
disableConcurrentBuilds()
// 在构建失败后,尝试重新运行流水线构建的次数
retry(3)
// 在控制台输出时间
timestamps()
}
stages {
stage('Stage Name') {
steps {
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# parameters
定义构建时需要的参数,在执行构建时需要提供指定的参数,当然也可以直接使用指定的默认值。
格式为:
parameters { 参数类型(name: '参数名', defaultValue: '默认值', description: '描述') }
参数类型:
string
字符串参数。例如:
string(name: 'DEPLOY_ENV', defaultValue: 'staging', description: '')
text
文本参数,可以包含多行。例如:
text(name: 'DEPLOY_TEXT', defaultValue: 'One\nTwo\nThree\n', description: '')
booleanParam
布尔参数,值为true或false。例如:
booleanParam(name: 'DEBUG_BUILD', defaultValue: true, description: '')
choice
选择参数,提供一个列表供构建时选择。例如:
choice(name: 'CHOICES', choices: ['one', 'two', 'three'], description: '')
password
密码参数,提供一个密码框供构建时输入。例如:
password(name: 'PASSWORD', defaultValue: 'SECRET', description: 'A secret password')
pipeline {
agent any
// 构建参数,多个用换行隔开
parameters {
string(name: 'BRANCH_NAME', defaultValue: 'Test', description: '')
booleanParam(name: 'RUN_TESTS', defaultValue: true, description: '')
}
stages {
stage('Stage Name') {
steps {
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# triggers
定义流水线构建触发器,在Pipeline中配置的同类型触发器会覆盖通用配置中的同类型触发器。
以下是一些常用的触发器类型配置:
pollSCM
:该类型触发器会按Cron风格字符串定时检查源代码管理系统(Git/GitLub等) 中的更改,并在检测到更改时触发构建。pipeline { agent any // 触发器配置 triggers { // 表示每5分钟检查一次SCM是否有变化 pollSCM('H/5 * * * *') } stages { stage('Stage Name') { steps { } } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14cron
:该类型触发器会按Cron风格字符串定时触发构建。pipeline { agent any // 触发器配置 triggers { // 周一到周五的某个随机小时执行一次 cron('H H * * 1-5') } stages { stage('Stage Name') { steps { } } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# tools
指定构建时使用的构建工具及版本,需要指定为已安装并配置的构建工具,工具名称必须在系统设置->全局工具配置中定义。
pipeline {
agent any
// 构建工具配置
tools {
jdk 'JDK 8'
maven 'apache-maven-3.0.1'
}
stages {
stage('Stage Name') {
steps {
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# post
用于根据流水线的运行状态执行步骤,它可以包含以下条件块:
always
:无论流水线构建结果如何,总是执行。changed
:当前流水线构建结果与上次运行的结果不一样时执行。success
:当流水线构建成功时执行。unstable
:当流水线构建成功,但被标记为不稳定时执行,例如测试失败等情况。failure
:当流水线构建失败时执行。aborted
:当流水线被中止时执行。unsuccessful
:当流水线未成功完成(包括失败和不稳定)时执行。
例如:
pipeline {
agent any
stages {
stage('Stage Name') {
steps {
}
}
}
post {
always {
echo '总是运行'
}
success {
echo '构建成功时运行'
}
unsuccessful {
echo '构建不成功时运行'
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# input
在步骤阶段中添加,执行到该步骤时会弹出输入框,由用户决定是否执行该阶段,它还可以提示用户传入构建参数。
pipeline {
agent any
stages {
stage('Stage Name') {
// 输入框
input {
// 提示信息
message "Should we continue?"
// 确认按钮信息,默认为OK
ok "Yes, we should."
// 可选,指定允许执行该阶段的用户名。默认允许任何用户执行,默认设置由环境变量submitterParameter配置。
submitter "alice,bob"
// 可选,让用户传入针对该步骤的构建参数
parameters {
string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
}
}
// 步骤
steps {
echo "Hello, ${PERSON}, nice to meet you."
}
}
}
}
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
# when
在步骤阶段中添加,执行到该步骤时会根据给定条件决定是否应该执行该阶段。
when指令必须包含至少一个条件。
如果when指令包含多个条件,则所有的条件必须返回True,阶段才能执行。
它可以包含以下条件:
branch
:当构建的分支与指定的分支匹配时,条件成立,只适用于多分支流水线。例如:when { branch 'master' }
environment
:当指定的环境变量等于指定值时,条件成立。例如:when { environment name: 'version', value: 'pro' }
expression
:当指定的Groovy表达式为true
时,条件成立。例如:when { expression { return params.DEBUG_BUILD } }
not
:当嵌套条件为false时,条件成立,嵌套条件必须包含一个条件。格式:when { not { branch 'master' } }
allOf
:当嵌套条件都为true时,条件成立,嵌套条件必须包含一个条件。格式:when { allOf { branch 'master'; environment name: 'version', value: 'pro' }
anyOf
:当嵌套条件有一个为true时,条件成立,嵌套条件必须包含一个条件。格式:when { anyOf { branch 'master'; branch 'staging' } }
例如:
pipeline {
agent any
stages {
stage('Example Build') {
steps {
echo 'Hello World'
}
}
stage('Example Deploy') {
when {
branch 'production'
}
steps {
echo 'Deploying'
}
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# parallel
在步骤阶段主区域中添加,用来包裹stage,被包裹的stage会被并行执行。
stage指令可以具有parallel指令或steps指令,但不能同时具有两者。
parallel指令中的一个stage指令不能嵌套另一个parallel指令,仅允许steps。
在内部具有parallel指令的stage指令不能定义“agent”或“tools”指令。
pipeline {
agent none
stages {
stage('并行执行') {
parallel {
stage('Test On Windows') {
agent {
label "windows"
}
steps {
bat "run-tests.bat"
}
}
stage('Test On Linux') {
agent {
label "linux"
}
steps {
sh "run-tests.sh"
}
}
}
}
}
}
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
# 常用步骤
在steps或其他需要执行步骤语句的块中使用。
# sh
在Unix/Linux系统上执行Shell命令。
sh 'make build'
# bat
在Windows系统上执行批处理命令。
bat 'build.bat'
# echo
打印消息到控制台。
echo 'Hello, World!'
# checkout
从版本控制系统检出代码到本地。
checkout([$class: 'GitSCM', branches: [[name: '*/main']], userRemoteConfigs: [[url: 'https://github.com/your-repo.git']]])
# input
在流水线中暂停执行,等待用户输入。
input 'Proceed with deployment?'
# timeout
具有超时时间的执行块中的步骤。
timeout(time: 30, unit: 'MINUTES') {
sh 'long-running-script.sh'
}
2
3
# retry
重试步骤,如果失败则重新尝试步骤。
retry(3) {
sh 'unstable-command.sh'
}
2
3
# parallel
并行执行多个步骤,parallel也可以定义在steps中。
parallel(
stageName1: {
sh 'script1.sh'
},
stageName2: {
sh 'script2.sh'
}
)
2
3
4
5
6
7
8
# 生成pipeline语法片段
# Pipeline使用案例
基本流程:提交py代码到Gitlab,然后通过WEBHook触发Jenkins构建,先将程序通过Dockfile构建成镜像,然后启动测试用例测试页面是否能正常访问通,如果测试通过则发布到K8S集群,否则不进行发布提示构建失败。
# 1.创建项目
创建一个流水线类型作业,名称为hello-test
# 2.基本配置
# 3.上传代码到Gitlab
我这里上传到python/hello项目的main分支中,文件名main.py。
#!/usr/bin/env python3
import socket
# 服务端80端口
server = socket.socket()
server.bind(('0.0.0.0', 888))
server.listen(5)
while 1:
conn, addr = server.accept()
# 接受HTTP请求
data = conn.recv(1024)
print(data)
# 返回HTTP响应
content = b'HTTP/1.1 200 OK\r\nName: test\r\n\r\n##-CONTENT-##'
conn.send(content)
conn.close()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 3.上传jenkinsfile文件
将Jenkinsfile文件也上传到Gitlab上,文件名就叫Jenkinsfile即可,当然也可以是其他的。
pipeline {
agent any
options {
// 超时时间、重试次数、时间戳
timeout(time: 5, unit: 'MINUTES')
timestamps()
}
parameters {
text(name: 'PAGE_CONTENT', defaultValue: 'Hello, world!', description: 'hello页面内容')
}
stages {
// 检出代码操作
stage('checkOut') {
steps {
// 通过'流水线语法'页面生成,不然得事先知道凭证Id
git branch: 'main', credentialsId: 'a4a9ea9e-717b-45b9-ac77-4f6e06ad8180', url: 'git@192.168.10.21:python/hello.git'
}
}
stage('build') {
steps {
sh 'sed -i "s/##-CONTENT-##/$PAGE_CONTENT/g" main.py'
}
}
stage('deploy') {
steps {
script {
withEnv(['JENKINS_NODE_COOKIE=dontKillMe']) {
sh '''
netstat -lntup | grep ":888 " | awk -F'[ /]+' '{print $(NF-2)}' | xargs -i kill {}
sleep 3
nohup python3 main.py > /dev/null 2>&1 &
'''
}
}
}
}
}
post {
always {
echo 'PipeLine over.'
}
}
}
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
# 4.作业配置中指定Jenkinsfile文件
选择从SCM中获取Jenkinsfile文件,脚本路径指定为刚刚上传的Jenkins文件名,默认即是Jenkinsfile。
# 5.然后测试构建即可
记得防火墙放行端口。