在今年三月 InfoQ 发布的一篇译文《构建开发工具正当时》中,作者提到:
如果说软件是科技进步的一阶助推器,那么面向开发者的工具软件则是助推器的助推器(二阶助推器)。
长期以来,面向云计算的开发者工具并不广泛为人所知,但实际上,开发工具作为开发者最亲密的伙伴,它潜移默化地影响了我们操作云的方式,同时也改变了软件开发模式和生产关系,甚至创造了新的岗位,但与此同时也产生了新的挑战。
本文将从工具研发的顶层视角,向大家完整地介绍云计算行业的工具链产品体系,以及 UCloud 在标准化交付开发者工具的过程中,所做的一些工作,希望能够为这个行业,注入新鲜的活力。开发工具通常指用于优化软件的编写、调试、测试、部署等软件构建过程的工具。这里提及的云开发工具,则主要专注于和云资源相关的构建过程。常见的云开发工具包括 SDK、CLI、CDK 和 SaaS(Web 交互式)工具等多个品类。多年来,云相关的工具研发存在几个普遍的问题,包括:接下来,我们将整体介绍 UCloud 在开发者工具方面的一些工作,并通过对该领域的开发准则和技术方案的解读,使大家能够近距离地了解,UCloud 是如何面对上述两个挑战的。云计算领域的开发者工具是一个层次清晰、职责明确的产品体系:- SDK-可使用户采用自己熟悉的编程语言,直接调用云上 API 指令。特点:命令式 API + 通用编程语言;
- CLI-作为云上新一代的用户界面,可以使用户采用命令行管理云上资源。特点:形态多种多样;
- CDK-可使用户采用通用编程语言声明云上资源,并执行自动化编排。特点:声明式 API + 通用编程语言;
- SaaS-通常以 Web 控制台产品的形态呈现给用户。特点:开箱即用。
除此之外,开发者中心/导航作为所有开发者工具的统一入口,为信息的检索和触达提供支持。关于开发者工具的详细介绍,可以移步文章末尾的开源社区主页深入了解。
开发者工具是云计算产品体系中,为数不多的All in 开源的产品线,这在浩如烟海的云计算产品体系中也是颇为少见的。主要有以下两个原因:只有开源才能取得用户的信赖。其它的托管类产品,如 IaaS、PaaS 产品不同,大部分的开发者工具都必须部署在客户机上,这意味着该工具所有的源码必须是客户能够完全信赖的,那么公布源代码就成为了一个必要的前提。
只有开源才能够与社区集成。许多知名的开发者工具并非由单一云厂商独立开发,而是由一个中立的商业或非商业组织主导(如 CNCF、HashiCorp 等),多个厂商(如 UCloud 等)协作完成的,因此开源也成为了这种协作模式的基础。
除了上述的技术因素之外,文化因素也很大程度上决定了开发者工具的形态。随着云原生时代的到来,开源软件如雨后春笋般涌现。开发者工具的增长同样遵循开源软件的「礼物文化」。这个概念来自于《大教堂与集市》,是指开源社区的贡献和赠予是一种非零和的博弈,开发者工具的开源并不会给云厂商造成经济上的损失,反而可以获得声誉、品牌影响力上的回馈。在 UCloud 的开发者工具的路线中,开源文化贯穿始终。对于日新月异的技术发展,UCloud 采取了积极向开源社区上游集成的路线,比如 Terraform、Packer、Pulumi 等。这样既可以避免社区的割裂,让用户可以使用自己最喜欢的工具;同时也可以通过技术贡献,反哺社区的发展,加速新技术的引进,为国内基础软件行业贡献出自己的一份力量。开发者工具代表了用户的使用习惯,形态各异,纷繁复杂。长期以来,由于新的工具不断涌现,对于云服务提供商的工程能力,形成了极大的挑战。
例如工具开发团队,原本要为 N 个产品,提供 M 款工具的支持,那么则需要 M*N 次开发、测试和版本交付的过程。在 UCloud 的实践中,所有的开发者工具都按照层次结构和架构风格来划分,将每个层次或架构风格中,一组工具的共性提取出来,形成一个权威的单一事实来源(trusted source)。同类工具则全部采用代码生成技术,从事实来源中自动化构建。单一事实来源的存在,使得开发工具从一个 M*N 的开发成本,优化至了 M+N,同时基于此完成了职责分离(SoD),从根本上改变了云服务提供商在工具成本效率上面临的困境。本文在接下来的内容中,将详细介绍:如何针对不同的架构风格,通过构建代码生成流水线来生成工具类产品。
通常情况下,云服务提供商向用户所提供的服务,往往由这三类用户接口构成:
命令式(Imperative)的 API 和工具,常常以动词来描述如何操作某个具体的资源,例如创建云主机、开/关机等。RESTFul、Action 等常见的 API 架构风格,都是命令式 API 的一个实例。
声明式(Declarative)的 API 和工具,则仅需要描述所期望的资源是什么样子。而具体执行哪些动作,则由工具或平台自动完成。例如Kubernetes Operator、Terraform 等,工具本身往往需要对比当前实际资源状态和期望状态之间的差异,从而自动化地决策和执行一系列的编排逻辑。
交互式(Interactive)的工具,通过一系列的交互设计,以即时响应的渐进式方式,一步一步靠近用户最终的目标。例如 API 调试器可以使用户不断地修改参数、发起请求,直到获得用户想要的结果。
那么这三类架构风格,本质上都是对「 如何根据用户的意图,使目标系统收敛至符合期望的状态」这一问题的抽象。相关的研究包括 Mark Burgess 在配置管理领域关于收敛算子和不动点的理论,以及后来 Puppet、HashiCorp、CNCF 等组织的一系列相关工程实现。UCloud 的开发者工具,以命令式的 API 为底座,基于它构建更高层次的其它种类用户接口。每个层次的用户接口,都以开发者工具形态提供,并通过下文中提及的代码生成流水线来自动化构建。根据Martin Fowler在《Domain-Specific Languages》中的定义,代码生成的策略包括基于转换器和基于模版的代码生成。前者是指采用通用编程语言如 Go、Python 进行文本处理,更加灵活多变;后者是指通过编写模版 DSL 生成代码,因为模版具有和目标代码类似的结构,因此可读性更优。UCloud 在代码生成的实践中,同时支持两种生成策略。转换器用于构建领域语义模型,即模型到模型的生成,例如文档中心需要额外的导航信息,转换器从外部系统获取该信息并进行语义模型变换。模版则用于模型到代码的生成,例如文档中心的 Markdown 文档。明确了适用场景后,可以让关联团队的职责更加清晰,模版较低的书写成本,也使得非研发团队可以参与模版的设计和修改,极大程度提高了工程效率。图中红色的文字代表需要录入/开发的部分,绿色的文字代表代码生成的过程。产品业务部门录入 API 文档后,由特定的内部开发者工具转换为一个标准化的中间表示。
基于中间表示生成各语言的 SDK/CLI,这一阶段,完成了命令式(Imperative)API 的交付。
工具产品研发团队,通过编写API 的调和(Reconcile)逻辑,实现从命令式到声明式(Declarative)API 的转换。
基于声明式 API,构建 Terraform 云供应商插件,生成 CDK 类工具。
最终将所有工具信息抽取到统一的存储中,暴露给 SaaS 类的应用和开发者工具来使用。
以上环节完成了开发者工具全线产品的自动化生成。图中橙色的文字表示已完成待发布的产品,蓝色的文字表示 Q4 Roadmap 中的特性,所有产品的状态和路线图都可以在 Github 中获取。基于代码生成流水线的软件交付,使工具的构建成本,从 M*N 优化至 M+N,同时职责更加清晰,从根本上改变了云服务提供商在工具成本效率上面临的困境。