扩展 Envoy 代理 - 使用 Golang 的 WASM 过滤器
[](https://res.cloudinary.com/practicaldev/image/fetch/s--zXYq1lhr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/6vnr2s9a9f2uo66kyt96.p
[](https://res.cloudinary.com/practicaldev/image/fetch/s--zXYq1lhr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/6vnr2s9a9f2uo66kyt96.png)
Envoy 是专为云原生应用程序设计的开源服务代理。它具有多种功能,例如连接池、重试机制、TLS 管理、压缩、健康检查、故障注入、速率限制、授权等。这些功能是通过内置 http 过滤器实现的。今天我将讨论一个特殊的过滤器,它的名称是WASM Filter。
[![由 Emre Savcı 在 excalidraw.com 中绘制<br>
](https://res.cloudinary.com/practicaldev/image/fetch/s--OgUudXR5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com /uploads/articles/zrxi0yr80kn319furt2p.png)](https://res.cloudinary.com/practicaldev/image/fetch/s--OgUudXR5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/zrxi0yr80kn319furt2p.png)
这篇文章不是为了解释什么是 WASM,所以我将跳过解释 WASM,而是在文章末尾添加相关资源。
为什么我们使用 WASM 过滤器
在 Trendyol 科技。我们使用 Istio 作为服务网格。而我们团队(DevX)的职责是通过开发满足微服务常见需求的应用程序(如缓存、授权、速率限制、跨集群服务发现等)来改善开发人员体验。
既然我们已经在使用 Istio,为什么不利用 Envoy Proxy 的可扩展性优势。
我们的用例是为识别该微服务应用程序的微服务获取 JWT 令牌。当我们想避免每个团队用不同的语言编写相同的代码时,我们可以创建一个 WASM 过滤器并将其注入到 Envoy Proxies 中。
WASM 过滤器的优点:
-
它允许用任何支持 WASM 的语言编写代码
-
动态加载代码到 Envoy
-
WASM 代码与 Envoy 隔离,因此 WASM 中的崩溃不会影响 Envoy
在 Envoy Proxy 中有处理传入请求的工作线程。每个工作线程都有自己的 WASM VM。因此,如果您编写基于时间的操作代码,它会为每个线程单独工作。
在 Envoy Proxy 中,每个工作线程都相互隔离,并拥有一个或多个 WASM VM。还有一个概念叫WASM Service用于线程间通信和数据共享(我们不涉及这个)。
[在 excalidraw.com 中绘制](https://res.cloudinary.com/practicaldev/image/fetch/s--_xXjIU50--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https: //dev-to-uploads.s3.amazonaws.com/uploads/articles/sb18ug366p0p41nbuy33.png)
在 Go 中编写 WASM
我们将使用tetratelabs/proxy-wasm-go-sdk在 Go 中编写 WASM。我们还需要TinyGo来将我们的 Go 代码构建为 WASM。
我们的用例非常简单,因此我们编写了一个每 15 秒向 JWT Api 发送请求的代码。它提取授权标头并将其值设置为全局变量,并将该值放入每个传入请求的响应标头中。我们还将“hello from wasm”值设置为另一个名为“x-wasm-filter”的标头。
在 OnTick 函数中,我们对 Envoy 称为集群的服务进行 http 调用。
让我们将 go 代码构建为 WASM:
tinygo build -o optimized.wasm -scheduler=none -target=wasi ./main.go
进入全屏模式 退出全屏模式
现在我们需要配置 Envoy 代理以使用 WASM 过滤器处理传入请求。我们将为我们的 WASM 代码定义一个路由规则和一个 WASM 过滤器,我们还将定义一个代表我们服务的集群。
我把所有的文件放到同一个目录下。现在让我们在 Docker 中运行 Envoy Proxy:
docker run -it — rm -v "$PWD"/envoy.yaml:/etc/envoy/envoy.yaml -v "$PWD"/optimized.wasm:/etc/envoy/optimized.wasm -p 9901:9901 -p 10000:10000 envoyproxy/envoy:v1.17.0
进入全屏模式 退出全屏模式
正如我们从日志中看到的那样,我们的 WASM 过滤器开始工作并每 15 秒向 JWT Api 发送请求
[](https://res.cloudinary.com/practicaldev/image/fetch/s--jBcv8Lwl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/6g5d52fe3jt0o42o146p.png)
现在让我们向 Envoy Proxy 发送一个请求。我们将 Envoy 配置为监听来自 1000 端口的传入请求,并使用端口映射启动容器。所以我们可以向 localhost:10000 发送请求:
[](https://res.cloudinary.com/practicaldev/image/fetch/s--tERCtZsq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to- uploads.s3.amazonaws.com/uploads/articles/hiffztzdp2qerh2jn8xz.png)
在响应标头中,我们可以看到“x-wasm-filter: hello from wasm”和“x-auth”值。
感谢您到目前为止的阅读。我希望它能让您了解如何以及为什么在 Envoy Proxy 中使用 WASM。
您可以在 github 中查看完整示例:
mstrYoda/envoy-proxy-wasm-filter-golang
用 Golang 编写的 Envoy 代理的 WASM 过滤器
特使-代理-wasm-filter-golang
用 Golang 编写的 Envoy 代理的 WASM 过滤器
构建
tinygo build -o optimized.wasm -scheduler=none -target=wasi ./main.go
使用 WASM 过滤器在 Docker 中运行 Envoy 代理
docker run -it --rm -v "$PWD"/envoy.yaml:/etc/envoy/envoy.yaml -v "$PWD"/optimized.wasm:/etc/envoy/optimized.wasm -p 9901:9901 -p 10000:10000 envoyproxy/envoy:v1.17.0
在 GitHub 上查看
资源
webassembly.org
WebAssembly | MDN
WebAssembly 是一种可以在现代 Web 浏览器中运行的新型代码——它是一种低级的类汇编语言,具有紧凑的二进制格式,以接近本机的性能运行,并提供 C/C++、C# 和 Rust 等语言带有编译目标,以便它们可以在 Web 上运行。它还被设计为与 JavaScript 一起运行,允许两者一起工作。
developer.mozilla.org
Wasm 模块和 Envoy 可扩展性解释,第 1 部分 – 新堆栈
如果您曾经想知道 WebAssembly (Wasm) 是什么以及它如何融入服务网格生态系统,那么这就是您想要阅读的文章。
thenewstack.io
tetratelabs/proxy-wasm-go-sdk
用于代理的 WebAssembly(Go SDK)
此项目处于早期阶段,API可能会发生变化且不稳定。
WebAssembly for Proxies (Go SDK)[](https://github. com/tetratelabs/proxy-wasm-go-sdkLICENSE)
Go SDK forProxy-Wasm,使开发人员可以在 Go 中编写 Proxy-Wasm 插件 此 SDK 由TinyGo提供支持,不支持官方 Go 编译器。
入门
-
示例目录包含此 SDK 之上的示例代码。
-
OVERVIEW.mdProxy-Wasm 的概述、此 SDK 的 API 以及编写插件时应了解的事项。
要求
-
去1.17 或更高。
-
TinyGo- 此 SDK 依赖于 TinyGo 并利用其WASI(WebAssembly 系统接口)目标。请按照此处的官方说明安装 TinyGo。
-
Envoy- 要运行已编译的示例,您需要有 Envoy 二进制文件。我们建议使用func -e作为开始使用 Envoy 的最简单方法。或者,您可以按照官方说明进行操作。
安装
go get
不能用...
在 GitHub 上查看
[](https://res.cloudinary.com/practicaldev/image/fetch/s--GTL2o-dm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev- to-uploads.s3.amazonaws.com/uploads/articles/vox3yovcym9tyhqn7uvp.png)
你可以关注我:
推特
领英
Github
更多推荐
所有评论(0)