BuildRock:某海外协作平台公司的 Jenkins 构建平台升级实践

📅 2026/7/9 3:38:47 👁️ 阅读次数 📝 编程学习
BuildRock:某海外协作平台公司的 Jenkins 构建平台升级实践

本文介绍某海外协作平台公司如何围绕 Jenkins、Kubernetes、GitOps 和 Build-as-a-Service,对其
构建平台进行升级改造。通过标准化 Jenkins 配置、引入不可变基础设施、强化 SecOps 和左移实践,构建团队显著提升了构建部署效率、安全性、可维护性和平台扩展能力。

构建平台是保障代码高效、安全地部署到生产环境的关键基础设施。随着业务规模不断扩大,这一平台也经历了多次演进。2021 年,构建团队开始从长期视角重新审视构建平台的发展方向。

当时,构建团队希望回答几个核心问题:

  • 我们应该在什么时机投入资源升级构建平台?
  • 构建平台中的技术债务应该如何治理?
  • 在代码构建和部署过程中,我们能否做到更快、更安全?
  • 能否在不影响现有生产构建流程的前提下完成这些投入?
  • 现有的构建方式应该如何演进?

本文将介绍该构建团队如何持续投入 Jenkins 构建平台建设,以解决既有问题,并为未来的规模化发展做好准备。

构建平台的演进背景:从 Jenkins 集群到平台化治理

自公司成立早期以来,Jenkins 就一直被用作核心构建平台。随着业务快速增长,产品和服务对 Jenkins 的依赖不断加深,不同团队也陆续开始使用 Jenkins 完成各自的构建任务。

这些团队的需求各不相同,涉及插件、凭证、安全实践、备份策略、作业管理、软件包与 Jenkins 升级、Jenkins 代理配置、部署变更,以及基础设施问题修复等多个方面。

在早期阶段,这种方式非常有效。每个团队都可以独立定义自己的需求,并快速部署各自的 Jenkins 集群。然而,随着时间推移,管理这些“雪花式”Jenkins 集群变得越来越困难。每个集群都逐渐形成了独特的生态系统:基础设施需求不同、插件版本不同、漏洞处理方式不同,管理流程也各不相同。

这当然并不是理想状态。但它真的已经成为一个迫在眉睫的问题了吗?毕竟,大多数人似乎只是偶尔才会遇到构建基础设施方面的问题。

事实并非如此。设计不佳的构建系统会在日常工作中持续影响用户体验。我们观察到的主要痛点包括:

  • 缺少不可变基础设施,导致构建结果难以保持一致,也让故障排查更加困难。
  • 凭证需要手动添加,使得日后重新创建 Jenkins 集群变得困难。
  • 资源管理不够理想,主要原因是系统仍大量依赖静态云虚拟机作为 Jenkins 代理。
  • 技术债务沉重,导致基础设施变更难以推进。
  • 业务逻辑与部署逻辑耦合在一起。
  • 缺少面向构建系统的备份和灾难恢复策略。
  • 可观测性、日志记录和链路追踪尚未成为标准实践。
  • Jenkins 集群的部署和升级既困难又高风险;由于集群并非无状态,重建过程也十分繁琐,进而阻碍了定期更新和部署。
  • 缺少左移实践,导致问题往往在构建服务部署之后才被发现,而不是在部署之前提前暴露。

从业务角度来看,这些问题进一步带来了以下影响:

  • 事故频发,开发人员生产力下降。主要原因是修改 SSH 密钥等配置、升级软件等操作都比较困难。
  • 大量人力被消耗在运营维护工作上,例如升级、功能添加和配置管理。
  • 资源利用率不理想,现有 Jenkins 服务器上存在较高比例的闲置内存和 CPU 资源。
  • 即使在维护期间,也难以保证 Jenkins 全天候稳定运行。
  • Jenkins 宕机时,CI 构建历史记录等相关数据可能会丢失。
  • SLA/SLO 难以清晰定义,同时团队仍希望对 Jenkins 服务拥有更强的控制力。
  • Jenkins 服务器上存在高危安全告警。

Jenkins 构建平台升级:问题已经明确,该如何解决?

基于上述需求,团队开始探索新的解决方案。但与此同时,团队也清楚地认识到,不能简单地完全抛弃现有构建系统,原因包括:

  • 现有系统总体上仍然可用,尽管仍有许多改进空间。
  • 构建基础设施中的部分脚本位于核心部署流程的关键路径上,替换它们的成本和风险都比较高。
  • 构建基础设施与 Jenkins 生态系统已经深度耦合。
  • 与迁移到一个完全不同的构建系统相比,修复关键问题、升级已部署集群,并在公司内部标准化 Jenkins 配置清单,是资源利用效率更高的选择。

基于这些考虑,团队选择继续围绕 Jenkins 快速构建新构建系统的原型。

从整体设计来看,构建团队希望提供一个“构建即服务”(Build-as-a-Service)平台,并通过足够丰富的参数化能力,让不同团队能够按需定制 Jenkins 集群。

