什么是云原生?

小窍门

此内容摘自电子书《为 Azure 架构云原生 .NET 应用程序》,可在 .NET 文档 查阅或下载免费的 PDF 离线阅读。

Azure 平台的云原生 .NET 应用电子书封面缩略图。

停止你正在做的工作,要求同事定义术语“云原生”。 你很有可能会得到几个不同的答案。

让我们从简单的定义开始:

云原生体系结构和技术是一种设计、构建和运行在云端生成的工作负载,并充分利用云计算模型优势的方法。

Cloud Native Computing Foundation 提供官方定义

云原生技术使组织能够在现代动态环境(如公共、私有云和混合云)中生成和运行可缩放的应用程序。 容器、服务网格、微服务、不可变基础结构和声明性 API 演示了此方法。

这些技术可实现弹性、可管理且可观测的松散耦合系统。 与可靠的自动化相结合,工程师可以频繁且可预测的方式进行高影响的变化,只需最少的辛苦。

云原生是关于速度和敏捷性的。 业务系统正在从支持业务能力转变为战略转型的武器,从而加速业务运作速度和增长。 必须立即将新的想法推向市场。

同时,业务系统也越来越复杂,用户的需求也越来越高。 他们期望快速响应能力、创新功能和零停机时间。 性能问题、重复错误和无法快速移动不再可接受。 你的用户将访问你的竞争对手。 云原生系统旨在实现快速变化、大规模和复原能力。

下面是一些实施云原生技术的公司。 考虑他们实现的速度、敏捷性和可伸缩性。

公司 经验
Netflix 在生产环境中有 600 多种服务。 每天部署 100 次。
Uber 在生产环境中有 1,000 多种服务。 每周部署数千次。
微信 在生产环境中有 3,000 多种服务。 每天部署 1,000 次。

如你所看到的,Netflix、Uber 和 WeChat 公开由许多独立服务组成的云原生系统。 这种建筑风格使它们能够快速响应市场状况。 它们可即时更新实时复杂应用程序的小型区域,而无需完全重新部署。 它们根据需要单独缩放服务。

云原生的支柱

云原生的速度和敏捷性派生自许多因素。 最重要的是 云基础结构。 但还有更多:图 1-3 中显示的其他五个基础支柱也为云原生系统提供了基石。

云原生基础支柱

图 1-3. 云原生基础支柱

让我们花些时间更好地了解每个支柱的重要性。

云原生系统充分利用云服务模型。

这些系统旨在在动态虚拟化的云环境中茁壮成长,利用 平台即服务(PaaS) 计算基础结构和托管服务。 它们将底层基础结构视为可处置:可在几分钟内进行预配,并根据需要重设大小、缩放或销毁(通过自动化)。

考虑我们如何对待宠物和商品之间的区别。 在传统的数据中心,服务器被视为宠物:物理机,给定有意义的名称,并照顾。 通过将更多资源添加到同一台计算机以实现纵向扩展。 如果服务器生病,你会把它恢复健康。 如果服务器不可用,每个人都会注意到。

商品服务模式不同。 将每个实例预配为虚拟机或容器。 它们是相同的,并分配了一个系统标识符,例如 Service-01、Service-02 等。 通过创建更多实例(横向扩展)进行扩展。 当实例不可用时,没有人注意到。

商品模型采用不可变的基础结构。 不会修复或修改服务器。 如果某个环节失败或需要更新,它就会被销毁,然后预配一个新的——所有这些都是通过自动化完成的。

云原生系统采用商品服务模型。 在基础设施缩小或扩大时,它们将继续运行,无需考虑其运行的计算机。

Azure 云平台支持这种高度弹性的基础结构,具有自动缩放、自我修复和监视功能。

新式设计

如何设计云原生应用? 你的体系结构会是什么样子? 要遵循哪些原则、模式和最佳做法? 哪些基础结构和运营问题非常重要?

十二要素应用程序

构建基于云的应用程序的广泛接受方法是 Twelve-Factor 应用程序。 它描述了开发人员遵循的一组原则和做法,以构造针对新式云环境优化的应用程序。 特别注意跨环境和声明性自动化的可移植性。

