很多时候,围绕云原生的讨论会直接进入技术选择,如容器化和微服务。毫无疑问,这些都是云原生项目的潜在组成部分,但肯定不是全部。在本系列文章中,我们将从几个不同的角度探索云原生,包括技术和基础设施,还包括架构、设计,以及可能最容易被忽视的人员和流程。用最简单的术语来说,云原生不只是说要迁移到云,而是要充分利用云基础设施和服务的独特性来快速交付业务价值。
云原生的概念在这个术语投入使用之前就已经存在了。从某种意义上说,云原生是从公有云提供商开始提供简单廉价的弹性计算能力实例开始的。接下来的问题就变成了,你该如何编写应用程序来利用这种新的基础设施的灵活性,以及你可以因此获得什么业务收益?
在过去的十年中,云原生方法和技术已经发生了很大的变化,并且仍在不断发展,但是云原生应用程序所要实现的核心的技术和业务目标仍然没有变,这包括:
敏捷性和生产力:支持业务指标指导下的快速创新。降低维护风险并保持环境的持续更新。
弹性和可伸缩性:以自修复和无停机时间的持续可用性为目标。提供弹性缩放和容量无限的感觉。
优化和效率:优化基础设施和人力资源成本。可以在不同位置和提供商之间自由迁移。
在后续的文章中,当我们回顾云原生的“为什么”时,我们将对这些目标进行更细的分解,但即使从这个简单的定义来看,我们也应该清楚,云原生并不仅仅是指简单地迁移到一种新类型的基础设施,其含义要更广泛。然而,尽管这些目标很正确,但我们很难看到它们被应用于具体的云原生环境。我们需要做更多的工作来明确云原生到底是什么意思。
一些与云原生相关的流行的参照标准,比如微服务,以及更早的宣言,比如12要素应用,可能会让你得出这样的结论:云原生是一种架构风格的描述,其他选择都是遵从这一架构。这当然有一定的道理,云原生架构确实存在。然而,为了在云原生应用上取得成功,企业必须有一个更全面的视角。除了架构和基础设施决策,还有组织和过程决策。这让我们认识到一个关键问题:
技术本身并不能获得业务成果。
下图显示了这些决策之间的相互作用。
技术本身并不能获得业务成果。
在文章“避免不完全的云原生”中,我们举了一个很好的例子,描述了这些方面相互之间是如何链接在一起的,并专门指出了这些链接断开时会发生什么。在本系列文章中,我们将探讨云原生的成功与以下三个关键领域的协同变革的关系:架构与设计、技术与基础设施、人员与流程。下面我们将逐项进行讨论。
技术与基础设施:“云原生”语境下的“云”是什么?
十多年前,“云”这个词很大程度上指的是位置。通常,它指的是可以通过互联网访问的位于他人数据中心里的基础设施。然而,如今的“云”更多的是指如何与那个基础设施交互。事实上,位置元素已经基本消失了,因为现在常见的是,一个类似云的设施运行在自己的数据中心里——“私有云”,以及混合解决方案(可能会包含跨云的服务和工作负载)。
所以,如今的云计算更多的是关于你如何与基础设施交互,它至少要提供以下内容:
自助配置:可以即时申请新的虚拟资源(服务器、存储、网络)。
弹性:根据需求自动调整资源(及相关成本)。
自动恢复:资源可按设计在没有人为干预的情况下从故障中恢复,将对服务可用性的影响降至最低。
然而,随着云平台及概念的成熟,云原生中的云实际上还意味着对底层基础设施的进一步抽象。
不可变部署——例如,基于容器镜像的部署。
声明式配置——“基础设施即代码”提供将来状态。
运行时无关——平台将组件(例如容器)视为黑盒,不需要理解它们的内容。
组件编排——通过通用的声明式策略和配置赋能管理(监控、伸缩、可用性、路由等)。
在云原生的早期,这些功能通常是高度专有的,但现在,容器以及容器编排功能(如 Kubernetes)似乎已无处不在。像上面这样的列表是针对容器的,还有其他值得注意的选项,如无服务器/函数即服务(function As a service),它们被进一步从基础设施中抽象出来,而且将来可能会变得更加突出。
我们可能会涉及更多,如构建自动化、服务网格、日志、跟踪、分析、软件定义网络和存储等等。因而,届时我们将进入云平台上目前看来更专有的方面。希望随着时间的推移,这些方面也会变得更加标准化。因此,在这里,“云”实际上是指具有上述特性的基础设施和技术。
架构与设计:“云原生”里的“原生”是什么意思?
我们所说的“原生(native)”是指我们将构建的解决方案不仅仅是“运行在云上”,而是专门利用了云平台的独特性。应用程序不会魔法般地继承底层云基础设施的优点,我们必须教会它们方法。
我们在语言上要特别小心。当我们使用“原生”来指“云平台的独特性”时,我们并不是指特定云提供商的特定方面。那将是“云提供商原生”,实际上,这将完全背离可移植性和使用开放标准的目标。我们指的是,对于所有云平台来说在概念上都通用的东西。换句话说,就是我们在上一节中所强调的基础设施和技术。
这对架构和设计有重要的影响。例如,我们需要确保编写的解决方案可以水平伸缩,并且可以利用自动恢复机制。在这里,云原生可能与微服务概念存在很大的重叠。例如,这包括编写具有以下特性的组件:
将有状态性降至最低
减少依赖
有明确定义的接口
轻量级
一次性
我们将在下一篇文章中更深入地描述它们,但是现在,最重要的是要注意,它们之间存在着高度的依赖关系。例如,如果组件是高度有状态的,那么创建一个一次性的组件就会困难很多。本质上,减少依赖关系有助于使组件更加轻量化。定义良好的接口将使得重新绑定一次性组件更容易,诸如此类。这只是一个小例子,是为了说明更广泛的观点,即迁移到云原生方法需要同时在许多相关方面进行变革。我们逐渐发现,这些云原生要素是相辅相成的。
人员和流程:“云原生”对我们的组织和工作方式有何影响?
这可能不太明显,当我们运用上述关于架构和底层基础设施的假设和决策时,我们就获得了从根本上改变人员和流程处理方式的机会。事实上,我们可以说,它需要这些改变。
下面我们探讨了微服务方法对人员/流程的一些影响:
微服务意味着你将在小型、自治团队中构建服务。这只是康威定律的简单应用——如果你希望自己的系统是由解耦的小组件组成,那么你的团队也必须很小,并且与其他团队之间是松耦合的——只允许通过定义良好且妥善治理的接口进行正式通信。
微服务还意味着你正在使用敏捷方法,并将DevOps原则应用到开发过程中。如果没有,你会无法获得端到端的反馈和对代码的快速迭代,这是该方法的核心优势。DevOps则意味着进一步的流程改进,如持续集成和持续交付/部署(CI/CD)。
DevOps需要你采用其他特定的技术流程,如自动化测试(可能包括测试驱动开发),并引导你走向基于主干的开发。最小化测试周期的愿望可能会进一步引导你探索改变人们工作的方式(例如,结对编程)。
同样,容器技术对所需的技能集、角色和流程也有影响:
通常,云基础设施使用通用的云平台技能(比如Kubernetes的知识)来实现更多的操作(部署、扩展、高可用性等),而不是特定的运行时或产品技能。这从根本上减少了跨技术领域工作人员的学习曲线,并实现了更广泛的角色和知识共享,提高了效率,降低了成本。它还鼓励人们向站点可靠性工程师转变,尽可能地实现操作任务的自动化。
容器,特别是容器镜像技术简化了CI/CD管道的自动化,缩短了构建/发布周期,提高了生产率。管道实现方式趋同,意味着它们更容易维护,实际上也更容易被更广泛的人群所使用。
不可变容器镜像与声明式“基础设施即代码”相结合,提高了跨不同环境部署的一致性,降低了测试和诊断成本,提高了部署速度,并减少了停机时间。从流程的角度来看,这使得可靠性、性能和安全测试等方面的“左移”成为可能。反过来,这也增强了DevOps/DevSecOps文化,使开发人员对代码的操作质量负起更多的责任。
小结:“云原生”到底意味着什么?
综上所述,我们可以看到,云原生需要从三个不同的方面进行定义。
对基础设施复杂性进行抽象的平台。(基础设施和技术)
充分利用基础架构抽象的解决方案。(架构和设计)
开发、操作和业务流程的自动化,以及开发团队自治性的提升。(人员和流程)
如今,技术方面的重点当然是容器化,但重要的是该技术的自助配置、弹性和自动恢复等特性,而不是技术本身。
在架构上,我们最常用的方法是,根据微服务原则来创建更加轻量级、细粒度、状态最小化的组件,以便可以更好地映射到抽象的基础设施。如果没有正确的设计原则,那么我们的解决方案将无法从平台中获益。例如,它不会动态伸缩,或提供细粒度的弹性,或提供快速构建和部署,或与平台上的其他应用程序保持操作一致性。
通常,人们会认为,人员和流程的变革与云原生无关,但实际上,它们关系密切,我们将它们视为是特性定义的一部分。缺少软件开发生命周期的自动化,将意味着团队要将更多的时间花在日常事务上,而将相对较少的时间花在业务价值上。一个笨重的、自上而下的组织和治理结构将无法提供团队所需的自主权来帮助他们进行业务创新。
因此,在对云原生的实际含义有了更具体的定义后,我们就可以进行下一步并扩展前面的图表了。
在上面的图表中,我们针对这些方面的关键要素列出了一些问题。在本系列的后续文章中,我们将考虑“如何”构建云原生解决方案,并从人员和流程方面入手详细研究每个要素。
然而,应该清楚的是,实现完全的云原生并非易事,并且需要业务支持。因此,在另一篇文章中,我们将对成功实现云原生所需的投入进行总结,并回过头来,重新考虑下,你实现微服务的初衷是什么,以及你希望获得什么样的好处。