Wasm 是 WebAssembly 的缩写,可以编写二进制形式的指令加载到 envoy filter chain 中,实现网格数据面能力扩展。这种形式使得 envoy 和扩展组件的解耦,用户不再需要通过修改 envoy 代码、编译特殊的 envoy 版本来实现能力扩展,并且还具备动态加载和安全隔离等优势。
从 Istio 1.6 版本开始,Proxy-Wasm 沙盒 API 取代了 Mixer 作为 Istio 主要的扩展实现方案,用于实现 envoy 和 wasm 虚拟机之间的交互,因此通过 wasm filter 来扩展 envoy 需要使用 Proxy-WASM SDK。
通常编写 wasm 文件扩展网格数据面能力主要分为以下几步:
1. 编写 wasm filter,可请参见 示例。
2. 将 wasm filter 注入到 configmap 中,通过 configmap 将 wasm filter 挂载到任意工作负载,避免将 wasm filter 拷贝到多个 node 上。
kubectl create cm -n foo example-filter --from-file=example-filter.wasm
3. 将 wasm filter 挂载到业务工作负载,可利用 Istio 的 annotation 机制,在创建工作负载的时候自动挂载相应的文件:
sidecar.istio.io/userVolume: '[{"name":"wasmfilters-dir","configMap": {"name": "example-filter"}}]'sidecar.istio.io/userVolumeMount: '[{"mountPath":"/var/local/lib/wasm-filters","name":"wasmfilters-dir"}]'
将 annotation 应用到对应的工作负载之上:
kubectl patch deployment -n foo frontpage-v1 -p '{"spec":{"template":{"metadata":{"annotations":{"sidecar.istio.io/userVolume":"[{\\"name\\":\\"wasmfilters-dir\\",\\"configMap\\": {\\"name\\": \\"example-filter\\"}}]","sidecar.istio.io/userVolumeMount":"[{\\"mountPath\\":\\"/var/local/lib/wasm-filters\\",\\"name\\":\\"wasmfilters-dir\\"}]"}}}}}'
4. 创建 envoyfilter,将 wasm filter 添加到对应工作负载的 envoy filter chain 中,使其生效。
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:name: frontpage-v1-examplefilternamespace: foospec:configPatches:- applyTo: HTTP_FILTERmatch:listener:filterChain:filter:name: envoy.http_connection_managersubFilter:name: envoy.routerpatch:operation: INSERT_BEFOREvalue:name: envoy.filters.http.wasmtyped_config:'@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasmconfig:name: example-filterroot_id: my_root_idvm_config:code:local:filename: /var/local/lib/wasm-filters/example-filter.wasmruntime: envoy.wasm.runtime.v8vm_id: example-filterallow_precompiled: trueworkloadSelector:labels:app: frontpageversion: v1
至此,wasm filter 部署完成,另一种 wasm filter 的使用形式是镜像,请参见 制作 wasm filter 镜像,利用 WASME 工具部署,请参见 使用 wasme 部署 wasm filter。