1.2.2 重新定义软件交付模式
基于容器和Kubernetes的交付平台,可以屏蔽底层不同硬件环境的差异,包括主机差异、存储差异、网络差异、操作系统差异、第三方软件差异等。因为从应用的角度看,它们都是在隔离的环境中单独运行,从CPU、内存、网络、IPC(Inter-Process Communication,进程间通信)到第三方软件依赖,都是独享的一份。而这些差异,恰恰是传统软件交付方式所面临的巨大挑战。在传统的软件交付过程中,交付人员需要通过文档学习和技能提升来填平不同环境的差异,这本质上是一个知识转移链条,依赖于知识的质量和交付人员的水平,任何环节出现问题,都会导致软件交付困难。传统软件交付模式如图1-3所示。
从图1-3中可以看到,在传统软件交付模式下,交付人员在学习手册/文档后,需要在新环境中完成应用的“安装配置”和“与遗留系统集成”两方面的工作。“安装配置点”主要包括软件在硬件上的安装配置、应用在软件(OS和第三方库)上的安装配置和应用本身的安装配置;“集成点”主要包括新环境中的硬件、软件和应用与遗留系统的集成工作,比如,监控、服务调用、文件传输、消息集成、ITSM系统等的集成。传统软件交付模式很难自动完成相关的安装配置与集成,究其原因是上层所依赖的底层环境在不同交付环境中往往是不同的,而传统交付模式缺乏脚本能够“理解”的方式来表达这些不同;此外,运维人员经常会变更应用安装好之后的环境,比如,更新OS和第三方库、修改应用或系统参数配置等,这些变更与应用的要求又缺乏校验关系,所以下次升级时应用很容易发生故障。
图1-3 传统软件交付模式
云原生软件交付模式如图1-4所示。
从图1-4中可以看到,相较于传统模式,云原生软件交付模式主要有如下几个变化。
1)利用容器做整体交付。整体交付减少了容器内部组件之间的安装配置工作,随着容器及编排的开源和普及,更多硬件得到支持,使得容器成为软件交付的标准“底座”。这种标准“底座”加整体交付的方式,极大地降低了安装配置的错误风险。此外,还可以通过工具(如Terraform)和脚本自动完成软件交付,提升交付的效率。这就像购买组装家具一样,顾客更期望得到的服务是厂家到家里将家具组装好,以免自己在组装时出现错误。
2)将Git作为“Single Version of Truth”(唯一真实版本)。Git作为交付和运维的仓库,记录了所有软件变更的版本、配置参数、脚本、用户名和密码等信息,同时所有脚本、工具和Kubernetes的Operator,都读取Git中的信息作为事实的唯一来源,即使是做版本升级或回滚,以及变更评审,都以Git中的信息为准。
图1-4 云原生软件交付模式
3)声明式API。很多软件交付都是“告诉”系统需要做什么,特别是脚本中往往会写明如何进行部署;而声明式API首先是“告诉”系统期望的目标状态是什么,比如,在这种环境下部署需要用到两个实例,其次才是脚本或工具需要做什么才能交付这个目标状态(即如何做)。声明式API本身并不复杂,实际上它是一种开发理念的彻底升级,因为系统更多的是关注需要什么(达到什么状态),所有的“如何做”都是围绕这个目标状态来服务的。
4)尽量采用OpenAPI作为系统间的集成方式。标准化的OpenAPI更有利于系统间的集成,因为OpenAPI有明确的契约描述或接口规格描述,且提供了各种开放的工具,可以用来做IoT(连通性测试)、SIT(集成测试)等。同时,由于其开放接口(比如,基于RESTful)的特性,可以实现快速集成,从而提升集成的效率。
所以,云原生软件交付模式可以方便地提升软件交付过程的自动化程度,更便于企业实施CI/CD,也可以极大地提升交付效率。根据WeaveWorks的统计,在实施了云原生持续交付后,高水平团队的部署频率将提升200倍,同时变更的错误率将降低为之前的1/3,应用恢复的速度将提升24倍,效果非常明显。