使用 Wasm Filter 扩展数据面
更新时间:2024-10-09
概述
WebAssembly(简称 Wasm)是一种高效的二进制代码格式,它允许开发者将编写的指令集加载至 Envoy 过滤器链中,从而扩展服务网格的数据面功能。这种方法实现了 Envoy 核心与扩展组件之间的解耦,避免了用户为了扩展功能而需要修改 Envoy 源代码或编译定制版本的 Envoy。此外,Wasm 还带来了动态加载和运行时安全隔离等显著优势。本文介绍如何使用 Wasm Filter 扩展服务网格数据面的能力。
步骤一:构建 wasm 文件并挂载至 configmap 中
- 以下采用名为 wasm-example-filter.wasm 的 wasm 文件举例。
- 创建 configmap,将 wasm filter 存储到 configmap 中。
# 创建名为 wasm-example-filter 的 configmap,将 wasm-example-filter.wasm 注入到 configmap 中
kubectl create cm wasm-example-filter --from-file=wasm-example-filter.wasm
步骤二:命名空间级别 wasm 注入
- 通过 configmap 将 wasm filter 挂载到工作负载上。
- 服务网格 CSM 提供命名空间级别的 wasm 注入,可以通过为命名空间添加标签
sidecar-injection-wasm-configmap:{configmap 文件名}
的方式开启命名空间注入 wasm 文件,该功能会将指定 configmap 中的内容挂载到指定命名空间的所有工作负载中。即挂载到 istio-proxy 容器的 /var/local/lib/wasm-filters 目录下。 - Pod 重新创建后,在 istio-proxy 的 /var/local/lib/wasm-filters 目录下可以查看到 wasm-example-filter.wasm 文件。
# 为 test 命名空间开启 wasm 注入,将名为 wasm-example-filter 的 configmap 挂载到 sidecar 容器中
kubectl label namespace test sidecar-injection-wasm-configmap=wasm-example-filter
说明: 正在运行中的 Pod 重启后才会生效。
步骤三:创建 EnvoyFilter
- 目前已经成功将编译后的 wasm 文件挂载到了 Envoy 中,但此时 Envoy 并不知道这个文件是用来做什么的。因此,需要创建一个名为 EnvoyFilter 的 CRD 资源对象,将 wasm filter 添加到对应工作负载的 envoy filter chain 中,使其生效。
- 比如可以使用下面的配置来将 wasm 插件挂载到 Envoy 中:
# my-envoyfilter.yaml
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: my-envoyfilter
spec:
workloadSelector:
labels:
app: app1 # 表示只对 app1 这个 Pod 进行过滤
configPatches: # 用于配置 Envoy 的过滤器
- applyTo: HTTP_FILTER
match: # 用于匹配 Envoy 的过滤器
context: SIDECAR_INBOUND # 仅对入站流量进行过滤
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
patch: # 用于指定要挂载的 wasm 插件
operation: INSERT_BEFORE # 在 router 之前插入
value:
name: mydummy
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config: # 指定了插件的配置信息以及 wasm 插件的路径
configuration:
"@type": type.googleapis.com/google.protobuf.StringValue
value: dummy
root_id: "regex_replace"
vm_config:
code:
local:
filename: var/local/lib/wasm-filters/wasm-example-filter.wasm
runtime: envoy.wasm.runtime.v8
vm_id: myvmdummy
- 应用上面的资源对象:
kubectl apply -f httpbin-wasm-filter.yaml
- 至此,wasm filter 部署完成。