wasme 只支持到 istio 1.9,而我使用的是 Istio 1.14,因此本篇直接使用 tinygo 进行验证和学习。
1. 安装 tinygo
Go v1.18+
1
2
| brew tap tinygo-org/tools
brew install tinygo
|
1
2
3
| tinygo version
tinygo version 0.27.0 darwin/amd64 (using go version go1.19.3 and LLVM version 15.0.0)
|
2. 创建 wasm-istio 项目
1
2
3
| mkdir wasm-istio
cd wasm-istio
go mod init wasm-istio
|
见 https://github.com/shaowenchen/demo/blob/master/wasm-istio/main.go 主要是下面这段
1
2
3
4
5
6
7
8
9
| func (ctx *httpHeaders) OnHttpResponseHeaders(_ int, _ bool) types.Action {
proxywasm.LogInfof("adding header: %s=%s", ctx.headerName, ctx.headerValue)
// Add a hardcoded header
if err := proxywasm.AddHttpResponseHeader("hello", "world"); err != nil {
proxywasm.LogCriticalf("failed to set response constant header: %v", err)
}
...
}
|
1
| tinygo build -o plugin.wasm -scheduler=none -target=wasi -no-debug
|
3. 打包发布到镜像仓库
1
2
| FROM scratch
COPY plugin.wasm ./
|
1
| docker build -t shaowenchen/wasm-istio:v1 .
|
1
| docker push shaowenchen/wasm-istio:v1
|
4. 发布到 Istio WasmPlugin
1
2
3
| kubectl label namespace default istio-injection=enabled --overwrite
kubectl create deploy blog --image=nginx
kubectl expose deploy blog --port 80
|
网关配置见 https://github.com/shaowenchen/demo/blob/master/wasm-istio/blog.yaml
blog 应用具有以下标签
1
2
3
4
| kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
blog-64db778565-swdxg 2/2 Running 0 62s app=blog,pod-template-hash=64db778565,security.istio.io/tlsMode=istio,service.istio.io/canonical-name=blog,service.istio.io/canonical-revision=latest
|
1
2
3
4
5
6
7
8
9
10
11
| apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: add-header-hello-world
namespace: default
spec:
selector:
matchLabels:
app: blog
url: oci://docker.io/shaowenchen/wasm-istio:v1
phase: UNSPECIFIED_PHASE
|
matchLabels 指定插件应用的 Pod 范围,需要注意 WasmPlugin 是命名空间级别的对象。phase 指定插件应用的阶段。其他参数可以参考 https://istio.io/latest/docs/reference/config/proxy_extensions/wasm-plugin/ 。
1
2
3
4
| kubectl get wasmplugins.extensions.istio.io
NAME AGE
add-header-hello-world 27s
|
1
2
3
4
5
6
| 2023-02-22T08:31:10.017446Z info ads Push debounce stable[75] 1 for config WasmPlugin/default/add-header-hello-world: 100.09877ms since last change, 100.098558ms since last push, full=true
2023-02-22T08:31:10.017744Z info ads XDS: Pushing:2023-02-22T08:31:10Z/49 Services:10 ConnectedEndpoints:3 Version:2023-02-22T08:31:10Z/49
2023-02-22T08:31:10.017990Z info ads LDS: PUSH for node:istio-egressgateway-7fcb98978c-ppkdx.istio-system resources:0 size:0B
2023-02-22T08:31:10.018241Z info ads LDS: PUSH for node:istio-ingressgateway-55b6cffcbc-w6lwv.istio-system resources:1 size:3.7kB
2023-02-22T08:31:10.020476Z info ads LDS: PUSH for node:blog-7cc68f9d6b-m9rpd.default resources:20 size:96.8kB
2023-02-22T08:31:10.066004Z info ads ECDS: PUSH request for node:blog-7cc68f9d6b-m9rpd.default resources:1 size:327B
|
如果有报错,可能是访问镜像仓库权限问题。虽然 WasmPlugin 也支持 S3、文件服务地址,但支持 OCI 的镜像仓库是更好的选择。
在本地配置 hosts 将 VirtualService 中的域名,指向网关所在主机的 IP。在终端访问,查看响应头部:
1
2
3
4
5
6
7
8
9
10
11
12
| curl http://istio.chenshaowen.com:31990/ -I
HTTP/1.1 200 OK
server: istio-envoy
date: Wed, 22 Feb 2023 08:36:52 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 13 Dec 2022 15:53:53 GMT
etag: "6398a011-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 2
hello: world
|
此时,响应头部会比之前多出来一对 key: value,即 hello: world。
5. 参考