Higress wasm-go 插件开发指南:从 SDK 构建、部署到测试的完整实践

发布时间:2026/9/16 18:32:24

Higress wasm-go 插件开发指南:从 SDK 构建、部署到测试的完整实践 Higress wasm-go 插件开发指南从 SDK 构建、部署到测试的完整实践【免费下载链接】higress AI Gateway | AI Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/hi/higress本篇技术指南以 Higress 官方的 wasm-go SDK 文档为核心系统讲解如何使用 Go 语言为 Higress 开发 WebAssemblyWASM插件涵盖基于 Higress wasm-go builder 的一键构建、本地手工编译与镜像推送、通过WasmPluginCRD 让插件在全局/路由级/域名级生效以及单元测试与 E2E 测试的完整编写与运行流程。读完本文你将掌握从零编写一个可运行的 Higress Go WASM 插件以 request-block 参考插件为例所需的全部技能。一、wasm-go SDK 与插件运行机制概览Higress 的 wasm-go SDK 用于使用 Go 语言开发 Higress 的 WASM 插件。插件以plugin.wasm的形态被加载到 Envoy/Higress 网关的 WASM 运行时中通过 proxy-wasm ABI 与网关进行交互。其核心依赖为github.com/higress-group/proxy-wasm-go-sdk参考插件 request-block 的 go.mod 中同时依赖该 SDK 与github.com/higress-group/wasm-go封装库Go 版本要求为 1.24。从参考插件 plugins/wasm-go/examples/request-block/main.go 的源码结构可以清晰看到 SDK 的标准用法func init() { wrapper.SetCtx( request-block, wrapper.ParseConfigBy(parseConfig), wrapper.ProcessRequestHeadersBy(onHttpRequestHeaders), wrapper.ProcessRequestBodyBy(onHttpRequestBody), ) }插件通过init()注册插件名称、配置解析函数以及请求头/请求体处理函数parseConfig负责把 WasmPlugin 的defaultConfigJSON 解析为结构体onHttpRequestHeaders与onHttpRequestBody分别在请求头与请求体阶段执行拦截逻辑命中规则后调用proxywasm.SendHttpResponseWithDetail直接返回阻断响应。此外文档还提到一个特殊场景mcp-server插件的 MCP2026-07-28一致性验证有独立的构建入口该入口不依赖批量构建器仅扫描VERSION以-alpha结尾插件的规则可直接执行make build-mcp-server-wasmplugin cd plugins/wasm-go/extensions/mcp-server ./testdata/interop/run.sh其互操作测试固定锁定官方 Go SDKv1.7.0与 TypeScript Client2.0.0分别要求 Go 1.25 与 Node.js 20详见 mcp-server 文档。二、使用 Higress wasm-go builder 快速构建wasm-go 插件可以使用 Higress 提供的构建器镜像一键构建。执行以下命令即可构建参考插件 request-block# NOTE: 如果想在构建插件时设置额外的构建参数 EXTRA_TAGS # 请更新 ${PLUGIN_ROOT}/${PLUGIN_NAME} 插件目录下对应的 .buildrc 文件 # NOTE: 如果想自定义最终推送的镜像短名覆盖默认的插件目录名 # 可以在 .buildrc 中添加 IMAGE_NAMEyour-image-name。 # 镜像短名只能包含小写字母、数字、.、_、-否则构建会失败。 # 本设置仅影响推送的镜像 tag不影响源码路径。 $ PLUGIN_ROOTexamples PLUGIN_NAMErequest-block make build构建输出大致如下DOCKER_BUILDKIT1 docker build --build-arg PLUGIN_ROOTexamples --build-arg PLUGIN_NAMErequest-block \ -t request-block:20230223-173305-3b1a471 \ --output examples/request-block . [] Building 67.7s (12/12) FINISHED image: request-block:20230223-173305-3b1a471 output wasm file: examples/request-block/plugin.wasm该命令最终构建出一个 wasm 文件和一个 Docker 镜像。本地的plugin.wasm文件会被输出到对应插件的目录下如上例为examples/request-block/plugin.wasm可直接用于本地调试。如果想在构建的同时推送镜像可以直接使用make build-push。构建参数说明参数名称可选/必须默认值含义PLUGIN_NAME可选hello-world要构建的插件名称PLUGIN_ROOT可选extensions插件所在的根目录构建参考插件时设为examplesREGISTRY可选空生成的镜像的仓库地址如example.registry.io/my-name/。注意REGISTRY值应当以/结尾IMG可选如不设置则根据仓库地址、插件名称、构建时间以及 git commit id 生成生成的镜像名称如非空则会覆盖REGISTRY参数这些参数与 plugins/wasm-go/Makefile 中的定义一一对应PLUGIN_NAME ? hello-world、PLUGIN_ROOT ? extensions镜像 tag 由构建时间BUILD_TIME格式YYYYMMDD-HHMMSS与 git commit idCOMMIT_ID取git rev-parse --short HEAD拼接而成例如20230223-173305-3b1a471IMG ? ${REGISTRY}${PLUGIN_NAME}:${IMAGE_TAG}即为最终镜像名。构建器镜像默认使用wasm-go-builder:go1.24.4-oras1.0.0对应 Makefile 中的GO_VERSION ? 1.24.4、ORAS_VERSION ? 1.0.0构建时会通过--output参数把产物目录挂出到宿主机。构建器镜像的底层逻辑见 plugins/wasm-go/Dockerfile它先从wasm-go-builder基础镜像中复制 Go 工具链与 ORAS 工具然后在/workspace/$PLUGIN_ROOT/$PLUGIN_NAME目录下执行go mod tidy、可选执行prepare.sh最终以GOOSwasip1 GOARCHwasm go build -buildmodec-shared -o /main.wasm .编译出 WASM 产物并放入FROM scratch的最终镜像中重命名为plugin.wasm。而构建器镜像本身plugins/wasm-go/DockerfileBuilder则负责下载指定版本的 Go 与 ORAS 二进制支持 amd64 / arm64 双架构。三、本地构建 wasm 并推送镜像如果不想依赖云端构建器也可以先在本地把 wasm 编译出来再拷贝到 Docker 镜像中。本地编译环境要求Go 版本 1.24需要支持 wasm 构建特性下面是本地多步骤构建 request-block 参考插件的完整示例。step1. 编译 wasmGOOSwasip1 GOARCHwasm go build -buildmodec-shared -o ./examples/request-block/main.wasm ./examples/request-block这里使用了 Go 的 WASI 编译目标wasip1并指定-buildmodec-shared以生成可被 WASM 运行时加载的动态库格式产物main.wasm。这一命令与 plugins/wasm-go/Makefile 中local-build目标的逻辑一致只是后者还支持在执行编译前先运行插件目录下可选的prepare.sh脚本。如果需要更复杂的 Header 状态管理等高级用法可进一步查阅 Higress 官方文档中关于 Go 开发插件的最佳实践章节。step2. 构建并推送插件的 Docker 镜像使用这份简单的 DockerfileFROM scratch COPY main.wasm plugin.wasmdocker build -t your_registry_hub/request-block:2.0.0 -f your_dockerfile . docker push your_registry_hub/request-block:2.0.0FROM scratch意味着最终镜像仅包含一个plugin.wasm文件体积极小Higress 网关运行时只关心镜像内的plugin.wasm文件并将其加载进 WASM 虚拟机执行。推送完成后该镜像地址就是后续 WasmPlugin 资源中url字段的取值。四、创建 WasmPlugin 资源使插件生效编译并推送好镜像后通过创建 WasmPlugin 自定义资源即可让插件在网关中生效。WasmPlugin 的完整字段语义可以参考 Istio 官方 WasmPlugin API 文档文档中提及apiVersion: extensions.higress.io/v1alpha1这是 Higress 在 Istio WasmPlugin 基础上的扩展 CRD。编写 WasmPlugin 资源如下apiVersion: extensions.higress.io/v1alpha1 kind: WasmPlugin metadata: name: request-block namespace: higress-system spec: defaultConfig: block_urls: - swagger.html url: oci://your_registry_hub/request-block:2.0.0 # 之前构建和推送的 image 地址使用kubectl apply -f your-wasm-plugin-yaml使资源生效。资源生效后如果请求 url 携带swagger.html则该请求会被拒绝例如curl your_gateway_address/api/user/swagger.html返回结果HTTP/1.1 403 Forbidden date: Wed, 09 Nov 2022 12:12:32 GMT server: istio-envoy content-length: 0这里defaultConfig中的block_urls就是 main.go 中parseConfig解析的第一个配置项插件把block_urls中声明的关键字swagger.html与请求路径:path做包含匹配strings.Contains命中即返回 403。除block_urls外request-block 插件还支持更多配置项均可在defaultConfig中使用配置项含义block_urls请求路径包含指定关键字即拦截block_exact_urls请求路径精确等于指定值即拦截block_regexp_urls请求路径匹配指定正则即拦截block_headers请求头包含指定关键字即拦截block_bodies请求体包含指定关键字即拦截blocked_code拦截响应状态码默认 403仅接受 100~599 的合法状态码否则回退 403blocked_message拦截响应体内容case_sensitive是否大小写敏感默认false不敏感匹配前统一转小写从源码实现看onHttpRequestHeaders阶段依次做精确 URL 匹配、关键字 URL 匹配、正则 URL 匹配、请求头关键字匹配当配置中存在block_bodies时才读取请求体否则通过ctx.DontReadRequestBody()跳过请求体读取以节省开销onHttpRequestBody阶段再对请求体做关键字匹配并返回阻断响应。五、路由级与域名级生效WasmPlugin 的matchRules字段允许把同一份插件代码以不同的配置应用到指定的 Ingress 或域名上实现路由级、域名级的差异化策略。示例如下apiVersion: extensions.higress.io/v1alpha1 kind: WasmPlugin metadata: name: request-block namespace: higress-system spec: defaultConfig: # 跟上面例子一样这个配置会全局生效但如果被下面规则匹配到则会改为执行命中规则的配置 block_urls: - swagger.html matchRules: # 路由级生效配置 - ingress: - default/foo # default 命名空间下名为 foo 的 ingress 会执行下面这个配置 config: block_bodies: - foo - ingress: - default/bar # default 命名空间下名为 bar 的 ingress 会执行下面这个配置 config: block_bodies: - bar # 域名级生效配置 - domain: - *.example.com # 若请求匹配了上面的域名, 会执行下面这个配置 config: block_bodies: - foo - bar url: oci://your_registry_hub/request-block:2.0.0所有规则会按上面配置的顺序依次执行匹配当有一个规则匹配时就停止匹配并选择匹配的配置执行插件逻辑defaultConfig作为兜底配置只对未被任何matchRules命中的请求生效。这一机制使得单个插件镜像即可同时服务于不同 Ingress 或不同域名的差异化拦截策略无需为每种策略分别构建镜像。六、单元测试在开发 wasm 插件时建议同时编写单元测试来验证插件功能。wasm-go SDK 提供了完整的测试框架github.com/higress-group/wasm-go/pkg/test可以在不启动真实网关的情况下通过模拟测试主机TestHost对插件的配置解析与请求处理逻辑进行验证。单元测试结构示例文档给出的通用测试骨架如下func TestMyPlugin(t *testing.T) { test.RunTest(t, func(t *testing.T) { // 1. 创建测试主机 config : json.RawMessage({key: value}) host, status : test.NewTestHost(config) require.Equal(t, types.OnPluginStartStatusOK, status) defer host.Reset() // 2. 设置请求头 headers : [][2]string{ {:method, GET}, {:path, /test}, {:authority, test.com}, } // 3. 调用插件请求头处理方法 action : host.CallOnHttpRequestHeaders(headers) require.Equal(t, types.ActionPause, action) // 4. 模拟外部调用响应如果需要 // host.CallOnRedisCall(0, test.CreateRedisRespString(OK)) // host.CallOnHttpCall([][2]string{{:status, 200}}, []byte({result: success})) // 5. 完成请求 host.CompleteHttp() // 6. 验证结果如果插件里返回了响应 localResponse : host.GetLocalResponse() require.NotNil(t, localResponse) assert.Equal(t, uint32(200), localResponse.StatusCode) }) }这个示例展示了测试的基本结构创建测试主机 → 注入请求头 → 调用插件处理方法 → 可选模拟外部调用 → 完成请求 → 断言本地响应。测试框架还提供了CallOnHttpRequestBody、GetMatchConfig、GetHttpStreamAction等方法覆盖配置解析、请求头处理、请求体处理、本地响应等全部验证维度。结合 request-block 的完整单测示例参考插件 request-block 自带了一套非常完整的单元测试见 plugins/wasm-go/examples/request-block/main_test.go。其测试配置覆盖了插件的全部规则类型var testConfig func() json.RawMessage { data, _ : json.Marshal(map[string]interface{}{ blocked_code: 403, blocked_message: Access denied, case_sensitive: false, block_urls: []string{blocked, forbidden}, block_exact_urls: []string{/exact-block, /admin}, block_regexp_urls: []string{/api/v\d/blocked}, block_headers: []string{blocked-header, malicious}, block_bodies: []string{blocked-content, spam}, }) return data }()基于该配置测试覆盖了如下典型场景配置解析TestParseConfig通过host.GetMatchConfig()拿到解析后的*RequestBlockConfig逐一断言各规则列表与blockedCode、blockedMessage、caseSensitive的取值URL 关键字拦截TestBlockUrlByKeyword请求/api/blocked/endpoint命中关键字blocked断言返回 403 且响应体为Access deniedURL 精确拦截TestBlockUrlByExactMatch请求/exact-block命中精确规则返回 403URL 正则拦截TestBlockUrlByRegexp请求/api/v1/blocked命中\d正则规则返回 403请求头拦截TestBlockByHeaders携带blocked-header头的请求返回 403请求体拦截TestBlockByBody先调用CallOnHttpRequestHeaders建立上下文再调用CallOnHttpRequestBody注入包含blocked-content的请求体断言返回 403放行合法请求TestAllowValidRequest无命中规则时GetLocalResponse()返回nil请求不被拦截大小写不敏感TestCaseInsensitiveBlockingcase_sensitive: false时大写路径/API/BLOCKED/ENDPOINT同样被拦截自定义拦截状态码TestCustomBlockedCode设置blocked_code: 429时返回 429配置边界情况TestParseConfigEdgeCases验证非法blocked_code如 999回退默认 403、case_sensitive: true时规则保持原大小写、空字符串规则被过滤、完全没有 block 规则时插件启动失败OnPluginStartStatusFailed。运行测试可直接在插件目录执行go test ./...依赖包会通过go.mod拉取wazero 等间接依赖用于在本地模拟 WASM 宿主环境。这一整套测试为插件的正确性提供了充分的回归保障。七、E2E 测试当你完成一个 Go 插件功能时可以同时创建关联的 E2E 测试用例并在本地完成插件功能的端到端验证。E2E 测试会真正把插件加载进 Higress 网关通过真实 HTTP 请求验证拦截行为。step1. 编写 test cases在目录test/e2e/conformance/tests/下面分别添加xxx.yaml文件和xxx.go文件。例如测试插件 request-blocktest/e2e/conformance/tests/request-block.yamlapiVersion: networking.k8s.io/v1 kind: Ingress ... ... spec: defaultConfig: block_urls: - swagger.html url: file:///opt/plugins/wasm-go/examples/request-block/plugin.wasm注意上述url中examples后面的request-block为参考插件所在文件夹名称参考插件不参与官方插件发布。test/e2e/conformance/tests/request-block.go定义suite.ConformanceTest测试结构。仓库中现成的 test/e2e/conformance/tests/go-wasm-request-block.go 是 request-block 的 Go 版 E2E 实现它以foo.com为 Host构造了多组断言访问/swagger.html、/env/info、/web/info期望返回 403POST 请求体为hello world期望返回 403而请求体为hello higress时期望返回 200 放行并校验响应体回显一致性。测试通过http.MakeRequestAndExpectEventuallyConsistentResponse发起请求并等待最终一致的结果。step2. 添加 test cases将上述所写 test cases 添加到 E2E 测试列表中即 test/e2e/e2e_test.go... cSuite.Setup(t) var higressTests []suite.ConformanceTest if *isWasmPluginTest { if strings.Compare(*wasmPluginType, CPP) 0 { m : make(map[string]suite.ConformanceTest) m[request_block] tests.CPPWasmPluginsRequestBlock m[key_auth] tests.CPPWasmPluginsKeyAuth higressTests []suite.ConformanceTest{ m[*wasmPluginName], } } else { higressTests []suite.ConformanceTest{ tests.WasmPluginsRequestBlock, // 这里新增你新写的 case 方法名称 } } } else { ...从代码可以看出测试框架通过命令行参数区分插件语言类型wasmPluginType为CPP时走 C 插件测试分支否则走 Go 插件测试分支并按wasmPluginName选择要执行的测试用例新增的 Go 插件用例只需把自己的ConformanceTest变量加进higressTests列表即可。step3. 编译插件并执行 test cases考虑到本地构建 wasm 比较耗时测试框架支持只构建需要测试的插件同时你也可以临时修改上面第二小步的测试 cases 列表只执行你新写的 casePLUGIN_ROOTexamples PLUGIN_NAMErequest-block make higress-wasmplugin-test该命令会只针对examples/request-block插件进行构建然后执行你在 E2E 列表中登记的相关用例在本地完成从构建、加载到真实请求验证的完整闭环。八、总结围绕 wasm-go SDKHigress 提供了一条完整的 Go WASM 插件开发链路构建既可通过make build/make build-push使用 Higress wasm-go builder 一键完成 wasm 产物与镜像的构建推送也可用GOOSwasip1 GOARCHwasm go build -buildmodec-shared在本地手工编译Go 1.24部署通过extensions.higress.io/v1alpha1的WasmPlugin资源引用 OCI 镜像利用defaultConfig与matchRules实现全局、路由级、域名级的多级差异化配置规则按顺序匹配、命中即止验证单元测试借助pkg/test的 TestHost 模拟宿主环境验证配置解析与拦截逻辑E2E 测试则把插件加载进真实网关后通过 HTTP 断言验证端到端行为。参考插件 plugins/wasm-go/examples/request-block 及其配套的 main_test.go 和 E2E 用例 是理解整个开发流程的最佳起点——你可以把它作为模板替换为自己的业务逻辑快速产出第一个 Higress Go WASM 插件。【免费下载链接】higress AI Gateway | AI Native API Gateway项目地址: https://gitcode.com/GitHub_Trending/hi/higress创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/16 18:32:24

