WebAssembly是一种可以将多种语言编译成目标字节码,并在相应的wasm虚拟机中运行的技术。
在service mesh中,通常使用envoy作为proxy sidecar。而envoy是基于c++编写,扩展和定制稍有不便。
借助WebAssembly,我们可以利用其他语言比如AssemblyScript(ts),Rust等来编写envoy的扩展(类似与用lua扩展nginx),并在envoy中运行。
目前envoy官方仓库仅有wasm分支对wasm进行了实验性支持,所以本文基于gloo(官方支持wasm的一个api网关)进行搭建。
ECS:阿里云香港,2c4g,ubuntu20.04
本机:ubuntu18
参考:https://docs.docker.com/engine/install/ubuntu/
# 卸载原有docker安装
$ sudo apt-get remove docker docker-engine docker.io containerd runc
$ sudo apt-get update
# 安装必要依赖
$ sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common
# 下载key
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 验证key
$ sudo apt-key fingerprint 0EBFCD88
# 添加仓库
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
# 更新源、安装
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
# 验证安装
$ sudo docker run hello-world
先安装kubectl
参考:https://kubernetes.io/docs/tasks/tools/install-kubectl/
由于google连不上,本机国内安装参考:
https://zhuanlan.zhihu.com/p/38118017
https://www.cnblogs.com/dudu/p/12155869.html
$ sudo apt-get update && sudo apt-get install -y apt-transport-https gnupg2 curl
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
$ echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
$ sudo apt-get update
$ sudo apt-get install -y kubectl
再安装minikube
参考:https://minikube.sigs.k8s.io/docs/start/#install-minikube
本机国内安装参考:https://developer.aliyun.com/article/221687
# 下载安装
$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
$ sudo install minikube-linux-amd64 /usr/local/bin/minikube
# 启动(默认使用docker驱动)
$ minikube start
# 如果连接docker报错(/var/run/docker.sock: connect: permission denied),可能是用户权限的问题:
$ sudo usermod -aG docker $USER
$ newgrp docker
$ sudo service docker restart
# 验证
$ kubectl get po -A
gloo是一个基于envoy的api gateway,介绍及文档:https://docs.solo.io/gloo/latest/
# 安装glooctl工具
$ curl -sL https://run.solo.io/gloo/install | sh
$ export PATH=$HOME/.gloo/bin:$PATH
$ glooctl version
# 安装gloo的upstream示例程序petstore
$ kubectl apply -f https://raw.githubusercontent.com/solo-io/gloo/master/example/petstore/petstore.yaml
# 安装gloo的wasm版本
$ glooctl install gateway --values <(echo '{"crds":{"create":true},"global":{"wasm":{"enabled":true}}}')
# 添加virtual service路由
$ cat <<EOF | kubectl apply -f-
apiVersion: gateway.solo.io/v1
kind: VirtualService
metadata:
name: default
namespace: gloo-system
spec:
virtualHost:
domains:
- '*'
routes:
- matchers:
- prefix: /
routeAction:
single:
upstream:
name: default-petstore-8080
namespace: gloo-system
EOF
# 验证路由
$ curl -v $(glooctl proxy url)/api/pets
# 正常情况下输出
* Trying 192.168.49.2:30277...
* TCP_NODELAY set
* Connected to 192.168.49.2 (192.168.49.2) port 30277 (#0)
> GET /api/pets HTTP/1.1
> Host: 192.168.49.2:30277
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: application/xml
< date: Fri, 16 Oct 2020 03:49:56 GMT
< content-length: 86
< x-envoy-upstream-service-time: 1
< server: envoy
<
[{"id":1,"name":"Dog","status":"available"},{"id":2,"name":"Cat","status":"pending"}]
编译wasm示例:https://docs.solo.io/web-assembly-hub/latest/tutorial_code/getting_started/
# 安装wasme工具
$ curl -sL https://run.solo.io/wasme/install | sh
$ export PATH=$HOME/.wasme/bin:$PATH
$ wasme --version
# 初始化wasm工程
$ wasme init ./new-filter
# 选择语言
? What language do you wish to use for the filter:
cpp
▸ assemblyscript
? With which platforms do you wish to use the filter?:
▸ gloo:1.3.x, istio:1.5.x
# 编译
$ wasme build assemblyscript -t webassemblyhub.io/$YOUR_USERNAME/add-header:v0.1 .
# 查看本地编译结果
$ wasme list
# 到webassemblyhub.io创建一个账号
# 推送编译结果到仓库
$ wasme login -u $YOUR_USERNAME -p $YOUR_PASSWORD
$ wasme push webassemblyhub.io/$YOUR_USERNAME/add-header:v0.1
# 查看推送结果
$ wasme list --search $YOUR_USERNAME
验证结果,header中已包含插件写入的hello world
# 将wasm filter注入到gloo网关中
$ wasme deploy gloo webassemblyhub.io/$YOUR_USERNAME/add-header:v0.1 --id=add-header
# 再次访问
$ curl -v $(glooctl proxy url)/api/pets
* Trying 192.168.49.2:30277...
* TCP_NODELAY set
* Connected to 192.168.49.2 (192.168.49.2) port 30277 (#0)
> GET /api/pets HTTP/1.1
> Host: 192.168.49.2:30277
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: application/xml
< date: Fri, 16 Oct 2020 03:49:56 GMT
< content-length: 86
< x-envoy-upstream-service-time: 1
< hello: world!
< server: envoy
<
[{"id":1,"name":"Dog","status":"available"},{"id":2,"name":"Cat","status":"pending"}]
相关参考:
编写wasm插件:https://docs.solo.io/web-assembly-hub/latest/tutorial_code/build_tutorials
部署wasm插件:https://docs.solo.io/web-assembly-hub/latest/tutorial_code/deploy_tutorials
搭建istio环境:https://istio.io/latest/docs/setup/getting-started/#download