wasm项目 envoy为什么使用WASM filter 通过 WASM filter的实现,我们可以得到: 
敏捷性 - 过滤器可以动态加载到正在运行的 Envoy 进程中,而无需停止或重新编译。
可维护性 - 我们不必更改 Envoy 的代码库来扩展其功能。
多样性 - 流行的编程语言如 C/C++ 和 Rust 可以编译成 WASM,因此开发人员可以使用他们选择的编程语言来实现过滤器。
可靠性和隔离 - 过滤器部署到 VM(沙箱)中,因此与托管 Envoy 进程本身隔离(例如,当 WASM 过滤器崩溃时,它不会影响 Envoy 进程)。
安全性 - 由于过滤器通过定义良好的 API 与主机(Envoy 代理)通信,因此它们可以访问并且只能修改有限数量的连接或请求属性。
 
它还具有一些需要考虑的缺点: 
性能比原生 C++ 快约 70%。 
由于需要启动一个或多个 WASM 虚拟机,因此内存使用量更高。 
 
envoy 代理 WASM SDK Envoy Proxy 在基于堆栈的虚拟机中运行 WASM 过滤器,因此过滤器的内存与主机环境隔离。嵌入主机(Envoy Proxy)和 WASM 过滤器之间的所有交互都是通过 Envoy Proxy WASM SDK 提供的函数和回调实现的。WASM SDK 具有多种编程语言的实现,例如:
C++ 
rust 
AssemblyScript 
Go 
 
在这篇文章中,我们将讨论如何使用Go Envoy Proxy WASM SDK为 Envoy 编写 WASM 过滤器。我们不打算详细讨论 Envoy Proxy WASM SDK 的 API,因为它超出了本文的范围。但是,我们将涉及掌握为 Envoy 编写 WASM 过滤器的基础知识所必需的一些内容。
1 2 3 4 5 6 7 8 9 10 11 12 type  rootContext struct  {	 	 	proxywasm.DefaultRootContext } type  httpHeaders struct  {	 	proxywasm.DefaultHttpContext 	contextID uint32  } 
初始化wasm项目 
 
1 2 3 4 5 6 7 8 9 ➜  cmd git:(istio-1.9.4-dev) ✗ ./cmd init demo  buildVersion = unknown, buildGitRevision = unknown, buildStatus = unknown, buildTag  = unknown, buildHub = unknown Use the arrow keys to navigate: ↓ ↑ → ←  ? What language do  you wish to use for  the filter:    ▸ cpp     rust     assemblyscript     tinygo 
项目结构如下:
1 2 3 4 demo |-- go.mod |-- main.go |-- runtime-config.json 
我们在代码中加上我们所需的代码 例如:
1 2 3 4 5 6 7 func  (ctx *httpHeaders)  OnHttpResponseHeaders (numHeaders int , endOfStream bool )  types .Action 	if  err := proxywasm.SetHttpResponseHeader("hello" , "world" ); err != nil  { 		proxywasm.LogCriticalf("failed to set response header: %v" , err) 	} 	return  types.ActionContinue } 
编译demo项目
 
使用go语言构建wasm的时候需要安装tinygo
macos
安装完成后,在当前项目的根目录执行:
1 tinygo build -o filter.wasm -target=wasi -wasm-abi=generic . 
执行当前命令后会生成 filter.wasm
将wasm的包scp 到某个sidecar 容器中, 例如: 
 
1 2 3 4 5 6 7 8 9 10 11 kubectl get po -n demo NAME                              READY   STATUS    RESTARTS   AGE details-v1-5588477696-2sw7b       2/2     Running   0          8d productpage-v1-5bd6875444-j75dp   2/2     Running   0          8d ratings-v1-c9d5c65fc-l65mq        2/2     Running   0          8d reviews-v2-c789c7bdc-tsg7q        2/2     Running   0          8d reviews-v3-78944b866f-96nbw       2/2     Running   0          8d kubectl cp filter.wasm -n demo productpage-v1-5bd6875444-j75dp:/var/local /filter.wasm 
我们查看一下容器中是否包含filter.wasm
1 2 3 4 ➜  wasm git:(main) ✗ k exec  -it productpage-v1-5bd6875444-j75dp ls /var/local  Defaulting container name to productpage. Use 'kubectl describe pod/productpage-v1-5bd6875444-j75dp -n demo'  to see all of the containers in  this pod. filter.wasm 
可以看到/var/local 中包含filter.wasm
创建envoyfilter 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 kubectl  apply  -f-<<EOF apiVersion:  networking.istio.io/v1alpha3 kind:  EnvoyFilter metadata:   name:  productpage-v1-examplefilter    namespace:  demo  spec:   configPatches:    -  applyTo:  HTTP_FILTER      match:        context:  SIDECAR_INBOUND        proxy:          proxyVersion:  '^1\.8.*'        listener:          portNumber:  8080          filterChain:            filter:              name:  envoy.http_connection_manager              subFilter:                name:  envoy.router      patch:        operation:  INSERT_BEFORE        value:          config:            config:              name:  productpage-demo              rootId:  my_root_id              vmConfig:                code:                  local:                    filename:  /var/local/filter.wasm                runtime:  envoy.wasm.runtime.v8                vmId:  filter                allow_precompiled:  true          name:  envoy.filters.http.wasm    workloadSelector:      labels:        app:  productpage        version:  v1  EOF 
向productpage服务上的 HTTP 端口 8080 发送一些流量: 
 