构建平台原型系统的主要特性

团队调研了海外某些公司在构建系统中使用的技术方案,也与海外某些公司进行交流,讨论构建系统相关问题。这些调研帮助团队了解了业界的实践方式,并在可行的情况下借鉴其中的经验。

团队将调研获得的经验记录下来,并与利益相关方和平台用户进行讨论,最终形成了原型系统的核心设计。

无状态、不可变的 CI 服务

通过将业务逻辑与底层构建基础设施解耦,CI 服务实现了无状态化。这不仅提升了构建和部署速度,也增强了安全性,并为左移实践提供了更好的基础,同时提升了整体可维护性。

例如,所有与构建相关的脚本都被迁移到独立仓库中,与业务逻辑代码分离。团队使用 Kubernetes 构建这些 Jenkins 服务,从而更好地解决基础设施不可变性、资源利用效率和高可用性等问题。

此外,系统还尽可能消除了残留状态。每次构建服务时,都会从头开始重新构建,从而保证环境的一致性和可复现性。

静态代理与临时代理

用户可以使用两类 Jenkins 构建代理:

  • 临时代理:基于 Kubernetes 工作节点运行构建任务,并在任务完成后终止。
  • 静态代理:基于云虚拟机实例运行构建作业,作业完成后仍保持可用。

保留静态云虚拟机代理,是为了在全面迁移到临时工作节点之前提供一个渐进式过渡方案。迁移到临时工作节点需要更多改造和测试,因此分阶段推进更加稳妥。

将 SecOps 纳入服务部署流程

在每次构建 Jenkins 服务时执行漏洞扫描至关重要。这确保了安全运维(SecOps)真正成为构建流程的一部分,而不是部署完成后的补救环节。

团队还为每个集群实施了身份与访问管理策略,以及基于角色的访问控制(RBAC)策略。这些机制对于安全地管理集群至关重要。

进一步左移,尽早发现问题

为了避免在后期才发现问题,团队引入了更充分的左移实践。

团队使用覆盖范围较广的测试集群和预部署环境,在正式部署到其他预生产环境之前,先测试 CI 系统中不同影响范围的变更。这样,高风险变更就可以在进入生产环境之前经过更长时间的验证。

用户也可以根据需要,在部署到生产环境之前灵活增加更多阶段。

为了在部署前尽早发现构建基础设施问题,团队引入了大量测试,并提供相应工具,使用户能够在基础设施代码部署之前,在本地调试和修复大多数问题。这有助于提升开发人员效率,并显著改善用户体验。

Jenkins 配置标准化与平台抽象化

标准化意味着同一个修复方案可以统一应用到所有 Jenkins 配置清单中。团队通过 Jenkins Configuration as Code(JCasC)插件实现了这一点。

该插件提供单一 YAML 配置文件,用于管理整个 Jenkins 控制器,从而简化凭证、安全矩阵以及其他 Jenkins 配置的管理。构建团队也与相关开源项目保持密切协作。

集中式插件管理确保所有 Jenkins 实例使用相同版本的插件,避免不同 Jenkins 集群之间出现版本不一致的问题。此外,插件可以自动升级,无需人工干预,也减少了版本兼容性方面的担忧。

Jenkins 状态管理

团队通过托管文件存储服务管理状态。一些构建数据,例如构建历史记录和配置变更,需要进行状态管理。该文件存储服务会定期自动备份,并支持灾难恢复和回滚能力。这对于生产系统至关重要。

GitOps 风格的状态管理

所有构建和运行时配置都不在 Jenkins 控制器中手动维护。团队使用 GitOps 来强制执行这一策略。

由于不允许手动变更,大多数流程反而变得更容易执行。所有变更都从 Git 仓库中获取,Git 仓库也因此成为唯一可信数据源。

配置管理通过模板实现,方便用户创建集群,并复用已有配置和子配置,从而轻松完成配置变更。团队使用 Jinja2 实现了这一能力。

所有基础设施运维都基于 Git,并采用 GitOps 模型。这意味着整个构建基础设施可以从零开始重建,而且每次都能得到完全一致的结果。

构建平台的配置管理与可观测性

每个集群都启用了相关指标、日志记录和链路追踪能力,以便进行调试。团队使用 Prometheus 管理指标,使用 ELK 技术栈处理日志,并使用某可观测性平台进行链路追踪。

集中式凭证管理使得凭证能够在适用场景下被轻松复用。由于所有内容都包含在容器镜像构建文件中,升级 Jenkins、操作系统、软件包和插件都变得更加简单快捷。

服务构建与部署能力

每个服务负责人都可以完全掌控其服务的构建和部署时机。该流程是可配置的,服务负责人可以根据需要,在某代码托管平台发生代码推送时触发服务构建或部署。

对于某些使用场景,立即迁移到 Kubernetes 并不现实。好在原型系统支持“原地容器化部署”(container-in-place deployment),这为后续迁移到 Kubernetes 奠定了重要基础。

