首页
/ Envoy Wasm 网络过滤器:用 WebAssembly 插件扩展 Envoy 的 Network Filter 能力

Envoy Wasm 网络过滤器:用 WebAssembly 插件扩展 Envoy 的 Network Filter 能力

2026-09-12 11:33:08作者:咎岭娴Homer

本篇指南基于 Envoy 官方文档中的 Wasm Network Filter 配置章节展开,完整讲解 envoy.filters.network.wasm 过滤器的定位、实验性状态、YAML 配置写法与全部关键字段(PluginConfigVmConfigfailure_policy 等),并结合仓库中的 protobuf 定义与 C++ 实现源码,说明该过滤器从配置解析到 VM 加载的完整调用链,帮助读者理解如何在 Envoy 的 TCP 网络过滤器链中安全地接入 Wasm 插件。

1. 什么是 Wasm 网络过滤器

Wasm 网络过滤器(Wasm Network Filter)用于用一个 Wasm 插件实现一个网络过滤器,即它工作在 Envoy 的 L4 网络过滤器链上(envoy.filters.network.wasm),而不是 HTTP 过滤器链上。插件以 Proxy-Wasm ABI 编写,编译为 .wasm 二进制后由 Envoy 内置的 Wasm 运行时加载执行。

官方文档中有明确的实验性声明,这一点在评估生产可用性时必须注意:

The Wasm filter is experimental and is currently under active development. Capabilities will be expanded over time and the configuration structures are likely to change.

(Wasm 过滤器目前是实验性的,正在积极开发中,能力会随时间扩展,配置结构也可能发生变化。)

对应 v3 API 参考文档为 envoy.extensions.filters.network.wasm.v3.Wasm

2. 基本配置示例

文档给出的完整过滤器配置如下,它从本地磁盘加载一个 Wasm 二进制文件:

name: envoy.filters.network.wasm
typed_config:
  "@type": type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm
  config:
    config:
      name: "my_plugin"
      vm_config:
        code:
          local:
            filename: "/etc/envoy_filter_http_wasm_example.wasm"
        allow_precompiled: true

逐层解读这个配置:

  • name: envoy.filters.network.wasm:过滤器在过滤器链中的名称,取自注册名。源码中 WasmFilterConfig 构造函数以 NetworkFilterNames::get().Wasm 作为注册名(见 config.h)。
  • @type:指向 proto 消息 envoy.extensions.filters.network.wasm.v3.Wasm,该消息只有一个字段 config,类型为 envoy.extensions.wasm.v3.PluginConfig(见 wasm.proto)。
  • config.name: "my_plugin":插件在 VM 中的唯一名称,用于日志和调试;当同一个 vm_idroot_id 下存在多个插件时,用它来区分。
  • vm_config.code.local.filename:Wasm 代码来源,这里使用 AsyncDataSource 的本地文件方式。也可以改用远程获取(remote)方式下发。
  • allow_precompiled: true:允许 wasm 文件包含预编译代码(仅限支持该特性的运行时)。

需要注意的是,官方示例中文件名沿用了 envoy_filter_http_wasm_example.wasm 这类 HTTP Wasm 示例的命名习惯;对于网络过滤器,插件需实现 Proxy-Wasm 的 network filter 相关回调(如 proxy_on_connectproxy_on_data),由同一个 VM 基础设施驱动。

3. 核心配置字段详解

Wasm 过滤器的实际配置主体是 PluginConfigwasm.proto),以下字段对配置该过滤器时理解行为至关重要。

3.1 插件标识与 VM 复用

字段 说明
name 插件唯一名称,用于同一 VM 内多插件的标识与日志调试
root_id 同一 VM 中共享 RootContext/Contexts 的插件分组 ID(例如一个 Wasm HTTP 过滤器与一个 Wasm 访问日志)。留空时,vm_id 相同且 root_id 为空的插件共享 Context
vm_config.vm_id 与 wasm 代码哈希一起决定使用哪个 VM。所有使用相同 vm_id 和代码的插件将复用同一个 VM。留空即可。共享 VM 可降低内存占用、便于数据共享,但可能有安全影响

3.2 运行时与代码来源

  • vm_config.runtime:Wasm 运行时类型,默认使用 Envoy 构建时第一个可用的引擎,查找优先级为 v8 -> wasmtime -> wamr。内置可用运行时:
    • envoy.wasm.runtime.null:Null 沙箱,Wasm 模块必须编译链接进 Envoy 二进制,注册名写在 code 字段的 inline_string 中;
    • envoy.wasm.runtime.v8:基于 V8 的运行时;
    • envoy.wasm.runtime.wamr:基于 WAMR 的运行时(官方构建未启用);
    • envoy.wasm.runtime.wasmtime:基于 Wasmtime 的运行时(官方构建未启用)。
  • vm_config.code:类型为 config.core.v3.AsyncDataSource,支持本地文件(local)、远程获取(remote)与内联字符串(inline_string)。
  • vm_config.allow_precompiled:允许 wasm 文件携带预编译代码。警告:预编译代码不做校验,只能对可信来源开启。
  • vm_config.nack_on_code_cache_miss:若代码需要远程获取且缓存未命中,为 true 时直接 NACK 该配置更新并在后台拉取填充缓存;否则异步拉取代码并进入 warming 状态。

3.3 插件初始化配置

  • vm_config.configuration(VM 级):用于 proxy_on_start 初始化 VM。google.protobuf.Struct 会序列化为 JSON 传给插件;google.protobuf.BytesValuegoogle.protobuf.StringValue 直接透传。
  • configuration(插件级):用于 proxy_on_configure 配置或重配置插件,序列化规则同上。

3.4 环境变量注入

