跳转至

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 脚本管理器在自带的里面执行

1
2
3
4
5
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