Istio 1.30 的 TrafficExtension API:一个 API 统管 Wasm 与 Lua 扩展

2026-05-18 19 预计阅读时间:1 分钟
来源:istio.io AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:8 分钟

Istio 的数据面扩展能力一直是其设计核心——从自定义认证到专用遥测采集再到请求/响应实时改写,都依赖往 Envoy sidecar 里注入自定义逻辑。但直到现在,这条路走得并不顺畅:WasmPlugin 只管 WebAssembly 扩展,想写 Lua 脚本只能绕道 EnvoyFilter,后者强大却极易配错。Istio 1.30 推出 TrafficExtension API,把 Wasm 和 Lua 两种扩展方式收进同一个 API,同时补上了 ambient 模式的支持。

为什么需要 TrafficExtension

旧方案有两个痛点:

  • Lua 用户没有正式 API。EnvoyFilter 是 Envoy 层面的底层机制,直接操作 filter chain,参数写错一行就可能让整个代理崩溃,排查成本高。
  • WasmPlugin 只覆盖 Wasm。如果你同时需要 Lua 做轻量 header 操作和 Wasm 做复杂策略执行,就要维护两套完全不同的 API 资源,selector 逻辑各写一遍。

TrafficExtension 把两者统一到 extensions.istio.io/v1alpha1 这个 API 组下,一个资源里可以声明 Lua 或 Wasm,selector/targetRefs 共用,执行顺序也用同一套 phase + priority 机制控制。

Lua 与 Wasm:怎么选

TrafficExtension 支持两种扩展类型,适用场景泾渭分明:

维度 Lua WebAssembly
代码形式 内嵌 inline 脚本,无需分发模块 OCI 镜像仓库拉取,支持 Go/Rust/C++/AssemblyScript
适合场景 header 操作、简单日志、条件判断 复杂策略、遥测采集、payload 改写
协议层 仅 Layer 7 (HTTP) Layer 7 + Layer 4 (TCP)
性能 轻量,无沙箱开销 沙箱隔离,启动有冷启动成本
依赖 无外部模块 需 OCI 仓库或 HTTP 拉取

一句话决策:能用 Lua 解决的别上 Wasm,需要多语言/复杂逻辑/TCP 层面的才用 Wasm。

写一个 Lua 扩展:给请求加奇偶标记

下面这个示例读取请求头 x-number,判断奇偶,然后在响应头里加 x-parity。整个脚本内嵌在 TrafficExtension 资源里,不需要额外分发任何文件。

apiVersion: extensions.istio.io/v1alpha1
kind: TrafficExtension
metadata:
  name: parity
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  lua:
    inlineCode: |
      function envoy_on_request(request_handle)
        local number = tonumber(request_handle:headers():get("x-number"))
        if number == nil then
          return
        end
        local parity = number % 2 == 0 and "even" or "odd"
        request_handle:streamInfo():dynamicMetadata():set(
          "envoy.filters.http.lua", "parity", parity)
      end

      function envoy_on_response(response_handle)
        local meta = response_handle:streamInfo():dynamicMetadata():get(
          "envoy.filters.http.lua")
        if meta == nil then
          return
        end
        response_handle:headers():add("x-parity", meta["parity"])
      end

部署后,发一个带 x-number: 42 的请求,响应里就会出现 x-parity: even。注意脚本把中间结果存到 dynamicMetadata 里再在 response 阶段取出来——这是 Envoy Lua filter 的标准做法,避免直接在 request 阶段改 response headers(那时 response 对象还不存在)。

运行验证:

# 假设 ingress gateway 暴露在 $INGRESS_HOST:$INGRESS_PORT
curl -H "x-number: 7" http://$INGRESS_HOST:$INGRESS_PORT/productpage -I
# 响应头中应出现: x-parity: odd

写一个 Wasm 扩展:给网关加 Basic Auth

Lua 处理不了的场景——比如需要 TCP 层策略、或者逻辑复杂到值得用 Go/Rust 写——就该上 Wasm。下面用 Istio 社区预构建的 basic_auth 插件,给 /productpage 路径加 Basic 认证:

apiVersion: extensions.istio.io/v1alpha1
kind: TrafficExtension
metadata:
  name: basic-auth
  namespace: istio-system
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  phase: AUTHN
  wasm:
    url: oci://ghcr.io/istio-ecosystem/wasm-extensions/basic_auth:1.12.0
    pluginConfig:
      basic_auth_rules:
        - prefix: "/productpage"
          request_methods: ["GET", "POST"]
          credentials: ["ok:test"]

