2.2.1 核心技术
1.容器技术
(1)背景与价值
2008年Linux提供了Cgroups资源管理机制、Linux Namespace隔离方案,让应用得以运行在独立沙箱环境中,避免相互之间产生冲突和影响。直到Docker容器引擎开源,才在很大程度上降低了容器技术的使用复杂性,加速了容器技术的普及。Docker容器基于操作系统虚拟化技术,共享操作系统内核,轻量、没有资源损耗、秒级启动,极大提升了系统的应用部署密度和弹性。更重要的是,Docker提出了创新的应用打包规范——Docker镜像,解耦了应用与运行环境,使应用可以在不同计算环境间一致、可靠地运行。借助容器技术呈现了一个优雅的抽象场景:让开发所需要的灵活性、开放性和运维所关注的标准化、自动化达成相对平衡。容器镜像迅速成为应用分发的工业标准。
容器作为标准化软件单元,它将应用及其所有依赖项打包,使应用不再受环境限制,可以在不同计算环境间快速、可靠地运行。
传统部署、虚拟化部署和容器部署三种模式的比较如图2-13所示。
图2-13 传统部署、虚拟化部署和容器部署三种模式的比较
在过去几年,容器技术已经被广泛地应用在生产环境中,容器技术最受关注的三个核心价值如下:
● 敏捷性。容器技术在提升企业IT架构敏捷性的同时,让业务迭代更加迅捷,为创新探索提供了坚实的技术保障。比如在新冠肺炎疫情期间,教育、视频、公共健康等行业的在线化需求出现爆发性增长,很多企业通过容器技术适时把握住了突如其来的业务快速增长机遇。据业界统计,使用容器技术可以获得3~10倍交付效率的提升,大大提高了新产品迭代的效率,并降低了试错成本。
● 弹性。在互联网时代,企业IT系统经常需要面对促销活动、突发事件等各种预期内外的爆发性流量增长。通过容器技术,企业可以充分发挥云计算弹性优势,降低运维成本。一般而言,借助容器技术,企业可以通过部署密度提升和弹性降低50%的计算成本。以在线教育行业为例,面对新冠肺炎疫情之下呈指数级增长的流量,教育信息化应用工具提供商Seewo(希沃)利用ACK(Alibaba Cloud Container Service for Kubernetes,阿里云容器服务)和ECI(Elastic Container Instance,弹性容器实例)大大满足了快速扩容的迫切需求,为数十万名老师提供了良好的在线授课环境,帮助百万名学生进行在线学习。
●可移植性。容器已经成为应用分发和交付的标准技术,将应用与底层运行环境进行解耦。Kubernetes成为资源调度和编排的标准,屏蔽了底层架构的差异性,帮助应用平滑运行在不同的基础设施上。CNCF(云原生计算基金会)推出了Kubernetes一致性认证,进一步保障了不同Kubernetes实现的兼容性,这也让企业愿意采用容器技术来构建云时代应用基础设施。
(2)容器编排
凭借优秀的开放性、可扩展性以及社区活跃度,Kubernetes已成为容器编排的事实标准,被广泛用于自动部署、扩展和管理容器化应用。凭借优良的架构设计和可移植性,Kubernetes已经被大家视为云应用的操作系统,越来越多的应用运行在其上。一些无状态的外部应用,以及企业核心的交易类应用、数据智能应用等,也运行在Kubernetes平台之上。
企业可以通过Kubernetes,结合自身业务特征来设计云架构,从而更好地支持多云/混合云,免去被厂商锁定的顾虑。随着容器技术逐步标准化,进一步促进了容器生态的分工和协同。基于Kubernetes,生态社区开始构建上层的业务抽象,比如服务网格Istio、机器学习平台Kubeflow、无服务器应用框架Knative等。
Kubernetes提供了如下分布式应用管理的核心能力。
● 资源调度:根据应用请求的CPU、内存资源量,或者GPU等设备资源,在集群中选择合适的节点来运行应用。
● 应用部署与管理:支持应用的自动发布、回滚,以及与应用相关的配置管理;也可以自动化存储卷的编排,让存储卷与容器应用的生命周期相关联。
● 自动修复:Kubernetes可以监测集群中所有的宿主机,当宿主机或者OS出现故障时,节点健康检查会自动进行应用迁移;Kubernetes也支持应用的“自愈”,极大简化了运维管理的复杂性。
● 服务发现与负载均衡:通过Service资源出现各种应用服务,结合DNS和多种负载均衡机制,支持容器化应用之间的相互通信。
● 弹性伸缩:Kubernetes可以监测业务所承担的负载,如果业务本身的CPU利用率过高,或者响应时间过长,则可以对这个业务进行自动扩容。
Kubernetes的控制平面包含四个主要的组件:API Server、Controller Manager、Scheduler以及Etcd,如图2-14所示。
Kubernetes关键设计理念如下。
● 声明式API:开发者可以关注应用自身,而非系统执行细节。比如Deployment(无状态应用)、StatefulSet(有状态应用)、Job(任务类应用)等不同资源类型,提供了对不同类型工作负载的抽象;对Kubernetes实现而言,基于声明式API的level-triggered相对于edge-triggered方式可以提供更加健壮的分布式系统实现。
● 可扩展性架构:所有K8s组件都是基于一致的、开放的API实现和交互的;第三方开发者也可通过CRD(Custom Resource Definition)/Operator等方式提供与领域相关的扩展实现,极大提升了K8s的能力。
●可移植性:K8s通过一系列抽象如LB(负载均衡)、CNI(容器网络接口)、CSI(容器存储接口),帮助业务应用屏蔽底层基础设施的实现差异,实现容器灵活迁移的设计目标。
图2-14 Kubernetes架构
2.微服务
(1)微服务发展背景
过去开发一个后端应用,最为直接的方式就是通过单体应用提供并集成所有的服务,即单体模式。随着业务的发展以及需求的不断增长,单体应用功能愈发复杂,参与开发的工程师规模可能由最初几个人发展到十几个人,应用迭代效率因集中式研发、测试、发布、沟通模式而显著降低。为了解决单体模式带来的项目迭代流程过度集中的问题,微服务模式应运而生。
微服务模式将业务单元按照独立部署和发布的标准进行抽取与隔离,一个大而全的复杂应用能够被拆分成多个微小的相互独立的子功能,这些子功能被称为“微服务”,多个“微服务”共同形成了一个物理独立但逻辑完整的分布式微服务体系。这些微服务相对独立,通过解耦研发、测试与部署流程,提高了整体迭代效率。当其中的某一微服务无法支撑时,可以横向水平扩展,从而保证应用的高可用性,具有独立应用生命周期管理、独立版本开发与发布等能力,从根本上解决了单体应用在拓展性和稳定性上存在的先天架构缺陷。
微服务模型也面临着分布式系统的典型挑战,例如,如何高效调用远程方法、如何实现可靠的系统容量预估、如何建立负载均衡体系、如何面向松耦合系统进行集成测试、如何部署与运维大规模复杂关联应用……
(2)微服务架构
在微服务架构中,旁路服务注册中心作为协调者来完成服务的自动注册和发现。服务之间的通信以及容错机制开始模块化,形成独立服务框架。Apache Dubbo微服务架构如图2-15所示。
图2-15 Apache Dubbo微服务架构
(3)主要微服务技术
● Apache Dubbo是阿里巴巴的一款开源的高性能的RPC(Remote Procedure Call)框架,其特性包括基于透明接口的RPC、智能负载均衡、自动服务注册和发现、可扩展性高、运行时流量路由与可视化的服务治理。经过数年发展,它已是国内使用最广泛的微服务框架并构建了强大的生态体系。2018年阿里巴巴陆续开源了Spring-Cloud Alibaba(分布式应用框架)、Nacos(注册中心&配置中心)、Sentinel(流控防护)、Seata(分布式事务)、Chaosblade(故障注入),以便让用户享受阿里巴巴十年沉淀的微服务体系,获得高性能、高可用等核心能力。从Dubbo v3开始了Service Mesh(服务网格)方面的技术演讲,目前Dubbo协议已被Envoy支持,数据层选址、负载均衡和服务治理方面的工作还在继续,目前控制层在持续丰富对Istio/Pilot-discovery的支持。
● Spring Cloud 为开发者提供了分布式系统需要的配置管理、服务发现、断路器、智能路由、微代理、控制总线、一次性Token、全局锁、决策竞选、分布式会话与集群状态管理等能力和开发工具。
● Eclipse MicroProfile作为Java微服务开发的基础编程模型,致力于定义企业Java微服务规范,提供指标、API文档、运行状况检查、容错与分布式跟踪等能力,使用它创建的云原生微服务可以自由地部署在任何地方,包括Service Mesh架构。
● Tars 是腾讯将其内部使用的微服务框架TAF(Total Application Framework)多年的实践成果总结而成的开源项目,在腾讯内部有上百个产品使用,服务于内部数千名C++、Java、Go、Node.js与PHP开发者。Tars包含一整套开发框架与管理平台,兼顾多语言、易用性、高性能与服务治理,理念是让开发更聚焦于业务逻辑,让运维更高效。
● SOFAStack(Scalable Open Financial Architecture Stack)是由蚂蚁金服开源的一套用于快速构建金融级分布式架构的中间件,也是在金融场景下锤炼出来的最佳实践。MOSN是SOFAStack的组件,它是一款采用Go语言开发的Service Mesh数据平面代理,其功能和定位类似于Envoy,旨在提供分布式、模块化、可观测、智能化的代理能力。MOSN支持Envoy和Istio的API,可以与Istio集成。
● Dapr(Distributed Application Runtime,分布式应用运行时)是微软推出的一种可移植的、Serverless、事件驱动的运行时,使用它开发人员可以轻松构建弹性、无状态和有状态的微服务,这些服务运行在云和边缘上,并包含多种语言和开发框架。
3.Service Mesh
随着服务框架内功能的日益增多,跨语言的基础功能复用变得十分困难,这也就意味着微服务的开发者被绑定在某种特定语言上,从而违背了微服务的敏捷迭代原则。2016年出现了一种新的微服务架构——Service Mesh(服务网格),原来被模块化到服务框架里的微服务基础能力,被进一步从一个SDK演进成为一个独立进程——Sidecar。这个变化使得多语言支持问题得以彻底解决,微服务基础能力演进和业务逻辑迭代彻底解耦。这种架构就是云原生时代的微服务架构——Cloud Native Microservices,Sidecar进程开始接管微服务应用之间的流量,承载了服务框架的功能,包括服务发现、调用容错以及丰富的服务治理功能,例如权重路由、灰度路由、流量重放、服务伪装等。
(1)技术特点
Service Mesh是分布式应用在微服务架构之上发展起来的新技术,旨在将微服务之间的连接、安全、流量控制和可观测等通用功能下沉为平台基础设施,实现应用与平台基础设施的解耦。这个解耦意味着开发者无须关注微服务相关治理问题,而是聚焦于业务逻辑本身,提高了应用开发效率,加速了业务探索和创新。换句话说,因为大量非功能性的代码实现从业务进程剥离到另外的进程中,Service Mesh以无侵入的方式实现了应用轻量化。Service Mesh的典型架构如图2-16所示。
图2-16 Service Mesh的典型架构
在图2-16中,Service A调用Service B的所有请求都被其下的Proxy(在Envoy中是Sidecar)截获,代理Service A完成到Service B的服务发现、熔断、限流等策略,而这些策略的总控是在控制平面上配置的。
从架构上看,Istio可以运行在虚拟机或容器中,Istio的主要组件包括Pilot(服务发现、流量管理)、Galley(注册管理)、Mixer(访问控制、可观测性)、Citadel(终端用户认证、流量加密)。整个服务网格关注连接和流量控制、可观测性、安全和可运维性。相比较来说,虽然服务网格场景增加了4个IPC通信的成本,但随着软硬件能力的提升,并不会给整体调用的延迟带来显著的影响,特别是对于百毫秒级别的业务调用而言,可以控制在2%以内。此外,服务化的应用并没有做任何改造,就获得了强大的流量控制、服务治理、可观测性、“4个9”以上的高可用性、容灾和安全等能力,再加上业务的横向扩展能力,整体收益仍然是远大于额外IPC通信支出的。
在服务网格的技术发展上,数据平面与控制平面之间的协议标准化是必然趋势。大体上,Service Mesh的技术发展围绕着“事实标准”来展开——共建各云厂商所共同采纳的开源软件。
从接口规范的角度看,Istio采用了Envoy所实现的xDS协议,将该协议当作数据平面和控制平面之间的标准协议。微软提出了Service Mesh Interface(SMI),致力于让数据平面和控制平面的标准化做更高层次的抽象,以期为Istio、Linkerd等Service Mesh解决方案在服务观测、流量控制等方面实现最大程度的开源能力复用。UDPA(Universal Data Plane API)是基于xDS协议发展起来的,根据不同云厂商的特定需求可以便捷地进行扩展并由xDS承载。此外,数据平面插件的扩展性和安全性也得到了社区的广泛重视。
从数据平面角度看,Envoy得到了包括Google、IBM、Cisco、微软、阿里云等的参与共建,以及主流云厂商的采纳而成为事实标准。在Envoy的软件设计为插件机制提供良好扩展性的基础上,目前正在探索运用Wasm技术对各种插件进行隔离,避免因为某一插件的软件缺陷而导致整个数据平面不可用。Wasm技术的优势除了能提供沙箱功能,还能很好地支持多语言,最大程度地让掌握不同编程语言的开发者可以使用自己所拥有的技能去扩展Envoy的能力。
在安全方面,Service Mesh和零信任架构天然有很好的结合,包括POD Identity、基于mTLS的链路层加密、在RPC上实施RBAC的ACL、基于Identity的微隔离环境(动态选取一组节点组成安全域)。
(2)主流技术
2017年发起的服务网格Istio开源项目,清晰地定义了数据平面(由开源软件Envoy承载)和管理平面(Istio自身的核心能力)。Istio为微服务架构提供了流量管理机制,同时也为其他增值功能(包括安全性、监控、路由、连接管理与策略等)创造了基础。Istio利用久经考验的Lyft Envoy代理进行构建,可在无须对应用程序代码做出任何改动的前提下实现可视性与控制能力。2019年发布的Istio 1.12版本已达到小规模集群上线生产环境水平,但其性能仍受业界诟病。开源社区正试图通过架构层面演进解决这一问题。由于Istio是建构于Kubernetes技术之上的,所以它天然地可运行于提供Kubernetes容器服务的云厂商环境中,同时Istio成为大部分云厂商默认使用的服务网格方案。
除了Istio,还有Linkerd、Consul、Conduit等相对小众的Service Mesh解决方案。Linkerd在数据平面采用Rust编程语言实现了linkerd-proxy,控制平面与Istio一样采用Go语言编写。最新的性能测试数据显示,Linkerd在时延、资源消耗方面比Istio更具优势。Consul在控制平面上直接使用Consul Server,在数据平面上可以选择性地使用Envoy。与Istio不同的是,Linkerd和Consul在功能上不如Istio完整。
Conduit作为Kubernetes的超轻量级Service Mesh,其目标是成为最快、最轻、最简单且最安全的Service Mesh。它使用Rust构建了快速、安全的数据平面,用Go开发了简单、强大的控制平面,总体设计围绕着性能、安全性和可用性进行。它能透明地管理服务之间的通信,提供可观测性、可靠性、安全性和弹性的支持。虽然它与Linkerd相仿,数据平面是在应用代码之外运行的轻量级代理,控制平面是一个高可用的控制器,但是Conduit的设计更倾向于Kubernetes中的低资源部署。
4.Serverless
(1)技术特点
随着以Kubernetes为代表的云原生技术成为云计算的容器界面,Kubernetes成为云计算的新一代操作系统。面向特定领域的后端云服务(BaaS)则是这个操作系统上的服务API,存储、数据库、中间件、大数据、AI等领域的大量产品与技术都开始提供全托管的云形态服务,如今越来越多的用户已习惯使用云服务,而不是自己搭建存储系统、部署数据库软件。
当这些BaaS云服务日趋完善时,Serverless因为屏蔽了服务器的各种运维复杂度,让开发人员可以将更多精力用于业务逻辑设计与实现,而逐渐成为云原生主流技术之一。下面给出Serverless全景图,如图2-17所示。
图2-17 Serverless全景图
Serverless计算包含以下特征。
● 全托管的计算服务:用户只需要编写代码构建应用,无须关注同质化的、负担繁重的服务器等基础设施的开发、运维、安全、高可用等工作。
● 通用性:结合云BaaS API的能力,能够支撑云上所有重要类型的应用。
● 自动的弹性伸缩:用户无须为资源的使用提前进行容量规划。
● 按量计费:企业的使用成本得到有效降低,无须为闲置资源付费。
Serverless的三大核心价值如下。
● 快速交付:Serverless通过进行大量的端对端整合以及云服务之间的集成,为应用开发提供了最大化的便利性,让开发者无须关注底层的IaaS资源,而是更专注于业务逻辑开发,聚焦于业务创新,大大缩短了业务的上市时间。
● 极致弹性:在Serverless之前,一旦遇到突发流量,可能就会直接导致各种超时异常,甚至是系统崩溃。即使有限流保护以及提前扩容等手段,也依然会出现评估不准的情况,进而引发灾难性的后果。有了Serverless之后,由于它具备毫秒级的弹性能力,应对突发流量会变得更加从容。
● 更低成本:就跟生活中使用“水电煤”一样,我们只为实际消耗的资源买单,而无须为闲置的资源付费。Serverless提供的端到端的整合能力,极大地降低了运维的成本与压力,使NoOps成为可能。
基于快速交付、极致弹性、更低成本的三大核心价值,Serverless被认为是云时代的全新计算范式,引领云在下一个十年乘风破浪。那么,下一个十年的Serverless将会有什么趋势呢?
● 标准开放。通过支持开源的工具链和研发框架,Serverless能够在多云环境下使用,无厂商锁定,免除用户后顾之忧。
● 与云原生结合。阿里云Serverless将借助容器出色的可移植性和灵活性,实现应用交付模式统一。通过复用云原生生态,Serverless在存储、网络、安全、可观测等方面更加标准、强大。
● 事件驱动。通过采用统一的事件标准,如CloudEvent来建立云上的事件枢纽,让Serverless开发集成云服务、云边端应用更简单。
●解锁更多业务类型。Serverless早已不再局限于代码片段、短任务、简单逻辑,长时间运行、大内存的任务,有状态的应用,以及GPU/TPU的异构计算任务都会在Serverless产品上得到支持。
● 更低成本。在使用成本方面,采用Serverless产品的TCO会比基于服务器自建更低。一方面,引入预付费等计费模式,比按量计费节省30%以上的费用;另一方面,随着Serverless的不断演进,资源池更大、资源利用率更高,成本会被进一步压低。在迁移成本方面,可以通过选择不同形态的Serverless产品,采用迁移工具,甚至一行代码不改,存量应用就能迁移到Serverless,享受Serverless红利。
(2)函数计算
函数计算(Function as a Service)是Serverless中最具代表性的产品形态。通过把应用逻辑拆分成多个函数,每个函数都通过事件驱动的方式触发执行,例如,对象存储(OSS)中产生的上传/删除对象等事件,能够自动、可靠地触发FaaS函数处理且每个环节都是弹性的和高可用的,用户能够快速实现大规模数据的实时并行处理。同样,通过消息中间件和函数计算的集成,用户可以快速实现大规模消息的实时处理。下面给出FaaS全景图,如图2-18所示。
图2-18 FaaS全景图
目前函数计算这种Serverless形态在普及方面尚存一定困难,例如:
● 函数编程以事件驱动方式执行,这在应用架构、开发习惯方面,以及研发交付流程上都会有比较大的改变。
● 函数编程的生态仍不够成熟,应用开发者和企业内部的研发流程需要重新适配。
● 细粒度的函数运行也引发了新技术挑战,比如冷启动会导致应用响应延迟,按需建立数据库连接成本高,等等。
(3)Serverless on Kubernetes
针对函数计算面临的情况,Serverless计算中又诞生了更多其他形式的服务形态,典型的就是与容器技术进行融合创新,通过良好的可移植性,容器化应用能够无差别地运行在开发机、自建机房以及公有云环境中。基于容器工具链能够加快解决Serverless的交付问题。
云厂商如阿里云提供了ECI(弹性容器实例)以及更上层的SAE(Serverless App Engine,Serverless应用引擎),SAE架构如图2-19所示;Google提供了CloudRun服务,这都帮助用户专注于容器化应用构建,而无须关心基础设施的管理成本。
图2-19 SAE架构
此外,Google也开源了基于Kubernetes的Serverless应用框架Knative。Knative受众如图2-20所示。
图2-20 Knative受众
相对于函数计算的编程模式,这类Serverless应用服务支持容器镜像作为载体,无须修改即可部署在Serverless环境中,享受Serverless带来的全托管免运维、自动弹性伸缩、按量计费等优势。
5.常见应用场景
近两年来,Serverless呈加速发展趋势,用户使用Serverless架构在可靠性、成本和开发运维效率等方面获得显著收益。
(1)小程序/Web/Mobile/API后端服务
后端服务场景如图2-21所示。
图2-21 后端服务场景
在小程序、Web/Mobile应用、API服务等场景中,业务逻辑复杂多变,对迭代上线速度要求高,而且这类在线应用的资源利用率通常小于30%,尤其是小程序等长尾应用,资源利用率更是低于10%。Serverless免运维、按需付费的特点非常适合构建小程序/Web/Mobile/API后端服务,通过预留计算资源+实时自动伸缩,开发者能够快速构建延时稳定、能承载高频访问的在线应用。在阿里巴巴内部,使用Serverless构建后端服务是落地最多的场景,包括前端全栈领域的Serverless For Frontends、机器学习算法服务、小程序平台实现,等等。
(2)大规模批处理任务
批处理任务场景如图2-22所示。
图2-22 批处理任务场景
在构建典型的任务批处理系统时,例如大规模音视频文件转码服务,需要包含计算资源管理、任务优先级调度、任务编排、任务可靠执行、任务数据可视化等一系列功能。如果从机器或者容器层开始构建,用户通常需要使用消息队列进行任务信息的持久化和计算资源分配,使用Kubernetes等容器编排系统实现资源的伸缩和容错,自行搭建或集成监控报警系统。而通过Serverless计算平台,用户只需要专注于任务处理逻辑,而且Serverless计算的极致弹性可以很好地满足突发任务对算力的需求。
通过将对象存储和Serverless计算平台集成的方式,能实时响应对象创建、删除等操作,实现以对象存储为中心的大规模数据处理。用户既可以通过增量处理对象存储上的新增数据,也可以创建大量函数实例来并行处理存量数据。
(3)基于事件驱动架构的在线应用和离线数据处理
事件驱动场景如图2-23所示。
图2-23 事件驱动场景
典型的Serverless计算服务通过事件驱动的方式,可以广泛地与云端各种类型服务集成,用户无须管理服务器等基础设施和编写集成多个服务的“胶水”代码,就能够轻松地构建松耦合、基于分布式事件驱动架构的应用。
通过与事件总线的集成,无论是一方的BaaS云服务,还是第三方的SaaS服务,或者是用户自建的系统,所有事件都可以快速便捷地被函数计算处理。例如,通过与API网关集成,外部请求可以转化为事件,从而触发后端函数处理。通过与消息中间件的事件集成,用户能快速实现对海量消息的处理。
(4)开发运维自动化
通过定时触发器,用户使用函数的方式就能够快速实现定时任务,而无须管理执行任务的底层服务器。通过将定时触发器和监控系统的时间触发器集成,用户可以及时接收机器重启、宕机、扩容等IaaS层服务的运维事件,并自动触发函数执行处理。