发布 WebAssembly 插件 Alpha 版本
介绍新的 Wasm 插件 API 以及 Envoy 和 Istio 中基于 Wasm 的插件支持的更新。
Istio 1.9 引入了对 WebAssembly (Wasm) 模块分发和 Wasm 扩展生态系统存储库的实验性支持,其中包含扩展开发的规范示例和用例。在过去的 9 个月里,Istio、Envoy 和 Proxy-Wasm 社区继续共同努力,使 Wasm 可扩展性稳定、可靠且易于采用,我们很高兴地宣布 Istio 1.12 中对 Wasm 可扩展性的 Alpha 支持!在以下部分中,我们将逐步介绍为 1.12 版本对 Wasm 支持所做的更新。
新的 WasmPlugin API
通过 extensions.istio.io
命名空间中的新 WasmPlugin
CRD,我们引入了一个新的高级 API,用于使用自定义 Wasm 模块扩展 Istio 代理的功能。这项工作建立在过去两年中对 Proxy-Wasm 规范和实现所做的出色工作之上。从现在开始,您不再需要使用 EnvoyFilter
资源将自定义 Wasm 模块添加到您的代理中。相反,您现在可以使用 WasmPlugin
资源
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: your-filter
spec:
selector:
matchLabels:
app: server
phase: AUTHN
priority: 10
pluginConfig:
someSetting: true
someOtherSetting: false
youNameIt:
- first
- second
url: docker.io/your-org/your-filter:1.0.0
WasmPlugin
和 EnvoyFilter
之间有很多相似之处和一些不同之处,因此让我们逐个了解这些字段。
以上示例将 Wasm 模块部署到与 selector
字段匹配的所有工作负载(包括网关 Pod) - 这与 EnvoyFilter
中的工作方式非常相似。
下一个字段是 phase
。这决定了 Wasm 模块将在代理过滤器链中的哪个位置注入。我们为注入定义了四个不同的阶段
AUTHN
:在任何 Istio 身份验证和授权过滤器之前。AUTHZ
:在 Istio 身份验证过滤器之后,但在任何一级授权过滤器之前,即在应用AuthorizationPolicy
资源之前。STATS
:在所有授权过滤器之后,但在 Istio 统计信息过滤器之前。UNSPECIFIED_PHASE
:让控制平面决定插入位置。这通常在过滤器链的末尾,在路由器之前。这是此phase
字段的默认值。
pluginConfig
字段用于配置您的 Wasm 插件。您放入此字段中的任何内容都将以 JSON 编码并传递给您的过滤器,您可以在 Proxy-Wasm SDK 的配置回调中访问它。例如,您可以使用 C++ SDK 中的 onConfigure
、Rust SDK 中的 on_configure
或 Go SDK 中的 OnPluginStart
回调来检索配置。
url
字段指定从哪里拉取 Wasm 模块。您会注意到此示例中的 url
是一个 Docker URI。除了通过 HTTP、HTTPS 和本地文件系统(使用 file://)加载 Wasm 模块之外,我们还引入了 OCI 镜像格式作为分发 Wasm 模块的首选机制。
最后需要注意的是,目前 Wasm Plugin API 仅适用于入站 HTTP 过滤器链。将来会增加对网络过滤器和出站流量的支持。
Wasm 镜像规范
我们认为容器是存储、发布和管理代理扩展的理想方式,因此我们与 Solo.io 合作,扩展了他们现有的 Proxy-Wasm 容器格式,并添加了一个旨在与所有注册表和 CLI 工具链兼容的变体。根据您的流程,您现在可以使用现有的容器 CLI 工具(如 Docker CLI 或 buildah)构建代理扩展容器。
要了解如何构建 OCI 镜像,请参阅 这些说明。
Istio 代理中的镜像获取器
从 Istio 1.9 开始,Istio 代理通过利用 istio 代理内部的 xDS 代理和 Envoy 的扩展配置发现服务 (ECDS),为加载从 EnvoyFilters
中配置的远程 HTTP 源获取的 Wasm 二进制文件提供了一个可靠的解决方案。相同的机制适用于 Istio 1.12 中新的 Wasm API 实现。您可以可靠地使用 HTTP 远程资源,而无需担心当远程获取失败时 Envoy 可能会卡在错误的配置上。
此外,Istio 1.12 将此功能扩展到 Wasm OCI 镜像。这意味着 Istio 代理现在能够从任何 OCI 注册表(包括 Docker Hub、Google Container Registry (GCR)、Amazon Elastic Container Registry (Amazon ECR) 等)获取 Wasm 镜像。获取镜像后,Istio 代理会从中提取和缓存 Wasm 二进制文件,然后将其插入 Envoy 过滤器链中。
Envoy Wasm 运行时的改进
Envoy 中由 V8 提供支持的 Wasm 运行时自 Istio 1.5 以来一直在交付,并且此后已经有很多改进。
WASI 支持
首先,现在支持一些 WASI(WebAssembly 系统接口)系统调用。例如,可以从 Wasm 程序发出 clock_time_get
系统调用,因此您可以在 Rust 中使用 std::time::SystemTime::now()
或在 Go 中使用 time.Now().UnixNano()
在您的 Envoy Wasm 扩展中,就像任何其他原生平台一样。另一个示例是 Envoy 现在支持 random_get
,因此“crypto/rand”包在 Go 中可用作密码安全的随机数生成器。我们目前也在研究文件系统支持,因为我们已经看到来自在 Envoy 中运行的 Wasm 程序的读取和写入本地文件的请求。
可调试性
接下来是可调试性的改进。Envoy 运行时现在会在程序导致运行时错误时发出程序的堆栈跟踪,例如,当在 C++ 中发生空指针异常或在 Go 或 Rust 中调用 panic 函数时。虽然 Envoy 错误消息以前不包含任何关于原因的信息,但现在它们显示了跟踪,您可以使用它来调试程序
Function: proxy_on_request_headers failed: Uncaught RuntimeError: unreachable
Proxy-Wasm plugin in-VM backtrace:
0: 0xdbd - runtime._panic
1: 0x103ab - main.anotherCalculation
2: 0x10399 - main.someCalculation
3: 0xea57 - main.myHeaderHandler
4: 0xea15 - proxy_on_request_headers
以上是基于 Go SDK 的 Wasm 扩展的堆栈跟踪示例。您可能会注意到输出在跟踪中不包含文件名和行号。这是未来一项重要的工作项目,也是与 WebAssembly 的 DWARF 格式和 WebAssembly 规范的异常处理提案相关的未解决问题。
Wasm 程序的 strace 支持
您可以看到 Envoy 发出的等效于 strace
的日志。使用 Istio 代理的组件日志级别 wasm:trace
,您可以观察所有跨越 Wasm 虚拟机和 Envoy 之间边界的系统调用和 Proxy-Wasm ABI 调用。以下是此类 strace
日志流的示例
[host->vm] proxy_on_context_create(2, 1)
[host<-vm] proxy_on_context_create return: void
[host->vm] proxy_on_request_headers(2, 8, 1)
[vm->host] wasi_snapshot_preview1.random_get(86928, 32)
[vm<-host] wasi_snapshot_preview1.random_get return: 0
[vm->host] env.proxy_log(2, 87776, 18)
这在运行时调试 Wasm 程序的执行时特别有用,例如,验证它没有进行任何恶意系统调用。
Wasm 中指标的任意 Prometheus 命名空间
最后一个更新是关于指标的。Wasm 扩展能够定义自己的自定义指标并在 Envoy 中公开它们,就像任何其他指标一样,但在 Istio 1.12 之前,所有这些自定义指标都以 envoy_
Prometheus 命名空间为前缀,用户无法使用自己的命名空间。现在,您可以选择任何您想要的命名空间,并且您的指标将在 Envoy 中按原样公开,而不会以 envoy_
为前缀。
请注意,为了实际公开这些自定义指标,您必须在 meshConfig
中配置 ProxyConfig.proxyStatsMatcher
以进行全局配置,或者在 proxy.istio.io/config
中配置以进行每个代理配置。有关详细信息,请参阅 Envoy 统计信息
。
未来的工作和寻求反馈
尽管我们已经宣布了 Wasm 插件的 Alpha 版本,但仍有许多工作要做。一项重要的工作项目是 Wasm API 中的“镜像拉取密钥”支持,这将允许您轻松地在私有存储库中使用 OCI 镜像。其他工作包括对 L4 过滤器的首级支持、Wasm 二进制文件的签名验证、Envoy 中的运行时改进、Proxy-Wasm SDK 改进、文档等。
这仅仅是我们计划在 Istio 中提供一流 Wasm 支持的开始。我们希望听到您的反馈,以便我们能够在 Istio 的未来版本中改进使用 Wasm 插件的开发人员体验!