Pipeline
Jenkins Pipeline 是用 代码(Groovy DSL) 描述的自动化流程,支持版本控制,重现性好。
两种主要类型:
- Declarative Pipeline(声明式) ✅ 推荐,语法清晰易维护
- Scripted Pipeline(脚本式) 适合高级场景,写法更灵活但复杂
执行单位
- Agent:指定在哪个节点/容器中运行任务
- Stage:阶段,表示一个阶段性任务(如 构建、测试、部署)
- Step:步骤,具体的命令或操作
- Environment:环境变量配置
- Post:执行完阶段或 Pipeline 后的清理逻辑(如 always, success, failure)
语法
groovy
pipeline {
agent any // 或 kubernetes、docker、label、自定义
environment {
MAVEN_OPTS = "-Dmaven.repo.local=/cache/.m2"
}
options {
timeout(time: 30, unit: 'MINUTES')
skipDefaultCheckout() // 禁用自动 checkout
}
parameters {
string(name: 'BRANCH', defaultValue: 'main', description: '构建分支')
}
stages {
stage('Checkout') {
steps {
git branch: "${params.BRANCH}", url: 'https://github.com/xxx/your-repo.git'
}
}
stage('Build') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Deploy') {
steps {
sshagent(['ssh-key-cred-id']) {
sh '''
ssh user@host "docker run -d your-image"
'''
}
}
}
}
post {
success {
echo "构建成功!"
}
failure {
echo "构建失败!"
}
}
}
Agent
- 全局 Agent(整个 Pipeline 使用同一个环境)
groovy
agent {
kubernetes {
yamlFile 'jenkins/agent-pod.yaml' // 指定 agent pod 定义
}
}
- 分阶段 Agent(每个 Stage 使用不同的 agent)
groovy
stage('Build') {
agent {
docker {
image 'maven:3.9.6-eclipse-temurin-17'
args '-v /root/.m2:/root/.m2'
}
}
steps {
sh 'mvn clean package'
}
}
自定义的 Agent
- 构建 Agent 镜像
dockerfile
FROM jenkins/inbound-agent:4.13.3-1
USER root
# 安装依赖
RUN apt-get update && apt-get install -y curl tar unzip && rm -rf /var/lib/apt/lists/*
# 安装 JDK 8(Temurin)
ENV JAVA_VERSION=8u402-b06
ENV JAVA_HOME=/opt/java/openjdk
RUN mkdir -p $JAVA_HOME && \
curl -L https://github.com/adoptium/temurin8-binaries/releases/download/jdk8u402-b06/OpenJDK8U-jdk_x64_linux_hotspot_8u402b06.tar.gz \
| tar -xz -C $JAVA_HOME --strip-components=1 && \
ln -s $JAVA_HOME/bin/java /usr/bin/java && \
ln -s $JAVA_HOME/bin/javac /usr/bin/javac
ENV PATH=$JAVA_HOME/bin:$PATH
# 安装 Maven
ENV MAVEN_VERSION=3.9.6
RUN curl -fsSL https://downloads.apache.org/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz \
| tar -xz -C /opt && \
ln -s /opt/apache-maven-${MAVEN_VERSION} /opt/maven
ENV MAVEN_HOME=/opt/maven
ENV PATH=$MAVEN_HOME/bin:$PATH
# 切回 jenkins 用户
USER jenkins
- 编辑 Helm jenkins values
yaml
agent:
customJenkinsLabels: build-agent
image: your-registry/jenkins-agent:jdk17-maven396
tag: latest
alwaysPullImage: true
- upgrade
shell
helm upgrade jenkins jenkins/jenkins -f values.yaml
环境变量
enironment
groovy
pipeline {
agent any
environment {
MY_NAME = "ChatGPT"
BUILD_ENV = "production"
}
stages {
stage('Print Env') {
steps {
echo "Name: ${MY_NAME}"
echo "Environment: ${env.BUILD_ENV}"
}
}
}
}
stage 或者 step
- 在某个 stage 或 step 中临时设置
groovy
pipeline {
agent any
stages {
stage('Temp Env') {
steps {
withEnv(["TEMP_VAR=123", "FOO=bar"]) {
sh 'echo $TEMP_VAR'
sh 'echo $FOO'
}
}
}
}
}
shell
- 在 Shell 中直接定义(仅限 sh、bat 命令作用域)
groovy
pipeline {
agent any
stages {
stage('Inline Shell') {
steps {
sh '''
export TEMP_VAR=inline
echo $TEMP_VAR
'''
}
}
}
}
预定义环境变量
变量名 | 含义 |
---|---|
BUILD_NUMBER | 当前构建编号 |
BUILD_ID | 构建 ID(时间戳) |
JOB_NAME | 当前 Job 名称 |
WORKSPACE | 当前工作目录 |
BRANCH_NAME | SCM 分支名称(如 Git 分支) |
GIT_COMMIT | 当前提交的 Git hash 值 |
shell
echo "Build number: ${env.BUILD_NUMBER}"
参数化构建
Jenkins 会在用户点击“Build with Parameters”按钮时弹出这些参数选项,让用户输入或选择。
groovy
pipeline {
agent any
parameters {
string(name: 'BRANCH', defaultValue: 'main', description: 'Git 分支')
choice(name: 'ENV', choices: ['dev', 'test', 'prod'], description: '部署环境')
}
environment {
// 可以设置为环境变量
DEPLOY_ENV = "${params.ENV}"
}
stages {
stage('Checkout') {
steps {
echo "拉取分支:${params.BRANCH}"
checkout([$class: 'GitSCM',
branches: [[name: "*/${params.BRANCH}"]],
userRemoteConfigs: [[url: 'git@github.com:your/repo.git']]
])
}
}
stage('Deploy') {
steps {
echo "部署环境是:${params.ENV}"
sh '''
echo 正在部署到环境: $DEPLOY_ENV
'''
}
}
}
}
构建示例
Groovy
pipeline {
agent {
kubernetes {
label 'build-agent'
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: your-registry/jenkins-agent:jdk8-maven396
command:
- cat
tty: true
"""
}
}
environment {
// 远程服务器SSH配置
REMOTE_HOST = 'your.remote.server.ip'
REMOTE_USER = 'your_ssh_user'
// 需在 Jenkins 凭据管理添加 SSH 私钥
SSH_KEY = credentials('your-ssh-key-id')
DOCKER_IMAGE = "your-docker-repo/your-app:latest"
}
stages {
stage('Checkout') {
steps {
git branch: 'main', url: 'git@github.com:your/repo.git'
}
}
stage('Build') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Docker Build & Push') {
steps {
script {
docker.withRegistry('https://registry.hub.docker.com', 'dockerhub-credentials') {
def appImage = docker.build(DOCKER_IMAGE)
appImage.push()
}
}
}
}
stage('Deploy') {
steps {
script {
sshagent(credentials: ['your-ssh-key-id']) {
sh """
ssh -o StrictHostKeyChecking=no ${REMOTE_USER}@${REMOTE_HOST} \\
'docker pull ${DOCKER_IMAGE} && \\
docker stop your-container-name || true && \\
docker rm your-container-name || true && \\
docker run -d --name your-container-name -p 8080:8080 ${DOCKER_IMAGE}'
"""
}
}
}
}
}
}
并行顺序构建
groovy
pipeline {
agent any
stages {
stage('准备阶段') {
steps {
echo "准备环境..."
}
}
stage('并行构建模块') {
parallel {
stage('模块 A') {
steps {
echo "构建模块 A"
}
}
stage('模块 B') {
steps {
echo "构建模块 B"
}
}
}
}
stage('部署阶段') {
steps {
echo "部署中..."
}
}
}
}
- 动态构建
groovy
def modules = ['a', 'b', 'c']
pipeline {
agent any
stages {
stage('动态并行') {
steps {
script {
def builds = [:]
for (int i = 0; i < modules.size(); i++) {
def m = modules[i]
builds["构建-${m}"] = {
echo "构建模块 ${m}"
}
}
parallel builds
}
}
}
}
}
最佳实践
使用 Jenkinsfile
- 在项目仓库根目录下创建一个名为 Jenkinsfile 的文件。
- 它使用 Groovy DSL 编写,描述整个流水线逻辑。
- 支持 声明式(declarative) 或 脚本式(scripted) 两种语法。