• 解读云原生技术

blog-thumb

云原生的技术体系看似纷乱繁杂,但在不同视角都体现着“牵一发而动全身”的主线。从时间线来看,容器技术的发展催生了云原生思潮,在底层解决了资源供给问题,随后开源的 Kubernetes 成为容器编排的标准规范,当基于 Kubernetes 可扩展能力的开放应用平台逐渐丰富,使其成为了云原生生态最重要的基石。随后 Service Mesh、Serverless 技术的核心思想更偏重在业务侧实现价值——将更多的能力下沉到基础设施,为应用的轻量化、上云提供可能

从技术需求的角度来看,微服务架构是解决单体复杂度问题的首选方式,却带来整个系统的整体复杂度大幅增加,容器技术和 Kubernetes 分别解决了微服务架构下大量应用的部署、以及容器的管理和调度问题,同时,Kubernetes 也为 Service Mesh 提供了更好的底层支撑,也带来了底层基础设施的 Serverless 云原生化和中间件能力的进一步下沉。

业务需求驱动云原生技术发展

云原生底层技术

容器

容器是将进程有效的划分一个独立空间,以便在独立的空间之间平衡资源使用冲突的技术。本质上,容器是一种特殊的进程,其核心功能是通过约束和修改进程的动态表现创造出一个“边界”,此外,其资源限制能力、以及基于镜像功能表现出的“强一致性”,都使得容器技术成为云原生最关键的底层技术之一。

Docker 容器因具有和虚拟机相似的隔离效果,而常常被称为”轻量级“虚拟化技术,但这样的说法并不严谨。在虚拟机中,Hypervisor是最主要的部分,它通过硬件虚拟化功能,模拟出 CPU、内存、I/O设备等各类硬件,之后在这些虚拟的硬件上安装了一个新的操作系统,即 Guest OS,在虚拟的操作系统中运行的应用进程被相互隔离。

Docker 与虚拟机的差异体现在进程隔离方式的不同,Docker 通过为应用附加额外设置的Namespace参数实现进程的隔离,并没有一个真正的”Docker容器“运行在宿主机中,这样的“障眼法”操作让进程仿佛运行在一个与世隔绝的“容器”里面,使得容器减少了额外的资源消耗和占用,在敏捷和高性能方面具有很大优势。

虚拟机(左)与Docker容器(右)工作原理

此外,容器的核心功能还包括基于 Cgroups 的资源限制能力、以及镜像功能。Cgroups 的作用是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等资源。镜像功能使得容器技术表现出“强一致性”,即在任何地点下载的镜像内容完全一致,完全复现镜像制作者当初的完整环境,这打通了“开发 - 测试 - 部署”等流程的各个环节,使得容器技术成为软件的主流发布方式。

编排与管理

Kubernetes

当容器镜像成为应用分发的工业标准,能够定义容器组织和管理规范的“容器编排”技术便成为了整个容器技术栈上的关键价值节点。主要的容器编排工具包括 Docker 公司的 Compose+Swarm 组合、Mesosphere 公司的 Mesos+Marathon 组合、Google 与 RedHat 公司共同主导的 Kubernetes 项目、 以及基于 Kubernetes 构建的 OpenShift 和 Rancher 项目。最终,Kubernetes 项目凭借优秀的开放性、可扩展性以及活跃开发者社区,在容器编排之战中脱颖而出,成为分布式资源调度和自动化运维的事实标准。

Kubernetes 项目的主要设计思想在于,从更宏观的角度,以统一的方式来定义任务之间的各种关系,并且为将来支持更多种类的关系留有余地。 从功能的角度来看,Kubernetes 更擅长按照用户的意愿和整个系统的规则,自动化地处理好容器之间的各种关系,即容器的编排,包括部署、调度和节点集群间扩展等主要功能。而 Mesos、Swarm 等项目擅长把一个容器,按照某种规则,放置在最佳节点运行起来,即容器的调度。这也是 Kubernetes 项目最终脱颖而出的重要原因。

