JENKINS / 从第一次成功构建开始

Jenkins 基础概念,一张张图看懂。

先认识 Job、Build、Pipeline、Controller、Agent 等核心概念,
再对照 Jenkinsfile,理解你刚跑通的 Hello World。

配套知识点:约 20 分钟本页:7 张图 + 18 张核心概念卡无需安装插件 · 可离线打开
01 / 基础概念全景

Jenkins 是什么?先把“事、人、地方、结果”分清。

Jenkins 是自动化调度工具:收到触发后,按你写的流程安排工作,并记录结果。把它想成一个调度中心:Job 是工作单,Pipeline 是操作清单,Build 是一次实际执行;Controller 负责安排,Agent 负责执行。

Jenkins 核心概念与关系总览触发器触发任务,任务使用流水线定义产生一次构建,控制器调度需要节点的工作,在队列等待资源,Agent 在节点的工作区执行,结果可归档为产物。Trigger · 触发器什么时候开始?点击 / GitJob · 任务保存一项可重复执行的工作Pipeline · 流水线定义阶段与步骤Build · 一次运行这次执行:#1 / #2 / #3Controller · 控制器管理任务、安排执行Queue · 等待队列等待匹配节点与空闲执行槽Node · 一个登记的执行环境Agent · 执行代理连接控制器,执行分配的工作Workspace · 工作区源码和生成文件的操作目录Artifact · 归档产物保存到某次 Build 的结果触发使用产生一次运行由它调度需要节点的工作分配工作在此执行文件操作归档保存Label 是节点的匹配标签;Executor 是节点可承接工作的执行槽。图中是独立 Agent 的常见模型;Hello World 暂时使用控制器内置节点。

核心术语卡:一个词,回答一个问题

Job / 任务

做什么工作?
例如 hello-world,是可以反复运行的任务。

Build / 一次运行

这一次发生了什么?
例如 hello-world #2,有自己的参数、日志、结果。

Pipeline / 流水线

按什么流程做?
完整流程定义;Jenkinsfile 是保存它的文件。

Stage / 阶段

工作分成哪几段?
例如 Hello、Shell、Artifact,用来组织操作。

Step / 步骤

具体执行哪条操作?
例如 echo、sh、writeFile;阶段名本身不会做事。

Controller / 控制器

谁负责管理和调度?
提供 Jenkins 网页,管理任务与执行记录。

Node / 节点

有哪些执行环境?
可以是物理机、虚拟机或容器环境,不专指云服务器。

Agent / 代理

谁执行分配的工作?
连接控制器的执行程序;日常也常指其所在环境。

Executor / 执行槽

能同时承接多少工作?
像工位,不等同于 CPU 核;没有空位就可能排队。

Label / 标签

这份工作交给谁?
mac-local 用于匹配节点,不会自动创建 Agent。

Workspace / 工作区

执行时在哪读写文件?
在执行节点上;可被清理,不适合当永久存储。

Artifact / 产物

哪些结果值得保存?
hello.txt 归档后属于对应 Build,能从详情页下载。

Parameter / 参数

这次让用户输入什么?
NAME 是本次问候对象,不改变 Job 的身份。

Environment / 环境变量

步骤使用什么运行环境?
env.BUILD_NUMBER 是编号,IMAGE_TAG 可作为镜像标签。

Credential / 凭据

访问外部系统用什么身份?
保存 token、密码或私钥,流水线通过凭据 ID 引用。

Plugin / 插件

Jenkins 要扩展什么能力?
如 Pipeline、Timestamper;不等于安装了节点命令。

SCM / 源码管理

代码和流程定义从哪来?
例如 Git;网页粘贴模式不会自动读取本地文件。

Trigger / 触发器

什么时候运行?
手动点击、定时、SCM 轮询或配置好的 webhook。

02 / 从概念对应到代码

看 Jenkinsfile 时,把语法翻译成问题。

这张图是语法对照表,不是一段完整脚本。Hello World 已使用其中大部分;environment 会在 Go 应用案例中出现。先看懂“在哪做、做什么、怎么收尾”,不必先学完整 Groovy。

Jenkinsfile 语法与基础概念逐行对应十组写法分别对应整体流程、执行位置、输入参数、环境变量、阶段、步骤、文件产物、运行规则和收尾逻辑。pipeline { ... }整体流程把本次流水线的配置组织起来agent any执行位置申请合适的可用节点,不保证是 Macparameters { ... }运行输入定义 NAME;params.NAME 读取本次值environment { ... }环境变量例如 IMAGE_TAG;供步骤和子进程读取stages { ... }阶段集合按顺序组织 Hello、Shell、Artifactstage('Hello') { ... }一个阶段名称便于看进度;里面还要写操作steps { echo ...; sh ... }具体步骤echo 写日志,sh 在节点运行 ShellwriteFile / archiveArtifacts生成与保存前者写工作区文件,后者归档构建结果options { ... }运行规则例如日志时间戳、超时和历史保留post { success / failure }按结果收尾用对应代码块输出结果或清理你在 Jenkinsfile 里看到的写法它对应的概念和用途
03 / WHAT