1 2 3 kubectl run curl --image=xxx --restart=Never -it --rm sh ~  
在响应中,我们希望看到过滤器的标头添加到响应标头中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 *  About  to  connect()  to  frontpage.backyards-demo  port  8080  (#0) *    Trying  10.10 .178 .38 ... *  Adding handle: conn:  0x10eadbd8 *  Adding handle: send:  0 *  Adding handle: recv:  0 *  Curl_addHandleToPipeline: length:  1 *  -  Conn  0  (0x10eadbd8)  send_pipe:  1 ,  recv_pipe:  0 *  Connected  to  frontpage.backyards-demo  (10.10.178.38)  port  8080  (#0) >  GET  /  HTTP/1.1 >  User-Agent:  curl/7.30.0 >  Host:  frontpage.backyards-demo:8080 >  Accept:  */* > <  HTTP/1.1  200  OK <  content-type:  text/plain <  date:  Thu,  16  Apr  2020 16:32:20  GMT <  content-length:  9 <  x-envoy-upstream-service-time:  10 <  resp-header-demo:  added  by  our  filter <  x-envoy-peer-metadata:  CjYKDElOU1RBTkNFX0lQUxImGiQxMC4yMC4xLjU3LGZlODA6OmQwNDM6NDdmZjpmZWYwOmVkMjkK2QEKBkxBQkVMUxLOASrLAQoSCgNhcHASCxoJZnJvbnRwYWdlCiEKEXBvZC10ZW1wbGF0ZS1oYXNoEgwaCjU3OGM2NTU0ZDQKJAoZc2VjdXJpdHkuaXN0aW8uaW8vdGxzTW9k ZRIHGgVpc3RpbwouCh9zZXJ2aWNlLmlzdGlvLmlvL2Nhbm9uaWNhbC1uYW1lEgsaCWZyb250cGFnZQorCiNzZXJ2aWNlLmlzdGlvLmlvL2Nhbm9uaWNhbC1yZXZpc2lvbhIEGgJ2MQoPCgd2ZXJzaW9uEgQaAnYxChoKB01FU0hfSUQSDxoNY2x1c3Rlci5sb2NhbAonCgROQU1FEh8aHWZyb250cGFnZS12MS01N zhjNjU1NGQ0LWxidnFrCh0KCU5BTUVTUEFDRRIQGg5iYWNreWFyZHMtZGVtbwpXCgVPV05FUhJOGkxrdWJlcm5ldGVzOi8vYXBpcy9hcHBzL3YxL25hbWVzcGFjZXMvYmFja3lhcmRzLWRlbW8vZGVwbG95bWVudHMvZnJvbnRwYWdlLXYxCi8KEVBMQVRGT1JNX01FVEFEQVRBEhoqGAoWCgpjbHVzdGVyX2lkEg gaBm1hc3RlcgocCg9TRVJWSUNFX0FDQ09VTlQSCRoHZGVmYXVsdAofCg1XT1JLTE9BRF9OQU1FEg4aDGZyb250cGFnZS12MQ== <  x-envoy-peer-metadata-id:  sidecar~10.20.1.57~frontpage-v1-578c6554d4-lbvqk.backyards-demo~backyards-demo.svc.cluster.local <  x-by-metadata:  CjYKDElOU1RBTkNFX0lQUxImGiQxMC4yMC4xLjU3LGZlODA6OmQwNDM6NDdmZjpmZWYwOmVkMjkK2QEKBkxBQkVMUxLOASrLAQoSCgNhcHASCxoJZnJvbnRwYWdlCiEKEXBvZC10ZW1wbGF0ZS1oYXNoEgwaCjU3OGM2NTU0ZDQKJAoZc2VjdXJpdHkuaXN0aW8uaW8vdGxzTW9kZRIHGgVp c3RpbwouCh9zZXJ2aWNlLmlzdGlvLmlvL2Nhbm9uaWNhbC1uYW1lEgsaCWZyb250cGFnZQorCiNzZXJ2aWNlLmlzdGlvLmlvL2Nhbm9uaWNhbC1yZXZpc2lvbhIEGgJ2MQoPCgd2ZXJzaW9uEgQaAnYxChoKB01FU0hfSUQSDxoNY2x1c3Rlci5sb2NhbAonCgROQU1FEh8aHWZyb250cGFnZS12MS01NzhjNjU1N GQ0LWxidnFrCh0KCU5BTUVTUEFDRRIQGg5iYWNreWFyZHMtZGVtbwpXCgVPV05FUhJOGkxrdWJlcm5ldGVzOi8vYXBpcy9hcHBzL3YxL25hbWVzcGFjZXMvYmFja3lhcmRzLWRlbW8vZGVwbG95bWVudHMvZnJvbnRwYWdlLXYxCi8KEVBMQVRGT1JNX01FVEFEQVRBEhoqGAoWCgpjbHVzdGVyX2lkEggaBm1hc3 RlcgocCg9TRVJWSUNFX0FDQ09VTlQSCRoHZGVmYXVsdAofCg1XT1JLTE9BRF9OQU1FEg4aDGZyb250cGFnZS12MQ== *  Server  istio-envoy  is  not  blacklisted <  server:  istio-envoy <  x-envoy-decorator-operation:  frontpage.backyards-demo.svc.cluster.local:8080/* < *  Connection  frontpage