go+proxy-wasm-go-sdk+tinygo 开发 wasm

一、创建项目

go mod init xxxxxx

二、安装proxy-wasm-go-sdk

go get github.com/tetratelabs/proxy-wasm-go-sdk

三、创建main.go 文件

touch main.go

四、编辑代码

 1 package main
 2 
 3 import (
 4     "strconv"
 5 
 6     "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
 7     "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
 8 )
 9 
10 type vmContext struct {
11     types.DefaultVMContext
12 }
13 
14 type pluginContext struct {
15     types.DefaultPluginContext
16 }
17 
18 type httpHeaders struct {
19     types.DefaultHttpContext
20     contextID uint32
21     authority string
22 }
23 
24 func main() {
25     proxywasm.SetVMContext(&vmContext{})
26 }
27 
28 func (*vmContext) NewPluginContext(contextId uint32) types.PluginContext {
29     return &pluginContext{}
30 }
31 
32 func (*pluginContext) NewHttpContext(contextID uint32) types.HttpContext {
33     return &httpHeaders{contextID: contextID}
34 }
35 
36 func (ctx *httpHeaders) OnHttpRequestHeaders(numHeaders int, endOfStream bool) types.Action {
37     authority, err := proxywasm.GetHttpRequestHeader(":authority")
38     if err != nil {
39         return types.ActionContinue
40     }
41     ctx.authority = authority
42     return types.ActionContinue
43 }
44 
45 func (ctx *httpHeaders) OnHttpResponseHeaders(numHeaders int, endOfStream bool) types.Action {
46     status, err := proxywasm.GetHttpResponseHeader(":status")
47     if err != nil {
48         proxywasm.LogErrorf("responseCode:%v", err)
49         return types.ActionContinue
50     } else {
51         statusi, err := strconv.ParseInt(status, 0, 64)
52         if err != nil {
53             return types.ActionContinue
54         }
55         if statusi >= 400 {
56             proxywasm.RemoveHttpResponseHeader("content-length")
57             headers := [][2]string{}
58             headers = append(headers, [2]string{"content-type", "text/html;charset=UTF-8"})
59             err = proxywasm.SendHttpResponse(uint32(statusi),
60                 headers,
61                 []byte("<html><body>"+status+"</body></html>"),
62                 -1)
63             if err != nil {
64                 proxywasm.LogErrorf("更改Body出现问题:%v", err)
65             }
66         }
67     }
68 
69     return types.ActionContinue
70 }

代码演示了 当状态码大于等于400 就返回一段html 展示状态,隐藏真实的未经处理错误信息(可能会暴露一些服务器、代码信息)。

五、一些常用的方法

5.1. 启动加载配置项

OnVMStart

OnPluginStart

5.2. http调用

proxywasm.DispatchHttpCall

5.3. 共享数据

SetSharedData

GetShareData

5.4. 请求头、响应头操作 这个打印一下就知道有哪些了

   Add、Remove、Replace

5.5. 获取属性数据

1 var protocolAttr []string = []string{"request", "protocol"}
2 var clusterName []string = []string{"cluster_name"}
3 var responseCode []string = []string{"response", "code"}
4 var grpcStatus []string = []string{"response", "grpc_status"}
5 
6 proxywasm.GetProperty(responseCode)

能获取到的属性,参考文档

https://www.envoyproxy.io/docs/envoy/v1.24.0/intro/arch_overview/advanced/attributes.html?highlight=property

(我当时写代码的时候知道能获取属性,但是不知道有哪些属性,这个给我愁坏了)

六. 打包

tinygo build -o xxx.wasm -scheduler=none -target=wasi ./main.go

七、发布

7.1 envoy 配置文件部署

- name: envoy.filters.http.wasm
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
              config:
                name: "xxx"
                root_id: "xxx"
                configuration:
                  '@type': type.googleapis.com/google.protobuf.StringValue
                  value: |
                    {
                      
                      }
                vm_config:
                  runtime: "envoy.wasm.runtime.v8"
                  configuration:
                    '@type': type.googleapis.com/google.protobuf.StringValue
                    value: {}
                  code:
                    local:
                      filename: './xxx.wasm'

7.2 发布istio

7.2.1 envoyfilter发布

---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: xxx
  namespace: xxx
spec:
  configPatches:
    - applyTo: EXTENSION_CONFIG
      patch:
        operation: INSERT_BEFORE
        value:
          name: xxx
          typed_config:
            '@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
            config:
              configuration:
                '@type': type.googleapis.com/google.protobuf.StringValue
                value: |
                  {}
              root_id: xxx
              vm_config:
                code:
                  remote:
                    http_uri:
                      timeout: 10s
                      uri: 'https://xxxxxx/betapreauth.wasm'
                configuration:
                  '@type': type.googleapis.com/google.protobuf.StringValue
                  value: |
                    {
                      
                    }
                runtime: envoy.wasm.runtime.v8
                vm_id: xxx
    - applyTo: HTTP_FILTER
      match:
        listener:
          filterChain:
            filter:
              name: envoy.filters.network.http_connection_manager
              subFilter:
                name: envoy.filters.http.router
      patch:
        operation: INSERT_BEFORE
        value:
          config_discovery:
            config_source:
              ads: {}
            type_urls:
              - type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
          name: xxx
  workloadSelector:
    labels:
      app: xxxx

7.2.2 wasmplug

Docker打包镜像

FROM tinygo/tinygo as build
WORKDIR /src

COPY . .
RUN go env -w GOPROXY=https://goproxy.cn,direct
RUN tinygo build -o xxxx.wasm -scheduler=none -target=wasi ./main.go

FROM scratch as final

COPY --from=build /src/betaerrconvert.wasm ./plugin.wasm

docker build -t xxxx -f Dockerfile .

docker push xxxxx

yaml部署文件

---
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: xxxx
  namespace: istio-system
spec:
  imagePullPolicy: IfNotPresent
  imagePullSecret: xxxx
  selector:
    matchLabels:
      app: istio-ingressgateway
  url: 'oci://xxxxx'

 https://istio.io/latest/docs/reference/config/proxy_extensions/wasm-plugin/

posted @ 2023-02-11 12:03  王鹏翀  阅读(525)  评论(0编辑  收藏  举报