彭大帅的CI/CD实战第4篇 构建节点:SSH 纳管与 Maven 环境
一台纯构建机:控制器不动手,干活的另有其人
系列第 4 篇 · 共 10 篇
环境版本:Maven 3.6.3 / OpenJDK 21.0.13 / Jenkins agent over SSH
目 录
一、角色定位:为什么要单独一台构建机
第2篇 GitLab → 第3篇 Jenkins 控制器 → 第4篇 构建节点 ◀── 你在这里
第5篇 双活集群 → 第6~8篇 流水线 → 第9篇 重建与运维
本篇的主角 build-agent(主机名 jenkins-agent,10.10.10.78)是一台「纯构建机」,只做一件事:把源码编译成 war 包。控制器与构建机分离,不是架构洁癖,而是实实在在的收益:
| 对比项 | 单机(控制器兼构建) | 分离(本方案) |
| 编译压力 | 拖慢 Jenkins 界面与 Webhook 响应 | 控制器保持轻量响应 |
| 工具链 | Maven/JDK 与 Jenkins 版本互相牵制 | 构建机可随时换 JDK/Maven 版本 |
| 扩容方式 | 只能垂直升级 | 加同 label 节点即横向扩容 |
| 故障域 | 控制器挂 = 全部挂 | 构建机挂只影响任务排队 |
扩容机制特别说一下:Jenkinsfile 里写的是 agent 标签 build-agent,将来要提升并发,再加一台同样打这个标签的节点即可,流水线一个字不用改。当前 1 台节点、每节点 2 个执行器。
二、系统准备:三件工具一次装齐
hostnamectl set-hostname jenkins-agent
dnf install -y java-21-openjdk java-21-openjdk-devel maven git
java -version # openjdk version "21.0.13"
mvn -v # Apache Maven 3.6.3 (Red Hat 3.6.3-23)
git --version # git version 2.52.0
一个 Rocky 9 专属细节:这里的 Maven 是打包版,安装时会自动带上 maven-openjdk21 适配包:
rpm -qa | grep maven
# maven-3.6.3-23.el9
# maven-openjdk21-3.6.3-23.el9 <- JDK21 适配,关键
如果不装这个适配包,Maven 会去找老版本 JDK 的 tools.jar 路径然后告警——JDK 9 以后根本没有 tools.jar。rpm 打包版自动处理了这个兼容性,这也是本系列坚持「能 rpm 就不 tar」的又一个理由。
三、Jenkins 侧纳管(SSH 方式)
操作路径:Manage Jenkins → Nodes → New Node。节点类型选固定节点,启动方式选「通过 SSH 启动 agent」——这种方式不需要在构建机上装任何守护进程,控制器主动 SSH 过来拉起 agent 进程。
本机实际落盘的节点配置(/var/lib/jenkins/nodes/build-agent/config.xml)关键项与选择理由:
| 配置项 | 取值与原因 |
| Remote root directory | /data/jenkins——独立目录,便于单独扩容和清理 |
| Labels | build-agent——Jenkinsfile 用它精确调度 |
| 执行器数 | 2——1 核小机跑 2 并发比较稳妥,再多互相抢 CPU |
| 凭据 | build-agent-ssh-key(SSH 私钥类型) |
| Host Key 验证 | Non verifying——实验环境避免指纹变更卡住;生产建议启用 known_hosts 校验 |
三个前置条件,缺一个连接必失败,先在构建机上做好:
# 1) 工作目录存在
mkdir -p /data/jenkins
# 2) sshd 在跑、22 端口通
ss -lntp | grep :22
# 3) 免密私钥(在控制器上生成并分发)
ssh-keygen -t rsa -b 4096 -f ~/.ssh/jenkins_agent -N ""
ssh-copy-id -i ~/.ssh/jenkins_agent.pub root@10.10.10.78
然后把私钥内容粘进 Jenkins 凭据(类型:SSH Username with private key,ID 填 build-agent-ssh-key,用户名 root)。
安全提示必须说透:凭据指向 root,意味着构建进程以 root 身份运行(实测工作区属主就是 0:0)。这是本环境最大的安全待优化项——构建代码可以执行任意逻辑,root 身份等于给它整个系统的权限。整改方向是建专用低权账号,第 9 篇优化清单里登记了此项。
四、工作目录结构与 @tmp 坑
节点跑起来后,/data/jenkins 里会长出这样的结构(实测):
/data/jenkins/
workspace/cicd-demo/ # 流水线工作区(clone 下来的源码)
workspace/cicd-demo@tmp/ # 流水线临时脚本目录
workspace/test-agent-env/ # 节点可用性验证用的测试任务
重点认识 @tmp 目录:它是流水线 sh 步骤临时脚本的存放处。两个规则:构建执行中删它会导致构建异常退出;清理残留要在没有构建运行时进行。安全做法是先查节点空闲再删:
curl -s -u "peng:<TOKEN>" \
http://10.10.10.77:8080/computer/build-agent/api/json \
| tr "," "\n" | grep idle
五、Maven 本地仓库与镜像加速
首次构建会把依赖下载到本地仓库,之后构建秒级完成(本环境预热后仓库仅 28M,因为 demo 项目的 pom 很轻):
du -sh ~/.m2/repository # 28M(预热后)
实测 /etc/maven/settings.xml 未配置镜像,依赖直接从 Maven Central 拉。内网环境出网慢的话,首次构建可能卡在依赖下载上(流水线里有 20 分钟超时,超了直接失败)。建议提前配阿里云镜像,往 settings.xml 的 mirrors 段加入:
<mirror>
<id>aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Aliyun Maven</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
六、验证节点可用
三种方式,由浅入深:
- 看状态:Manage Jenkins → Nodes → build-agent 显示在线。
- 查 API:
curl -s -u "peng:<TOKEN>" \
http://10.10.10.77:8080/computer/build-agent/api/json \
| tr "," "\n" | grep -E "idle|offline|numExecutors"
- 真跑一次:建一个临时任务执行环境自检命令,本机保留的 test-agent-env 任务就是干这个的,可随时复测:
java -version && mvn -v && git --version
七、排障速查
节点连不上或构建跑不动,先对这张表(全部来自实测环境验证过的现象):
| 现象 | 排查命令 / 原因 |
| 节点离线,日志 Auth fail | 凭据错误或用户无 SSH 权限;手动 ssh -i 私钥 root@10.10.10.78 复现 |
| Connection refused | sshd 未启动或端口改过 |
| Unable to create directory | /data/jenkins 不存在,或该 SSH 用户无写权限 |
| 构建报 java: command not found | agent 的 PATH 不含 JDK;确认 java-21-openjdk 已装 |
| 构建卡在 clone | 构建机到 GitLab 80 不通;curl -I http://10.10.10.76 验证 |
| 构建卡在 mvn 下载 | 无外网或未配镜像;curl -I 验证 Maven 仓库可达性 |
| 磁盘打满 | /data/jenkins 与本地仓库持续增长;du -sh 分目录排查 |
读法提示:这些现象分别对应第 1 篇端口矩阵里的两条链路——构建机到 GitLab(clone)、构建机到外网(依赖下载)。环境问题九成能在这张表里对号入座。
八、本章验证
构建节点就绪的验收标准,四条:
- 节点 build-agent 在线,label 正确,执行器数 2。
- 临时任务在节点上跑通 java、mvn、git 三件套自检。
- 构建机到 GitLab 的 80 端口可达(clone 链路通)。
- Maven 依赖下载链路可达(配了阿里云镜像或确认外网通畅),本地仓库预热完成。
至此,链路的「大脑」和「双手」都齐了。下一篇搭最后一块基础设施:双活 Web 集群——发布的终点站。
更多推荐
所有评论(0)