作者 | 潘义文(空易)
来源|阿里巴巴云原生公众号
起源
1. 云原生(Cloud Native)的由来
云原生的概念最早开始于 2010 年,在当时 Paul Fremantle 的一篇博客中被提及,他一直想用一个词表达一种架构,这种架构能描述应用程序和中间件在云环境中的良好运行状态。因此他抽象出了 Cloud Native 必须包含的属性,只有满足了这些属性才能保证良好的运行状态。当时提出云原生是为了能构建一种符合云计算特性的标准来指导云计算应用的编写。
后来到 2013 年 Matt Stine 在推特上迅速推广云原生概念,并在 2015 年《迁移到云原生架构》一书中定义了符合云原生架构的特征:12 因素、微服务、自服务、基于 API 协作、扛脆弱性。而由于这本书的推广畅销,这也成了很多人对云原生的早期印象,同时云原生也被 12 要素变成了一个抽象的概念。Matt Stine 认为在单体架构向 Cloud Native 迁移的过程中,需要文化、组织、技术共同变革。 解读:**云原生架构本质上也是一种软件架构,最大的特点是在云环境下运行,也算是微服务的一种延伸**。
2. CNCF 基金会成立及云原生概念的演化
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.
总结一下就是:
-
基于容器、服务网格、微服务、不可变基础设施和声明式 API 构建的可弹性扩展的应用。
-
基于自动化技术构建具备高容错性、易管理和便于观察的松耦合系统。
-
构建一个统一的开源云技术生态,能和云厂商提供的服务解耦。
可以看出,CNCF 在当前定义基础上加上了服务网格 (service mesh) 和声明式 API,这为云原生的概念阐述增加了更深一层的意义,也就是建立一个相对中立的开源云生态。这对云原生的生态定位是很重要的,也算 CNCF 最初成立的宗旨之一,打破云巨头的垄断。
解读:概念随着新的技术发展而演化
- 第一阶段:容器化封装+自动化管理+面向微服务
- 第二阶段:DevOps、持续交付、微服务、容器
- 第三阶段:DevOps、持续交付、容器、服务网格、微服务、声明式API
3. 对云原生的解构
对一个词的解读,除了看其历史发展背景,还有一种偏向于语言学的方法解读,也就是我们常说的从“字面意思”来理解。
Cloud Native,从词面上拆解其实就是 Cloud 和 Native,也就是云计算和土著的意思——云计算上的原生居民,即天生具备云计算的亲和力。
首先从 Cloud 来理解,云可以看作是一种提供稳定计算存储资源的对象。为了实现这一点,云提供了像虚拟化、弹性扩展、高可用、高容错性、自恢复等基本属性,这是云原生作为一种云计算所具备的第一层含义。第二层要从 Native 来看,云原生和在云上跑的传统应用不同。一些基于公有云搭建的应用是基于传统的 SOA 架构来搭建的,然后再移植到云上去运行,那么这些应用和云的整合非常低。
为什么低呢?云作为一种分布式架构,其“土著居民”也应该是基于分布式架构设计出来的,而微服务或 Serverless 这种将服务或函数拆分成一个个模块的松耦合系统,天然具备分布式设计的属性。这是 Native 的第一种表现。
其次云作为一种 PaaS 服务,这位“土著居民”从出生(设计)到成长(开发),再到生活(部署)都应该是基于云的理念来实现的,那么就需要一套自动化的开发流程 CI/CD 来实现。这是 Native 的第二种表现。
而最后“土著居民”的特点希望做到能够适应所有云端,都能做到无缝的运行和连接。
解读:前面三节都是来自《什么是云原生?聊聊云原生的今生》这篇文章中。
关键点
下面介绍云原生架构的一些关键技术点。涉及内容由微服务、分布式常见架构设计(性能、数据一致性、可扩展性、高可用)、研发流程、DevOps、组织文化等,可以根据目录选择性的看看,基本上都是一些介绍,详细的设计可以查看相关文档进一步了解。
1. 微服务
Martin Fowler 与 James Lewis 共同提出了微服务的概念,定义了微服务架构是以开发一组小型服务的方式来开发一个独立的应用系统,每个服务都以一个独立进程的方式运行,每个服务与其他服务使用轻量级(通常是 HTTP API)通信机制。这些服务是围绕业务功能构建的,可以通过全自动部署机制独立部署,同时服务会使用最小规模的集中管理(例如 Docker)能力,也可以采用不同的编程语言和数据库。
1)优势
-
敏捷开发帮助我们减少浪费、快速反馈,以用户体验为目标。
-
持续交付促使我们更快、更可靠、更频繁地改进软件;基础设施即代码(Infrastructure As Code)帮助我们简化环境的管理。
2)什么时候开始微服务架构
-
几乎所有成功的微服务架构都是从一个巨大的单体架构开始的,并且都是由于单体架构太大而被拆分为微服务架构。
-
在所一开始就构建微服务架构的故事中,往往都有人遇到了巨大的麻烦。
3)如何决定微服务架构的拆分粒度
微服务架构中的“微”字,并不代表足够小,应该解释为合适。
4)单体架构 VS 微服务架构对比
流行的微服务框架:spring-cloud/dubbo。
2. 敏捷基础设施及公共基础服务
敏捷基础设施及公共基础服务是微服务架构成败的关键因素之一,能够简化业务开发。
1)敏捷基础设施的目标
- 标准化:所有的基础设施最好都是标准的。
- 可替换:任意节点都能够被轻易地创建、销毁、替换。
- 自动化:所有的操作都通过工具自动化完成,无须人工干预。
- 可视化:当前环境要做到可控,就需要对当前的环境状况可视。
- 可追溯:所有的配置统一作为代码进行版本化管理,所有的操作都可以追溯。
- 快速:资源申请及释放要求秒级完成,以适应弹性伸缩和故障切换的要求。
2)基于公共基础服务的平台化
-
平台化是指利用公共基础服务提升整体架构能力。
-
公共基础服务是指与业务无关的、通用的服务,包括监控服务、缓存服务、消息服务、数据库服务、负载均衡、分布式协调、分布式任务调度等。
3)常见的平台服务
- 监控告警服务
- 分布式消息中间件服务
- 分布式缓存服务
- 分布式任务调度服务
3. 分布式架构 - 可用性设计
可用性(Availability)是关于系统可以被使用的时间的描述,以丢失的时间为驱动(Be Driven by Lost Time)。
可用性公式:A=Uptime /(Uptime+Downtime)。其中,Uptime 是可用时间,Downtime 是不可用时间。
1)什么降低了可用性
-
发布
-
故障
-
压力
-
外部依赖
2)设计阶段考虑如下几个比较重要的方法
- 20/10/5,设计系统的时候,以实际流量的 20 倍来设计;开发系统的时候,以实际流量的 10 倍来开发系统;发布系统的时候,以实际流量的 5 倍来部署。这只是一个通用的原则,可以根据实际情况来确定,不需要严格按照倍数来执行。
- Design for failure,预测可能发生的问题,做好预案。
3)容错设计
如果说错误是不可避免或者难以避免的,那么我们应该换一个思路,保证错误发生时,我们可以从容应对。
- 消除单点
- 特性开关
- 服务分级
- 降级设计
- 超时重试
4)隔离策略
隔离是为了在系统发生故障时,限制传播范围和影响范围,特别要注意非核心系统的故障对核心系统的影响。
- 线程池隔离
- 进程隔离
- 集群隔离
- 用户隔离
- 租户隔离
- 逻辑隔离
- 物理隔离
- 混合隔离
5)熔断器
熔断器模式(Circuit Breaker Patten)的原理类似于家里的电路熔断器的原理。当发生短路或者超负荷时,熔断器能够主动熔断电路,以避免灾难发生。
Spring Cloud Hystrix 提供了熔断器、线程隔离等一系列服务保护的能力,使用起来非常简单,引入依赖的 JAR 包,通过简单的注解即可实现。
6)流控设计
-
限流算法。限流也就是调节数据流的平均速率,通过限制速率保护自己,常见的算法有:
- 固定窗口算法(fixed window)。
- 漏桶算法(Leaky Bucket):漏桶算法主要目的是控制数据注入网络的速率,平滑网络上的突发流量。
- 令牌桶算法(token bucket):令牌桶控制的是一个时间窗口内通过的数据量,通常我们会以 QPS、TPS 来衡量。
-
流控策略
-
请求入口处。
-
业务服务入口处。
-
公共基础服务处。
-
基于 Guava 限流:Guava 是 Google 提供的 Java 扩展类库,其中的限流工具类 RateLimiter 采用的就是令牌桶算法,使用起来非常简单。
-
基于 Nginx 限流。
-
7)容量预估
互联网公司普遍采用全链路压测的方式,来进一步预估容量。
8)故障演练
- 随机关闭生产环境中的实例。
- 让某台机器的请求或返回变慢,观察系统的表现,可以用来测试上游服务是否有服务降级能力,当然如果响应时间特别长,也就相当于服务不可用。
- 模拟 AZ 故障,中断一个机房,验证是否跨可用区部署,业务容灾和恢复的能力。
- 查找不符合最佳实践的实例,并将其关闭。
9)数据迁移
- 逻辑分离,物理不分离。
- 物理分离 。
4. 分布式架构 - 可扩展设计
- 水平扩展,指用更多的节点支撑更大量的请求。
- 横向扩展通常是为了提升吞吐量,响应时间一般要求不受吞吐量影响即可。
1)AKF 扩展立方体
2)如何扩展数据库
- X 轴扩展——主从复制集群
- Y 轴扩展——分库、垂直分表
- Z 轴扩展——分片(sharding)
5. 分布式架构 - 性能设计
1)性能指标
- 响应时间(Latency),就是发送请求和返回结果的耗时。
- 吞吐量(Throughput),就是单位时间内的响应次数。
- 负载敏感度,是指响应时间随时间变化的程度。例如,当用户增加时,系统响应时间的衰减速度。
- 可伸缩性,是指向系统增加资源对性能的影响。例如,要使吞吐量增加一倍,需要增加多少服务器。
2)如何树立目标
-
通过缓存提升读性能。
-
通过消息中间件提升写性能。
6. 分布式架构 - 一致性设计
1)事务的四大特征
- 原子性(Atomicity)。
- 一致性(Consistency)是指通过事务保证数据从一种状态变化到另一种状态。
- 隔离性(Isolation)是指事务内的操作不受其他操作影响,当多个事务同时处理同一个数据的时候,多个事务之间是互不影响的。
- 持久性(Durability)是指事务被提交后,应该持久化,永久保存下来。
2)CPA 定理
该定理认为对于一个分布式计算系统来说,不可能同时满足以下三点:
- 一致性(Consistence)
- 可用性(Availability)
- 分区容错性(Partition tolerance)
分布式意味着必须满足分区容错性,也就是 P,因此一般只能是 AP 或 CP。
3)BASE 理论
BASE 理论的核心思想是:如果无法做到强一致性,或者做到强一致性要付出很大的代价,那么应用可以根据自身业务特点,采用适当方式来使系统达到最终一致性,只要对最终用户没有影响,或者影响是可接受的即可。
- BA:Basically Available,基本可用。
- S:Soft state,软状态。
- E:Eventually consistent,最终一致。
4)Quorum 机制(NWR 模型)
如果多个服务分别向三个节点写数据,为了保证强一致,就必须要求三个节点全部写成功才返回;同步写三个节点的性能较低,如果换一个思路,一致性并不一定要在写数据的时候完成,可以在读的阶段再决策,只要每次能读到最新版本即可。
Quorum 机制就是要满足公式 W+R>N,式中 N 代表备份个数,W 代表要写入至少 W 份才认为成功,R 表示至少读取 R 个备份。
5)租约机制(Lease)
如果现在我们有三个节点,为了实现一致性,要确保有且只有一个是 Leader,另外两个为 Follower,只有 Leader 是可写的,Follower 只能读。管理节点 M 通过心跳判断各个节点的状态,用 M 去指定 Leader,一旦 Leader 死掉,就可以重新指定一个 Leader。
6)脑裂问题
- 一种是采用投票机制(Paxos 算法)。
- 一种是采用租约机制——Lease,租约机制的核心就是在一定时间内将权力下放。
7)分布式系统的一致性分类
- 建立多个副本。可以把副本放到不同的物理机、机架、机房、地域,当一个副本失效时,可以让请求转到其他副本。
- 对数据进行分区。复制多个副本解决了读的性能问题,但是无法解决写的性能问题。
8)以数据为中心的一致性模型
从数据存储的角度出发的,包括数据库、文件等。
- 严格一致性(Strict Consistency)
- 顺序一致性(Sequential Consistency)
- 因果一致性(Causal Consistency)
9)以用户为中心的一致性模型
以下一致性模型适应的场景为不会同时发生更新操作,或者同时发生更新操作时能够比较容易地化解。因为这里的数据更新默认有一个与之关联的所有者,此所有者拥有唯一被允许修改数据的权限,可以按照用户 ID 进行路由。
- 单调读一致性(Monotonic-read Consistency)
- 单调写一致性(Monotonic-write Consistency)
- 写后读一致性(Read-your-writes Consistency)
- 读后写一致性(Writes-follow-reads Consistency)
10)业界常用的一致性模型
- 弱一致性:写入一个数据 a 成功后,在数据副本上可能读出来,也可能读不出来。不能保证每个副本的数据一定是一致的。
- 最终一致性(Eventual Consistency):写入一个数据 a 成功后,在其他副本有可能读不到 a 的最新值,但在某个时间窗口之后保证最终能读到。
- 强一致性(Strong Consistency):数据 a 一旦写入成功,在任意副本任意时刻都能读到 a 的最新值。
11)如何实现强一致性
- 两阶段提交
- 三阶段提交(3PC)
12)如何实现最终一致性
- 重试机制:超时时间,重试的次数,重试的间隔时间,重试间隔时间的衰减度。
- 本地记录日志。
- 可靠事件模式。
- Saga 事务模型:又叫 Long-running-transaction,核心思想是把一个长事务拆分为多个本地事务来实现,由一个 Process manager 统一协调。
- TCC 事务模型:两阶段提交是依赖于数据库提供的事务机制,再配合外部的资源协调器来实现分布式事务。TCC(Try Confirm Cancel)事务模型的思想和两阶段提交虽然类似,但是却把相关的操作从数据库提到业务中,以此降低数据库的压力,并且不需要加锁,性能也得到了提升。
7. 十二因素
12 因素应用是一系列云原生应用架构的模式集合。这些模式可以用来说明什么样的应用才是云原生应用,关注速度、安全、通过声明式配置扩展、可横向扩展的无状态/无共享进程以及部署环境的整体松耦合。
在 12 因素的背景下,应用指的是独立可部署单元。组织中经常把一些互相协作的可部署单元称作一个应用。
- 基准代码,一份基准代码,多份部署,使用 GIT 或者 SVN 管理代码,并且有明确的版本信息。
- 依赖,显示声明依赖。
- 配置:环境中存储配置。
- 后端服务:把后端服务当作附加资源。后端服务是指程序运行所需要的通过网络调用的各种服务,如数据库(MySQL、CouchDB)、消息/队列系统(RabbitMQ、Beanstalkd)、SMTP 邮件发送服务(Postfix),以及缓存系统(Memcached)。
- 构建、发布、运行:严格分离构建和运行。
- 进程,以一个或多个无状态进程运行应用,如果存在状态,应该将状态外置到后端服务中,例如数据库、缓存等。
- 端口绑定,通过端口绑定提供服务,应用通过端口绑定来提供服务,并监听发送至该端口的请求。
- 并发,通过进程模型进行扩展,扩展方式有进程和线程两种。进程的方式使扩展性更好,架构更简单,隔离性更好。线程扩展使编程更复杂,但是更节省资源。
- 易处理,快速启动和优雅终止可最大化健壮性,只有满足快速启动和优雅终止,才能使服务更健壮。
- 开发环境与线上环境等价,尽可能保持开发、预发布、线上环境相同。
- 日志,把日志当作事件流,微服务架构中服务数量的爆发需要具备调用链分析能力,快速定位故障。
- 管理进程,把后台管理任务当作一次性进程运行,一些工具类在生产环境上的操作可能是一次性的,因此最好把它们放在生产环境中执行,而不是本地。
8. 研发流程
1)为什么选择 DevOps
能提高交付速度、更新频率,这两点是衡量一个公司能力的重要指标。
2)Gartner 提出的 DevOps 模型
文化、技术、过程和人,其中团队文化才是最难改变的,技术方面包括基础设施即代码、全局监控、持续监控。
3)自动化测试
- 自动化测试可以代替人工测试。
- 测试成了全栈工程师的工作,因为不沟通才是最有效率的沟通。
4)Code Review
- 提升代码易读性。
- 统一规范、标准。
- 技术交流,提升能力。
- Code Review 原则:以发现问题为目标,团队开放、透明,整个 Code Review 的过程对事不对人,不设置惩罚。
- 线上线下接合的方式,长期线上,定期线下。
5)流水线
持续交付:降低交付周期,通过自动化工具实现设计、开发、测试、发布、运维各个阶段的重复性工作,通过工具实现标准化、规范化,降低出错概率。
6)开发人员自服务
对于开发过程来说,少交流、少沟通、少开会就是最高效的。
- 高覆盖率的自动化测试
- 全面的监控
- 持续交付流水线
- 敏捷基础设施
- 自动化/智能化运维
- 好的架构
- 全栈工程师
- 服务型管理
- 工程师文化
- 信任文化
- 分享文化
7)代码即设计
-
模糊敏捷研发流程阶段性:业务需求太多和技术变化速度太快。
-
整个进化设计需要简单的架构+持续集成+重构+整个研发流程设计。
9. 团队文化
团队文化就好比土壤,要培养什么样的员工,就要有适合他的土壤。
1)团队规模导致的问题
- 缺乏信任。由于人数众多,难于管理,只能通过制度、流程、规范、绩效约束。
- 没有责任感。高层管理者忙着开各种决策会议。
- 部门墙。跨部门协调还不如与第三方合作。
- 不尊重专业人士。当所有的生杀大权都掌握在少数人手中的时候。
- 管理层级太深。管理层级太深导致的问题很多。
2)组织结构 - 康威定律
设计系统的组织,其产生的设计和架构等价于组织间的沟通结构。通俗来讲,就是什么样的团队结构,就会设计出什么样的系统架构。如果将团队拆分为前端、后端、平台、数据库,那么系统也会按照前端、后端、平台、数据库结构隔离。
- 第一定律:Communication dictates design,即组织沟通方式会通过系统设计呈现。
- 第二定律:There is never enough time to do something right,but there is always enough time to do it over,即时间再多,一件事情也不可能做得完美,但总有时间做完一件事情。
- 第三定律:There is a homomorphism from the linear graph of a system to the linear graph of its design organization,即线型系统和线型组织架构间有潜在的异质同态特性。
- 第四定律:The structures of large systems tend to disintegrate during development,qualitatively more so than with small systems,即大的系统组织总是比小系统更倾向于分解。
3)“沟通漏斗”是指工作中团队沟通效率下降的一种现象
如果一个人心里想表述事项目标的 100%,当你在众人面前、在开会的场合用语言表达时,你说出来的只剩下 80%。而进入别人的耳朵时,由于文化水平、知识背景等关系,只留存了 60%。实际上,真正被别人理解了大概只有 40%。等到这些人遵照领悟的 40% 具体行动时,只具备了当初事项目标的 20% 了。三个月后信息只剩下 5% 了。
4)环境氛围
- 公开透明的工作环境.
- 学习型组织:让团队拥有共同愿景、目标,并持续学习。
- 减少无效的正式汇报。
- 高效的会议:缩小会议范围,常规会议不应该超过 45 分钟;限制“意见领袖”的发言时长;会议中不允许开小差;会议中的分歧不应该延伸到会议之外。
10. Serverless
随着以 Kubernetes 为代表的云原生技术成为云计算的容器界面,Kubernetes 成为云计算的新一代操作系统。面向特定领域的后端云服务 (BaaS) 则是这个操作系统上的服务 API,存储、数据库、中间件、大数据、 AI 等领域的大量产品与技术都开始提供全托管的云形态服务,如今越来越多用户已习惯使用云服务,而不是自己搭建存储系统、部署数据库软件。
当这些 BaaS 云服务日趋完善时,Serverless 因为屏蔽了底层设施的运维复杂度,让开发人员可以将更多精力用于业务逻辑设计与实现,而逐渐成为云原生主流技术之一。Serverless 计算包含以下特征:
- 全托管的计算服务,客户只需要编写代码构建应用,无需关注同质化的、负担繁重的基础设施开发、运维、安全、高可用等工作。
- 通用性,结合云 BaaS API 的能力,能够支撑云上所有重要类型的应用。
- 自动的弹性伸缩,让用户无需为资源使用提前进行容量规划。
- 按量计费,让企业使用成本得有效降低,无需为闲置资源付费。
函数计算 (Function as a Service) 是 Serverless 中最具代表性的产品形态。通过把应用逻辑拆分多个函数,每个函数都通过事件驱动方式触发执行,例如当对象存储 (OSS) 中产生的上传 / 删除对象等事件, 能够自动、可靠地触发 FaaS 函数处理且每个环节都是弹性和高可用的,客户能够快速实现大规模数据的实时并行处理。同样的,通过消息中间件和函数计算的集成,客户可以快速实现大规模消息的实时处理。
Serverless 不足的地方:
- 成功案例太少
- 很难满足个性化
- 缺乏行业标准
- 初次访问性能差
- 缺乏开发调试工具
11. Service Mesh 技术
Service Mesh 是分布式应用在微服务软件架构之上发展起来的新技术,旨在将那些微服务间的连接、安全、流量控制和可观测等通用功能下沉为平台基础设施,实现应用与平台基础设施的解耦。这个解耦意味着开发者无需关注 微服务相关治理问题而聚焦于业务逻辑本身,提升应用开发效率并加速业务探索和创新。换句话说,因为大量非功能性从业务进程剥离到另外进程中,Service Mesh 以无侵入的方式实现了应用轻量化,下图展示了 Service Mesh 的 典型架构:
在这张架构图中,Service A 调用 Service B 的所有请求,都被其下的 Proxy(在 Envoy 中是 Sidecar) 截获, 代理 Service A 完成到 Service B 的服务发现、熔断、限流等策略,而这些策略的总控是在 Control Plane 上配置。
服务网格的技术发展上数据平面与控制平面间的协议标准化是必然趋势。控制平面可以认为是注册中心及管理配置面板;数据平面可以认为是由服务化框架依赖的组件独立而成的一个进程,数据平面代理业务服务的注册发现、负载均衡、容错等能力。 为什么需要 Service Mesh:
- 在微服务架构中,让开发人员感觉不到微服务之间的通信。
- 当服务数量越来越多,升级微服务框架变得越来越复杂的时候,微服务框架不可能一直不变且没有 bug。
- Service Mesh 则从业务进程集成客户端的方式演进为独立进程的方式,客户端变成了一个独立进程。
- 对这个独立进程升级、运维要比绑在一起强得多。
- 微服务架构更强调去中心化、独立自治、跨语言。Service Mesh 通过独立进程的方式进行隔离,低成本实现跨语言。
- 每个服务独立占用一个容器,将服务、依赖包、操作系统、监控运维所需的代理打包成一个镜像。这种模式促成了 Service Mesh 的发展,让 Service Mesh 实现起来更容易。
12. 云原生架构成熟度模型
由于云原生架构包含了 6 个关键架构维度(简写为 SESORA,Service + Elasticity + Serverless + Observability + Resilience + Automation),因此我们先定义关键维度的成熟度级别:
现状
容器的标准化使用改变了软件开发方式,基于云原生的开发能够帮助我们构建更灵活、更强大的应用。近日,CNCF(云原生计算基金会)就发布了云原生开发现状的报告解读。
该报告通过对 17,000 多位软件开发人员的调查数据,对云原生开发深入分析,希望能够帮助大家更好地掌握云原生开发生态系统的当前状况。其要点包括:
- 全球云原生开发人员超过 470 万。
- 使用 Kubernetes 的开发人员超过 170 万。
- 使用 Serverless 架构及云函数的开发人员超过 330 万。
- Kubernetes 用户更有可能影响购买决策。
1. 市场规模
据估计,全球云原生开发人员数量超过 470 万,占后端开发的 36%。其中包括 290 万使用编排的用户,以及 330 万使用云函数或 Serverless 架构的开发人员。二者分别占据了后端开发的 22% 和 25%。
该估算数据还考虑了 150 万同时使用编排和 Serverless 技术的开发人员。
2. 各个国家及地区的情况
全球范围内云原生技术的使用差异很大。
总的来说,欧洲和北美的容器使用率远超亚洲。容器的使用已在东欧得到普及,54% 的后端开发人员使用容器。北美和西欧等发达地区的使用率也很高。在北美、西欧和以色列,一半后端开发人员都使用了容器。同时在三个地区内,25%-26% 的后端开发人员采用编排技术来管理这些容器。
大洋洲地区云原生技术的使用情况非常独特。尽管容器的使用在该地区并没有其他地区那么普遍,但与全球其他地区相比,Serverless 以及容器编排等技术在大洋洲的普及率最高。
亚洲、中东和非洲地区的开发人员采用容器和云原生技术的速度较慢。中国的各大公司在向云的迁移方面一直滞后,并且云原生技术的使用也呈现同样的趋势。随着阿里巴巴的 CaaS 获得市场的青睐,相信将来东亚地区会涌现更多云原生开发人员。
3. 云原生开发人员掌握多种基础架构
云原生开发的灵活性让各个组织更灵活地操作分布式基础架构,并按需合理分配工作资源。
与未参与云原生的开发人员相比,云原生开发人员掌握的计算基础架构确实更多。这些开发人员更加愿意在私有云、公共云、混合云和本地服务器等四种环境中运行代码,且平均使用了1.8种环境,而未参与云原生开发人员的平均值为1.5。数据显示,270万云原生开发人员(58%)在公共云上运行后端代码,220万开发人员(47%)选择了私有云,选择本地服务器的开发人员为220万(47%),而选择混合云的开发人员为170万( 36%)。
无论是云原生开发人员还是传统开发人员,选择在本地服务器上运行代码的比例都相同。这表明,尽管云原生开发人员已经掌握了云的灵活性,但他们并未放弃本地服务器。
4. 云的使用在各个行业各不相同
虽然开发人员采用了云原生开发策略,但运行这些软件的计算资源在各个行业往往各不相同。
例如,与本地服务器或私有云相比,软件公司更倾向于在公共云中运行代码。在软件公司工作的云原生开发人员中,近三分之二在公共云中运行代码,同时该行业一半的开发人员在私有云上运行代码。
数据分析、商业智能以及硬件领域的开发人员更倾向于在公共云上运行软件。与其他行业的平均水平相比,这些行业中的云原生开发人员在公共云中运行代码的概率高 7%。
在涉及敏感数据的行业工作的云原生开发人员更倾向于在本地服务器或私有云上运行代码。与其他行业相比,金融服务领域的云原生开发人员在本地服务器上运行代码的比例高 12%,而医疗保健领域的开发人员的比例高 8%。
他们希望通过本地计算,更好地控制敏感数据。
市场营销、娱乐和房地产领域的云原生开发人员不太可能在本地服务器上运行代码。这些行业的重点是内容,因此需要轻松快速地访问。可访问性和性能对这些领域的成功至关重要,而本地服务器可能无法满足这些要求。
另外,电信和*/国防领域的云原生开发人员使用私有云、公共云和本地服务器的比例大致相同。这些开发人员使用公共云的比例相对较低。
未来
“未来的软件一定是生长于云上的”,这是云原生理念的最核心假设。
1. 容器技术发展趋势
1)趋势一:无处不在的计算催生新一代容器实现
随着互联网的发展到万物智联,5G、AIoT 等新技术的涌现,随处可见的计算需求已经成为现实。针对不同计算场景,容器运行时会有不同需求。KataContainer、Firecracker、gVisor、Unikernel 等新的容器运行时技术层出不穷,分别解决安全隔离性、执行效率和通用性三个不同维度要求。OCI(Open Container Initiative)标准的出现, 使不同技术采用一致的方式进行容器生命周期管理,进一步促进了容器引擎技术的持续创新。
2)趋势二:云原生操作系统开始浮现
Kubernetes 已经成为云时代的操作系统。对比 Linux 与 Kubernetes 概念模型,两者都定义了开放的、标准化的访问接口:向下封装资源,向上支撑应用。
它们都提供了对底层计算、存储、网络、异构计算设备的资源抽象和安全访问模型,可以根据应用需求进行资源调度和编排。Linux 的计算调度单元是进程,调度范围限制在一台计算节点。而 Kubernetes 调度单位是 Pod, 可以在分布式集群中进行资源调度,甚至跨越不同云环境。
过往 Kubernetes 上主要运行着无状态的 Web 应用。随着技术演进和社区发展,越来越多有状态应用和大数据 / AI 应用负载逐渐迁移到 Kubernetes 上。Flink、Spark 等开源社区以及 Cloudera、Databricks 等商业公司都 开始加大对 Kubernetes 的支持力度。
统一技术栈提升资源利用率:多种计算负载在 Kubernetes 集群统一调度,可以有效提升资源利用率。
统一技能栈降低人力成本:Kubernetes 可以在 IDC、云端、边缘等不同场景进行统一部署和交付。云原生提 倡的 DevOps 文化和工具集可以有效提升技术迭代速度并降低人力成本。
加速数据服务的云原生化:由于计算存储分离具备巨大的灵活性和成本优势,数据服务的云原生化也逐渐成为 趋势。容器和 Serverless 的弹性可以简化对计算任务的容量规划。结合分布式缓存加速(比如 Alluxio 或阿里云 Jindofs)和调度优化,大大提升数据计算类和 AI 任务的计算效率。
3)趋势三:Serverless 容器技术逐渐成为市场主流
Serverless 和容器技术也开始融合得到了快速的发展。通过 Serverless 容器,一方面根本性解决 Kubernetes 自身复杂性问题,让用户无需受困于 Kubernetes 集群容量规划、安全维护、故障诊断等运维工作; 一方面进一步释放云计算能力,将安全、可用性、可伸缩性等需求下沉到基础设施实现。
4)趋势四:动态、混合、分布式的云环境将成为新常态
上云已是大势所趋,但对于企业而言,有些业务出于对数据主权、安全隐私的考量,会采用混合云架构。一些企业为了满足安全合规、成本优化、提升地域覆盖性和避免云厂商锁定等需求,会选择多个云厂商。混合云 / 多云架构已成为企业上云新常态。Gartner 指出“到 2021,超过 75% 的大中型组织将采用多云或者混合 IT 战略。”
2. 基于云原生的新一代应用编程界面
Kubenetes 已经成为了云原生的操作系统,而容器成为了操作系统调度的基本单元,同时定义了应用交付的标准。但对于开发者来说,这些还远没有深入到应用的架构,改变应用的编程界面。但是这种变革已经在悄然发生了,而且有不断加速之势。
-
Sidecar 架构彻底改变了应用的运维架构。由于 Sidecar 架构支持在运行时隔离应用容器与其他容器,因此 原本在虚拟机时代和业务进程部署在一起的大量运维及管控工具都被剥离到独立的容器里进行统一管理。对于应用来说,仅仅是按需声明使用运维能力,能力实现成为云平台的职责。
-
应用生命周期全面托管。在容器技术基础上,应用进一步描述清晰自身状态(例如通过 Liveness Probe), 描述自身的弹性指标以及通过 Service Mesh 和 Serverless 技术将流量托管给云平台。云平台能够全面管理应用的生命周期,包括服务的上下线、版本升级、完善的流量调配、容量管理等保障业务稳定性。
-
用声明式配置方式使用云服务。云原生应用的核心特点之一就是大量依赖云服务(包括数据库、缓存、消息等) 构建,以实现快速交付。
-
语言无关的分布式编程框架成为一种服务。为了解决分布式带来的技术挑战,传统中间件需要在客户端 SDK 编写大量的逻辑管理分布式的状态。我们看到很多项目在把这些内容下沉到 Sidecar 中,并通过语言无关的 API (基于 gRPC/HTTP) 提供给应用。这一变化进一步简化应用代码逻辑和应用研发的职责,例如配置绑定,身份认证和鉴权都可以在 Sidecar 被统一处理。
综上,包括生命周期管理、运维管理、配置范围和扩展和管理、以及语言无关的编程框架,一起构成了崭新的应用与云之间的编程界面。这一变革的核心逻辑还是把应用中和业务无关的逻辑和职责,剥离到云服务,并在这一过程中形成标准,让应用开发者能够在专有云、公有云或者混合云的场景中,能有一致的研发运维体验。
Sidecar 架构模式
将应用程序的组件部署到单独的进程或容器中以提供隔离和封装。这种模式还可以使应用程序由异构组件和技术组成,该模式被命名为 Sidecar,因为它类似于连接到摩托车的辅助车,辅助车被附加到父应用程序并为应用程序提供支持功能。
3. Serverless 发展趋势
近年来,Serverless 一直在高速发展,呈现出越来越大的影响力。在这样的趋势下,主流云服务商也在不断丰富云产品体系,提供更便捷的开发工具,更高效的应用交付流水线,更完善的可观测性,更丰富的产品间集成。
1)趋势一:Serverless 将无处不在
任何足够复杂的技术方案都可能被实现为全托管、Serverless 化的后端服务。不只是云产品,也包括来自合作 伙伴和三方的服务,云及其生态的能力将通过 API + Serverless 来体现。事实上,对于任何以 API 作为功能透出方式的平台型产品或组织,Serverless 都将是其平台战略中最重要的部分。
2)趋势二:Serverless 将通过事件驱动的方式连接云及其生态中的一切
通过事件驱动和云服务连接,Serverless 能力也会扩展到整个云生态。
3)趋势三:Serverless 计算将持续提高计算密度,实现最佳的性能功耗比和性能价格比
虚拟机和容器是两种取向不同的虚拟化技术,前者安全性强、开销大,后者则相反。Serverless 计算平台一方面要求兼得最高的安全性和最小的资源开销,另一方面要保持对原有程序执行方式的兼容,比如支持任意二进制文件, 这使得适用于特定语言 VM 的方案不可行。
当 Serverless 计算的规模与影响力变得越来越大,在应用框架、语言、硬件等层面上根据 Serverless 负载特点进行端对端优化就变得非常有意义。新的 Java 虚拟机技术大幅提高了 Java 应用启动速度,非易失性内存帮助实例更快被唤醒,CPU 硬件与操作系统协作对高密环境下性能扰动实现精细隔离,新技术正在创造崭新的计算环境。
实现最佳性能功耗比和性能价格比的另一个重要方向是支持异构硬件。由于 x86 处理器的性能越来越难以提升,而在 AI 等对算力要求极高的场景,GPU、FPGA、TPU(Tensor Processing Units)等架构处理器的计算效率更具优势。随着异构硬件虚拟化、资源池化、异构资源调度和应用框架支持的成熟,异构硬件的算力也能通过 Serverless 的方式释放,大幅降低企业使用门槛。