乐趣区

关于webassembly:WebAssembly让Istio变得更强大

1 Wasm 为 Envoy 带来新的扩展性
Envoy 是一个高性能、可编程的 L3/L4 和 L7 网络代理,许多服务网格和网关都采纳 Envoy 作为数据面。
Envoy 通过监听器(Listener)捕捉网络数据包,依据数据包的内容匹配某个过滤器链(Filter Chain)中,之后按程序执行该链中的过滤器(Network Filter)对捕捉的数据包进行操作,实现用户定义的各种流量治理策略。Envoy 自身自带很多品种的过滤器,这些开箱即用的过滤器 cover 了大部分的利用场景,然而在某些须要自定义性能的场景下,用户必须实现本人的过滤器。

Envoy filter chains
在 Wasm 呈现之前,增加过滤器有两种形式:

  1. 批改 Envoy 代码,应用 C ++ 语言编写原生的过滤器(Native C++ filters)。在晚期(2019 年初),Envoy 是一个动态编译的二进制文件,其所有扩大都在构建时编译。这意味着提供自定义扩大的我的项目必须保护和散发本人的二进制文件。这种形式须要开发者相熟 C ++ 语言和 Envoy 过滤器的开发模式,在开发实现后从新编译一个新的 Envoy 二进制且保护它与上游社区的版本。目前 Istio 社区采纳的就是这种形式,Istio fork 了上游的 Envoy,在其根底之上增加了本人定制的一些插件。然而,这种形式对开发者要求较高,且须要破费额定的精力保护。
  2. 应用 Lua 脚本编写过滤器。这种形式相比于上一种更加简略,用户能够间接在 xDS 配置中间接编写 Lua 脚本(inline)或指定本地的一个 Lua 脚本文件,适宜过滤器逻辑非常简单的状况。然而,这种形式并不适用于过滤器逻辑简单的状况,而且须要用户在 Istio 中手动创立 EnvoyFilter 进行额定的配置。
    能够看出,上述两种扩大 Envoy 的形式都不是十分“优雅”。为了解决这个问题,Envoy 社区提出了 Wasm Filter 个性,在 Envoy 中内嵌了一个 Wasm 运行时,通过 proxy-wasm 定义的网络代理相干接口来运行 Wasm 二进制。这意味着 Envoy 能够在运行中动静地加载用户开发的 Wasm 模块,并将其作为一个过滤器插入到过滤器链中。Wasm 可能解决上述传统形式的各种问题,用户可能用任何反对的语言开发本人的 Wasm 过滤器,对 Envoy 自身无侵入。Envoy 发起者称“Wasm 是 Envoy 可扩展性的将来”。

Envoy 与 Wasm 的交互

2 Istio WasmPlugin API

Envoy 对 Wasm 的反对为 Istio 带来了全新的扩大机制。在晚期,用户能够应用 EnvoyFilter 手动在 Envoy 配置中增加 Wasm filter,这种形式十分地繁琐,用户体验并不敌对,且 EnvoyFilter 是一个“break glass”API,社区并不保障其不同版本的向后兼容性。
为了更好地反对 Wasm,Istio 在 1.12 版本中增加了一个新的 CRD,即 WasmPlugin。用户能够通过 WasmPlugin 不便灵便地将 Wasm 插件下发到指定的工作负载,使得开发人员能够更简略强壮地扩大网格性能。

WasmPlugin yaml 示例
上图展现了一个最根本的 WasmPlugin 配置,在配置中用户须要指定 Wasm 模块的 url,该 url 能够是像容器镜像一样的 OCI 格局的 Wasm,也能够是代理本地的一个文件(通常要求用户手动挂载到容器中),或者是 http 协定的 url,用于间接获取近程 Wasm 模块文件。个别举荐的形式第是一种,将编写好的代码编译成 Wasm 二进制后,打包成一个 OCI 镜像,不便散发和复现。
用户能够通过 selector 指定要下发 Wasm 的 proxy,如果 selector 为空,则代表下发到该 namespace 下的所有 proxy。
除此之外,如果用户须要指定 Wasm 插件在过滤器链中执行的地位,能够通过 phase 和 priority 两个参数来管制。phase 用来指定在 http filter 链中的何处插入此 Wasm 插件,能够设置为 authentication,authorization 或 istio stats filter 之前,未设置时会在 istio stats filter 之后插入;priority 用来管制多个 WasmPlugin 在同一个 phase 中的执行程序,priority 值大的优先。

03Istio 下发 Wasm 配置流程解析

Istiod 推送过程
每当用户更新 WasmPlugin 时,istiod 就会触发一次 config update。首先,istiod 会更新本次 xDS push 的 context,将以后的 WasmPlugin 信息依照 namespace 分类,保留到 push context 中。
之后,在 LDS(Listener Discovery Service)推送的过程中,istiod 为 proxy 构建 Listener 的 http filter 时,会从 push context 中找出与该 proxy 匹配的 WasmPlugin 并依照 priority 排序,最初依据 phase 将 Wasm filter 插入到 http filter chain 中的某个地位。

Istio 插入 Wasm filter 代码
留神此处插入的只是 Wasm filter 的名称,具体的 Wasm filter 配置则是通过后续的 ECDS(Extension Config Discovery Service)下发的。在 ECDS 中,istiod 会构建出理论的 Wasm filter 配置并推送给 proxy。

 Wasm filter envoy 配置示例

04 Proxy 接管过程 Proxy 接管过程

Envoy 的 Wasm filter 配置自身是不反对应用 OCI 镜像格局作为 data source 的。那么 Istio 是如何反对应用 OCI 镜像散发 Wasm 二进制的呢?
答案是通过 istio-agent 的代理。Istio 的 proxy 中蕴含两个过程,一个是 Envoy 自身,另一个是 istio-agent。istio-agent 会代理 Envoy 与 istiod 之间的 xDS 通信。对于 ECDS,istio-agent 在收到推送时,会读取其内容,如果其中的 Wasm filter 应用 OCI 镜像或者 http/https 作为 data source(即须要执行的 Wasm 二进制),那么 istio-agent 会从近程仓库中拉取该 Wasm 二进制并缓存至本地。之后会批改 ECDS 的内容,将 Wasm filter 的 data source 改为方才保留的本地文件,再将批改后的 ECDS 内容发送给 Envoy。
对 Wasm 为 Envoy 带来新的扩展性的价值简要总结:综上,Envoy 和 Istio 对 Wasm 的反对大大增强了服务网格的扩展性。用户通过 Wasm 可能以可扩大、灵便、平安的形式对代理进行自定义配置,应答各种场景的业务需要,例如认证、受权、Tracing、申请内容转换 / 查看等等。同时,Istio 提供的 API 使 Wasm 成为了服务网格中的“一等公民”,用户能够不便地将 Wasm 下发到指定的工作负载,该过程是齐全动静的,利用无需重启。这种高效率的扩大形式使得服务网格具备了可编程性。

05 将来瞻望

目前,Wasm 仍在疾速倒退,相干的个性在 Istio 和 Envoy 中还处在 alpha 阶段。为了减速 Wasm 生态,让所有 Wasm 程序有一个“common language”,社区正在设计一个规范的 Wasm interface —— WASI(WebAssembly System Interface),用于拜访和操作系统资源。将来 proxy-wasm 可能会与 WASI 交融,为 Wasm 程序提供一个规范的交互接口。同时,Wasm 将反对更多高级语言作为前端,用于构建轻量、高性能的应用程序。随着 Wasm 生态的逐渐成熟,期待它能在云计算畛域中带来更多令人兴奋的可能性。

退出移动版