友浩达CTO、华为云MVP张善友:基于Kubernetes与Dapr打造云原生应用

2022年6月21日,在CSDN云原生系列在线峰会第10期"华为云HCDE专场暨分布式技术峰会"上,深圳市友浩达科技CTO、华为云MVP张善友分享了基于Kubernetes与Dapr打造云原生应用的实践,他从云原生应用构建的痛点出发,引出了云原生应用的发展趋势,最后重点介绍了Dapr如何更好地打造云原生应用。

要点简述

    Dapr是一个可移植的、事件驱动的运行时,它使任何开发人员都能够轻松构建出弹性的、无状态和有状态的应用程序。

    Dapr提供了与编程语言无关的HTTP和gRPC两种API,从而支持多种编程语言和开发框架。

    Dapr提供了很多分布式能力,可以无缝地运行在云平台或边缘计算中。

云原生架构演进

IDC预测,到2022年,产品化软件中云原生的占比将达到36%,中国信通院发布的白皮书也得出云原生将成为驱动业务增长的重要引擎的结论。

目前,云原生架构采纳用户的生产集群还是以中小规模为主,规模化应用还存在较高的技术门槛。云原生在规模化应用时会涉及到安全性、连续性以及性能等诸多因素,这些因素成为了用户侧落地的主要顾虑,这些顾虑占比高达61%。同时陡峭的学习成本以及如何与现有平台的整合演进,也成为了用户侧的次要顾虑,这些顾虑占比达到47%。

基于这样的背景,目前云原生有如下发展趋势:

    Kubernetes编排统一化,编排对象不断扩展延伸

    服务治理Mesh化,加速传统应用转型

    应用服务Serverless化,更加聚焦业务的核心价值

    从资源云到业务云,最终趋于全面云原生化

云原生应用首先是一个分布式应用,所以将单体业务转化成云原生业务时,首先需要将它转化为一个分布式应用。

而在分布式应用中集成了非常多的非功能性需求,包括服务注册、服务治理、弹性伸缩、熔断、限流、服务解耦、配置管理等。这些非功能性需求在以Spring Cloud为代表的分布式框架中是跟实际的业务需求融合在一起的。

如下图所示,Spring Cloud针对不同的非功能需求开发了不同的子项目来处理,比如服务发现有Eureka,负载均衡有Ribbon,发布订阅有Spring Cloud Stream共计有超过30多个子项目,数量众多的子项目对前期应用和后期维护升级均造成了一定的困难。

而以Kubernetes为基础,同时配合服务网格lstio为代表的云原生应用框架则大大缩减了子项目数,将服务调用、服务发现交由Service处理,但它只解决了服务调用、流量调度这类的网络需求,不能覆盖分布式应用的大部分需求。

如下图所示,分布式应用需要解决四大问题:网络(Networking)、生命周期(Lifecycle)、状态(State)、捆绑(Binding)。Dapr则可以将云原生应用中的大部分非功能性需求都交由Sidecar来实现,将分布式能力进行封装下沉作为运行时以简化分布式应用开发的技术复杂度。

多运行时架构开源项目Dapr

Dapr(Distributed Application Runtime,分布式应用运行时)是一款可移植、事件驱动运行时,是由微软发起的一个开源项目,目前已加入CNCF孵化器。这里有几个概念需要先说明一下:

    运行时:是指程序运行时依赖的执行环境

    可移植:表示Dapr可以将不同的系统集成到应用程序中而无需硬编码

    分布式应用:指应用程序分布在不同计算机上,通过网络来共同完成一项任务的工作方式

Dapr是如何简化分布式应用开发的呢?下面来看一看Dapr的主要特性。

Dapr通过以HTTP/gRPC API这种与语言无关的方式暴露封装的分布式能力,供应用调用,从而支持使用任意语言或框架进行开发集成。

目前官方提供了Go、Node、Python、.NET、Java、C++、PHP、Rust、JavaScript的SDK,简化Dapr的集成。