Kubernetes 核心能力

  • 服务发现和负载均衡: 通过 Service 资源展现各种应用服务,结合 DNS 和多种负载均衡机制,支持容器化应用之间的相互通信。
  • 存储编排: 通过 plungin 的形式支持多种存储,如本地、nfs、ceph、公有云块存储等。
  • 资源调度: 设置 pod 调度的所需资源和资源限制,支持应用的自动发布和应用回滚,管理应用的相关配置。
  • 自动修复: 监测集群中所有宿主机,自动发现和处理集群内异常,更换需重启的 pod 节点,使容器集群运行在用户的期望状态。
  • 密钥和配置管理: 通过 secret 存储敏感信息,通过 configmap 存储应用的配置文件,避免将配置文件固定在镜像中,增加容器编排的灵活性。
  • 横向扩展功能: 实现基于 CPU 利用率或基于平台级的弹性伸缩,如自动增加、删除 nodes 节点。

Kubernetes全局架构

Kubernetes 项目由控制节点 Master 和计算节点 Node 组成。Master 作为控制管理的节点,由三个紧密协作的独立组件组成:kube-apiserver 负责 API 服务,kube-scheduler 负责资源调度,kube-controller-manager 负责容器编排,另外,集群的持久化数据由 kube-apiserver 处理后保存在 Etcd 中,如 Pod、Service 等对象信息。计算节点 Node 作为项目的工作负载,kubelet 组件是其最核心的部分,负责 Pod 对应的容器的创建、启停等任务,同时与 Master 节点密切协作,实现集群管理的基本功能。

如今,Kubernetes 项目不仅是容器技术的事实标准,更成为整个云原生体系发展的基石,重新定义了基础设施领域对应用编排与管理的各种可能。在整个云原生生态中,Kubernetes 项目起到了承上启下的作用。对上,Kubernetes 暴露出基础设施能力的格式化数据抽象,如 Service、Ingress、Pod、Deployment,都是 Kubernetes 本身原生 API 为用户暴露出来的能力。而对下,Kubernetes 提供了基础设施能力接入的标准接口,如 CNI、CSI、DevicePlugin、CRD,让云能够作为能力提供商,通过标准化的方式把能力接入到 Kubernetes 的体系中。伴随着微服务、DevOps 等技术理念的发展,基于 Kubernetes 可扩展能力的开放应用平台将取代 PaaS 成为主流,而云的价值会回归应用本身,越来越多的开源项目会以云原生理念去开发、部署和运维,最后直接演进成为一种云服务。

微服务

微服务是服务架构演进的产物,在历经单体架构、垂直架构、面向服务的架构(SOA)之后,微服务架构(MSA)可视为 SOA 架构的分布式实现方式。随着业务发展与需求不断增加,单体应用功能愈发复杂,应用迭代效率由于集中式研发、测试、发布、沟通模式而显著下滑。

微服务架构本质上是通过承受更高的运维复杂度来换取更好的敏捷性,其优势在于小而治之、去中心化,但也导致基础架构的需求、成本和复杂性激增。

目前为止,微服务并没有统一的标准定义,结合 Martin Fowler 的描述:微服务架构是一种架构模式 / 架构风格,将单独的应用程序开发为一套小服务并独立运行在自己的进程中,相互之间使用 HTTP API 等轻量级机制通信。这些服务围绕着具体业务进行构建,通过完全自动化部署机制来独立部署,并可使用不同的编程语言书写,以及不同数据存储技术,并保持最低限度的集中式管理。

单体架构、垂直架构、SOA、微服务架构对比

Dubbo 和 Spring Cloud 走向融合,更多的功能将被下沉到基础设施

  • Spring Cloud

    Spring Cloud 是第一代微服务架构的翘楚,为实现微服务架构提供了一站式解决方案,作为一个全家桶式的技术栈,为开发者提供了快速构建分布式系统的通用模型的工具,包括配置管理、服务发现、熔断器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话、集群状态等。

  • Dubbo

    Dubbo 作为由阿里巴巴开源的分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及 SOA 服务治理方案。核心部分包含:远程通讯、集群容错、自动发现等。

    近年来 Dubbo 生态不断完善,2019年5月,Dubbo-go 的正式加入 Dubbo 官方生态,随后实现了 REST 协议以及 gRPC 的支持,打通了 Spring Cloud 和 gRPC 生态,Go 项目与 Java&Dubbo 项目的互通问题得到了有效解决。时至今日,由于 Spring Cloud Alibaba 的出现,Dubbo 将无缝整合 Spring Cloud 生态的各种周边产品。

