在 Debian 上构建高可用的 Jenkins 实践
一 架构选型与总体思路
- 将系统拆分为两层:
- 控制面高可用:对外提供稳定的 HTTP(S) 访问 与 Agent 入站通道;
- 构建面弹性扩展:通过 Master–Agent(Controller–Agent) 分布式执行,将构建负载从控制器卸载到多个代理节点。
- 在 Debian 上常用做法:
- 使用 Nginx/HAProxy 做前端负载均衡与健康检查,对外暴露 8080(Web)与 50000(JNLP/代理入站)端口;
- 控制器层建议 Active/Standby 双实例 + 共享存储(如 NFS/块存储)以共享 JENKINS_HOME;
- 构建任务全部在 Agent 上执行,控制器尽量不做构建;
- 如需更强的弹性与自愈,可在 Kubernetes 上运行控制器(StatefulSet + PVC)与弹性 Agent(Kubernetes 插件动态 Pod)。
二 前置条件与基础加固
- 系统与资源:
- 推荐 Debian 11/12,安装 OpenJDK 11(生产建议 4–8 GB 内存、SSD 存储);
- 安装与启动:sudo apt update && sudo apt install openjdk-11-jdk jenkins -y && sudo systemctl enable --now jenkins。
- 端口与连通性:
- 开放 8080/TCP(Web)与 50000/TCP(Agent 入站);如使用防火墙(如 ufw),放行端口并确保控制器与代理可互通。
- 安全基线:
- 禁用匿名访问,启用基于角色的访问控制(如 Role-Based Strategy);
- 使用强凭据与凭据集中管理,限制构建节点的系统权限;
- 定期更新系统与插件,降低漏洞风险。
三 控制面高可用部署步骤
- 共享存储与目录:
- 准备 NFS 或块存储,将 /var/lib/jenkins 挂载到共享卷,使 Active/Standby 实例看到同一份配置、作业与插件;
- 首次初始化建议只在一个实例完成(解锁、安装插件、创建管理员),完成后另一实例即可读取同一数据目录。
- 前端负载均衡:
- 以 Nginx 为例(HTTP 层):
- 配置 upstream 指向两个控制器实例,开启 HTTP 健康检查 与 会话保持(如基于 IP 的 hash);
- 对外暴露 80/443,反向代理到 8080;
- 以 HAProxy 为例(支持 TCP 转发):
- 配置 frontend 监听 8080/TCP 与 50000/TCP,分别转发到后端控制器池;
- 开启 health check 与 maxconn,避免单点拥塞。
- 控制器实例要点:
- 两个实例以 不同主机名 运行,挂载同一 JENKINS_HOME;
- 避免同时写同一目录(通过外部 LB 保证同一时刻仅一台对外提供写入);
- 建议将 JVM 堆 设置为物理内存的约 50%(如 4 GB 内存可设 -Xmx2g),并开启 GC 日志与监控。
四 构建面扩展与弹性
- 分布式 Agent 接入方式:
- SSH 方式:在控制器上生成 SSH 密钥,将公钥分发到各 Agent(如 /home/jenkins/.ssh/authorized_keys),在 Jenkins 中新增节点选择 Launch agents via SSH,配置并发构建数与工作目录;
- JNLP/入站方式:在 Agent 上启动 agent.jar 连接控制器的 50000/TCP,适合受限网络或临时节点。
- 规模化与弹性:
- 按技术栈与项目划分 标签(Label),在 Job/Pipeline 中使用 agent { label ‘xxx’ } 绑定;
- 需要更高弹性时,使用 Kubernetes 插件 动态创建/销毁 Pod 模板 作为临时 Agent,实现按需扩缩;
- 代理节点按需安装 JDK、Maven、Node、.NET 等构建依赖,保持与项目一致的环境镜像/模板。
五 备份恢复与日常运维
- 备份策略:
- 定期备份 JENKINS_HOME(含 jobs/、plugins/、config.xml、secrets/ 等),建议每日增量、每周全量,并保留 ≥30 天;
- 备份窗口避开构建高峰,备份完成后进行 恢复演练 校验可用性。
- 日志与监控:
- 使用 logrotate 管理 /var/log/jenkins/jenkins.log(如每日轮转、保留 7 天、压缩);
- 将日志接入 ELK/Graylog,并设置 告警(如构建队列过长、节点离线、磁盘空间不足);
- 配置 监控探针(HTTP 200/500、50000 端口连通性、JVM 堆与 GC 指标)。
- 升级与变更:
- 遵循“先备份、后升级、滚动切换”的流程:先在 Standby 验证插件与 Job 兼容性,再通过 LB 切换流量,验证无误后升级原 Active;
- 插件采用“少量、可回滚”的策略,变更前在测试环境验证。