尽管适用于任何基于 Web 的应用程序,但许多从业者认为 Twelve-Factor 构建云原生应用的坚实基础。 基于这些原则构建的系统可以快速部署和缩放,并添加功能来快速应对市场变化。

下表重点介绍了 Twelve-Factor 方法:

因子 说明
1 - 基本代码 每个微服务的单个代码库,存储在其自己的存储库中。 使用版本控制进行跟踪,它可以部署到多个环境(QA、过渡、生产)。
2 - 依赖项 每个微服务将其自身的依赖项隔离并打包,从而在不影响整个系统的情况下独立处理更改。
3 - 配置 配置信息从微服务移出,并通过代码外部的配置管理工具进行外部化。 相同的部署可以在配置正确的情况下跨环境进行传播。
4 - 支持服务 应通过可寻址 URL 公开辅助资源(数据存储、缓存、消息中转站)。 这样做可将资源与应用程序分离,使资源可互换。
5 - 生成、发布、运行 每个版本必须强制在生成、发布和运行阶段之间严格分离。 各自都应使用唯一 ID 进行标记,并支持回滚功能。 现代 CI/CD 系统有助于实现此原则。
6 - 进程 每个微服务都应在其自己的进程中执行,独立于其他正在运行的服务。 将所需状态外部化到支持服务,例如分布式缓存或数据存储。
7 - 端口绑定 每个微服务都应自包含,其接口和功能在其自己的端口上公开。 这样做可提供与其他微服务的隔离。
8 - 并发 当容量需要增加时,跨多个相同的进程(副本)横向扩展服务,而不是在最强大的计算机上纵向扩展单个大型实例。 开发应用程序以实现并发,从而在云环境中实现无缝横向扩展。
9 - 可处置性 服务实例应是可处置的。 支持快速启动以增加可伸缩性机会和正常关闭,使系统处于正确状态。 Docker 容器以及业务流程协调程序本质上满足此要求。
10 - 开发/生产等同 使环境在整个应用程序生命周期中尽可能类似,避免成本高昂的快捷方式。 在这里,采用容器可以通过促进相同的执行环境做出很大贡献。
11 - 日志记录 将微服务生成的日志视为事件流。 使用事件聚合器处理它们。 将日志数据传播到 Azure Monitor 或 Splunk 等数据挖掘/日志管理工具,并最终传播到长期存档。
12 - 管理流程 以一次性进程的形式运行管理/管理任务,例如数据清理或计算分析。 使用独立工具从生产环境调用这些任务,但独立于应用程序。

超越十二要素应用一书中,作者 Kevin Hoffman 详细介绍了原始的所有 12 个要素(于 2011 年撰写)。 此外,他还讨论了反映当今现代云应用程序设计的三个额外因素。

新因素 说明
13 - API First 使所有内容服务化 假设你的代码将由前端客户端、网关或其他服务使用。
14 - 遥测 在工作站上,你可以深入了解应用程序及其行为。 在云中,你无法这样。 请确保设计包括监控、领域特定和系统/运行状况数据的集合。
15 - 身份验证/授权 从一开始就建立身份认证。 请考虑公有云中提供的 RBAC(基于角色的访问控制) 功能。

我们将在本章和整本书中参考许多十二个以上因素。

Azure Well-Architected Framework

设计和部署基于云的工作负载可能很有挑战性,尤其是在实现云原生体系结构时。 Microsoft提供了行业标准最佳做法,可帮助你和团队提供可靠的云解决方案。

Microsoft Well-Architected Framework 提供了一组指导原则,可用于提高云原生工作负荷的质量。 该框架由体系结构卓越五大支柱组成:

原则 DESCRIPTION
成本管理 专注于提前生成增量值。 应用 Build-Measure-Learn 原则,以加快上市时间,同时避免资本密集型解决方案。 使用即用即付策略,随着规模的扩展逐步进行投资,而不是提前进行大量投资。
卓越运营 自动化环境和操作,以提高速度和减少人为错误。 快速回滚或前滚问题更新。 从一开始就实施监视和诊断。
性能效率 高效地满足对工作负载的需求。 支持水平缩放(横向扩展),并将其设计到系统中。 持续执行性能和负载测试,以确定潜在的瓶颈。
可靠性 生成可复原和可用的工作负载。 复原能力使工作负荷能够从故障中恢复并继续运行。 可用性可确保用户随时访问工作负荷。 将应用程序设计为预期故障并从中恢复。
安全性 在应用程序的整个生命周期内实现安全性,从设计和实现到部署和作。 密切关注标识管理、基础结构访问、应用程序安全性和数据主权和加密。