其中,Dapr的核心构建块(Building Block)就是用来提供各种不同的分布式能力,例如Service-to-service invocation(服务调用)、State Management(状态存储)、Publish and subscribe(发布订阅),Resource bindings and triggers(资源绑定及事件触发)、Actors(Dapr中的Actor模型)、Observability(遥测)、Secrets(安全)等。后面会对这些核心的分布式能力进行详细介绍。

Sidecar架构

Dapr以Sidecar架构的方式公开其API,可以是容器,也可以是进程,不需要应用程序包含任何Dapr运行时代码。Dapr部署在Kubernetes上时,会向应用中注入Sidecar(边车),也就是说Sidecar会和主应用部署在一起作为一个辅助应用,这个辅助应用不一定属于应用程序的一部分,而只是与应用相连接。这就像是挎斗摩托车,每个摩托车都有自己独立的辅助部分,它随着主应用启动或停止。如下图所示,主应用作为摩托,而Sidecar作为挎斗。

如下图所示,Sidecar其实是一个独立的服务,那么可以在上面做很多事情,例如Sidecar之间通信或者通过统一的节点控制Sidecar,从而达到Service Mesh。

引入Sidecar之前:业务逻辑和非业务逻辑混合在一个进程内,应用既有业务逻辑,也有各种非业务的功能(体现为各种客户端SDK)。

引入Sidecar之后:客户端SDK的功能剥离,业务进程专注于业务逻辑,而SDK中的大部分功能被拆解为独立进程,以Sidecar的模式运行。

通过引入Sidecar模式,Dapr成功实现了关注点分离和独立维护两大目标。

Dapr提供了HTTP和gRPC两种方式的API,其调用方式与传统的调用方式有所不同,它只需要知道被调用方的appid,比如nodeapp暴露了一个API:

按照传统的方式,直接HTTP POST这个API访问就得了,但在Dapr中,其提供了服务间方法调用的接口规范,需要按照下面的格式进行访问:

那假设pythonapp需要访问nodeapp的方法,就需要POST一个请求到:

Dapr将其API作为Sidecar体系结构(容器或进程)公开,不需要应用程序代码包含任何Dapr运行时代码。这使得与Dapr的集成易于与其他运行时集成,并提供了应用逻辑的分离,从而提高了可支持性。

Sidecar为我们解决了服务调用、网络安全和分布式跟踪等功能。

Dapr助力云原生落地

Dapr服务调用流程如下图所示。

    服务A对服务B发起HTTP/gRPC的调用

    Dapr通过托管平台(Local&K8s)的名称解析组件获取服务B的地址

    Dapr将消息转发至服务B的Dapr边车

    服务B的Dapr边车将请求转发到服务B上的特定断点(或方法),服务B随后运行其业务逻辑代码

    服务B发送响应给服务A,响应将转至服务B的边车

    Dapr将消息转发至服务A的Dapr边车

    服务A接收响应

Dapr使用了CloudEvents的标准,它可以把不同消息中间件进行标准化,这样就可以非常容易地将同样的解决方案应用到不同的场景中,只需要简单地进行配置调整即可。

例如,现在很多开发商基于云厂商的平台去做应用开发时,可以实现云原生应用的可移植性,将云原生应用适配到本地以及不同的云环境。

Dapr主要的设计目标是可移植性,云原生应用可以适配到不同的端以及云上。

Dapr提供标准API、语言SDK和Runtime,它可以使应用开发者可以更加专注于应用本身,不再局限于某个具体的开发语言,不像原先使用Spring Cloud,必须通过Java来集成。

Dapr提供了非常多的分布式能力,这些分布式以非常标准的方式提供,对外暴露的是HTTP和gRPC的接口,这样对应用来说可以提供非常大的可控制力。这也是Dapr给云原生应用带来的价值。

总结

综上,Dapr以标准的HTTP和gRPC接口的方式提供服务,使得云原生应用不再局限于某个具体的开发语言,实现了非常大的可控制力。同时,通过Dapr还可以很方便地将云原生应用迁移到不同的私有云和边缘上。