作者 | 潘义文(空易)
来源|阿里巴巴云原生公众号
云原生的概念最早开始于 2010 年,在当时 Paul Fremantle 的一篇博客中被提及,他一直想用一个词表达一种架构,这种架构能描述应用程序和中间件在云环境中的良好运行状态。因此他抽象出了 Cloud Native 必须包含的属性,只有满足了这些属性才能保证良好的运行状态。当时提出云原生是为了能构建一种符合云计算特性的标准来指导云计算应用的编写。
后来到 2013 年 Matt Stine 在推特上迅速推广云原生概念,并在 2015 年《迁移到云原生架构》一书中定义了符合云原生架构的特征:12 因素、微服务、自服务、基于 API 协作、扛脆弱性。而由于这本书的推广畅销,这也成了很多人对云原生的早期印象,同时云原生也被 12 要素变成了一个抽象的概念。Matt Stine 认为在单体架构向 Cloud Native 迁移的过程中,需要文化、组织、技术共同变革。 解读:**云原生架构本质上也是一种软件架构,最大的特点是在云环境下运行,也算是微服务的一种延伸**。
2015 年由 Linux 基金会发起了一个 The Cloud Native Computing Foundation(CNCF) 基金组织,CNCF基金会的成立标志着云原生正式进入高速发展轨道,Google、Cisco、Docker 各大厂纷纷加入,并逐步构建出围绕 Cloud Native 的具体工具,而云原生这个的概念也逐渐变得更具体化。因此,CNCF 基金最初对云原生定义是也是深窄的,当时把云原生定位为容器化封装+自动化管理+面向微服务:
The CNCF defines “cloud-native” a little more narrowly, to mean using open source software stack to be containerized, where each part of the app is packaged in its own container, dynamically orchestrated so each part is actively scheduled and managed to optimize resource utilization, and microservices-oriented to increase the overall agility and maintainability of applications.
这主要因为 CNCF 基金会在当时的核心拳头软件就是 K8s,因此在概念定义上主要是围绕着容器编排建立起来的生态。其实这也是为什么我们可以看到 CNCF 定义云原生的时候有时感觉就是再说容器生态。
到了 2017 年, 云原生应用提出者之一的 Pivotal 在其官网上将云原生的定义概括为 DevOps、持续交付、微服务、容器四大特征,这也成了很多人对 Cloud Native 的基础印象。
而到 2018 年,随着 Service Mesh 的加入,CNCF 对云原生的定义发生了改变,而这也逐渐成为被大家认可的官方定义:
Cloud native technologies empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach.
These techniques enable loosely coupled systems that are resilient, manageable, and observable. Combined with robust automation, they allow engineers to make high-impact changes frequently and predictably with minimal toil.
The Cloud Native Computing Foundation seeks to drive adoption of this paradigm by fostering and sustaining an ecosystem of open source, vendor-neutral projects. We democratize state-of-the-art patterns to make these innovations accessible for everyone.
总结一下就是:
可以看出,CNCF 在当前定义基础上加上了服务网格 (service mesh) 和声明式 API,这为云原生的概念阐述增加了更深一层的意义,也就是建立一个相对中立的开源云生态。这对云原生的生态定位是很重要的,也算 CNCF 最初成立的宗旨之一,打破云巨头的垄断。
解读:概念随着新的技术发展而演化
对一个词的解读,除了看其历史发展背景,还有一种偏向于语言学的方法解读,也就是我们常说的从“字面意思”来理解。
Cloud Native,从词面上拆解其实就是 Cloud 和 Native,也就是云计算和土著的意思——云计算上的原生居民,即天生具备云计算的亲和力。
首先从 Cloud 来理解,云可以看作是一种提供稳定计算存储资源的对象。为了实现这一点,云提供了像虚拟化、弹性扩展、高可用、高容错性、自恢复等基本属性,这是云原生作为一种云计算所具备的第一层含义。第二层要从 Native 来看,云原生和在云上跑的传统应用不同。一些基于公有云搭建的应用是基于传统的 SOA 架构来搭建的,然后再移植到云上去运行,那么这些应用和云的整合非常低。
为什么低呢?云作为一种分布式架构,其“土著居民”也应该是基于分布式架构设计出来的,而微服务或 Serverless 这种将服务或函数拆分成一个个模块的松耦合系统,天然具备分布式设计的属性。这是 Native 的第一种表现。
其次云作为一种 PaaS 服务,这位“土著居民”从出生(设计)到成长(开发),再到生活(部署)都应该是基于云的理念来实现的,那么就需要一套自动化的开发流程 CI/CD 来实现。这是 Native 的第二种表现。
而最后“土著居民”的特点希望做到能够适应所有云端,都能做到无缝的运行和连接。
解读:前面三节都是来自《什么是云原生?聊聊云原生的今生》这篇文章中。
下面介绍云原生架构的一些关键技术点。涉及内容由微服务、分布式常见架构设计(性能、数据一致性、可扩展性、高可用)、研发流程、DevOps、组织文化等,可以根据目录选择性的看看,基本上都是一些介绍,详细的设计可以查看相关文档进一步了解。
Martin Fowler 与 James Lewis 共同提出了微服务的概念,定义了微服务架构是以开发一组小型服务的方式来开发一个独立的应用系统,每个服务都以一个独立进程的方式运行,每个服务与其他服务使用轻量级(通常是 HTTP API)通信机制。这些服务是围绕业务功能构建的,可以通过全自动部署机制独立部署,同时服务会使用最小规模的集中管理(例如 Docker)能力,也可以采用不同的编程语言和数据库。
微服务架构中的“微”字,并不代表足够小,应该解释为合适。
流行的微服务框架:spring-cloud/dubbo。
敏捷基础设施及公共基础服务是微服务架构成败的关键因素之一,能够简化业务开发。
可用性(Availability)是关于系统可以被使用的时间的描述,以丢失的时间为驱动(Be Driven by Lost Time)。
可用性公式:A=Uptime /(Uptime+Downtime)。其中,Uptime 是可用时间,Downtime 是不可用时间。
如果说错误是不可避免或者难以避免的,那么我们应该换一个思路,保证错误发生时,我们可以从容应对。
隔离是为了在系统发生故障时,限制传播范围和影响范围,特别要注意非核心系统的故障对核心系统的影响。
熔断器模式(Circuit Breaker Patten)的原理类似于家里的电路熔断器的原理。当发生短路或者超负荷时,熔断器能够主动熔断电路,以避免灾难发生。
Spring Cloud Hystrix 提供了熔断器、线程隔离等一系列服务保护的能力,使用起来非常简单,引入依赖的 JAR 包,通过简单的注解即可实现。
互联网公司普遍采用全链路压测的方式,来进一步预估容量。
该定理认为对于一个分布式计算系统来说,不可能同时满足以下三点:
分布式意味着必须满足分区容错性,也就是 P,因此一般只能是 AP 或 CP。
BASE 理论的核心思想是:如果无法做到强一致性,或者做到强一致性要付出很大的代价,那么应用可以根据自身业务特点,采用适当方式来使系统达到最终一致性,只要对最终用户没有影响,或者影响是可接受的即可。
如果多个服务分别向三个节点写数据,为了保证强一致,就必须要求三个节点全部写成功才返回;同步写三个节点的性能较低,如果换一个思路,一致性并不一定要在写数据的时候完成,可以在读的阶段再决策,只要每次能读到最新版本即可。
Quorum 机制就是要满足公式 W+R>N,式中 N 代表备份个数,W 代表要写入至少 W 份才认为成功,R 表示至少读取 R 个备份。
如果现在我们有三个节点,为了实现一致性,要确保有且只有一个是 Leader,另外两个为 Follower,只有 Leader 是可写的,Follower 只能读。管理节点 M 通过心跳判断各个节点的状态,用 M 去指定 Leader,一旦 Leader 死掉,就可以重新指定一个 Leader。
从数据存储的角度出发的,包括数据库、文件等。
以下一致性模型适应的场景为不会同时发生更新操作,或者同时发生更新操作时能够比较容易地化解。因为这里的数据更新默认有一个与之关联的所有者,此所有者拥有唯一被允许修改数据的权限,可以按照用户 ID 进行路由。
12 因素应用是一系列云原生应用架构的模式集合。这些模式可以用来说明什么样的应用才是云原生应用,关注速度、安全、通过声明式配置扩展、可横向扩展的无状态/无共享进程以及部署环境的整体松耦合。
在 12 因素的背景下,应用指的是独立可部署单元。组织中经常把一些互相协作的可部署单元称作一个应用。
能提高交付速度、更新频率,这两点是衡量一个公司能力的重要指标。
文化、技术、过程和人,其中团队文化才是最难改变的,技术方面包括基础设施即代码、全局监控、持续监控。
持续交付:降低交付周期,通过自动化工具实现设计、开发、测试、发布、运维各个阶段的重复性工作,通过工具实现标准化、规范化,降低出错概率。
对于开发过程来说,少交流、少沟通、少开会就是最高效的。
团队文化就好比土壤,要培养什么样的员工,就要有适合他的土壤。
设计系统的组织,其产生的设计和架构等价于组织间的沟通结构。通俗来讲,就是什么样的团队结构,就会设计出什么样的系统架构。如果将团队拆分为前端、后端、平台、数据库,那么系统也会按照前端、后端、平台、数据库结构隔离。
如果一个人心里想表述事项目标的 100%,当你在众人面前、在开会的场合用语言表达时,你说出来的只剩下 80%。而进入别人的耳朵时,由于文化水平、知识背景等关系,只留存了 60%。实际上,真正被别人理解了大概只有 40%。等到这些人遵照领悟的 40% 具体行动时,只具备了当初事项目标的 20% 了。三个月后信息只剩下 5% 了。
随着以 Kubernetes 为代表的云原生技术成为云计算的容器界面,Kubernetes 成为云计算的新一代操作系统。面向特定领域的后端云服务 (BaaS) 则是这个操作系统上的服务 API,存储、数据库、中间件、大数据、 AI 等领域的大量产品与技术都开始提供全托管的云形态服务,如今越来越多用户已习惯使用云服务,而不是自己搭建存储系统、部署数据库软件。
当这些 BaaS 云服务日趋完善时,Serverless 因为屏蔽了底层设施的运维复杂度,让开发人员可以将更多精力用于业务逻辑设计与实现,而逐渐成为云原生主流技术之一。Serverless 计算包含以下特征:
函数计算 (Function as a Service) 是 Serverless 中最具代表性的产品形态。通过把应用逻辑拆分多个函数,每个函数都通过事件驱动方式触发执行,例如当对象存储 (OSS) 中产生的上传 / 删除对象等事件, 能够自动、可靠地触发 FaaS 函数处理且每个环节都是弹性和高可用的,客户能够快速实现大规模数据的实时并行处理。同样的,通过消息中间件和函数计算的集成,客户可以快速实现大规模消息的实时处理。
Serverless 不足的地方:
Service Mesh 是分布式应用在微服务软件架构之上发展起来的新技术,旨在将那些微服务间的连接、安全、流量控制和可观测等通用功能下沉为平台基础设施,实现应用与平台基础设施的解耦。这个解耦意味着开发者无需关注 微服务相关治理问题而聚焦于业务逻辑本身,提升应用开发效率并加速业务探索和创新。换句话说,因为大量非功能性从业务进程剥离到另外进程中,Service Mesh 以无侵入的方式实现了应用轻量化,下图展示了 Service Mesh 的 典型架构:
在这张架构图中,Service A 调用 Service B 的所有请求,都被其下的 Proxy(在 Envoy 中是 Sidecar) 截获, 代理 Service A 完成到 Service B 的服务发现、熔断、限流等策略,而这些策略的总控是在 Control Plane 上配置。
服务网格的技术发展上数据平面与控制平面间的协议标准化是必然趋势。控制平面可以认为是注册中心及管理配置面板;数据平面可以认为是由服务化框架依赖的组件独立而成的一个进程,数据平面代理业务服务的注册发现、负载均衡、容错等能力。 为什么需要 Service Mesh:
由于云原生架构包含了 6 个关键架构维度(简写为 SESORA,Service + Elasticity + Serverless + Observability + Resilience + Automation),因此我们先定义关键维度的成熟度级别:
容器的标准化使用改变了软件开发方式,基于云原生的开发能够帮助我们构建更灵活、更强大的应用。近日,CNCF(云原生计算基金会)就发布了云原生开发现状的报告解读。
该报告通过对 17,000 多位软件开发人员的调查数据,对云原生开发深入分析,希望能够帮助大家更好地掌握云原生开发生态系统的当前状况。其要点包括:
据估计,全球云原生开发人员数量超过 470 万,占后端开发的 36%。其中包括 290 万使用编排的用户,以及 330 万使用云函数或 Serverless 架构的开发人员。二者分别占据了后端开发的 22% 和 25%。
该估算数据还考虑了 150 万同时使用编排和 Serverless 技术的开发人员。
全球范围内云原生技术的使用差异很大。
总的来说,欧洲和北美的容器使用率远超亚洲。容器的使用已在东欧得到普及,54% 的后端开发人员使用容器。北美和西欧等发达地区的使用率也很高。在北美、西欧和以色列,一半后端开发人员都使用了容器。同时在三个地区内,25%-26% 的后端开发人员采用编排技术来管理这些容器。
大洋洲地区云原生技术的使用情况非常独特。尽管容器的使用在该地区并没有其他地区那么普遍,但与全球其他地区相比,Serverless 以及容器编排等技术在大洋洲的普及率最高。
亚洲、中东和非洲地区的开发人员采用容器和云原生技术的速度较慢。中国的各大公司在向云的迁移方面一直滞后,并且云原生技术的使用也呈现同样的趋势。随着阿里巴巴的 CaaS 获得市场的青睐,相信将来东亚地区会涌现更多云原生开发人员。
云原生开发的灵活性让各个组织更灵活地操作分布式基础架构,并按需合理分配工作资源。
与未参与云原生的开发人员相比,云原生开发人员掌握的计算基础架构确实更多。这些开发人员更加愿意在私有云、公共云、混合云和本地服务器等四种环境中运行代码,且平均使用了1.8种环境,而未参与云原生开发人员的平均值为1.5。数据显示,270万云原生开发人员(58%)在公共云上运行后端代码,220万开发人员(47%)选择了私有云,选择本地服务器的开发人员为220万(47%),而选择混合云的开发人员为170万( 36%)。
无论是云原生开发人员还是传统开发人员,选择在本地服务器上运行代码的比例都相同。这表明,尽管云原生开发人员已经掌握了云的灵活性,但他们并未放弃本地服务器。
虽然开发人员采用了云原生开发策略,但运行这些软件的计算资源在各个行业往往各不相同。
例如,与本地服务器或私有云相比,软件公司更倾向于在公共云中运行代码。在软件公司工作的云原生开发人员中,近三分之二在公共云中运行代码,同时该行业一半的开发人员在私有云上运行代码。
数据分析、商业智能以及硬件领域的开发人员更倾向于在公共云上运行软件。与其他行业的平均水平相比,这些行业中的云原生开发人员在公共云中运行代码的概率高 7%。
在涉及敏感数据的行业工作的云原生开发人员更倾向于在本地服务器或私有云上运行代码。与其他行业相比,金融服务领域的云原生开发人员在本地服务器上运行代码的比例高 12%,而医疗保健领域的开发人员的比例高 8%。
他们希望通过本地计算,更好地控制敏感数据。
市场营销、娱乐和房地产领域的云原生开发人员不太可能在本地服务器上运行代码。这些行业的重点是内容,因此需要轻松快速地访问。可访问性和性能对这些领域的成功至关重要,而本地服务器可能无法满足这些要求。
另外,电信和政府/国防领域的云原生开发人员使用私有云、公共云和本地服务器的比例大致相同。这些开发人员使用公共云的比例相对较低。
“未来的软件一定是生长于云上的”,这是云原生理念的最核心假设。
随着互联网的发展到万物智联,5G、AIoT 等新技术的涌现,随处可见的计算需求已经成为现实。针对不同计算场景,容器运行时会有不同需求。KataContainer、Firecracker、gVisor、Unikernel 等新的容器运行时技术层出不穷,分别解决安全隔离性、执行效率和通用性三个不同维度要求。OCI(Open Container Initiative)标准的出现, 使不同技术采用一致的方式进行容器生命周期管理,进一步促进了容器引擎技术的持续创新。
Kubernetes 已经成为云时代的操作系统。对比 Linux 与 Kubernetes 概念模型,两者都定义了开放的、标准化的访问接口:向下封装资源,向上支撑应用。
它们都提供了对底层计算、存储、网络、异构计算设备的资源抽象和安全访问模型,可以根据应用需求进行资源调度和编排。Linux 的计算调度单元是进程,调度范围限制在一台计算节点。而 Kubernetes 调度单位是 Pod, 可以在分布式集群中进行资源调度,甚至跨越不同云环境。
过往 Kubernetes 上主要运行着无状态的 Web 应用。随着技术演进和社区发展,越来越多有状态应用和大数据 / AI 应用负载逐渐迁移到 Kubernetes 上。Flink、Spark 等开源社区以及 Cloudera、Databricks 等商业公司都 开始加大对 Kubernetes 的支持力度。
统一技术栈提升资源利用率:多种计算负载在 Kubernetes 集群统一调度,可以有效提升资源利用率。
统一技能栈降低人力成本:Kubernetes 可以在 IDC、云端、边缘等不同场景进行统一部署和交付。云原生提 倡的 DevOps 文化和工具集可以有效提升技术迭代速度并降低人力成本。
加速数据服务的云原生化:由于计算存储分离具备巨大的灵活性和成本优势,数据服务的云原生化也逐渐成为 趋势。容器和 Serverless 的弹性可以简化对计算任务的容量规划。结合分布式缓存加速(比如 Alluxio 或阿里云 Jindofs)和调度优化,大大提升数据计算类和 AI 任务的计算效率。
Serverless 和容器技术也开始融合得到了快速的发展。通过 Serverless 容器,一方面根本性解决 Kubernetes 自身复杂性问题,让用户无需受困于 Kubernetes 集群容量规划、安全维护、故障诊断等运维工作; 一方面进一步释放云计算能力,将安全、可用性、可伸缩性等需求下沉到基础设施实现。
上云已是大势所趋,但对于企业而言,有些业务出于对数据主权、安全隐私的考量,会采用混合云架构。一些企业为了满足安全合规、成本优化、提升地域覆盖性和避免云厂商锁定等需求,会选择多个云厂商。混合云 / 多云架构已成为企业上云新常态。Gartner 指出“到 2021,超过 75% 的大中型组织将采用多云或者混合 IT 战略。”
Kubenetes 已经成为了云原生的操作系统,而容器成为了操作系统调度的基本单元,同时定义了应用交付的标准。但对于开发者来说,这些还远没有深入到应用的架构,改变应用的编程界面。但是这种变革已经在悄然发生了,而且有不断加速之势。
综上,包括生命周期管理、运维管理、配置范围和扩展和管理、以及语言无关的编程框架,一起构成了崭新的应用与云之间的编程界面。这一变革的核心逻辑还是把应用中和业务无关的逻辑和职责,剥离到云服务,并在这一过程中形成标准,让应用开发者能够在专有云、公有云或者混合云的场景中,能有一致的研发运维体验。
将应用程序的组件部署到单独的进程或容器中以提供隔离和封装。这种模式还可以使应用程序由异构组件和技术组成,该模式被命名为 Sidecar,因为它类似于连接到摩托车的辅助车,辅助车被附加到父应用程序并为应用程序提供支持功能。
近年来,Serverless 一直在高速发展,呈现出越来越大的影响力。在这样的趋势下,主流云服务商也在不断丰富云产品体系,提供更便捷的开发工具,更高效的应用交付流水线,更完善的可观测性,更丰富的产品间集成。
任何足够复杂的技术方案都可能被实现为全托管、Serverless 化的后端服务。不只是云产品,也包括来自合作 伙伴和三方的服务,云及其生态的能力将通过 API + Serverless 来体现。事实上,对于任何以 API 作为功能透出方式的平台型产品或组织,Serverless 都将是其平台战略中最重要的部分。
通过事件驱动和云服务连接,Serverless 能力也会扩展到整个云生态。
虚拟机和容器是两种取向不同的虚拟化技术,前者安全性强、开销大,后者则相反。Serverless 计算平台一方面要求兼得最高的安全性和最小的资源开销,另一方面要保持对原有程序执行方式的兼容,比如支持任意二进制文件, 这使得适用于特定语言 VM 的方案不可行。
当 Serverless 计算的规模与影响力变得越来越大,在应用框架、语言、硬件等层面上根据 Serverless 负载特点进行端对端优化就变得非常有意义。新的 Java 虚拟机技术大幅提高了 Java 应用启动速度,非易失性内存帮助实例更快被唤醒,CPU 硬件与操作系统协作对高密环境下性能扰动实现精细隔离,新技术正在创造崭新的计算环境。
实现最佳性能功耗比和性能价格比的另一个重要方向是支持异构硬件。由于 x86 处理器的性能越来越难以提升,而在 AI 等对算力要求极高的场景,GPU、FPGA、TPU(Tensor Processing Units)等架构处理器的计算效率更具优势。随着异构硬件虚拟化、资源池化、异构资源调度和应用框架支持的成熟,异构硬件的算力也能通过 Serverless 的方式释放,大幅降低企业使用门槛。