任务可以反复运行,每次都有自己的记录。

Job 是保存的工作,Pipeline 是工作流程,Build 是这次执行。下面展开一次 Build,才能看到各个 Stage 和 Step。

任务、流水线与一次运行一个任务使用流水线定义,产生多次构建;展开其中一次构建,可见 Hello、Shell、Artifact 三个阶段及其步骤。展开 Build #2:按流水线定义执行Job · 固定的任务hello-world可以反复运行Pipeline · 流程定义网页脚本 / Jenkinsfile定义要做哪些事Build · 一次运行#1、#2、#3……每次都有日志与结果使用执行展开 #2Stage:HelloStep:echo 问候Step:echo 构建编号Stage:ShellStep:sh 执行命令whoami / java -versionStage:ArtifactStep:writeFileStep:archiveArtifactsStage 是一组操作;Step 才是具体操作。任务可以不编译任何代码,Jenkins 仍把一次运行叫 Build。

Job:要做的工作

例如首页里的 hello-world。下次点击构建,仍然运行同一个任务。

Pipeline:怎么做

定义阶段与步骤。Stage 的名字可以自定义,步骤才决定实际行为。

Build:做了一次

#1 和 #2 可以输入不同的 NAME,各有自己的日志、状态与产物。

04 / WHERE

浏览器是遥控器,执行节点才是工作的地方。

以下对应尚未添加独立 Agent 的 Hello World 环境。Mac 上打开 Jenkins,不代表 Shell 就在 macOS 上运行。Docker Desktop 的 Linux 容器底层由 Linux 虚拟机承载,此处省略该层。

Hello World 实际在哪里执行Mac 浏览器访问 Docker 内的 Jenkins 控制器,当前内置节点执行 Shell;工作区文件及构建归档保存在挂载的数据卷中。你的 Mac:浏览器与 Docker 都在这台主机上Jenkins 容器 · Linux 执行环境浏览器点击 Build NowController接收任务、调度、记录内置节点 / Executor当前案例由这里运行 shWorkspace · 工作区writeFile 在这里生成 hello.txtJenkins 数据卷 · 容器重建后仍可保留/var/jenkins_home:配置、历史、当前内置工作区、归档等HTTP分配配置与构建记录工作区也在挂载目录下青色:操作与调度 绿色:执行与工作区 紫色:保存数据

Workspace:操作目录

执行节点上的工作目录。writeFile 在这里生成文件,pwd 可以告诉你实际位置。

Artifact:归档结果

archiveArtifacts 将文件保存到对应构建记录,可在详情页下载。它不是永久备份。

Executor:可用工位

节点有空闲执行槽,任务才有机会开始。Label 用于匹配节点,不会替你创建节点。

05 / WHEN & RESULT

按顺序运行,也要知道在哪一步停止。

图中表示当前顺序流水线的普通成功与失败路径。catchError 等显式错误处理可以改变流程;超时、取消和节点失联也有不同处理情况。

一次构建的执行与失败路径触发、等待资源、分配工作区、执行阶段;普通失败跳过后续阶段,并在相应 post 块进行收尾。① 触发点击 / 定时 / Git② 等待资源节点在线、标签匹配③ 分配工作区节点上准备执行目录④ 执行步骤把步骤日志写入本次记录当前 Stage执行 echo / sh 等 Step后续 Stage普通成功路径post.success / always运行成功收尾普通未捕获失败 → 跳过后续正常阶段例如:sh 中 exit 1;错误处理可以改变此行为post.failure / always运行失败收尾通过失败失败先看具体 Build 的 Console Output;最后一行通常只是结果。

触发 ≠ 一定立刻开始

节点离线、标签不匹配、执行槽忙,都可能导致等待。排队不等于代码执行失败。

SUCCESS ≠ 自动上线

它表示你配置的步骤成功。没有部署步骤,就不会因为显示成功而更新应用。

看错误,要看上下文

Console Output 中找到最早的关键错误,再确认阶段、节点、用户、目录和退出码。

定时构建和 SCM 轮询一样吗?

定时构建按时间发起运行;SCM 轮询定期检查仓库,有相关变化才触发。Webhook 则由 Git 服务发通知。三者都需要正确配置。

UNSTABLE 和 ABORTED 是什么?

UNSTABLE 常表示测试报告等标记出问题,不保证后续阶段自动跳过。ABORTED 表示被中止,例如停止构建或超时。

