从Service Mesh到Multi-Runtime
聊聊从Service Mesh到Multi-Runtime的发展历程,了解其是如何形成了这样的架构模式。讨论在云原生中Multi-Runtime架构下可能带来的新的安全风险和安全研究方向。
演进历程
Service Mesh 的发展
Service Mesh中文译名服务网格,是用以处理服务与服务之间通信的基础设施层。功能在于处理服务间通信,职责是实现请求的可靠传递。在实践中,Service Mesh通常由服务与轻量级网络代理(Sidecar,与服务部署在一起)组合而成。它在原有的客户端和服务端之间加了一个代理,但对应用程序透明。
当其扩大到一定规模后,就会形成网格状(Mesh),即形成了Service Mesh的形态:
Service Mesh中这些相互连接的网络代理设计允许我们更优雅地管理东西流量和南北流量。它将底层那些难以控制的网络通讯统一管理,而上层的应用层协议只需关心业务逻辑即可。Service Mesh是一个用于处理服务间通信的基础设施层,它负责为构建复杂的云原生应用传递可靠的网络请求。
在 Service Mesh 的定义中,简短地描述了 Service Mesh 的关键特征:
- 定位基础设施层;
- 功能是服务间通讯;
- 采用 Sidecar 部署;
- 特别强调无侵入、对应用透明。
对于Service Mesh发展更加专注于解决服务调用和网络问题,因为其定位始终是提供 服务间通讯 的基础设施层,范围包括 HTTP 和 RPC——支持 HTTP1.1/REST,支持 HTTP2/gRPC,支持 TCP 协议等。
Multi-Mesh 的实践
从 2017 年底开始,蚂蚁就开始探索Service Mesh的技术方向,并提出了 基础设施统一,业务无感升级的愿景。在看到RPC能力Mesh化带来的巨大收益之后,蚂蚁开始将Service Mesh的Sidecar模式推广到其他的中间件领域。
在Multi-Mesh的实践中,蚂蚁除了RPC,还支持了更多中间件的Mesh化落地,包括消息、配置、缓存的等等。
这里本质上是将大量基础设施下沉Sidecar里,开始呈现一种重Sidecar轻框架趋势,而这种情况下Multi-Mesh方案的劣势也逐渐显现出来。
应用因为依赖了各种基础设施的SDK,但是每种SDK又以自己特有的方式跟MOSN进行交互,使用的往往都是由原生基础设施提供的私有协议,这直接导致了复杂的中间件能力虽然下沉,但是本质上仍需要支持不同协议不同序列化方式使得异构语言接入成本高,同时维护相对应的SDK成本开始增大。
简单来说Multi-Mesh虽然解决了重SDK的问题,但是可以发现依然有许多轻量级SDK存需要进行维护。其为了保证功能互不影响,每个功能又需要调用不同的端口和协议与MOSN进行调用,这样会无限增大sidecar维护成本同时降低安全性。
为了解决刚才的问题和场景,我们就在思考如下的几个点:
- 不同中间件、不同语言的 SDK 能否风格统一?
- 各个下沉能力的交互协议能否统一?
- 我们的中间件下沉是面向组件还是面向能力?
- 底层的实现是否可以替换?
Multi-Runtime 的探索
Multi-Runtime 的诞生
越来越多的项目开始引入Sidecar模式, Sidecar模式也逐渐被大家认可和接受。2020年,Bilgin lbryam发表了一篇名为Multi-Runtime Microservices Architecture提出了Multi-Runtime的理念,对基于Sidecar模式的各种产品形态进行了实践总结和理论升华。
首先作者把分布式服务的需求进行了抽象,总共分为了四大类:
- 生命周期(Lifecycle)
- 网络(Networking)
- 状态(State)
- 捆绑(Binding)
每种类型下面还有一些子能力,如 Point-to-Point, pub/sub, Caching 等比较经典的中间件能力。能够看到应用对分布式能力有如此多的需求,而Service Mesh显然不能满足应用的当前的需求。所以文章中提出了Multiple Runtime的理念来解决Service Mesh的困境。
Multi-Runtime的理论推导大体如下:
基于上述四大类需求,如果效仿Service Mesh,从传统中间件模式开始,那么主要会有下面两个步骤:
- 步骤一:将应用需要的分布式能力外移到各种 runtime,此时会出现数量众多的各种 Sidecar 或者 proxy,如上面中列出来的 Istio、Knative、Cloudstate、Camel、Dapr 等。
- 步骤二:这些 runtime 会逐渐整合,只保留少量甚至只有一两个 runtime。这种提供多种分布式能力的 runtime 也被称为 Mecha。
步骤二完成后,每个微服务就会由至少一个Mecha Runtime和应用Runtime共同组成,也就是每个微服务都会有多个(至少两个)runtime,这也就是 Multi-Runtime / Mecha名字的由来。
可以看到该理论的推演步骤一实际上相当于蚂蚁对于Service Mesh向Multi-Mesh发展的实践,而步骤二就是接下来我们要解决的问题,即如何将runtime能力整合,从而实现真正的云原生分布式能力。
可以理解为 Multi-Runtime 的本质是面向云原生应用的分布式能力抽象层。
Multi-Runtime 为了整合上述能力,需要拥有更强的抽象能力。与Service Mesh采用原协议转发不同,Multi-Runtime的方式是:
- 将能力抽象为 API:很多分布式能力没有类似HTTP这种业界通用的协议,因此Multi-Runtime的实现方式是将这些能力抽象为和通讯协议无关的API,只用于描述应用对分布式能力的需求和意图,尽量避免和某个实现绑定。
- 为每种能力提供多种实现:Multi-Runtime中的能力一般都提供有多种实现,包括开源产品和公有云商业产品。
- 开发时:这里我们引入一个“面对能力编程”的概念,类似于编程语言中的“不要面对实现编程,要面向接口编程”。Multi-Runtime中提倡面向“能力(Capability)”编程,即应用开发者面向的应该是已经抽象好的分布式能力原语,而不是底层提供这些能力的具体实现。
- 运行时:通过配置在运行时选择具体实现,不影响抽象层API的定义,也不影响遵循“面对能力编程”原则而开发完成的应用。
蚂蚁对于Multi-Runtime的实践
分布式应用运行时 Dapr
微软推出的Dapr项目是业界第一个Multiple Runtime的开源实践项目。Dapr是一个可移植的、事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的、无状态和有状态的应用程序,并可运行在云平台或边缘计算中,它同时也支持多种编程语言和开发框架。
运行时和Mesh的对比
Multi-Runtime 架构下的安全风险与研究方向
在介绍完Multi-Runtime后我们来简单聊聊Multi-Runtime架构下可能带来的安全风险和新的安全研究方向。
API 注入
通过上面的介绍我们可以知道运行时为了整合多个分布式能力,其里最主要的一部分就是 API 的定义,所以说是否有一套标准的API定义是运行时成败的关键。因此多个社区开始了API共建计划。
我们转换为安全的角度来看,以Dapr为例,核心是中间的这个API层
它统一了请求分布式能力的方式
既然多种能力都基于同一种API声明规范使得它们可以用来被调用,那么这里可能会出现一种攻击方式,这里我把它归结为API注入。
什么是API注入?也就是用户对于dapr的一部分API可控,当结合RFC差异或是用户可控内容过大,就可能造成注入到Component的情况。也就是类似我们可以将一次invoke服务调用请求注入成state调用类型,即转变为store存储读取的服务。
比如将
1 2 |
POST/GET/PUT/DELETE http://localhost:<daprPort>/v1.0/invoke/<appId>/method/<method-name> |
变为
1 2 |
GET http://localhost:<daprPort>/v1.0/state/<storename>/<key> |
不过上面这种情况场景过于苛刻,那么其API统一抽象的能力,在安全的角度还能带来什么可能性呢?
SSRF 攻击面增大
由于Multi-Runtime整合了大量分布式能力,这意味着当攻击拥有SSRF能力时,可以触达的信息源会更多。
1 2 3 4 5 6 7 8 9 10 11 12 |
// 查看metadata [root@Ruilin hello-world]# curl http://localhost:3500/v1.0/metadata {"id":"nodeapp","actors":[],"extended":{"cliPID":"17583","appCommand":"node app.js"},"components":[{"name":"pubsub","type":"pubsub.redis","version":"v1"},{"name":"statestore","type":"state.redis","version":"v1"}]} // 查看缓存 [root@Ruilin hello-world]# curl http://localhost:3500/v1.0/state/statestore/order {"orderId":"42"} // 获取可订阅的消息主题 [root@Ruilin hello-world]# curl http://localhost:3500/v1.0/subscribe // 查看一些的密钥 [root@Ruilin hello-world]# curl http://localhost:3500/v1.0/secrets/my-secrets-store/my-secret ...... |
WebAssembly 安全研究方向
WASM,是一个二进制指令集,最初是跑在浏览器上来解决JavaScript的性能问题,但由于它良好的安全性,隔离性以及语言无关性等优秀特性,很快人们便开始让它跑在浏览器之外的地方,随着WASI定义的出现,只需要一个WASM运行时,就可以让WASM文件随处执行。
由于WASM能够轻松的完成自定义扩展的需求以及其良好的安全性,越来越多的云原生架构将其融入其中,比如Service Mesh相关(Istio、Envoy),还有Serverless领域都已经开始尝试与支持。当然Multi-Runtime架构也不例外。
现在MOSN已经通过集成WASM Runtime的方式让WASM跑在MOSN上面,以此来满足对MOSN做自定义扩展的需求。同时,Layotto也是构建在MOSN之上。蚂蚁也希望将这两者结合起来,形成类似如下架构,开发者可以将编译好的WASM文件更加灵活的直接跑在MOSN上面。
目前WASM社区目前还处于初期阶段,WASM也在快速发展并在各种云原生架构下落地和实践,WASM的安全性开始变得更加重要,这也是整个云原生背景下引出的一个新的值得关注的安全研究方向。
参考
https://cloudblogs.microsoft.com/opensource/2019/10/16/announcing-dapr-open-source-project-build-microservice-applications/
https://www.sofastack.tech/blog/exploration-and-practice-of-antcloud-native-application-runtime-archsummit-shanghai/
https://mosn.io
近期评论