vm_config.environment_variables(类型 EnvironmentVariables)可向 VM 注入环境变量,插件通过 WASI 的 environ_get / environ_get_sizes_get 系统调用访问——这些调用通常由语言标准库隐式触发,插件代码可按原生日平台方式读取环境变量。

  • host_env_keys:从 Envoy 自身 的环境中透传指定 key(若 Envoy 环境中不存在该 key 则忽略);
  • key_values:以 "KEY=VALUE" 形式显式注入的键值对。
  • 注意:Envoy 会在键空间冲突时拒绝该配置。

4. 失败策略:failure_policy

VM 发生致命错误(如异常、abort()on_starton_configure 返回 false)时,按 failure_policy 处理。可选枚举值(wasm.proto):

策略 行为
UNSPECIFIED(默认) 未指定策略,使用默认策略 FAIL_CLOSED
FAIL_RELOAD VM 失败后,为新请求创建新的插件实例。注意仅对 proxy_wasm::FailState::RuntimeError 生效,其余失败会回退到 FAIL_CLOSED
FAIL_CLOSED 该 VM 关联的所有插件返回 HTTP 503 错误
FAIL_OPEN 该 VM 关联的所有插件被忽略,过滤器链继续处理(适合插件是可选能力的场景)

配套字段:

  • reload_config.backoff:仅当 failure_policyFAIL_RELOAD 时生效,控制 VM 失败重载的退避策略,不指定时默认 1s 基础间隔。
  • 旧字段 fail_open(布尔)已废弃(deprecated_at_minor_version "3.0"),被 failure_policy 取代。

另有一个重要注意点:当 on_starton_configure 在 xDS 更新过程中返回 false 时,xDS 配置会被拒绝;在初始启动时返回 false代理进程不会启动

5. 能力限制:capability_restriction_config

CapabilityRestrictionConfig 用于限制模块可用的 Proxy-Wasm 能力:

  • allowed_capabilities:以能力名为键的白名单。能力名遵循 Proxy-Wasm ABI;此外实现了以下 WASI 能力,可被允许:fd_writefd_readfd_seekfd_closefd_fdstat_getenviron_getenviron_sizes_getargs_getargs_sizes_getproc_exitclock_time_getrandom_get
  • 每个能力映射的 SanitizationConfig 目前未实现,应留空。
  • 限制在 VM 创建时生效,且被该 VM 中所有插件共享,因此它是 VM 的属性而非单个插件的属性。
  • 插件级旧字段 capability_restriction_config 已废弃:若插件级字段已设置而 vm_config.capability_restriction_config 未设置,则用插件级字段填充 VM 级字段。

6. 源码实现视角

结合仓库源码,可以看清配置到运行的完整链路。

过滤器注册config.cc 中,WasmFilterConfig 通过 FactoryBase<envoy::extensions::filters.network.wasm.v3::Wasm> 解析 Wasm proto,并在文件末尾以 REGISTER_FACTORY(WasmFilterConfig, Server::Configuration::NamedNetworkFilterConfigFactory) 完成静态注册,这正是配置中 envoy.filters.network.wasm 名称的来源。

工厂回调的 fail-open 语义

auto filter_config = std::make_shared<FilterConfig>(proto_config, context);
return filter_config -> void {
  auto filter = filter_config->createContext();
  if (filter) {
    filter_manager.addFilter(filter);
  } // else fail open
};

从源码结构看,若插件上下文创建失败,工厂回调不会向过滤器管理器添加任何过滤器,即请求“fail open”地绕过该 Wasm 过滤器继续走后续过滤器链——这与第 4 节 FAIL_OPEN 策略在连接建立阶段的默认行为相一致。同时该工厂在创建前会注册 Wasm 的自定义统计命名空间(Extensions::Common::Wasm::CustomStatNamespace),用于插件自定义指标。

配置基类wasm_filter.cc 中,网络过滤器的 FilterConfig 直接继承通用的 Extensions::Common::Wasm::PluginConfig,构造时把 proto 的 config.config()(即 PluginConfig)、统计作用域、InitManager 传入,最后一个参数 false 表明它不是 singleton 模式(每个 worker 拥有自己的 VM 实例,而非 WasmService 那种全局单例 VM)。也就是说,网络过滤器、HTTP 过滤器、访问日志等所有 Wasm 扩展共享同一套插件配置与 VM 管理逻辑,网络过滤器只是其在 L4 过滤器链上的一个出口。

7. 实战注意事项

  1. 实验性定位:文档明确标注该过滤器为实验性,配置结构可能变化,变更前应确认目标 Envoy 版本。
  2. allow_precompiled 只对可信代码开启:预编译代码不做校验,远程下发不可信 .wasm 时存在供应链风险。
  3. 默认失败策略是 fail closedUNSPECIFIED 回退到 FAIL_CLOSED(HTTP 503),若插件属于可选增强能力,应显式配置 FAIL_OPEN 以避免 VM 崩溃阻断流量。
  4. on_start/on_configure 返回 false 的后果:xDS 更新阶段会拒绝配置;启动阶段会直接阻止代理启动,调试插件时建议先本地验证这两个回调。
  5. VM 共享与 vm_id:多个插件配相同 vm_id 与代码会复用同一 VM,节省内存并便于插件间共享数据,但需评估跨插件数据可见性带来的安全影响。
  6. 远程代码与缓存:使用 remote 下发代码时,用 nack_on_code_cache_miss 控制缓存未命中的行为——true 时快速失败(NACK)加后台拉取,false 时进入 warming 异步拉取。

8. 相关资源索引

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
34
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.21 K
2.81 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
945
1.86 K
docsdocs
暂无描述
Markdown
906
5.84 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
537
607
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
864
1.36 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
4.28 K
1.03 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.39 K
1.48 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
550
401
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.19 K
347