Jenkins 上下游 Job + Docker 镜像部署完整实战(避坑版)

Jenkins 上下游 Job + Docker 镜像部署完整实战(避坑版)

目标读者:

  • 正在使用 Jenkins 做 CI/CD 的开发 / 运维
  • 已经踩过坑、或者马上就要踩坑的人
  • 想把「能跑」升级成「专业、稳定、可扩展」的人

一、背景说明(为什么会写这篇)

在实际项目中,我们经常会遇到这样的场景:

  • 有一个 上游 Job

    • 负责:编译 → 构建 → 打包 → Docker build → Docker push
  • 有一个或多个 下游 Job

    • 负责:从镜像仓库拉镜像 → 部署到多台服务器 / 多实例

看起来很简单,但在 Jenkins 里:

99% 的问题,不是 Docker,不是代码,而是"触发方式 + 参数传递"

本篇文章,就是一次完整的「踩坑 → 定位 → 纠正 → 升级」全过程总结。


二、整体架构一图看懂(先有全局感)

text 复制代码
┌────────────────────┐
│  上游 Job           │
│  luge.api.consume   │
│                    │
│  1. 编译            │
│  2. Docker build    │
│  3. Docker push     │
│  4. 生成 tag        │
│  5. 触发下游        │
└─────────┬──────────┘
          │ 传参 (IMAGE_TAG)
          ▼
┌────────────────────────────┐
│  下游 Job(部署流水线)     │
│                            │
│  - SSH 到服务器            │
│  - docker pull 镜像        │
│  - docker run 多实例       │
└────────────────────────────┘

记住一句话:

上游负责"产出事实",下游负责"执行事实"


三、准备工作:必备插件与环境说明

在开始之前,先把一个经常被忽略、但极其关键的前提说清楚:

Jenkins 的很多"神奇行为",本质都是插件是否安装、是否理解导致的。

3.1 必备 Jenkins 插件清单(缺一不可)

插件名称 作用 是否必须
Pipeline 支持 Jenkinsfile
Pipeline: Groovy 支持 Pipeline 语法
SSH Pipeline Steps / Publish Over SSH 通过 SSH 执行远程命令
Parameterized Trigger 上游向下游传参
Docker Pipeline(可选) Docker 相关语法封装

⚠️ 重点说明

  • Trigger parameterized build on other projects 就来自 Parameterized Trigger 插件
  • 如果你看不到"传参"相关选项,99% 是插件没装或版本太低

3.2 插件检查路径

text 复制代码
Jenkins → 系统管理 → 插件管理 → 已安装

确认以上插件存在后,再继续下面步骤。


四、上游 Job:只做一件事 ------ 产出「可用镜像」

3.1 上游 Job 的关键参数

上游是一个 Multi-configuration / 参数化 Job,核心参数如下:

参数名 说明 示例
imageName 镜像名 luge.api.consume
tag 镜像 tag 202601291616
port 构建时用 6300

最终 push 到仓库的镜像为:

text 复制代码
crpi-xxx.aliyuncs.com/tmios/luge.api.consume:202601291616

⚠️ 注意:
是否存在 latest 完全取决于你有没有 push latest


4.2 上游触发下游(唯一推荐方式)

上游 Job → 构建后操作 中:

选择:

✅ Trigger parameterized build on other projects

配置要点:

  • Projects to build:

    text 复制代码
    下游 Job 名
  • 参数传递方式:

    text 复制代码
    Predefined parameters
  • 示例:

    text 复制代码
    IMAGE_TAG=${tag}

这一步的含义是:

上游明确告诉下游:
"我刚刚产出的镜像,用这个 tag 去部署"


五、参数是如何从上游"流"到下游的(核心原理)

这是整套体系里最容易出错、但也是最关键的一环


5.1 参数传递的真实链路

text 复制代码
上游 Job 参数
   ↓
上游构建产出(Docker push)
   ↓
构建后操作:Trigger parameterized build
   ↓
参数注入到下游 Job
   ↓
下游 Pipeline parameters {}

一句话总结:

参数不是"自动继承"的,而是"上游显式注入"的。


5.2 上游如何传参(配置示例)

在【上游 Job → 构建后操作】中:

选择:

text 复制代码
Trigger parameterized build on other projects

关键配置:

  • Projects to build

    text 复制代码
    下游 Job 名
  • Add Parameters → Predefined parameters

    text 复制代码
    IMAGE_TAG=${tag}

这里的 ${tag}

  • 来自上游 Job 的参数
  • 或构建过程中生成的环境变量

