jenkins
Jenkins 项目产生两个发行线, 长期支持版本 (LTS) 和每周更新版本, 两个版本都以 .war 文件, 原生包, 安装程序, 和 Docker 容器的形式分发。
官网:https://jenkins.io/
代码仓库:https://github.com/jenkinsci/jenkins
三种构建方式
1、触发式构建:用于开发环境部署,开发人员push代码或者合并代码到 代码仓库,jenkins就部署代码到对应服务器。
2、参数化构建:用于测试环境预上线环境部署,开发push代码到代码仓库后,并不会立即部署代码,而是需要登录到jenkins的web界面,点击构建按钮,传入对应的参数(比如参数需要构建的tag,需要部署的分支)然后才会部署。
3、定时构建:用于APP自动打包,定时构建是在参数化构建的基础上添加的,开发人员可以登录jenkins手动传入tag进行打包,如果不手动打包,那么jenkins就每天定时打包。
安装
master 节点方式
推荐使用docker
| docker run -id --name myjenkins \
-p 8080:8080 -p 50000:50000 \
-v /var/jenkins_home:/var/jenkins_home \
jenkins/jenkins:lts
拉取远程镜像
docker pull jenkins/jenkins:lts-jdk11
两种部署方式任选
推荐:
docker run -d -v jenkins_home:/var/jenkins_home -p 8080:8080 -p 50000:50000 --restart=on-failure jenkins/jenkins:lts-jdk11
进阶 如果使用了这个选项 -v $PWD/exec:/usr/share/jenkins/ 必须保障 $PWD/exec 目录下已经存在 jenkins.war 及 ref目录
docker run -d -v $PWD:/var/jenkins_home -v $PWD/exec:/usr/share/jenkins/ -u root -p 8080:8080 -p 50000:50000 --restart=on-failure jenkins/jenkins:lts-jdk11
exec 映射的是 Jenkins war包所在的目录,便于升级修复
jenkins_home 是系统配置,包括插件、流水线、workspace等
|
任务节点
下图两种方式:
1、Launch agents via SSH
2、通过Java Web启动代理
| 特征 |
Launch agents via SSH |
通过 Java Web 启动代理 |
| 安全性 |
使用 SSH 协议加密通信 |
通过 HTTP 或 HTTPS 进行通信 |
| 配置复杂度 |
需要配置 SSH 密钥和主机凭据(最好手动指定java环境) |
通过 Jenkins Web 界配置(推荐) |
| 适用场景 |
适用于需要与远程服务器进行安全通信的场景 |
适用于内部网络且无需额外安全措施的场景 |
| 远程执行环境 |
需要在远程主机上安装 Java 和 Jenkins agent |
需要远程主机能够通过 HTTP 或 HTTPS 访问 Jenkins 主服务器 |
| 实现方式 |
通过 SSH 远程连接并启动 Jenkins agent(主动) |
通过 Jenkins 插件和 Web 容器实现代理启动(被动) |
| 配置管理 |
需要管理 SSH 密钥和凭据的安全性 |
可以在 Jenkins Web 界面上直接管理代理配置 |

