1.19. 扩展
您可以使用 WebAsembly 扩展直接将新功能添加到 Red Hat OpenShift Service Mesh 代理中。这可让您从应用程序中移出更多常见的功能,并使用编译到 WebAssembly 字节代码的单一语言实现它们。
IBM Z 和 IBM Power Systems 不支持 WebAsembly 扩展。
1.19.1. WebAssembly 模块概述
WebAsembly 模块可以在很多平台上运行,包括代理,并有广泛语言支持、快速执行以及沙盒安全模型。
Red Hat OpenShift Service Mesh 扩展是 Envoy HTTP Filters,为它们提供广泛的功能:
- 控制请求和响应的正文和标头。
- 对不在请求路径中的服务(如认证或策略检查)的带外 HTTP 请求。
- 用来相互通信的 sidechannel 数据存储和过滤器队列。
在创建新的 WebAsembly 扩展时,请使用 WasmPlugin API。ServiceMeshExtension API 从 Red Hat OpenShift Service Mesh 版本 2.2 开始已弃用,并将在以后的版本中删除。
编写 Red Hat OpenShift Service Mesh 扩展有两个部分:
- 您必须使用提供 proxy-wasm API 的 SDK 编写扩展,并将其编译到 WebAssembly 模块。
- 然后,您必须将模块打包到容器中。
支持的语言
您可以使用任何编译到 WebAssembly 字节码的语言来编写 Red Hat OpenShift Service Mesh 扩展,但以下语言具有公开 proxy-wasm API 的现有 SDK,以便直接使用它。
语言 | Maintainer | 软件仓库 |
---|---|---|
AssemblyScript | solo.io | |
C++ | proxy-wasm 团队(Istio 社区) | |
Go | tetrate.io | |
Rust | proxy-wasm 团队(Istio 社区) |
1.19.2. WasmPlugin
容器格式
Istio 在其 Wasm Plugin 机制中支持 OCI(Open Container Initiative) 镜像。您可以将 Wasm 插件分发为容器镜像,您可以使用 spec.url
字段来引用容器 registry 位置。例如: quay.io/my-username/my-plugin:latest
。
因为 WASM 模块的每个执行环境(runtime)都可以有特定于运行时的配置参数,因此 WASM 镜像由两个层组成:
-
plugin.wasm (必需)- 内容层。这个层包含一个包含 WebAssembly 模块字节码的
.wasm
二进制文件,它由运行时加载。您必须将此文件命名为plugin.wasm
。 - runtime-config.json (可选)- 配置层。这个层包含一个 JSON 格式的字符串,用于描述目标运行时模块的元数据。根据目标运行时,配置层也可以包含其他数据。例如,WASM Envoy Filter 的配置包含过滤器上的 root_ids。
1.19.3. WasmPlugin API 参考
WasmPlugins API 提供了通过 WebAssembly 过滤器扩展 Istio 代理提供的功能的机制。
您可以部署多个 WasmPlugins。phase
和 priority
设置决定了执行顺序(作为 Envoy 的过滤器链的一部分),允许对用户提供的 WasmPlugin 和 Istio 的内部过滤器配置复杂交互。
在以下示例中,身份验证过滤器实施 OpenID 流,并使用 JSON Web Token(JWT)填充 Authorization 标头。Istio 身份验证会消耗这个令牌,并将其部署到 ingress 网关。WasmPlugin 文件在代理 sidecar 文件系统中存在。请注意字段 url
。
apiVersion: extensions.istio.io/v1alpha1 kind: WasmPlugin metadata: name: openid-connect namespace: istio-ingress spec: selector: matchLabels: istio: ingressgateway url: file:///opt/filters/openid.wasm sha256: 1ef0c9a92b0420cf25f7fe5d481b231464bc88f486ca3b9c83ed5cc21d2f6210 phase: AUTHN pluginConfig: openid_server: authn openid_realm: ingress
以下是相同的示例,但这一次使用 OCI 镜像而不是文件系统中的文件。记录 url
、imagePullPolicy
、imagePullSecret
和 imagePullSecret 字段。
apiVersion: extensions.istio.io/v1alpha1 kind: WasmPlugin metadata: name: openid-connect namespace: istio-system spec: selector: matchLabels: istio: ingressgateway url: oci://private-registry:5000/openid-connect/openid:latest imagePullPolicy: IfNotPresent imagePullSecret: private-registry-pull-secret phase: AUTHN pluginConfig: openid_server: authn openid_realm: ingress
字段 | 类型 | 描述 | 必需 |
---|---|---|---|
spec.selector | WorkloadSelector |
用于选择应该应用此插件配置的特定 pod/VM 集合的条件。如果省略,此配置将应用于同一命名空间中的所有工作负载实例。如果 config root 命名空间中存在 | 否 |
spec.url | 字符串 |
Wasm 模块或 OCI 容器的 URL。如果没有方案,则默认为 | 否 |
spec.sha256 | 字符串 |
用于验证 Wasm 模块或 OCI 容器的 SHA256 checksum。如果 | 否 |
spec.imagePullPolicy | pullPolicy |
获取 OCI 镜像时要应用的拉取行为。只有在通过标签而不是 SHA 引用镜像时才相关。默认为 | 否 |
spec.imagePullSecret | 字符串 |
用于 OCI 镜像拉取的凭证。与 | 否 |
spec.phase | PluginPhase |
决定过滤器链中注入这个 | 否 |
spec.priority |
|
决定有同一 | 否 |
spec.pluginName | 字符串 | Envoy 配置中使用的插件名称。有些 Wasm 模块可能需要这个值来选择要执行的 Wasm 插件。 | 否 |
spec.pluginConfig | Struct | 将要传递给插件的配置。 | 否 |
spec.pluginConfig.verificationKey | 字符串 | 用于验证签名 OCI 镜像或 Wasm 模块的公钥。必须以 PEM 格式提供。 | 否 |
WorkloadSelector
对象指定用于确定过滤器是否可应用于代理的条件。匹配条件包括与代理关联的元数据、工作负载实例信息,如附加到 pod/VM 的标签,或代理在初始握手期间向 Istio 提供的任何其他信息。如果指定了多个条件,则所有条件都需要匹配才能选择工作负载实例。目前,只支持基于标签的选择机制。
字段 | 类型 | 描述 | 必需 |
---|---|---|---|
matchLabels | map<string, string> | 指定应应用策略的特定 pod/VM 集合的一个或多个标签。标签搜索范围仅限于存在资源的配置命名空间。 | 是 |
PullPolicy
对象指定要在获取 OCI 镜像时应用的 pull 行为。
值 | 描述 |
---|---|
<empty> |
默认值为 |
IfNotPresent | 如果在之前拉取了镜像的现有版本,则会使用它。如果本地没有镜像版本,我们将拉取最新版本。 |
Always | 应用此插件时,始终拉取镜像的最新版本。 |
Struct
代表结构化数据值,由映射到动态输入的值的字段组成。在某些语言中,Struct 可能受到原生表示的支持。例如,在脚本语言中,JavaScript astruct 等脚本语言表示为对象。
字段 | 类型 | 描述 |
---|---|---|
fields | map<string, Value> | 动态输入的值的映射。 |
PluginPhase
指定将注入插件的过滤器链中的阶段。
字段 | 描述 |
---|---|
<empty> | control plane 决定插入插件的位置。这通常位于过滤器链的末尾,在路由器前面。如果插件独立于其他插件,则不要指定 PluginPhase。 |
AUTHN | 在 Istio 身份验证过滤器前插入插件。 |
AUTHZ | 在 Istio 授权过滤器和 Istio 身份验证过滤器后插入插件。 |
STATS | 在 Istio stats 过滤器和 Istio 授权过滤器后插入插件。 |
1.19.3.1. 部署 WasmPlugin
资源
您可以使用 WasmPlugin
资源启用 Red Hat OpenShift Service Mesh 扩展。在本例中,istio-system
是 Service Mesh control plane 项目的名称。以下示例创建了一个 openid-connect
过滤器,它将执行 OpenID Connect 流来验证用户。
流程
创建以下示例资源:
plugin.yaml 示例
apiVersion: extensions.istio.io/v1alpha1 kind: WasmPlugin metadata: name: openid-connect namespace: istio-system spec: selector: matchLabels: istio: ingressgateway url: oci://private-registry:5000/openid-connect/openid:latest imagePullPolicy: IfNotPresent imagePullSecret: private-registry-pull-secret phase: AUTHN pluginConfig: openid_server: authn openid_realm: ingress
使用以下命令应用
plugin.yaml
文件:$ oc apply -f plugin.yaml
1.19.4. ServiceMeshExtension
容器格式
您必须有包含 WebAssembly 模块字节码的 .wasm
文件,以及容器文件系统根中的 manifest.yaml
文件,以使您的容器镜像成为有效的扩展镜像。
在创建新的 WebAsembly 扩展时,请使用 WasmPlugin。ServiceMeshExtension 从 Red Hat OpenShift Service Mesh 版本 2.2 开始已弃用,并将在以后的版本中删除。
manifest.yaml
schemaVersion: 1 name: <your-extension> description: <description> version: 1.0.0 phase: PreAuthZ priority: 100 module: extension.wasm
字段 | 描述 | 必需 |
---|---|---|
schemaVersion |
用于清单架构的版本。目前唯一可能的值是 | 这是必填字段。 |
name | 扩展名。 | 这个字段只是元数据且目前没有使用。 |
description | 扩展的描述。 | 这个字段只是元数据且目前没有使用。 |
version | 扩展名的版本。 | 这个字段只是元数据且目前没有使用。 |
phase | 扩展的默认执行阶段。 | 这个为必填字段。 |
priority | 扩展的默认优先级。 | 这个为必填字段。 |
module | 容器文件系统的 root 到 WebAssembly 模块的相对路径。 | 这是必填字段。 |
1.19.5. ServiceMeshExtension 参考
ServiceMeshExtension API 提供了通过 WebAssembly 过滤器扩展 Istio 代理提供的功能的机制。编写 WebAssembly 扩展有两个部分:
- 使用提供 proxy-wasm API 的 SDK 编写扩展,并将其编译到 WebAssembly 模块。
- 将它打包到容器中。
在创建新的 WebAsembly 扩展时,请使用 WasmPlugin。ServiceMeshExtension 从 Red Hat OpenShift Service Mesh 版本 2.2 开始已弃用,并将在以后的版本中删除。
字段 | 描述 |
---|---|
metadata.namespace |
|
spec.workloadSelector |
|
spec.config | 这是一个结构化字段,将被移交给扩展名,其语义取决于您要部署的扩展名。 |
spec.image | 指向包含扩展的镜像的容器镜像 URI。 |
spec.phase |
该阶段根据现有 Istio 功能,如身份验证、授权和指标生成,决定过滤器链中的扩展是否被注入。有效值为: PreAuthN、PostAuthN、PreAuthZ、PostAuthZ、PreStats、PostStats。此字段默认为扩展名的 |
spec.priority |
如果将具有相同 |
1.19.5.1. 部署 ServiceMeshExtension
资源
您可以使用 ServiceMeshExtension
资源启用 Red Hat OpenShift Service Mesh 扩展。在本例中,istio-system
是 Service Mesh control plane 项目的名称。
在创建新的 WebAsembly 扩展时,请使用 WasmPlugin。ServiceMeshExtension 从 Red Hat OpenShift Service Mesh 版本 2.2 开始已弃用,并将在以后的版本中删除。
有关使用 Rust SDK 构建的完整示例,请看标题附加过滤器。这是一个简单的过滤器,它会将一个或多个标头附加到 HTTP 响应中,其名称和值从扩展的 config
字段中获取。请参阅以下代码片段中的示例配置。
流程
创建以下示例资源:
ServiceMeshExtension 资源 extension.yaml 示例
apiVersion: maistra.io/v1 kind: ServiceMeshExtension metadata: name: header-append namespace: istio-system spec: workloadSelector: labels: app: httpbin config: first-header: some-value another-header: another-value image: quay.io/maistra-dev/header-append-filter:2.1 phase: PostAuthZ priority: 100
使用以下命令应用
extension.yaml
文件:$ oc apply -f <extension>.yaml
1.19.6. 从 ServiceMeshExtension
迁移到 WasmPlugin
资源
ServiceMeshExtension
API 从 Red Hat OpenShift Service Mesh 版本 2.2 开始已弃用,并将在以后的版本中删除。如果使用 ServiceMeshExtention
API,则必须迁移到 WasmPlugin
API 才能继续使用 WebAssembly 扩展。
API 非常相似。迁移由两个步骤组成:
- 重命名您的插件文件并更新模块打包。
-
创建引用更新的容器镜像的
WasmPlugin
资源。
1.19.6.1. API 更改
新的 WasmPlugin
API 与 ServiceMeshExtension
类似,但有一些区别,特别是在字段名称中:
ServiceMeshExtension | WasmPlugin |
---|---|
|
|
|
|
|
|
|
|
以下是如何将 ServiceMeshExtension
资源转换为 WasmPlugin
资源的示例。
ServiceMeshExtension 资源
apiVersion: maistra.io/v1 kind: ServiceMeshExtension metadata: name: header-append namespace: istio-system spec: workloadSelector: labels: app: httpbin config: first-header: some-value another-header: another-value image: quay.io/maistra-dev/header-append-filter:2.2 phase: PostAuthZ priority: 100
新的 WasmPlugin 资源等同于上面的 ServiceMeshExtension
apiVersion: extensions.istio.io/v1alpha1 kind: WasmPlugin metadata: name: header-append namespace: istio-system spec: selector: matchLabels: app: httpbin url: oci://quay.io/maistra-dev/header-append-filter:2.2 phase: STATS pluginConfig: first-header: some-value another-header: another-value
1.19.6.2. 容器镜像格式更改
新的 WasmPlugin
容器镜像格式与 ServiceMeshExtensions
类似,其区别如下:
-
ServiceMeshExtension
容器格式需要在容器文件系统的根目录中名为manifest.yaml
的元数据文件。WasmPlugin
容器格式不需要manifest.yaml
文件。 -
.wasm
文件(实际插件)以前可能具有任何文件名,现在必须命名为plugin.wasm
,且必须位于容器文件系统的根目录中。
1.19.6.3. 迁移到 WasmPlugin
资源
要将 WebAsembly 扩展从 ServiceMeshExtension
API 升级到 WasmPlugin
API,您可以重命名您的插件文件。
先决条件
-
ServiceMeshControlPlane
升级到 2.2 或更高版本。
因为这两个插件都会为每个请求调用,所以您可能需要在创建新 WasmPlugin
资源前删除现有的 ServiceMeshExtension
资源。您可能会获得不必要的结果,同时有两个插件活跃。
流程
更新您的容器镜像。如果插件已在容器内的
/plugin.wasm
中,则跳至下一步。如果没有:-
确保插件文件名为
plugin.wasm
。您需要将扩展文件命名为plugin.wasm
。 - 确保插件文件位于 root (/)目录中。您必须将扩展文件存储在容器文件系统的根目录中。
- 重新构建容器镜像并将其推送到容器 registry。
-
确保插件文件名为
-
删除
ServiceMeshExtension
资源,并创建一个WasmPlugin
资源来引用您构建的新容器镜像。