06 / NEXT STEP

构建出镜像之后,还要部署,再验证。

Go 案例让 Mac Agent 调用 Make 和 Docker。控制器负责调度;Go 工具负责测试与编译;Docker 负责镜像与容器;Compose 描述如何运行应用。

从 Hello World 到 Go 应用的构建部署控制器调度 Mac Agent,Agent 调用 Docker 测试、构建镜像,再调用 Compose 部署,最后验证实际服务版本。本地阶段:同一台 Mac 承担构建和部署Jenkins 控制器仍运行在 Docker 中负责调度和记录Mac Agent:mac-localMac 原生 Java 进程在工作区执行 make / dockerTest / BuildDocker 构建阶段Go 测试、编译、打包本地 Docker 镜像jenkins-goapp:build-N此时尚未说明部署完成Deploy:更新容器Mac Agent 调用 Compose使用指定镜像并等待健康Go 应用容器Mac 的 localhost:8081Verify:实际请求检查健康状态与版本分配任务使用镜像同一 Docker 引擎可以直接使用本地镜像;跨机器时才需要补上镜像分发。
CI · 持续集成

代码合入时自动构建和检查,尽早暴露问题。第一步先把测试与打包做好。

CD · 持续交付

让验证过的版本处于可发布状态。正式发布可以保留人工决定。

CD · 持续部署

通过检查的变更自动发布到目标环境。说 CD 时,要确认指的是哪一种。

07 / REAL SERVER

构建留在 Mac,应用运行到真实服务器。

Step 3 位于独立目录 goapp-server/,自带源码与构建配置;Step 2 的 goapp/ 保留 Mac 本地部署。新案例通过你配置的私有仓库 push/pull 分发镜像。Jenkins 仍调度 Mac Agent;Mac 上的 SSH 命令在服务器执行 Docker 部署操作。

通过可配置私有镜像仓库部署Mac 构建并 push 私有仓库;服务器 pull 固定 digest,部署并验证。SSH 只传配置、执行命令,回退重新拉取旧 digest。Mac · Jenkins Agent(构建机)Linux 服务器 · 独立 Docker 引擎与只读仓库身份测试与目标架构构建TARGET_PLATFORM 指定目标Push · 推送Jenkins 仓库写入凭据你的私有镜像仓库REGISTRY_HOST / REGISTRY_REPOSITORY推送后保存 digest:仓库@sha256:…Pull · 固定 digest拉取失败则停止部署Compose 更新容器检查目标架构、等待健康服务器 HTTP 验证健康状态与版本均需正确记录成功发布回退重新 pull 旧 digestSSH:部署配置与命令不承载镜像内容虚线:SSH 控制路径;实线:镜像分发与部署流程。浏览器通过 SSH 隧道访问;私有仓库登录与服务器 SSH 登录是两套凭据。

构建机 ≠ 部署机

Mac 将镜像 push 到 REGISTRY_HOST / REGISTRY_REPOSITORY;服务器独立登录并 pull。SSH 只发送部署配置。

按目标架构构建

Apple Silicon 常为 arm64,云服务器可能是 amd64。TARGET_PLATFORM 按服务器选择,脚本会检查。

SSH 与仓库分别认证

SSH 私钥与 known_hosts 校验连接身份。仓库另设凭据:Jenkins 可 push,服务器使用只读 pull 账号。

localhost 属于当前机器

服务器自检不等于 Mac 本地访问。SSH 隧道把 Mac 的 18081 转到服务器的 8081。

回退使用成功发布

发布记录固定 digest 和 Compose。server-rollback 从仓库拉取旧 digest;仓库需保留该镜像。

current 是成功记录

失败部署可能已经替换容器。current 仍指向上次成功版本,不能替代 Docker 实时状态检查。

08 / CHECK YOUR UNDERSTANDING

能回答这三题,就可以继续 Go 案例了。

我在 Mac 浏览器点击构建,为什么 uname -s 显示 Linux?

浏览器只是操作入口。当前 Hello World 在 Jenkins 容器的内置节点运行 Shell,因此看到的是容器的 Linux 环境。

第 2 次构建修改了 NAME,第 1 次 hello.txt 会变吗?

已归档到第 1 次构建的文件不会因为这次写工作区文件而变化。历史记录和产物仍可能被保留策略清理。

镜像已经 build 成功,为什么页面还显示旧版本?

构建只是得到软件包。还要在正确环境更新应用容器,并验证实际响应中的版本;Go 案例的 make verify 就是在检查这个结果。

建议下一步:在 Hello World 中观察 pwd、whoami、uname -s,再临时用 sh 'exit 1' 观察一次失败。做完后恢复脚本。

阅读完整知识点与练习 → 进入 Go 本地案例 → 进入真实服务器案例 →