首先,Microsoft提供了一组 在线评估 ,帮助你根据五大架构原则评估当前云工作负载。

微服务

云原生系统采用微服务,这是构建新式应用程序的常用体系结构风格。

微服务作为通过共享结构交互的小型独立服务的分布式集构建,具有以下特征:

  • 每个功能在更大的域上下文中实现特定的业务功能。

  • 每个系统都是自主开发的,可以独立部署。

  • 每个组件都是自包含的,封装其自己的数据存储技术、依赖项和编程平台。

  • 每个程序在其自己的进程中运行,并使用标准通信协议(如 HTTP/HTTPS、gRPC、WebSocket 或 AMQP)与他人通信。

  • 它们组合在一起以形成应用程序。

图 1-4 将整体式应用程序方法与微服务方法形成对比。 请注意整体结构如何由分层体系结构组成,该体系结构在单个进程中执行。 它通常使用关系数据库。 但是,微服务方法将功能分为独立的服务,每个服务都有自己的逻辑、状态和数据。 每个微服务托管自己的数据存储。

整体部署与微服务

图 1-4. 整体体系结构与微服务体系结构

请注意微服务如何促进来自Twelve-Factor 应用程序进程原则,本章前面已经讨论过。

Factor #6 指定“每个微服务都应在其自己的进程中执行,独立于其他正在运行的服务”。

为什么是微服务?

微服务提供敏捷性。

在本章的前面,我们比较了以单体架构构建的电子商务应用程序与微服务架构的电子商务应用程序。 在此示例中,我们看到了一些明显的优势:

  • 每个微服务都有一个自主生命周期,可以独立发展并频繁部署。 无需等待季度发布来部署新功能或更新。 可以更新实时应用程序的一小部分,并降低中断整个系统的风险。 无需完全重新部署应用程序即可进行更新。

  • 每个微服务可以独立伸缩。 无需将整个应用程序缩放为单个单元,而是仅横向扩展那些需要更多处理能力以满足所需性能级别和服务级别协议的服务。 细粒度缩放提供更精细的系统控制,并有助于降低总体成本,因为您只缩放系统的部分,而不是整个系统。

了解微服务的优秀参考指南是 .NET 微服务:容器化 .NET 应用程序的体系结构。 该书深入探讨微服务设计和体系结构。 它是 完整堆栈微服务参考体系结构 的配套,可从Microsoft免费下载。

开发微服务

可以在任何新式开发平台上创建微服务。

Microsoft .NET 平台是一个不错的选择。 免费和开放源代码,它具有许多简化微服务开发的内置功能。 .NET 是跨平台的。 可以在 Windows、macOS 和大多数 Linux 风格上构建和运行应用程序。

.NET 性能高,与 Node.js 和其他竞争平台相比,得分很高。 有趣的是, TechEmpower 在许多 Web 应用程序平台和框架中进行了广泛的 性能基准测试 。 .NET 在得分中位列前十名,远高于 Node.js 和其他竞争平台。

.NET 由 GitHub 上的Microsoft和 .NET 社区维护。

微服务挑战

虽然分布式云原生微服务可以提供巨大的敏捷性和速度,但它们带来了许多挑战:

通信

前端客户端应用程序如何与后端核心微服务通信? 是否允许直接通信? 或者,是否可以使用提供灵活性、控制和安全性的网关外观来抽象后端微服务?

后端核心微服务如何相互通信? 是否允许直接 HTTP 调用来提高耦合度并影响性能和敏捷性? 或者,是否考虑将消息与队列和主题技术分离?

云原生通信模式章节介绍了通信。

复原能力

微服务体系结构将系统从进程内网络通信转移到进程外网络通信。 在分布式体系结构中,当服务 B 未响应服务 A 的网络调用时,会发生什么情况? 或者,当服务 C 暂时不可用并且调用服务的其他服务被阻止时会发生什么情况?

