服务网格 ASM(Service Mesh)数据面基于Envoy实现了7层代理(包括网关、Sidecar和Waypoint),提供了多种扩展方式可以用于实现一些高级功能。本文将全面介绍当前ASM提供的各类扩展方式以及各自的使用场景。
扩展方式
目前ASM主要提供了以下扩展方式供您选择:
EnvoyFilter
Filter是Envoy中的一个重要概念。不同的Filter按照特定顺序组成Filter链,对进入Envoy的请求依次进行处理,最终将请求转发给上游服务。这些Filter使用C++开发,与Envoy的核心代码一起编译成二进制文件,以确保可以高性能地运行。
在服务网格场景下,EnvoyFilter是ASM提供的一种Kubernetes资源,您可以通过EnvoyFilter资源修改数据面代理中已有的Filter或者添加新的Filter。
EnvoyFilter具备高度灵活性,但由于EnvoyFilter中需要直接写Envoy的配置,可能会出现配置错误导致应用不可用或者不同版本之间不兼容的情况。因此,使用EnvoyFilter需要对数据面实现有一定的了解。
针对不同版本EnvoyFilter配置可能不同的问题,ASM提供了EnvoyFilter模板,请参见使用Envoy过滤器模板创建Envoy过滤器。
Lua、Wasm和自定义授权服务也是Envoy中的Filter。和普通的Filter不同,这些Filter可以实现一些用户自定义的逻辑。这里只讨论普通的实现特定功能的EnvoyFilter。
使用限制
只能使用Envoy官方提供的Filter,不支持自定义逻辑。
推荐场景
如果Envoy官方提供了可以满足您需求的Filter,则建议使用EnvoyFilter资源。例如,自定义错误页面、请求返回413时设置缓存大小等。
Lua
Lua是一种轻量、高效的脚本语言,主要用于嵌入式开发和游戏编程。它以简单易学和灵活可扩展闻名,广泛应用于多种领域。Envoy中有一个特殊的Lua Filter,您可以在Filter配置中直接编写Lua代码,Envoy会在处理请求的过程中直接调用这些代码来实现一些自定义逻辑。相关示例,请参见在ASM网关上基于Client IP进行路由。
目前Lua脚本只能在处理HTTP请求时生效,您无法使用它直接操作TCP字节流。
使用限制
不建议在Lua代码中编写太过复杂的逻辑。如果您直接在EnvoyFilter配置中编写逻辑过于复杂的Lua代码,由于无法引用外部的工具库,EnvoyFilter配置将变得难以维护。
不建议在Lua代码中处理请求或响应Body。在Lua脚本中处理请求或响应Body,Envoy会缓存整个Body。如果Body size较大,可能会导致Envoy内存占用过高,导致请求返回413(Payload Too Large)。
推荐场景
如果您的需求相对比较简单,使用少量代码即可完成自定义逻辑的编码。那么使用Lua是不错的选择,Lua脚本配置简单,运行效率高。
Wasm
WebAssembly(Wasm)是一种可移植的二进制可执行文件格式。它允许您将代码编译成高效的二进制文件,在沙箱环境中以接近本机的速度执行。Wasm严格控制资源的使用,通过清晰定义的API与主机进行交互,从而提高了安全性。
和Lua不同,您可以直接提供Wasm二进制文件给Envoy运行,因此这些扩展功能的代码可以单独管理,并且使用外部代码库来满足您的特殊需求。您可以使用多种编程语言,如Rust、C++和Go等来编写Wasm代码,示例如下:
同时,Wasm处理请求或响应的能力更加强大,主要分为以下几方面:
Wasm支持操作TCP字节流。
Wasm支持流式处理请求或响应Body。在Wasm中,您可以根据需要选择是否缓存整个Body,或者选择分块处理,这将显著提升Body处理效率并且降低内存占用。
支持使用第三方库。
使用限制
Wasm运行时对于GC(Garbage Collection)类语言(Java、C#、Go、Python等)支持存在问题。例如,使用Go编写Wasm插件在Envoy中执行时,其内存占用会显著提升。社区更推荐使用非GC类语言,如Rust、C++等。这类语言内存占用少,而且执行效率更高。但是这类语言通常编写或编译门槛较高。您可以根据需要自行选择。
推荐场景
如果您对相关开发语言熟悉,并了解Envoy的内部处理逻辑,且需求较为复杂,建议使用性能优化较好的语言。对于性能和资源占用不太敏感的场景,Go语言是一个简单易用的选择。如果对性能和资源占用有较高要求,建议使用Rust或C++。
自定义授权服务
自定义授权服务的实现原理是:Envoy支持配置一个外部鉴权的Filter,当请求被这个Filter处理时,这个Filter将会调用一个外部的标准HTTP或gRPC服务,由这个服务来判断拒绝或放行请求,并且可以修改或新增请求指定的请求头。
然而自定义授权服务操作请求的能力有限,不如Lua或Wasm灵活。但是其主要优势是与Envoy解耦,API十分稳定,并且不依赖特定编程语言或编程框架,您只需要实现Envoy要求的HTTP或gRPC接口即可。具体操作和配置示例如下:
使用限制
只能对请求生效,无法作用于响应。
操作请求元信息能力不如Lua和Wasm灵活。且只能读取请求Body,不能操作请求Body。
自定义授权服务无法自主决定哪些请求头可操作,需要进行额外的显式配置。
自定义授权服务需要单独部署,因此会增加一些请求处理延迟。
推荐场景
如果Lua不能满足您的需求,Wasm开发复杂度又过高,并且您可以接受上述限制,推荐使用自定义授权服务。
关于插件中心
ASM插件中心提供了多种内置插件,这些插件基于Envoy原生Filter的实现,或基于Lua和Wasm的实现。遇到定制化需求时,建议您优先查看插件市场是否有合适的内置插件,如果没有,再考虑自行配置或开发。更多信息,请参见使用插件市场扩展网格能力。