5.3 下游如何"接住"参数

在下游 Jenkinsfile 中:

groovy 复制代码
parameters {
    string(name: 'IMAGE_TAG', description: '上游传入的镜像 tag')
}

随后在 Pipeline 中即可直接使用:

groovy 复制代码
env.IMAGE_FULL = "xxx/luge.api.consume:${IMAGE_TAG}"

⚠️ 如果 IMAGE_TAG 为空:

  • 说明 上游没有传
  • 或传参方式选错(没用 Predefined parameters)

六、下游 Job:只做部署,不关心构建

4.1 下游 Job 的正确触发认知

下游 Job 不需要监听任何上游

也就是说:

  • ❌ 不要勾选:Build after other projects are built
  • ❌ 不要在 Pipeline 里写 build job:

下游只接受一种触发:

✅ 被上游"点名调用"


4.2 下游 Pipeline 参数定义

groovy 复制代码
parameters {
    string(name: 'IMAGE_TAG', description: '上游传入的镜像 tag')
}

这是整个部署是否成功的 生命线参数


4.3 下游部署核心流程

text 复制代码
接收 IMAGE_TAG
   ↓
拼接完整镜像地址
   ↓
SSH 登录服务器
   ↓
停止旧容器
   ↓
拉取新镜像
   ↓
启动新容器(多实例)

五、为什么会出现「下游 Pending 两个任务」?

这是 Jenkins 的经典误区。

5.1 根因分析

当以下 两种触发方式同时存在 时:

  • 上游:Trigger parameterized build on other projects
  • 下游:Build after other projects are built

结果就是:

同一个构建,被触发了两次

Jenkins 表现为:

  • Queue 里出现两个 Pending
  • Build number 看起来一样
  • executor 不够时尤为明显

5.2 解决原则(记住这句话)

一个下游 Job,只允许有一个触发源

最终推荐:

text 复制代码
上游主动触发  ✔
下游不监听    ✔

六、为什么"我没勾监听,下游还是触发了"?

答案只有一个:

这是上游主动触发的,和监听无关

验证方式:

在下游 Build 页面,你一定能看到:

text 复制代码
Started by upstream project luge.api.consume

看到这行字,说明配置是完全正确的


七、最终推荐的稳定架构(生产级)

text 复制代码
┌──────────────┐
│ 上游 CI Job   │
│              │
│ Docker Build │
│ Docker Push  │
│              │
│ Trigger 下游 │
└──────┬───────┘
       │ IMAGE_TAG
       ▼
┌────────────────────┐
│ 下游 CD Pipeline    │
│                    │
│ SSH + Docker Deploy│
│ Multi Instance     │
│ disableConcurrent  │
└────────────────────┘

并在下游加一道保险:

groovy 复制代码
options {
    disableConcurrentBuilds()
}

八、写在最后:从"能跑"到"体系化"

如果你走到了这里,其实你已经超过了 80% 的 Jenkins 使用者。

再往前一步,就是:

  • 蓝绿发布
  • 灰度切流
  • 失败自动回滚
  • 镜像版本可追溯
  • 发布审计

CI/CD 的本质不是 Jenkins,而是"工程化思维"


九、下一篇可以写什么?

  • Jenkins + Docker 蓝绿发布实战
  • 如何设计可回滚的镜像 Tag 体系
  • Jenkins 参数治理与发布规范
  • 从流水线到发布平台的演进

如果这篇文章帮你少踩一个坑,那它就值了。

相关推荐
_周游2 小时前
Java8 API 文档搜索引擎_1. 项目简介与模块划分
java·搜索引擎·servlet·maven·intellij-idea
惊鸿Randy2 小时前
Docker 环境下 PostgreSQL 16 安装 pgvector 向量数据库插件详细教程(Bitnami 镜像)
数据库·docker·postgresql
hexionly2 小时前
演示工厂模式和策略模式的基本用法
java·简单工厂模式·策略模式·开闭原则
shehuiyuelaiyuehao2 小时前
javaSE大总结
java
Paraverse_徐志斌2 小时前
针对 SAAS 私有化部署,如何优雅合并微服务
java·微服务·架构·saas·私有化
Free Tester2 小时前
在Docker Node环境下安装包
docker·容器
Knight_AL2 小时前
Spring Boot + Docker:实现可挂载可热更新的 config.json
spring boot·docker·json
黎雁·泠崖2 小时前
Java字符串API:String/StringBuffer/StringBuilder详解
java·开发语言