Java抽象类核心特性与应用实践指南

1. Java抽象类概述抽象类是Java面向对象编程中一个非常重要的概念,它介于普通类和接口之间,为代码复用和多态实现提供了强大的支持。抽象类用abstract关键字修饰,它不能被实例化,只能被继承。在实际开发中,抽象类常用于…

2026/9/16 18:27:23

60W反激电源硬件设计包:NCP1377+隔离PCB工程文件

简介:本资源是一份面向电子工程师、硬件开发者及电源设计学习者的完整反激式开关电源工程文件,解决AC220V高压交流电高效、安全转换为DC12V/5A稳定直流输出的实际需求,适用于LED驱动、嵌入式系统供电、小家电电源模块等场景。压缩包共7个文件…

2026/9/16 19:22:32

群晖NAS硬盘损坏数据救援:Ubuntu 18.04完整实操指南

“当你的群晖NAS在凌晨三点突然弹出一条‘硬盘已损坏’的警报时,心跳绝对会漏半拍。”这句话几乎每个用群晖超过三年的玩家都感同身受。我曾经就遇到过一次硬盘报错,系统直接提示“存储池已降级”,当时手边既没有额外的盘位,也没有…

2026/9/16 19:22:32

企业级智能体效能管理:实现可度量、可治理的落地指南

前阵子跟几个做企业数字化架构的朋友聊天,大家不约而同提到一个尴尬的现状:模型选型越来越强,Demo 越跑越顺,可一旦进入生产环境,智能体应用就开始“失控”——有的回答质量忽高忽低,有的链路频繁报错&…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/16 0:04:09

PHP源码部署实战:从环境配置到运行情侣游戏全攻略

简介:这是一套面向情侣互动场景的PHP完整源码,集成情侣飞行棋、真心话大冒险、情趣骰子等玩法,并内置完整分销制度,可自定义多种返佣比例,源码完全开源无加密,支持微信无感自动授权登录与第三方授权&#x…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/15 21:31:11

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码