无论是 Dubbo 还是 Spring Cloud,都或多或少限定于特定的应用场景和开发环境,缺少对通用性和多语言性的支持,并只解决了微服务 Dev 层面的问题,缺少 DevOps 的整体解决方案,这些都为Service Mesh 的兴起创造了条件。

作为微服务管理和通讯的完整解决方案,Dubbo 和 Spring Cloud 将长期共存并走向融合,但其提供的部分功能将逐渐被基础设施所取代。如部署在 kubernetes 集群上的微服务,利用 kubernetes 的服务注册和发现的功能会更加简单;再如使用 Istio 架构,流量管理和 circuit breaker 等功能将转移到 envoy 代理,越来越多的功能会从应用程序剥离并下沉到基础设施。

Service Mesh

Service Mesh 通常被译为服务网格,在云原生应用复杂的服务拓扑结构中,Service Mesh 作为基础设施层,负责在这些拓扑结构中实现请求的可靠传递。Service Mesh 通过在请求调用的路径中增加Sidecar,将原本由客户端完成的复杂功能下沉到 Sidecar 中,实现对客户端的简化和服务间通信控制权的转移,当系统中存在大量服务时,服务间的调用关系表现为网状,这也是服务网格名称的由来。

我们可以从以下几个特征对 Service Mesh 的定义给出概括和总结:

  • 抽象: Service Mesh 将通信功能从应用中剥离出来,形成一个单独的通信层,并将其下沉到基础设施层。
  • 功能: Service Mesh 负责实现请求的可靠传递,从功能上来说和传统的类库方式并无不同。
  • 部署: Service Mesh 在部署上体现为轻量级网络代理,以 Sidecar 模式和应用程序一对一部署,两者之间的通信通过 Localhost 远程调用。
  • 透明: Service Mesh 的功能实现完全独立于应用程序,可以独立部署升级、扩展功能、修复缺陷,应用程序无须关注 Service Mesh 的具体实现细节,即对应用程序是透明的。

Service Mesh 的核心价值不只体现在其功能和特性,更在于实现业务逻辑和非业务逻辑的分离。非业务逻辑将被从客户端 SDK 剥离,以 Proxy 独立进程运行,从而将原来存在于 SDK 中的各种能力下沉到基于容器、Kubernetes或 VM 的基础设施,实现云上的托管、应用的轻量化,以帮助应用云原生化。

主流的 Service Mesh 开源软件包括 Linkerd、Envoy 和 Istio。Linkerd 和 Envoy 都直接体现了 Service Mesh 的核心理念,在功能上较为相似,即实现服务发现、请求路由、负载均衡等功能,解决服务之间的通信问题,使得应用对服务通信无感知。而 Istio 站在了更高的角度,将 Service Mesh分为了 Data Plane 和 Control Plane,由 Data Plane 负责微服务间的所有网络通信,而 Control Plane 负责管理 Data Plane Proxy, 且 Istio 天然支持 Kubernetes,这也弥合了应用调度框架与 Service Mesh 之间的空隙。

微服务落地需要一套完整的基础设施,当容器成为微服务的最小工作单元,Kubernetes 作为通用的容器管理平台,能够发挥微服务架构的最大优势,使其成为云计算的新一代操作系统。Kubernetes 不仅能够支持运行云原生和传统的容器化应用,并且覆盖 Dev 和 Ops 阶段,与 Service Mesh 的结合可以为用户提供完整端到端的微服务体验。

Serverless

Serverless 将 Service Mesh 的应用场景泛化,不仅仅局限于服务间的同步通信,而是推广到有网络访问、通过客户端 SDK 实现的更多场景,包括计算、存储、数据库、中间件等各种服务。如在蚂蚁金服的 Serverless 实践中,Mesh 模式还延伸到了 Database Mesh(数据库访问 )、Message Mesh(消息机制 )、Cache Mesh(缓存)等场景。

目前,Serverless 通常被看作是 FaaS(函数即服务)、BaaS(后端即服务)的集合, 但 Serverless 只定义了一种用户体验,而不是某种技术,FaaS、BaaS 都只是 Serverless 的一种实现方式。随着 Serverless 技术的不断成熟,越来越多使用 kubernetes 服务的应用将转化成为 Serverless 应用。

