当前时间: 2026-03-07 20:35:33
分类:软件教程
评论(0)
Higress WASM 插件入门(一)
配置信息主要以 CRD 的形式存储在 K8s etcd 中,不依赖额外的存储组件。
控制台组件,提供 Web 页面方便管理插件、路由规则,后端基于 Java SpringBoot 构建,前端基于 NodeJS 飞冰(ICE)构建
核心组件,用于监听 K8s APIServer,完成对应等规则的转换:
K8s Ingress -> Istio API -> xDS,再实现配置下发;higress-controller 有两个容器,作用如下:
higress-core:监听 Kubernetes API,将 ingress & higress crd 等内容转换为istio api
pilot: 移植 istiod pilot 模块的能力。将 istio api 转换为 xDS,同时将其下发给 envoy
核心组件,底层集成了 envoy ,用于数据面的实际流量转发;目前 higress 数据面主要基于 envoy-1.27 分支定制。
内部包含两个子组件:Pilot Agent 和 Envoy。Pilot Agent 主要负责 Envoy 的启动和配置,同时代理 Envoy xDS 请求到 Discovery。 Envoy 作为数据面,负责接收控制面的配置下发,并代理请求到业务服务。 Pilot Agent 和 Envoy 之间通讯协议是使用 xDS 协议, 通过 Unix Domain Socket(UDS)进行通信。
Higress 提供丰富的插件扩展机制,插件位于 https://github.com/alibaba/higress/tree/main/plugins;
核心插件主要使用 Go 进行开发,可以参考《使用 GO 语言开发 WASM 插件》https://higress.cn/docs/latest/user/wasm-go;
一个独立的 primary 线程负责控制各种零散的协调任务,而一些 worker 线程则负责执行监听、过滤和转发任务;
一旦侦听器接受连接,该连接就会将其生命周期绑定到一个单独的 worker 线程。这使得 Envoy 的大部分工作基本上是单线程来处理的,只有少量更复杂的代码处理工作线程之间的协调。
通常情况下 Envoy 实现了 100% 非阻塞。对于大多数工作负载,建议将 worker 线程的数量配置为机器上的硬件线程数量。
-
Listener(监听器):定义了 Envoy 如何处理入站请求。一旦连接建立,请求会被传递给一组过滤器进行处理
-
Filter(过滤器):作为处理入站和出站流量的链式结构的一部分。可以通过集成特定功能的过滤器来实现额外的功能,例如,使用 Gzip 过滤器来压缩发送到客户端的数据;WASM 插件目前就工作在这一层。
-
Route(路由):用于将流量转发到具体的目标实例,这些目标实例在 Envoy 中被定义为集群
-
Cluster(集群):定义了流量的目标端点,同时还可以包含其他的可选配置,比如负载均衡策略等
xDS 是 Envoy 中一组发现服务(Discovery Service) 的统称。这里的“x”是一个占位符,代表多种不同类型的配置资源。其核心思想是让 Envoy 能够通过 动态配置 而非静态文件来获取其运行所需的各种资源,从而实现服务的动态发现和灵活管理。
Envoy 支持不同的模块进行动态配置,可配置的有如下几个 API(统称为 xDS):
-
EDS:端点发现服务,可以让 Envoy 自动发现上游集群的成员,这使得我们可以动态添加或者删除处理流量请求的服务。
-
CDS:集群发现服务,可以让 Envoy 通过该机制自动发现在路由过程中使用的上游集群。
-
RDS:路由发现服务,可以让 Envoy 在运行时自动发现 HTTP 连接管理过滤器的整个路由配置,这可以让我们来完成诸如动态更改流量分配或者蓝绿发布之类的功能。
-
VHDS:虚拟主机发现服务,允许根据需要与路由配置本身分开请求属于路由配置的虚拟主机。该 API 通常用于路由配置中有大量虚拟主机的部署中。
-
SRDS:作用域路由发现服务,允许将路由表分解为多个部分。该 API 通常用于具有大量路由表的 HTTP 路由部署中。
-
LDS:监听器发现服务,可以让 Envoy 在运行时自动发现整个监听器。
-
SDS:密钥发现服务,可以让 Envoy 自动发现监听器的加密密钥(证书、私钥等)以及证书校验逻辑(受信任的根证书、吊销等)。
-
RTDS:运行时发现服务, API 允许通过 xDS API 获取运行时层。这可以通过文件系统层进行补充或改善。
-
ECDS:扩展配置发现服务 , API 允许独立于侦听器提供扩展配置(例如 HTTP 过滤器配置)。当构建更适合与主控制平面分离的系统(例如 WAF、故障测试等)时,这非常有用。
-
ADS:EDS、CDS 等都是单独的服务,具有不同的 REST/gRPC 服务名称,例如 StreamListeners、StreamSecrets。对于希望强制资源按照不同类型的顺序到达 Envoy 的用户来说,有聚合的 xDS,这是一个单独的 gRPC 服务,在一个 gRPC 流中携带所有资源类型。(ADS 只支持 gRPC)。
WebAssembly(简称为 Wasm)的诞生源自前端,是一种为了解决日益复杂的 Web 前端应用以及有限的 JavaScript 性能而诞生的技术。它本身并不是一种语言,而是一种字节码标准。WASM 字节码和机器码非常接近,因此可以非常快速的装载运行。任何一种语言,都可以被编译成 WASM 字节码,然后在 WASM 虚拟机中执行,理论上,所有语言,包括 JavaScript、C、C++、Rust、Go、Java 等都可以编译成 WASM 字节码并在 WASM 虚拟机中执行。当然不仅可以嵌入浏览器增强 Web 应用,也可以应用于其他的场景。
有很多编程语言都支持编写 WASM 插件,比如 C、C++、Rust、Go、Java 等等,这里我们以 Go 语言为例来编写一个简单的 WASM 插件,编写 WASM 的工具有 Solo.io 团队的 wasme、tinygo等,之前 higress 的插件主要使用 tinygo 来编译,当时官方 Go 编译器无法生成可以在浏览器外部运行的 WASM 二进制文件,因此也无法生成与 Proxy-Wasm 兼容的二进制文件,但存在内存泄露、GC 性能差的问题,
Go 1.24 已支持用原生 Go 编写 Wasm 插件,可通过原生 GC 解决 tinygo + 保守式 GC 的内存泄漏问题。Higress 社区正升级,从 2.14 版本开始将以 Go 1.24 编写 Wasm 插件为主。
Proxy-Wasm是开源社区针对「网络代理场景」设计的一套 ABI 规范,定义了网络代理和运行在网络代理内部的 Wasm 虚拟机之间的接口,属于当前的事实规范。当前支持该规范的网络代理软件包括 Envoy、MOSN 和 ATS(Apache Traffic Server),支持该规范的 Wasm 扩展 SDK 包括 C++、Rust 和 Go。采用该规范的好处在于能让 Wasm 扩展程序在不同的网络代理产品上运行,比如 MOSN 的 Wasm 扩展程序可以运行在 Envoy 上,而 Envoy 的 Wasm 扩展程序也可以运行在 MOSN 上。
Proxy-Wasm Go SDK 是基于 Proxy-Wasm ABI 规范使用 Go 编程语言扩展网络代理(例如 Envoy)的 SDK,通过这个 SDK,可以轻松地生成符合 Proxy-Wasm 规范的 Wasm 二进制文件,而无需了解 Proxy-Wasm ABI 规范,同时开发人员可以依赖这个 SDK 的 Go API 来开发插件扩展 Enovy 功能。