引入更广泛的设计评审

该方案及其设计在公司内部进行了广泛的设计评审,内部员工以及指定的资深开发人员都可以提供反馈。

这帮助团队更深入地理解客户使用场景、设计决策对服务团队的影响,以及构建平台的扩展技术等问题。

分布式所有权:构建团队是否需要承担大量管理工作?

答案是否定的。

团队开始尝试一种分布式所有权模型。构建团队负责管理构建平台基础设施中的核心系统,其余系统则由使用构建平台的服务团队负责。

这种模式既能保证平台核心能力的一致性和可靠性,也能让服务团队在自身业务范围内拥有足够的自主权。对于需要进一步打通需求、开发、测试、发布和知识沉淀的研发团队,也可以借助 Pingcode这样的智能化研发管理工具,将构建平台产生的数据与研发全流程连接起来,更好地度量和提升研发效能。

构建平台升级带来的业务价值

影响是多方面的,其中最重要的一点是缩短产品上市时间(TTM)。各个服务不仅可以快速构建和部署,而且能够以更安全、更可靠的方式完成这些操作。修复安全漏洞所需的时间也显著缩短。

Jenkins 配置清单的标准化减少了维护整个集群所需的代码路径。以下是一些指标:

基础设施变更可以快速实施,并在必要时迅速回滚。

将新技术推广到现有基础设施中是否困难?

当然困难。团队在这一过程中遇到了不少挑战,也从中总结出许多经验:

  • 团队必须熟悉 Kubernetes,并在需要时为其他团队提供培训。
  • 为了让其他团队能够真正拥有基础设施,文档质量必须足够高。
  • 添加临时 Jenkins 代理颇具挑战性,因为这涉及对现有云虚拟机 Jenkins 代理进行逆向工程和重新实现,过程非常耗时。为了解决这个问题,团队采用了增量式方法:先将 Jenkins 控制器迁移到 Kubernetes,再将 Jenkins 代理迁移到 Kubernetes。
  • 团队必须为用户提供非常可靠的调试指南,因为在 Kubernetes 中调试与处理云虚拟机实例有很大不同。
  • 团队需要积极参与相关开源社区,了解其他团队和公司是如何解决类似问题的。在线交流渠道对于快速获得答案非常有帮助。
  • 迁移生产服务时必须格外谨慎,因为其中一些服务对于维持核心业务正常运行至关重要。
  • 团队搭建了新的构建基础设施,并统一了配置,使各团队能够轻松且有信心地测试各自工作流。
  • 在相关利益方完成工作流测试后,团队重新指定端点,并将旧基础设施切换到新基础设施。
  • 团队保留了旧基础设施,并将其置于不承载流量的服务端点之后作为备用方案,以便在需要时快速回滚。
  • 团队定期举办培训课程,与所有相关人员分享经验。
  • 团队意识到,现有构建脚本可以在新环境中复用,这意味着无需强迫用户学习并不必要的新内容。
  • 团队与用户紧密合作,帮助他们梳理问题并完成迁移。这有助于与用户社区建立良好关系。用户也积极为新框架做出贡献,添加他们认为重要的功能。
  • 在初期,培养 GitOps 思维方式具有一定挑战性,主要原因是团队长期以来已经形成了传统操作习惯。
  • 指标、日志记录和告警是大规模集群管理的关键。
  • 自动化测试是确保流程正确执行的关键,尤其是在越来越多用户参与进来的情况下。

在这类跨团队迁移过程中,任务拆解、文档沉淀、日程安排、审批流转和工时协同同样重要。对于需要统一管理这些协作事项的团队,可以使用
Worktile 这样的通用项目协作系统,减少复杂迁移过程中的信息断层。

作为第一步,团队先将几个现有的生产构建集群迁移到新方案中。这帮助团队学习并收集了宝贵反馈。

与此同时,所有新集群也都开始使用本文介绍的新系统构建,这显著提升了核心功能的交付速度。

目前,团队仍在继续推进所有服务向新构建系统的迁移。同时,团队也在尝试增加更多能力,以减少维护和自动化相关的手动工作。

未来,团队希望为 MLOps、SecOps 以及其他运维团队提供构建即服务(Build-as-a-Service)能力。这样,用户就可以专注于业务逻辑,而无需担心底层基础设施问题。这也将帮助公司进一步缩短产品上市时间(TTM)。

总结:构建平台升级的核心启示

这次构建平台升级表明,企业在治理 Jenkins 构建平台时,不一定要完全推翻现有体系。通过 Kubernetes、GitOps、标准化配置、不可变基础设施和 Build-as-a-Service 等方式,团队可以在保留既有能力的基础上,逐步提升构建平台的安全性、稳定性和扩展性。

对于正在推进 CI/CD 平台治理、Jenkins 集群标准化或构建平台现代化的技术团队而言,这一实践提供了一个可参考的渐进式升级路径。