Jenkins Pipeline 构建 CI/CD 流程

文章目录

    • [jenkins 安装](#jenkins 安装)
    • [jenkins 配置](#jenkins 配置)
    • [jenkins 快速上手](#jenkins 快速上手)
      • [在 jenkins 中创建一个新的 Pipeline 作业](#在 jenkins 中创建一个新的 Pipeline 作业)
      • 配置Pipeline
      • [运行 Pipeline 作业](#运行 Pipeline 作业)
    • Pipeline
      • 概述
      • [Declarative Pipeline](#Declarative Pipeline)
      • [Scripted Pipeline](#Scripted Pipeline)

jenkins 安装

安装环境:

官方给的下载方式很简单明了

此处博主的Jenkins 安装目录为:/home/fishpie/workspace/apps/

运行安装命令:

bash 复制代码
java -jar jenkins.war --httpPort=8080

如果遇到字体配置(Fontconfig)失败,可能是因为 linux 操作系统采用了最小化安装,缺失

  • fontconfig 包或相关字体
  • 缺少 libfontconfig 或其他图形依赖
bash 复制代码
SEVERE  hudson.util.BootFailure#publish: Failed to initialize Jenkins
java.lang.RuntimeException: Fontconfig head is null, check your fonts or fonts configuration

解决办法:

bash 复制代码
# 安装 fontconfig 和默认字体
sudo dnf install -y fontconfig dejavu-sans-fonts
# 安装图形相关依赖
sudo dnf install -y libX11 libXext libXrender libXtst libXi

另外如果出现 security 问题,需要注意系统时间是否正确


出现此页面证明Jenkins 安装完成,此时访问本机的 8080 端口即可访问 Jenkins

例如我本地装了 Jenkins 的机器:

http://192.168.156.129:8080/


jenkins 配置

密码登录进入后建议选择 安装推荐的插件

如果遇到插件安装错误可以多次尝试安装,可在

Manage Jenkins -> Plugins -> Download progress

中找到 安装完成后重启Jenkins 选项并勾选

正常的 jenkins 界面


jenkins 快速上手

前置环境:

  1. git
  2. docker
  3. 更新 OpenSSL 和 SSL 证书
bash 复制代码
# 安装或更新 OpenSSL
sudo dnf install -y openssl
# 更新 CA 证书
sudo dnf install -y ca-certificates
sudo update-ca-trust
  1. 安装 jenkins 的 docker pipline 插件

采用 github 项目 https://github.com/yeasy/simple-web 演示使用jenkins 构建和部署一个项目的完整过程

在 jenkins 中创建一个新的 Pipeline 作业

  1. 登录到你的 Jenkins 控制台。
  2. 在左侧菜单中点击 New Item(新建项目)。
  3. 输入作业名称,例如 SimpleWebPipeline。
  4. 选择 Pipeline (流水线)作为项目类型,然后点击 OK



配置Pipeline

  1. 在作业配置页面,向下滚动到 Pipeline(流水线)部分。
  2. Definition (定义)下拉菜单中,选择 Pipeline script(流水线脚本)。
  3. Script(脚本)文本框中,粘贴以下 Jenkinsfile 代码:
groovy 复制代码
pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                git 'https://github.com/yeasy/simple-web.git'
            }
        }
        stage('Build') {
            steps {
                script {
                    // 验证 Docker 环境
                    sh 'docker version'
                    // 构建 Docker 镜像
                    def image = docker.build("simple-web:latest")
                }
            }
        }
        stage('Deploy') {
            steps {
                script {
                    // 停止并删除已存在的容器
                    sh 'docker rm -f simple-web || true'
                    // 运行新容器
                    docker.image("simple-web:latest").run("-d -p 8081:80 --name simple-web")
                }
            }
        }
    }
}
  1. 点击 Save(保存)以保存作业配置。

运行 Pipeline 作业

  1. 在作业页面,点击 Build Now(立即构建)以启动流水线。
  2. 通过点击 Build History (构建历史)下的构建编号并选择 Console Output(控制台输出),监控构建过程。你将看到每个阶段(Checkout、Build、Deploy)的执行情况。



如果构建成功,则可在本机看到构建成功的镜像与进程

访问本机的 8081 端口可以正常看到网页


Pipeline

概述

Jenkins Pipeline(或简称为 "Pipeline")是一套插件,将持续交付的实现和实施集成到 Jenkins 中

Jenkins Pipeline 有两种主要语法:

  • Declarative Pipeline:结构化、易读,适合大多数场景,推荐初学者使用。

  • Scripted Pipeline:基于 Groovy 语言,灵活但复杂,


Declarative Pipeline

固定结构,主要由 pipeline 块构成,包含以下核心部分:

  • agent:定义执行 Pipeline 的环境。
  • stages:定义一系列构建阶段。
  • steps:每个阶段的具体操作。
  • post:构建后的处理逻辑。

pipeline 块

  • 作用:pipeline 的根节点,包含整个流水线的定义
  • 要求:所有的 Declarative Pipeline 必须以 pipeline {} 开始
  • 示例:
groovy 复制代码
pipeline {
    // 流水线内容
}

agent 指令

  • 作用:指定 pipeline或特定阶段运行的执行环境(节点或容器)
  • 常用选项:
    • any:可在任何节点上运行(默认)
    • none :不指定全局代理,需要在每个 stage 中定义
    • docker :在 Docker 容器中运行
    • label :在带有特定标签的节点上运行
  • 示例:
groovy 复制代码
// 表示 pipeline 在 jenkins 主节点或任意代理节点上运行
pipeline {
    agent any
}
groovy 复制代码
//使用 Docker 容器运行
pipeline {
    agent {
      docker {
          image 'maven:3.6.3-jdk-11'
          args '-v /root/.m2:/root/.m2'
      }
		}
}
//在 Maven 容器中运行,挂载本地 Maven 缓存

stages 和 stage

  • 作用:
    • stages :包含所有阶段的集合
    • stage :定义单个阶段(如拉取代码、构建、部署)

可以把"步骤(step)"看作一个执行单一动作的单一的命令。 当一个步骤运行成功时继续运行下一个步骤。 当任何一个步骤执行失败时,Pipeline 的执行结果也为失败

当所有的步骤都执行完成并且为成功时,Pipeline 的执行结果为成功

  • 结构:
groovy 复制代码
stages {
    stage('Stage Name') {
        steps {
            // 操作
        }
    }
}
  • 示例:
groovy 复制代码
pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                git 'https://github.com/yeasy/simple-web.git'
            }
        }
        stage('Build') {
            steps {
                script {
                    // 验证 Docker 环境
                    sh 'docker version'
                    // 构建 Docker 镜像
                    def image = docker.build("simple-web:latest")
                }
            }
        }
        stage('Deploy') {
            steps {
                script {
                    // 停止并删除已存在的容器
                    sh 'docker rm -f simple-web || true'
                    // 运行新容器
                    docker.image("simple-web:latest").run("-d -p 8081:80 --name simple-web")
                }
            }
        }
    }
}
  • Checkout:从 github 克隆代码
  • Build:构建 Docker 镜像
  • Deploy:运行 Docker 容器

