Istio 的声明式 WebAssembly 部署

以声明方式配置 Envoy 和 Istio 的 Wasm 扩展。

2020 年 3 月 16 日 | 作者:Christian Posta - Solo.io

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 代理)中的操作。

How the wasme operator works
了解 wasme 操作符的工作原理

目前,Wasm 镜像需要发布到注册表中,以便操作符能够正确地对其进行缓存。缓存 Pod 作为 DaemonSet 在每个节点上运行,以便缓存可以挂载到 Envoy 容器中。这正在改进,因为它不是理想的机制。理想情况下,我们不必处理任何挂载操作,并且可以将模块直接通过 HTTP 流式传输到代理,敬请关注更新(应该在未来几天内发布)。挂载是通过使用 sidecar.istio.io/userVolumesidecar.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。

了解更多

分享此文章