云原生复原一章中介绍了 复原能力

分布式数据

根据设计,每个微服务封装自己的数据,并通过其公共接口公开操作。 如果是这样,如何跨多个服务查询数据或实现事务?

原生数据模式 章节介绍了分布式数据。

机密

微服务如何安全地存储和管理机密和敏感配置数据?

云原生安全性一章中详细介绍了机密。

使用 Dapr 管理复杂性

Dapr 是分布式开源应用程序运行时。 通过可插入组件的体系结构,它极大地简化了分布式应用程序背后的 管道 。 它提供了一个 动态粘附 ,用于将应用程序与 Dapr 运行时中预生成的基础结构功能和组件绑定在一起。 图 1-5 显示了来自 20,000 英尺的 Dapr。

均分布有 Dapr 图 1-5。 20,000 英尺处的 Dapr。

在图首行中,请注意 Dapr 如何为热门开发平台提供 特定于语言的 SDK 。 Dapr v1 包括对 .NET、Go、Node.js、Python、PHP、Java 和 JavaScript 的支持。

虽然特定于语言的 SDK 增强了开发人员体验,但 Dapr 与平台无关。 在后台,Dapr 的编程模型通过标准 HTTP/gRPC 通信协议公开功能。 任何编程平台都可以通过其本机 HTTP 和 gRPC API 调用 Dapr。

图中心的蓝色框表示 Dapr 构建基块。 每个都公开应用程序可以使用的分布式应用程序功能的预生成管道代码。

组件行表示应用程序可以使用的大量预定义基础结构组件。 将组件视为无需编写的基础结构代码。

底部行突出显示了 Dapr 的可移植性及其可运行的各种环境。

展望未来,Dapr 有可能对云原生应用程序开发产生深远的影响。

容器

在任何云原生对话中,听到提及术语“容器”是很自然的事情。 在这本书中, 《云原生模式》的作者康妮莉亚·戴维斯观察到,“容器是云原生软件的伟大启用者”。Cloud Native Computing Foundation 将微服务容器化作为 其Cloud-Native 跟踪映射 中的第一步-面向开始云原生旅程的企业指南。

容器化微服务非常简单。 代码、其依赖项和运行时打包到名为 容器映像的二进制文件中。 映像存储在容器注册表中,该注册表充当映像的存储库或库。 注册表可以位于开发计算机、数据中心或公有云中。 Docker 本身通过 Docker 中心维护公共注册表。 Azure 云采用专用容器注册表,用于存储与将运行容器映像的云应用程序接近的容器映像。

当应用程序启动或缩放时,可将容器映像转换为正在运行的容器实例。 该实例在安装了 容器运行时 引擎的任何计算机上运行。 可以根据需要拥有任意数量的容器化服务实例。

图 1-6 显示了三个不同的微服务,每个微服务在其自己的容器中,都在单个主机上运行。

在容器主机上运行的多个容器

图 1-6. 在容器主机上运行的多个容器

请注意,每个容器如何维护其自己的一组依赖项和运行时,它们可能彼此不同。 在这里,我们看到在同一主机上运行的产品微服务的不同版本。 每个容器共享基础主机操作系统、内存和处理器的切片,但彼此隔离。

请注意容器模型如何从 Twelve-Factor 应用程序接受依赖项原则。

Factor #2 说明“每个微服务会对其自身依赖项进行隔离和打包,因为每个微服务均可接受更改而不必影响整体系统”。

容器支持 Linux 和 Windows 工作负载。 Azure 云公开接受这两者。 有趣的是,Linux 而不是 Windows Server,它已成为 Azure 中最受欢迎的作系统。

在众多容器供应商中,Docker 已经占据了市场的大部分。 该公司一直在推动软件容器运动。 它已成为打包、部署和运行云原生应用程序的事实标准。

为什么是容器?

容器提供可移植性并保证环境之间的一致性。 通过将所有内容封装到单个包中,可以将微服务及其依赖项与底层基础结构 隔离 开来。

可以在托管 Docker 运行时引擎的任何环境中部署容器。 容器化工作负载还消除了使用框架、软件库和运行时引擎预配置每个环境的费用。

