本文介绍某海外协作平台公司如何围绕 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 CodeJCasC插件实现了这一点。该插件提供单一 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 集群标准化或构建平台现代化的技术团队而言这一实践提供了一个可参考的渐进式升级路径。