私有化交付平台——概述篇
目录
打造面向私有云的包管理器,降低研发成本,提升交付效率。
私有化交付
私有化是ToB、ToG类业务的主要落地方式,而私有化交付旨在将业务系统提供给客户,即将公司研发的业务系统部署到客户现场的私有云上,以在其内部提供服务。
通常,私有化交付步骤包括私有场景下环境的构建、业务服务配置、业务系统部署、业务系统运维等。其前置条件为业务系统的研发与系统的质量测试。
私有化交付平台将上述交付流程集成到一个平台上,客户可以在这一平台上完成系统的配置、部署、运维、更新等操作,以提升交付效率。
私有化困境
私有化交付模式下的一个核心痛点是公司必须维护业务系统的多个版本,无法通过统一的”上线”流程将所有现场的版本都更新到最新版本。这是因为:
- 大量客户现场存在定制化功能,很难将这些定制化功能移植到一个通用的最新版本上。
- 某些版本间存在不兼容变动,涉及数据迁移等操作,而众多的客户现场会放大相关人工成本。
- 很多私有化项目以满足合同为首要目的,只要系统不出大问题,甲方不会主动要求升到最新版本;而乙方也不会为了取悦客户而耗费人力对客户现场的系统进行升级。
此外,根据公司的业务性质和技术形态,还存在如下的挑战:
- 很多客户现场的网络无法连接到互联网,比如对安全性要求较高的公网系统、政府系统等。无法通过远程的方式连到客户现场进行操作,只能通过人工出差或远程指导的方式运维,效率较低。
- 在容器平台百花齐放的早期时代,很多公司会选择自研容器部署平台。而当前K8S已成为云原生容器平台的标准,向云原生演进过程中,无法避免容器平台的迁移。此外一些私有化场景可能会要求由其提供诸如K8S集群用以部署业务应用,因此研发及部署需要考虑面向底座平台的可扩展性。
微服务困境
微服务架构因其职责单一、灵活性强、可以独立扩展、支持多种语言的优点,成为云原生核心技术之一,并广受开发者的拥趸。但是对于规模较大的系统而言,尤其对于私有化场景下的微服务部署而言,其面临大量挑战:
- 部署工作量大。大型系统一般会有近百个微服务,每个服务又有数十个配置,这种规模的系统部署起来工作量极大。如果扩散到多个私有化场景,在没有高效的部署工具的帮助下将会是一场灾难。
- 服务间依赖关系错综。微服务能替代原有的单体结构的核心在于服务间通信,这就带来的服务依赖的问题,比如业务应用会依赖数据库服务。这种依赖会影射到API兼容性、部署顺序等限制,给微服务管理带来挑战。
- 服务版本管理困难。在某个版本的系统中,每个服务的版本都是固定的,以确保每次交付的系统都是具有确定性的。但私有化场景下经常会存在一些升级需求,比如更新数据库版本以修复某个安全漏洞、更新业务服务版本以增加某个功能。这就意味着系统可能存在很多新旧版本混合的服务。QA很难对所有组合进行集成测试,这就意味着服务升级需要保证兼容性,即版本的定义需要满足一定的规范,比如semantic version。
- 系统发布风险高。在大规模的微服务下,每次系统发布需要协调各个服务的开发方,一旦一个服务没有按时ready,发布便存在延期的风险。
- 服务复用率低。公司内存在多个产品线,因私有化交付无法在公司内提供统一的基础设施,很多产品线不得不维护各自的基础设施。
平台设计理念
为解决私有化交付中版本管理难、部署难、发布难的问题,同时为了提升研发效率、发布效率、可维护性,本平台提出了如下设计理念:
- 我们需要一个公司级的软件包管理平台,提供统一的版本发布、打包和依赖管理机制。提高基础组件的复用率,解决软件之间依赖混乱等问题,同时降低因版本升级、维护不确定性带来的心智负担。
- 我们需要一个高效的部署工具,理想情况下可以做到一键配置并部署一个大型系统。
- 参考云原生理念中的声明式API和不可变基础设施,我们需要一个保证确定性的部署工具,一个环境下的多次部署行为应该是结果确定的,不应存在“惊喜”。
- 我们需要一个通用的编排底座,规范协议和接口,以节省掉一个产品就要一套编排工具带来的重复工作。
- 我们需要屏蔽掉底层不同容器平台(比如Docker Swarm和K8S)带来的差异,降低交付人员的心智负担,更无感地迈向云原生生态。
- 我们需要一个服务管理工具,为升降级、扩缩容、部署配置更新、备份等功能提供通用框架,而不是每个团队各自开发一套。
Why Not Helm?
Helm作为K8S的包管理器,为云原生应用部署提供了便捷。使用Helm可以很便捷地将一个复杂的应用部署到K8S上。就像npm一样,管理着多个版本的同时解析复杂的依赖关系,通过一键安装提升用户体验。
Helm可以满足我们对交付平台的绝大多数要求,但是存在如下几个限制:
- Helm专用于K8S平台,适配其他容器平台需要通过operator等方式,复杂度较高。
- Helm chart目前仅支持go template模板语言,对于复杂逻辑的编写十分不友好。
- Helm通过subchart实现依赖管理机制,此机制不支持递归依赖解析,必须将所有依赖拍平,无法实现模块级产品复用。
- Helm chart对依赖更新的限制较高,更新必须从顶级chart进行,对于细粒度升级场景不友好。
- Helm chart的values传值机制不够灵活,通常我们希望仅在顶级chart上暴露常用的配置,将其传递给所依赖的组件。chart具备向单个依赖传值的能力,但是并不具备单个value向一组依赖传值的能力(比如通过一个mode配置控制应用部署的形态,而globals values会破坏chart通用性)。
核心Features
- 支持starlark模板语言定义组件包,语法类似python,降低入门门槛。
- 支持深层依赖管理和版本解析,便于复用模块级组件。
- 支持更灵活的配置传递机制,如配置加工,配置多播传递等。
- 支持多维度的升级策略,如单个服务升级、模块化多服务升级、系统全量服务升级等。
- 原生面向自研容器平台,提供配套的调度和部署逻辑。同时提供相应的chart wrapper以兼容面向K8S的部署能力。
- 基于OCI的打包能力,将系统的编排、镜像、数据包高效地搬运到私有化环境。
系列文章
- 私有化交付平台——编排篇
- 私有化交付平台——调度部署篇
- 私有化交付平台——打包篇
- 私有化交付平台——升级篇【TODO】