通过共享基础作系统和主机资源,容器的占用空间比完整虚拟机要小得多。 较小的大小会增加给定主机一次可以运行的 密度或微服务数量。

容器业务流程

尽管 Docker 等工具创建映像并运行容器,但还需要工具来管理它们。 容器管理是使用名为 容器业务流程协调程序的特殊软件程序完成的。 在大规模运行许多独立运行容器时,编排是必不可少的。

图 1-7 显示了容器业务流程协调程序自动执行的管理任务。

容器编排工具的作用

图 1-7. 容器业务流程协调程序执行的任务

下表描述了常见的编排任务。

任务 说明
日程安排 自动预配容器实例。
亲和性/反亲和性 在附近或彼此距较远的地点提供容器,以提升可用性和性能。
健康监测 自动检测并更正失败。
故障转移 自动将失败的实例重新配置到正常运行的机器。
规模化 自动添加或删除容器实例以满足需求。
网络 管理用于容器通信的网络覆盖。
服务发现 使容器能够相互定位。
滚动升级 协调增量升级,以实现零停机时间的部署。 自动回滚有问题的更改。

请注意容器编排器如何采用来自 Twelve-Factor 应用程序易处理性并发原则。

Factor #9 指定“服务实例应可释放,有利于快速启动以增加可伸缩性机会和正常关闭,使系统保持正确状态。 Docker 容器以及业务流程协调程序本质上满足此要求。

因素 #8 指定“服务通过大量小型相同的进程(副本)进行横向扩展,而不是在可用的最强计算机上纵向扩展单个大型实例。”

虽然存在多个容器业务流程协调程序, 但 Kubernetes 已成为云原生世界事实上的标准。 它是一个可移植的可扩展开源平台,用于管理容器化工作负荷。

可以托管自己的 Kubernetes 实例,但随后需负责预配和管理其资源,这可能非常复杂。 Azure 云将 Kubernetes 用作托管服务。 Azure Kubernetes 服务(AKS)Azure Red Hat OpenShift (ARO)都使你能够充分利用 Kubernetes 作为托管服务的功能和功能,而无需安装和维护它。

Scaling Cloud-Native Applications中详细介绍了容器编排。

支持服务

云原生系统依赖于许多不同的辅助资源,例如数据存储、消息代理、监视和标识服务。 这些服务称为 后盾服务

图 1-8 显示了云原生系统使用的许多常见支持服务。

常见后盾服务

图 1-8. 常见后盾服务

可以托管自己的后备服务,但随后你将负责许可、预配和管理这些资源。

云提供商提供丰富的托管后端服务。 你无需拥有服务,只需使用它即可。 云提供商大规模运行资源,并负责性能、安全性和维护。 监视、冗余和可用性内置于服务中。 提供商保证服务级别性能并全面支持他们的托管服务——提交服务请求,他们会解决您的问题。

云原生系统支持来自云供应商的托管支持服务。 时间和劳动力的节省可能很重要。 承载自己的服务和遇到问题的运营风险会迅速变得十分昂贵。

最佳做法是将支持服务视为 附加资源,动态绑定到微服务,其中包含存储在外部配置中的配置信息(URL 和凭据)。 本指南在本章前面的 Twelve-Factor 应用程序中进行了说明。

Factor #4 指定“应通过可寻址 URL 公开支持服务”。 这样做可将资源与应用程序分离,使资源可互换。

Factor #3 指定“配置信息已移出微服务,并通过代码外部的配置管理工具进行外部化”。

使用此模式,可以附加和分离支持服务,而无需更改代码。 可以将微服务从 QA 提升到预发布环境。 将微服务配置更新为指向暂存中的支持服务,并通过环境变量将设置注入到容器中。

云供应商提供 API 供你与其专有支持服务通信。 这些库封装了专有管道和复杂性。 但是,直接与这些 API 通信会将代码紧密耦合到该特定的支持服务。 这是一种广泛接受的做法,可以隔离供应商 API 的实现细节。 引入一个中介层或中间 API,向服务代码公开通用操作,并在其中封装供应商代码。 这种松散耦合使你可以将一个后盾服务交换到另一个支持服务,或者将代码移到其他云环境,而无需更改主线服务代码。 前面讨论的 Dapr 通过预生成构建基块集来遵循此模型。