每个 stage 是一个逻辑单元,失败后会阻止后续阶段执行

阶段名称(如 Checkout)会显示在 Jenkins 的 Pipeline 视图中

节点名称可以自定义


steps 指令

  • 作用:定义阶段内的具体操作(如执行命令、调用插件)

  • 常用步骤:

    • sh :执行 Linux、BSD 和 Mac OS(类 Unix ) 系统中的 shell 命令
    • bat :执行 Windows 批处理命令
    • git :拉取 Git 仓库代码
    • docker :调用 Docker 命令(需要 Docker Pipeline 插件)
    • archiveArtifacts :归档构建产物

    如果在 archiveArtifacts 步骤中指定了多个参数, 那么每个参数的名称必须在步骤代码中明确指定, 即文件的路径、文件名和 fingerprint 三个参数 。 如果只需指定文件的路径和文件名, 那么可以省略参数名称 artifacts ,例如: archiveArtifacts 'build/libs/**/*.jar'

    • junit :发布测试报告
  • 示例:

groovy 复制代码
// 拉取指定 Git 仓库
steps {
    git 'https://github.com/yeasy/simple-web.git'
}
groovy 复制代码
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh './gradlew build'
            }
        }
        stage('Test') {
            steps {
                sh './gradlew check'
            }
        }
    }

    post {
        always {
            archiveArtifacts artifacts: 'build/libs/**/*.jar', fingerprint: true
            junit 'build/reports/**/*.xml'
        }
    }
}

script 块

  • 作用:允许在 Declarative Pipeline 中嵌入 Scripted Pipeline 的 Groovy 代码,用于复杂逻辑
groovy 复制代码
// 检查 docker 环境并构建镜像,负载操作采用 script 块包裹
steps {
    script {
        sh 'docker version'
        def image = docker.build("simple-web:latest")
    }
}

post 指令

  • 作用:钩子函数,定义构建完成后执行的操作,基于构建结果触发

  • 常用条件:

    • always :无论成功或失败都执行
    • success :构建成功时执行
    • failure :构建失败时执行
    • unstable:构建不稳定时执行(如测试失败)
  • 示例:

groovy 复制代码
// 如果构建成功则打包为 jar 包,否则发送指定邮件提醒
post {
    always {
        echo 'Pipeline finished!'
    }
    success {
        archiveArtifacts artifacts: '**/target/*.jar', allowEmptyArchive: true
    }
    failure {
        mail to: '[email protected]', subject: 'Build Failed', body: 'Check Jenkins for details.'
    }
}
groovy 复制代码
pipeline {
    agent any
    stages {
        stage('No-op') {
            steps {
                sh 'ls'
            }
        }
    }
    post {
        always {
            echo 'One way or another, I have finished'
            deleteDir() /* clean up our workspace */
        }
        success {
            echo 'I succeeeded!'
        }
        unstable {
            echo 'I am unstable :/'
        }
        failure {
            echo 'I failed :('
        }
        changed {
            echo 'Things were different before...'
        }
    }
}