云原生中间件

传统中间件类似于城市中的输水管道,推动并管理数据从一个应用流向另一个应用,其业务耦合度高、不能为用户带来直接价值。进入云时代,软件的异构现象、互联需求显著增加,中间件被赋予了新的功能定义,即功能独立、耦合度低、组件模块化,并被下沉到基础设施,成为实现高性能、高可用、高伸缩性和最终一致性的分布式应用开发架构的关键组成部分。

从功能定义来看,中间件是一类连接软件组件和应用的计算机软件,它包括一组服务,以便于运行在一台或多台机器上的多个软件通过网络进行交互,属于可复用软件范畴。云原生中间件包括 API、应用服务器、TP、RPC、MOM,也可以承担数据整合、应用整合的作用,任何位于内核和用户应用之间的软件都可以理解为中间件。

伴随 IoT、云计算技术的快速发展,EDA(事件驱动架构)正在被越来越多的企业采纳,通过事件的抽象、异步化,来提供业务解耦、加快业务迭代,也正在从支持垂直行业转向通用关键业务应用架构,应用在打包应用、开发工具、业务过程管理和监视等领域。

EDA 往往通过消息中间件实现,消息中间件旨在利用高效可靠的消息传递机制进行平台无关的数据交流,通过提供消息传递和消息排队模型,实现在分布式环境下扩展进程间的通信,并基于数据通信进行分布式系统的集成。常见的消息中间件包 括ActiveMQ、 RabbitMQ 、RocketMQ 、Kafka 等,可应用在跨系统的数据传递、高并发的流量削峰、数据异步处理等场景。

进入云计算时代,云厂商提供更加贴近业务的封装,多采用自身的 Serverless 服务来运行事件负载,中间件的能力很容易通过云服务来实现,包括阿里云 Function Compute、Azure Function、AWS Lambda 都集成了事件处理。

未来,应用中间件将不再是能力的提供方,而是能力接入的标准界面,这个标准界面将通过 HTTP、 gRPC 协议进行构建,并通过 Sidecar 解耦整个服务的接入层与应用业务逻辑,这与 Service Mesh 的思想一致。更进一步的,Sidecar 模型能够应用在所有的中间件场景,从而将中间件能力“下沉”到 Kubernetes 能力的一部分。

DevOps

伴随云原生开源生态不断完善、以及复杂功能不断下沉到云,基本统一了软件部署和运维的基本模式。在 DevOps 之前,从业人员使用瀑布模型或敏捷开发模型进行软件项目开发。DevOps 作为Development和Operations 的组合,被定义为实现软件开发和 IT 团队之间流程自动化的一组实践,这些实践建立在团队之间协作文化的基础上,填补了开发端和运维端之间的信息鸿沟,以便更快、更可靠地构建、测试和发布软件,目前已经成为主流的软件开发交付模式。

传统瀑布模型、敏捷开发模型、DevOps开发模型对比

总体来看,DevOps 包含了开发、测试和运维三部分。具体看来,它由多个阶段组成:持续开发、持续集成、持续测试、持续反馈、持续监测、持续部署、持续运维,统称为 DevOps 生命周期。

DevOps 功能的分与合在信息流转层面得到了充分体现,在开发交付测试、测试回馈、交付发布等阶段,各类信息的提供方、接收方使用优质的工具系统,进而实现顺畅精准的传输信息和高效的执行机械化操作。

从上述发展理念来看,DevOps 的思想源于基础设施层不够强大、不够标准化,所以业务侧需要一套工具来黏合研发、运维人员和相应的基础设施。但随着 Kubernetes 和基础设施越来越复杂,云原生生态会做出相应的抽象和分层,每一层的角色只和属于自己的数据抽象去交互,即开发侧和运维侧的关注点分离。不断泛化的 Serverless 也将成为 DevOps 的一种思想导向和组成部分。在能力侧,“轻运维”、“NoOps”、“自助式运维能力”会成为应用运维的主流方式。在应用侧,应用描述会广泛地进行用户侧的抽象,事件驱动和 Serverless 理念被拆分和泛化,可以被应用于 FaaS 之外的多样化的场景中。

DevOps信息流转模型