使用注意
1、master 节点尽量不运行任务
2、建议JOB设置静默期
3、轮询构建定时构建注意设置 TZ=Asia/Chongqing
4、建议设置丢弃旧的构建
5、制品可以临时存在Jenkins自带制品库,需要长久保存的 推荐 nexus等专业系统
6、中文乱码:本着不干扰原生环境,在确保node支持中文字符集后可以在节点属性上 环境变量新增键值对 key = LANG value = zh_CN.UTF-8
Jenkinsfile 语法
Jenkins 流水线的构建方式有很多,比如 执行shell、window命令、invoke Gradle script、Execute SonarQube Scanner等,
最核心的是 pipeline
Pipeline
Jenkins的Pipeline通过Jenkinsfile进行描述(类似于Dockerfile)
Jenkinsfile是Jenkins的特性(pipeline as code)
Pipeline是Jenkins的核心功能,提供一组可扩展的工具。
通过Pipeline 的DSL(Pipeline Domain Specific Language)语法可以完成从简单到复杂的交付流水线实现。
| 元素 |
作用域 |
是否必须 |
备注说明 |
| stages |
Pipeline 范围 |
可选 |
定义了 Pipeline 中的多个阶段 |
| stage |
stages 内部 |
必须 |
定义了 Pipeline 中的单个阶段 |
| steps |
stage 内部 |
必须 |
定义了执行在某个阶段中的具体步骤 |
| post |
Pipeline 范围 |
可选 |
定义了 Pipeline 在执行完所有阶段后进行的一些后续操作或清理工作 |
| options |
Pipeline 范围 |
可选 |
定义了 Pipeline 的全局选项,如超时、并发等 |
| environment |
Pipeline 范围 |
可选 |
定义了 Pipeline 执行时的环境变量 |
- stages:是用于将 Pipeline 分解为多个阶段的容器,可以在其中定义多个 stage。
- stage:定义了 Pipeline 中的一个阶段,Pipeline 中的每个阶段至少包含一个 stage。
- steps:在 stage 中定义的具体操作步骤,用于执行构建过程中的任务。
- post:在 Pipeline 执行完成后定义的一些后续操作,比如处理构建结果、清理资源等。
- options:定义了 Pipeline 的全局选项,允许设置超时、并发等全局属性。
- environment:定义了 Pipeline 执行时的环境变量,可以在整个 Pipeline 运行期间使用。
post
always 无论流水线或者阶段的完成状态。
changed 只有当流水线或者阶段完成状态与之前不同时。
failure 只有当流水线或者阶段状态为”failure”运行。
success 只有当流水线或者阶段状态为”success”运行。
unstable 只有当流水线或者阶段状态为”unstable”运行。例如:测试失败。
aborted 只有当流水线或者阶段状态为”aborted “运行。例如:手动取消
options运行选项
buildDiscarder: 为最近的流水线运行的特定数量保存组件和控制台输出。
disableConcurrentBuilds: 不允许同时执行流水线。 可被用来防止同时访问共享资源等。
overrideIndexTriggers: 允许覆盖分支索引触发器的默认处理。
skipDefaultCheckout: 在agent 指令中,跳过从源代码控制中检出代码的默认情况。
skipStagesAfterUnstable: 一旦构建状态变得UNSTABLE,跳过该阶段。
checkoutToSubdirectory: 在工作空间的子目录中自动地执行源代码控制检出。
timeout: 设置流水线运行的超时时间, 在此之后,Jenkins将中止流水线。
retry: 在失败时, 重新尝试整个流水线的指定次数。
timestamps 预测所有由流水线生成的控制台输出,与该流水线发出的时间一致。
下面简单示例
| agent{},指定node节点/workspace(定义好此流水线在某节点运行)
支持的有 any、none、node、label、docker、dockerfile
pipeline{
//指定运行此流水线的节点 tag 是 Bulid_21
agent {label 'Bulid_21'}
//随便那个节点自己跑
agent any
//设置构建超时时间为 1 秒
options {
timeout(time: 1, unit: 'SECONDS')
}
//全局变量
environment {
code = 'ccid'
}
//流水线的阶段
stages{
//阶段1 获取代码
stage("CheckOut"){
agent { label 'my-label1 || my-label2' }
environment {
ACCESS_KEY = credentials('my-ssh')
}
steps{
script{
println("获取代码")
}
}
}
stage("Build"){
//
agent { label 'my-label1 && my-label2' }
steps{
echo 'Hello, mibo'
sh('cd /home/mibo/'+env.fliepath+';svn log -l 5;')
sh 'make -j 40'
}
}
}
post {
always{
script{
println("流水线结束后,经常做的事情")
}
}
success{
script{
println("流水线成功后,要做的事情")
}
// 存档本次测试相关的资料
archiveArtifacts artifacts: 'alert_test_result.xlsx', followSymlinks: false
archiveArtifacts artifacts: 'all_result.txt', followSymlinks: false
}
failure{
script{
println("流水线失败后,要做的事情")
}
}
aborted{
script{
println("流水线取消后,要做的事情")
}
}
}
}
|
when条件判断
| //branch: 当正在构建的分支与模式给定的分支匹配时,执行这个阶段,这只适用于多分支流水线例如:
when { branch 'master' }
//environment: 当指定的环境变量是给定的值时,执行这个步骤,例如:
when { environment name: 'DEPLOY_TO', value: 'production' }
//expression 当指定的Groovy表达式评估为true时,执行这个阶段, 例如:
when { expression { return params.DEBUG_BUILD } }
//not 当嵌套条件是错误时,执行这个阶段,必须包含一个条件,例如:
when { not { branch 'master' } }
//allOf 当所有的嵌套条件都正确时,执行这个阶段,必须包含至少一个条件,例如:
when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
//anyOf 当至少有一个嵌套条件为真时,执行这个阶段,必须包含至少一个条件,例如:
when { anyOf { branch 'master'; branch 'staging' } }
stage('Example Deploy') {
when {
branch 'production'
environment name: 'DEPLOY_TO', value: 'production'
}
steps {
echo 'Deploying'
}
}
|
parallel并行执行
嵌套阶段本身不能包含 进一步的 parallel 阶段
| stage('Parallel Stage') {
when {
branch 'master'
}
failFast true //当其中一个进程失败时,强制所有的 parallel 阶段都被终止
parallel {
stage('Branch A') {
agent {
label "for-branch-a"
}
steps {
echo "On Branch A"
}
}
stage('Branch B') {
agent {
label "for-branch-b"
}
steps {
echo "On Branch B"
}
}
}
}
|
script脚本标签
通过使用script来包裹脚本语句,即可使用脚本语法
| pipeline {
agent any
stages {
stage('stage 1') {
steps {
script{
try {
sh 'exit 1'
}
catch (exc) {
echo 'Something failed'
}
}
}
}
}
}
|
通过python 快速控制Jenkinsjob 的 增删改查
关键代码示例
| import paramiko
import yaml
from api4jenkins import Jenkins, Folder, job
class ConfRead:
def __init__(self,jk_obj):
with open(r'jenkins_config.yaml', mode='rb') as f:
confs = yaml.safe_load(f)
self.conf = confs
jk_conf = confs.get(jk_obj)
jk_obj = Jenkins(jk_conf.get("url"), auth=(jk_conf.get("user"), jk_conf.get("token")), token=True)
self.jk_obj = jk_obj
for job in jenkins_obj.iter_jobs():
job_type = job._class # job的类型 Folder WorkflowJob FreeStyleProject 等
job.configure() # xml格式的job
job.delete() # 删除全部job
# 创建job
jenkins_obj.create_job(job_name, job_config.encode('utf-8'))
# 禁用job
jenkins_obj.get_job(job_name).disable()
|
清空history 脚本管理器在自带的里面执行
| item = Jenkins.instance.getItemByFullName("ABJ/CNEOS_4.4.15/SW64_CNEOS_4.4.15_server.v1.0")
item.builds.each() { build ->
build.delete()
}
item.updateNextBuildNumber(1)
|
Groovy
有点费劲,垃圾语言
https://groovy.apache.org/
FAQ
jenkins在添加从节点时 可以在启动方式中选择:Non verifying Verification Strategy
Jenkins很卡: master 节点尽量不要跑任务
在使用svn轮询时很占资源:Repository depth 选择 empty