tools 指令

  • 作用:指定构建所需的工具版本(如 JDK、Maven),从 jenkins 全局工具配置中加载
  • 示例:
groovy 复制代码
自动配置 Maven 和 JDK 环境
tools {
    maven 'Maven 3.6.3'
    jdk 'JDK 21'
}

需要在 Manage Jenkins > Tool 中预先配置工具


environment 指令

  • 作用:定义环境变量
  • 示例:
groovy 复制代码
// 创建环境变量,相当于 Java 中的定义字符串
environment {
    DOCKER_IMAGE = 'simple-web:latest'
    APP_PORT = '8081'
}
groovy 复制代码
// 引用上面的环境变量
sh "docker run -p ${APP_PORT}:80 ${DOCKER_IMAGE}"

同时,我们可以将 simple-web 的 pipeline 部分优化为:

groovy 复制代码
environment {
    IMAGE_NAME = 'simple-web:latest'
}
stages {
    stage('Build') {
        steps {
            script {
                docker.build("${IMAGE_NAME}")
            }
        }
    }
}

when 指令

Java 语言的本性

  • 作用:控制阶段是否执行,基于条件判断
  • 示例:
groovy 复制代码
stage('Deploy') {
    when {
        branch 'main'
    }
    steps {
        // 仅在 main 分支上部署
    }
}
  • 常用条件
    • branch :指定分支
    • environment:检查环境变量
    • expression :自定义 Groovy 表达式

try-catch

  • 作用:捕获并处理阶段失败,异常处理
  • 示例:
groovy 复制代码
steps {
    script {
        try {
            sh 'make test'
        } catch (Exception e) {
            echo "Tests failed: ${e}"
            currentBuild.result = 'UNSTABLE'
        }
    }
}
// 执行 make test 命令,如果未能正常执行,则回显异常并设置当前构建结果为 UNSTABLE

retry-timeout

  • 作用:重复执行步骤直到成功(重试)和如果一个步骤执行花费的时间太长则退出
groovy 复制代码
stage('Deploy') {
    steps {
        retry(3) {
            sh './flakey-deploy.sh'
        }

        timeout(time: 3, unit: 'MINUTES') {
            sh './health-check.sh'
        }
    }
}
// 在 Deploy 阶段重复执行 flakey-deploy.sh 脚本 3 次,然后等待 health-check.sh 脚本最长执行 3 分钟,如果 health-check.sh 超过 3 分钟内没有完成,pipeline 会标记此 Deploy 阶段为失败

Scripted Pipeline

Scripted Pipeline 是 Jenkins Pipeline 的另一种语法,基于 Groovy 语言,结构更自由但复杂

核心特点:

  • 使用 node 块定义执行环境
  • 直接编写 Groovy 代码,没有固定的 stages 或 steps 结构
  • 适合需要高度自定义的场景。

可以将上述的 jenkins 快速上手 中的 Declarative Pipeline 改写为 Scripted Pipeline

groovy 复制代码
node {
    stage('Checkout') {
        git 'https://github.com/yeasy/simple-web.git'
    }
    stage('Build') {
        def image = docker.build("simple-web:latest")
    }
    stage('Deploy') {
        sh 'docker rm -f simple-web || true'
        docker.image("simple-web:latest").run("-d -p 8081:80 --name simple-web")
    }
}

Declarative Pipeline 与 Scripted Pipeline 的区别

特性 Declarative Pipeline Scripted Pipeline
语法 结构化,固定格式 自由,基于 Groovy
易用性 简单,适合初学者 复杂,需熟悉 Groovy
可读性 高,清晰的阶段划分 较低,代码风格自由
灵活性 有限,需用 script 块扩展 高,完全自定义
错误处理 内置错误检查 需手动处理
相关推荐
PassLink_35 分钟前
[Kaggle]:使用Kaggle服务器训练YOLOv5模型 (白嫖服务器)
运维·服务器·yolo
朴拙数科39 分钟前
MongoDB Atlas与MongoDB连接MCP服务器的区别解析
服务器·数据库·mongodb
极小狐1 小时前
极狐GitLab 合并请求依赖如何解决?
运维·git·ssh·gitlab·github
程序猿(雷霆之王)2 小时前
Linux——进程间通信
linux·运维·服务器
riveting3 小时前
SD2351核心板:重构AI视觉产业价值链的“超级节点”
大数据·linux·图像处理·人工智能·重构·智能硬件
技术liul3 小时前
Docker Compose和 Kubernetes(k8s)区别
docker·容器·kubernetes
易保山3 小时前
MIT6.S081 - Lab10 mmap(文件&内存映射)
linux·操作系统·c
NoneCoder3 小时前
HTML 模板技术与服务端渲染
服务器·servlet·html
禅与Bug的修复艺术3 小时前
JAVA后端开发常用的LINUX命令总结
java·linux·面试·java面试·后端开发·java后端·面试经验
Cloud_Air7544 小时前
从零开始使用SSH链接目标主机(包括Github添加SSH验证,主机连接远程机SSH验证)
运维·ssh