phase: AUTHN 把这个插件放到认证阶段执行,确保它在授权和统计插件之前运行。credentials: ["ok:test"] 表示只允许用户名 ok、密码 test 通过。

验证:

# 无认证——应返回 401
curl http://$INGRESS_HOST:$INGRESS_PORT/productpage -I

# 带认证——应返回 200
curl -u ok:test http://$INGRESS_HOST:$INGRESS_PORT/productpage -I

两种目标定位方式

TrafficExtension 提供两种定位机制,对应不同部署模式:

selector——基于标签匹配 sidecar

  • 写在 istio-system 命名空间 → 集群级生效
  • 写在其他命名空间 → 只对该命名空间内匹配标签的 workload 生效

targetRefs——直接引用 Gateway 或 Service

这是 ambient 模式的必需方式,因为 waypoint proxy 不对应具体 workload 标签。同一个 basic-auth 扩展,定位到 ambient Gateway 时写法变为:

apiVersion: extensions.istio.io/v1alpha1
kind: TrafficExtension
metadata:
  name: basic-auth-gateway
spec:
  targetRefs:
    - kind: Gateway
      group: gateway.networking.k8s.io
      name: bookinfo-gateway
  phase: AUTHN
  wasm:
    url: oci://ghcr.io/istio-ecosystem/wasm-extensions/basic_auth:1.12.0
    pluginConfig:
      basic_auth_rules:
        - prefix: "/productpage"
          request_methods: ["GET", "POST"]
          credentials: ["ok:test"]

注意这里没有 namespace 字段——targetRefs 直接指定资源,不需要标签间接匹配。

多扩展的执行顺序

当多个 TrafficExtension 指向同一个代理时,phasepriority 控制先后:

  • phase 决定扩展在 filter chain 中的大位置:
  • AUTHN — 认证阶段
  • AUTHZ — 授权阶段
  • STATS — 可观测性阶段
  • 不设置 — 靠近 router(默认)
  • priority 在同一 phase 内排序,数值越大越先执行。

典型组合:一个 AUTHN phase 的 basic-auth Wasm 插件(priority 100)+ 一个 AUTHZ phase 的 RBAC 插件(priority 50)+ 一个未设 phase 的遥测 Lua 脚本。请求路径上依次是认证 → 授权 → 路由前遥测。

从 WasmPlugin 迁移

Istio 1.30 内部已经把所有 WasmPlugin 资源自动转换为 TrafficExtension 再下发配置,所以现有 WasmPlugin 完全兼容,没有强制迁移时间线

当你准备好迁移时,步骤很直接:

  1. kind: WasmPlugin 改为 kind: TrafficExtension
  2. apiVersion: extensions.istio.io/v1alpha1 保持不变(WasmPlugin 也在这个组)
  3. spec.wasm 下的字段按 TrafficExtension API reference 微调(主要是 phase/priority/targetRefs 等新字段)
  4. 删除旧 WasmPlugin 资源,创建新的 TrafficExtension 资源
  5. 观察代理配置是否正常下发

迁移前建议在测试集群跑一遍,确认 OCI 拉取、pluginConfig 解析、phase 定位都和旧资源行为一致。

当前状态与上手建议

TrafficExtension 目前是 alpha,API 行为可能随反馈调整。上手路径:

  1. 先用 Lua inline 脚本做简单 header 操作——零依赖,调试快
  2. 需要复杂逻辑时引入 Wasm,优先用社区预构建插件(Istio ecosystem 仓库里有 basic_auth、oauth2 等)
  3. 自建 Wasm 插件时参考 Proxy-Wasm SDK(Go/Rust/C++),走 OCI 镜像分发
  4. ambient 模式下务必用 targetRefs 定位 waypoint
  5. 遇到问题或有好想法,开 GitHub issue 或到 Istio Slack 反馈——alpha 阶段的社区输入直接决定 API 最终形态

一句话总结:TrafficExtension 让 Istio 数据面扩展从"两套 API 各管各的"变成"一个 API 选 Lua 或 Wasm",降低了配置复杂度,补上了 ambient 支持,是 WasmPlugin 的正式接班人。


相关推荐