最后一点,支持服务还促进本章前面所讨论的十二要素应用程序中的“无状态”原则

Factor #6 指定,“每个微服务都应在其自己的进程中执行,独立于其他正在运行的服务。 将所需状态外部化到支持服务,例如分布式缓存或数据存储。

支持服务在 云原生数据模式云原生通信模式中进行了讨论。

自动化

如你所见,云原生系统采用微服务、容器和现代系统设计,以实现速度和敏捷性。 但是,这只是故事的一部分。 如何预配运行这些系统的云环境? 如何快速部署应用功能和更新? 如何全面了解整个情况?

推行被广泛接受的 基础结构即代码(IaC)的做法。

使用 IaC,可以自动执行平台预配和应用程序部署。 你基本上将软件工程实践(如测试和版本控制)应用于 DevOps 实践。 基础结构和部署是自动化、一致且可重复的。

自动化基础结构

通过 Azure 资源管理器Azure Bicep、HashiCorp 的 TerraformAzure CLI 等工具,可以声明方式编写所需的云基础结构脚本。 资源名称、位置、容量和机密是参数化和动态的。 脚本会进行版本控制,并作为项目的生成工件签入到源代码管理中。 调用脚本在跨系统环境(如 QA、预上线和生产)中配置一致且可重复的基础设施。

在底层,IaC 是幂等的,这意味着可以反复运行相同脚本,而不会产生副作用。 如果团队需要进行更改,他们编辑并重新运行脚本。 只有更新的资源才会受到影响。

在本文中, 什么是基础结构即代码,作者 Sam Guckenheimer 介绍了如何“实现 IaC 的 Teams 可以快速大规模地提供稳定的环境。 它们通过代码表示环境所需的状态来避免手动配置环境并强制实施一致性。 使用 IaC 的基础结构部署是可重复的,并防止因配置偏移或缺少依赖项而导致的运行时问题。 DevOps 团队可与一组统一的做法和工具协作,以快速、可靠、大规模地交付应用程序和其支持基础结构。

自动部署

前面讨论 的Twelve-Factor 应用程序要求在将已完成的代码转换为正在运行的应用程序时执行单独的步骤。

Factor #5 指定“每个版本都必须在生成、发布和运行阶段强制实施严格的分离。 各自都应使用唯一 ID 进行标记,并支持回滚功能。”

现代 CI/CD 系统有助于实现此原则。 它们提供单独的生成和交付步骤,可帮助确保用户随时可用的一致和质量代码。

图 1-9 显示了跨部署过程的分离。

CI/CD 管道中的部署步骤

图 1-9. CI/CD 管道中的部署步骤

在上图中,请特别注意任务分离:

  1. 开发人员在开发环境中构建一个功能模块,通过代码编写、运行和调试进行反复迭代,这个过程被称为“内部循环”。
  2. 完成后,该代码 将推送 到代码存储库,例如 GitHub、Azure DevOps 或 BitBucket。
  3. 推送会触发将代码转换为二进制生成工件的生成阶段。 该工作是通过 持续集成(CI) 管道实现的。 它会自动生成、测试和打包应用程序。
  4. 发布阶段会选取二进制工件,应用外部应用程序和环境配置信息,并生成不可变版本。 该版本部署到指定环境。 该工作是通过 持续交付(CD) 管道实现的。 每个版本都应可识别。 你可以说,“此部署正在运行应用程序版本2.1.1发行版。”
  5. 最后,已发布的功能在目标执行环境中运行。 版本是不可变的,这意味着任何更改都必须创建新的版本。

应用这些做法时,组织已经从根本上演变了它们交付软件的方式。 许多人已从季度版本迁移到按需更新。 目标是在开发周期的早期发现问题,这样修复它们的成本会更低。 集成间隔时间越长,解决问题的成本就越高。 在集成过程中保持一致性后,团队可以更频繁地提交代码更改,从而提高协作和软件质量。

DevOps 中详细介绍了基础结构即代码和部署自动化,以及 GitHub 和 Azure DevOps