让我们开始
在开始之前,请确保你已经做到了以下几点:
- 熟悉 TSB 概念
- 安装了 TSB 环境。你可以使用 TSB 演示进行快速安装。
- 完成了 TSB 的快速入门。本文假定你已经创建了租户并熟悉工作区和配置组,并且需要将 tctl 配置到你的 TSB 环境。
在这个示例中,将使用httpbin
作为工作负载。通过 wasm 扩展执行,发送到 Ingress GW 的请求将在 HTTP 响应中添加一个头部。
部署httpbin
服务
请按照此文档中的所有说明创建httpbin
服务。
接下来的命令将假定你已经有一个组织=tetrate
,租户=tetrate
,工作区=httpbin
,网关组=httpbin-gateway
构建和部署 WASM 扩展
让我们使用一个已经存在的 WASM 扩展代码,该扩展将在 HTTP 响应中添加头部。 为了构建 WASM 扩展,下载存储库并按照这些说明进行操作:
make build.example name=http_headers
然后需要将其打包为 OCI 镜像:
docker build . -t docker.io/<your repo>/demo-wasm:0.1 -f examples/wasm-image.Dockerfile --build-arg WASM_BINARY_PATH=examples/http_headers/main.wasm
之后,使用适当的命令将镜像推送到你的镜像仓库:
docker push docker.io/<your repo>/demo-wasm:0.1
创建 Wasm 扩展
第一步是填写 WASM 扩展目录,添加可用于 TSB 资源的扩展。
必须指定包含扩展的 OCI 镜像(需要使用前缀oci://
)。
还有其他可选字段,如指向扩展源代码的source
字段,priority
字段将定义 WASM 扩展的执行顺序,allowedIn
用于限制此 WASM 扩展仅分配给特定租户的资源。
最后,字段config
将设置 WASM 扩展的默认可选配置。每个 WASM 扩展都可以定义此 JSON 格式配置的特定分类。在将 WASM 扩展附加到 TSB 资源时,可以重新定义 config 字段,以设置与默认值不同的值。
要创建扩展,可以使用UI
、tctl
命令行或kubernetes
资源(如果启用了GitOps)。
使用tctl
创建一个名为wasm-extension.yaml
的 yaml 文件,其中包含 WasmExtension 的定义:
apiVersion: extension.tsb.tetrate.io/v2
kind: WasmExtension
metadata:
name: wasm-add-header
organization: tetrate
spec:
description: Extension to modify the headers
image: oci://docker.io/<your repo>/demo-wasm:0.1
source: https://github.com/tetratelabs/proxy-wasm-go-sdk/tree/main/examples/http_headers
priority: 1
config:
header: x-wasm-header
value: tsb-header
在 TSB 上应用定义:
tctl apply -f wasm-extension.yaml
使用 UI
单击“Wasm 扩展”菜单以打开 WasmExtension 目录,然后单击右上角的“创建”按钮。填写扩展字段,然后单击底部的“创建”按钮。注意,配置必须采用 JSON 格式。
![image](/book/tsb/howto/wasm/wasm-try/wasm-ui-create.png)
可以有多个扩展,每个扩展都有不同的名称,并且可以分配给多个资源。
下一步是将此 WASM 扩展分配给资源,以便影响所需的工作负载。在我们的示例中,选择 IngressGateway 作为资源,以便在网关接收到的每个请求上执行 WASM 扩展。
在 IngressGateway 上创建附件
使用tctl
创建一个名为ingress-gateway.yaml
的文件,其中包含将包含WASM 附件的IngressGateway的定义:
apiVersion: gateway.tsb.tetrate.io/v2
kind: IngressGateway
metadata:
name: ingress-gw
group: httpbin-gateway
workspace: httpbin
tenant: tetrate
organization: tetrate
spec:
workloadSelector:
namespace: httpbin
labels:
app: httpbin-ingress-gateway
http:
- name: httpbin
port: 443
hostname: "httpbin.tetrate.io"
routing:
rules:
- route:
host: "httpbin/httpbin.httpbin.svc.cluster.local"
extension:
- fqn: "organizations/tetrate/extensions/wasm-add-header"
config:
header: x-wasm-header
value: igw-tsb
在 TSB 上应用它:
tctl apply -f ingress-gateway.yaml
使用 UI
READ
WasmExtension
权限的角色,以便他们可以使用 TSB UI 来附加 Wasm 扩展。
你可以使用 UI 将 WASM 扩展附加到 IngressGateway。转到 IngressGateway 配置 UI,然后单击“添加新的 WASM 扩展”。选择要使用的扩展
并指定配置。注意,配置必须采用 JSON 格式。
![image](/book/tsb/howto/wasm/wasm-try/wasm-ui-attach.png)
测试
export GATEWAY_IP=$(kubectl -n httpbin get service httpbin-ingress-gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl http://httpbin.tetrate.io:443 -kv --connect-to httpbin.tetrate.io:443:$GATEWAY_IP:443
你应该会看到类似于以下输出:
* Connecting to hostname: 35.230.60.29
* Connecting to port: 443
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 35.230.60.29:443...
* Connected to 35.230.60.29 (35.230.60.29) port 443 (#0)
> GET / HTTP/1.1
> Host: httpbin.tetrate.io:443
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< server: istio-envoy
< date: Wed, 09 Nov 2022 14:35:13 GMT
< content-type: text/html; charset=utf-8
< content-length: 9593
< access-control-allow-origin: *
< access-control-allow-credentials: true
< x-envoy-upstream-service-time: 54
< x-proxy-wasm-go-sdk-example: http_headers
< x-wasm-header: igw-tsb
<
{ [9593 bytes data]
100 9593 100 9593 0 0 22866 0 --:--:-- --:--:-- --:--:-- 23171
* Connection #0 to host 35.230.60.29 left intact
在响应中,你可以看到x-wasm-header
已根据 WASM 扩展的配置添加。这是通过执行 WASM 扩展的连接到网关工作负载来完成的。
它在 Istio / Envoy 中是如何结束的?
这些 WASM 分配将影响由 TSB 组件处理的工作负载,并最终转化为Istio WasmPlugins,这些插件由 Istio 处理并转化为 Envoy 过滤器配置在 envoy 代理中执行,其执行顺序取决于插件的阶段和优先级。 一旦配置到达 Envoy 代理,WASM 扩展将成为过滤器链的一部分,它们的位置将取决于它们的阶段,而优先级将确定它们在同一阶段中与其他 WASM 扩展的位置。