Istio 的声明式 WebAssembly 部署
以声明方式配置 Envoy 和 Istio 的 Wasm 扩展。
如 Istio 2020 季风博客 中所述,以及最近 在 Istio 1.5 中宣布,WebAssembly (Wasm) 现在是扩展 Istio 服务代理(Envoy 代理)功能的(alpha)选项。使用 Wasm,用户可以构建对新协议、自定义指标、日志记录器和其他过滤器的支持。我们社区(Solo.io)与 Google 密切合作,专注于构建、共享和将 Wasm 扩展部署到 Istio 的用户体验。我们已宣布 WebAssembly Hub 和 相关工具,以构建用于处理 Wasm 的“类似 Docker”的体验。
背景
使用 WebAssembly Hub 工具,我们可以使用 wasme
CLI 轻松地为 Envoy 启动一个 Wasm 项目,将其推送到存储库,然后将其拉取/部署到 Istio。例如,要使用 wasme
将 Wasm 扩展部署到 Istio,我们可以运行以下命令
$ wasme deploy istio webassemblyhub.io/ceposta/demo-add-header:v0.2 \
--id=myfilter \
--namespace=bookinfo \
--config 'tomorrow'
这会将 demo-add-header
扩展添加到 bookinfo
命名空间中运行的所有工作负载中。我们可以使用 --labels
参数更精细地控制哪些工作负载获得扩展
$ wasme deploy istio webassemblyhub.io/ceposta/demo-add-header:v0.2 \
--id=myfilter \
--namespace=bookinfo \
--config 'tomorrow' \
--labels app=details
这比手动创建 EnvoyFilter
资源并尝试将 Wasm 模块传递到您尝试定位的工作负载中包含的每个 Pod 要容易得多。但是,这是一种与 Istio 交互的非常命令式的方法。就像用户通常不会在生产环境中直接使用 kubectl
并更喜欢声明式、基于资源的工作流一样,我们希望对 Istio 代理进行自定义也采用相同的方式。
声明式方法
WebAssembly Hub 工具还包括 用于将 Wasm 扩展部署到 Istio 工作负载的操作符。该 操作符 允许用户使用声明式格式定义其 WebAssembly 扩展,并将其部署工作留给操作符处理。例如,我们使用 FilterDeployment
资源来定义需要扩展的镜像和工作负载
apiVersion: wasme.io/v1
kind: FilterDeployment
metadata:
name: bookinfo-custom-filter
namespace: bookinfo
spec:
deployment:
istio:
kind: Deployment
labels:
app: details
filter:
config: 'world'
image: webassemblyhub.io/ceposta/demo-add-header:v0.2
然后,我们可以获取此 FilterDeployment
文档并将其与 Istio 资源的其余部分一起进行版本控制。您可能想知道,当 Istio 已经拥有 EnvoyFilter
资源时,为什么我们需要此自定义资源来配置 Istio 的服务代理以使用 Wasm 扩展。
让我们仔细看看这一切在幕后是如何运作的。
工作原理
在幕后,操作符执行了一些有助于将 Wasm 扩展部署和配置到 Istio 服务代理(Envoy 代理)中的操作。
- 设置 Wasm 扩展的本地缓存
- 将所需的 Wasm 扩展拉取到本地缓存
- 将
wasm-cache
挂载到适当的工作负载 - 使用
EnvoyFilter
CRD 配置 Envoy 以使用 Wasm 过滤器
目前,Wasm 镜像需要发布到注册表中,以便操作符能够正确地对其进行缓存。缓存 Pod 作为 DaemonSet 在每个节点上运行,以便缓存可以挂载到 Envoy 容器中。这正在改进,因为它不是理想的机制。理想情况下,我们不必处理任何挂载操作,并且可以将模块直接通过 HTTP 流式传输到代理,敬请关注更新(应该在未来几天内发布)。挂载是通过使用 sidecar.istio.io/userVolume
和 sidecar.istio.io/userVolumeMount
注释来建立的。有关其工作原理的更多信息,请参阅 有关 Istio 资源注释的文档。
Wasm 模块正确缓存并挂载到工作负载的服务代理后,操作符将配置 EnvoyFilter
资源。
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: details-v1-myfilter
namespace: bookinfo
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: envoy.http_connection_manager
subFilter:
name: envoy.router
patch:
operation: INSERT_BEFORE
value:
config:
config:
configuration: tomorrow
name: myfilter
rootId: add_header
vmConfig:
code:
local:
filename: /var/local/lib/wasme-cache/44bf95b368e78fafb663020b43cf099b23fc6032814653f2f47e4d20643e7267
runtime: envoy.wasm.runtime.v8
vmId: myfilter
name: envoy.filters.http.wasm
workloadSelector:
labels:
app: details
version: v1
您可以看到 EnvoyFilter
资源配置代理以添加 envoy.filter.http.wasm
过滤器并从 wasme-cache
加载 Wasm 模块。
将 Wasm 扩展加载到 Istio 服务代理后,它将使用您引入的任何自定义代码扩展代理的功能。
后续步骤
在本博文中,我们探讨了将 Wasm 扩展安装到 Istio 工作负载中的选项。使用 Istio 上的 WebAssembly 入门最简单的方法是使用 wasme
工具 启动一个新的 Wasm 项目(使用 C++、AssemblyScript [或很快推出的 Rust!])。例如,要设置 C++ Wasm 模块,您可以运行
$ wasme init ./filter --language cpp --platform istio --platform-version 1.5.x
如果我们没有额外的标志,wasme init
将进入交互模式,引导您完成选择正确值的步骤。
查看 WebAssembly Hub wasme 工具,开始在 Istio 上使用 Wasm。
了解更多
重新定义可扩展性 使用 Envoy 和 Istio 上的 WebAssembly
WebAssembly SF 演讲(视频):网络代理的扩展,作者:John Plevyak
Solo.io YouTube 频道 上的视频