ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Tyk 插件编译器镜像(tyk-plugin-compiler)完全指南:构建、测试与发布 Go 插件

Tyk 插件编译器镜像(tyk-plugin-compiler)完全指南:构建、测试与发布 Go 插件 API网关后端云原生【免费下载链接】tykOpen Source API and AI Gateway supporting REST, GraphQL, TCP, gRPC and MCP (Model Context Protocol)项目地址https://gitcode.com/gh_mirrors/ty/tyk点击查看免费下载本文以 Tyk 开源仓库 ci/images/README.md 为核心结合仓库内 Dockerfile、构建脚本、测试套件与发布流水线源码系统讲解如何使用官方tyk-plugin-compiler镜像为 Tyk Gateway 构建 Go 插件goplugin、验证插件可用性以及自行重建该镜像的完整流程。读完本文你将掌握插件编译器的正确用法、build.sh底层参数与输出命名规则并理解 Go 插件与 Gateway 之间严格的编译环境一致性要求。一、为什么需要插件编译器Tyk Gateway 支持通过 Go 插件goplugin扩展请求处理逻辑。插件本质上是以-buildmodeplugin编译出的原生共享对象.so文件由 Gateway 在运行时通过plugin.Open加载。Go 官方 plugin 包文档原文档引用的权威来源对插件使用提出了非常苛刻的约束运行时崩溃几乎必然发生除非程序应用及其全部插件使用完全相同的工具链版本、相同的构建标签、以及某些标志与环境变量的相同取值编译。除非应用与插件的所有公共依赖都从完全相同的源码构建否则也很可能出现类似的崩溃问题。这正是 Tyk 提供tyk-plugin-compiler官方镜像的原因该镜像内置了与对应 Gateway 发布版本完全一致的 Go 工具链、依赖源码与构建标志-trimpath、CC、CGO_ENABLED、GOOS、GOARCH等从而把插件与 Gateway 二进制必须逐字节一致这一复杂要求封装进一个可复现的 Docker 镜像中。仓库中 docs/plugins/go-development-flow.md 也明确建议必须使用 Tyk Plugin Compiler Docker 镜像来构建与官方 Gateway 发布版兼容的插件。关于 Go modules 的历史说明原文档开头记录了一条重要的历史兼容性变更以删除线标注的历史行为3.2 版本之前Tyk Gateway 使用vendor目录管理依赖如果你的插件 vendor 了 Tyk Gateway 也使用的模块该模块会被 Tyk 使用的版本覆盖自 3.2 起Tyk 改用go.modGo modules你的 vendor 代码不再被 Tyk 的版本覆盖。这意味着现代版本下插件可以安全地携带自己的依赖但前提是共享依赖的版本必须与 Gateway 完全一致详见下文常见兼容性问题。二、使用镜像构建插件2.1 最简单的构建命令假设你位于插件源码目录且要为 v3.0.4 版本的 Gateway 构建插件原文档给出的核心命令是% docker run --rm -v pwd:/plugin-source tykio/tyk-plugin-compiler:v3.0.4 testplugin.so命令含义拆解参数说明--rm容器运行结束后自动删除-v \pwd:/plugin-source| 把当前插件源码目录挂载为容器内的/plugin-source这是镜像约定的插件源码挂载点tykio/tyk-plugin-compiler:v3.0.4镜像名 标签标签必须与目标 Gateway 版本一致testplugin.so插件名位置参数 1也是输出的.so文件名执行后当前目录会出现testplugin.so这个文件就是需要写进 API 定义API Definition的插件产物。2.2 构建脚本的完整参数源码级当前仓库中镜像的入口脚本是 ci/images/plugin-compiler/data/build.sh。结合脚本源码build.sh一共接受4 个位置参数参数含义说明1.plugin_name插件名如vendor-plugin.so必填为空时打印 usage 并退出2.plugin_id可选插件构建标识用于设置构建目录/opt/.../plugin_{插件名}{plugin_id}同时用于改写 go.mod 模块路径3.GOOS可选覆盖目标操作系统默认取go env GOOS4.GOARCH可选覆盖目标 CPU 架构默认取go env GOARCH输出文件命名规则脚本第 55 行{plugin_name去掉.so}_{GATEWAY_VERSION}_{GOOS}_{GOARCH}.so例如脚本注释中给出的示例./build.sh plugin.so - plugin_v5.13.0_linux_amd64.so其中GATEWAY_VERSION是从镜像的GITHUB_TAG环境变量形如v5.13.0中用正则v(\d).(\d).(\d)解析出来的旧版脚本用 perl新版 plugin-compiler-ng 的 build.sh 改为 Bash 正则二者逻辑一致。如果你不传 GOOS/GOARCH即用默认值构建本机架构则输出文件名不带版本与架构后缀直接是传入的插件名。2.3 构建脚本内部做了什么从 ci/images/plugin-compiler/data/build.sh 的源码可以看到一次构建的完整流程这也是理解插件编译器工作原理的关键准备构建目录把/plugin-source下的源码复制到$WORKSPACE_ROOT/plugin_{插件名}{plugin_id}WORKSPACE_ROOT即$TYK_GW_PATH的上级目录。ensureGoMod函数若插件没有go.mod自动执行go mod init tyk.internal/tyk_plugin{plugin_id}创建若提供了plugin_id则把插件原有的 module 路径改写为tyk.internal/tyk_plugin{plugin_id}并同步替换所有.go文件中的 import 路径——这正是官方文档所说提供build_id参数可确保同一插件可被重复构建的底层实现规避 Go 插件重复加载的已知问题若 module 路径不含点号会输出 WARN 建议使用github.com/org/plugin-repo这种带域名的路径以防冲突。创建 Go workspacego work init ./tyk go work use ./plugin_xxx让插件与镜像内置的 Gateway 源码处于同一 workspace确保共享依赖解析一致。可选环境变量GO_GET1时执行go get github.com/TykTechnologies/tyk{GITHUB_SHA}GO_TIDY1时执行go mod tidyDEBUG1时开启set -x并做 git 初始化以便查看差异。执行编译CC$CC CGO_ENABLED1 GOOS$GOOS GOARCH$GOARCH go build -buildmodeplugin -trimpath -tagsgoplugin${BUILD_TAG:,$BUILD_TAG} -o $plugin_name关键点-buildmodeplugin共享对象、-trimpath与 Gateway 构建标志一致、-tagsgopluginTyk 插件构建标签、CGO_ENABLED1启用 cgo插件可依赖 C 库。产物回写把构建出的*.so移动回/plugin-source即宿主机挂载目录并清理 workspace 文件。2.4 交叉编译通过传入 GOOS/GOARCH 即可交叉编译。原文档的测试流程详见下文展示了 arm64 交叉编译的用法测试脚本 ci/tests/plugin-compiler/test.sh 第 26 行docker run --rm -e GOARCHarm64 -v $PLUGIN_SOURCE_PATH:/plugin-source $PLUGIN_COMPILER_IMAGE plugin.so即通过-e GOARCHarm64环境变量覆盖目标架构。注意构建脚本中 GOOS/GOARCH 的默认值取自go env显式传参可以覆盖默认值。三、把插件接入 API 定义构建出的.so文件需要写进 API 定义API Definition的custom_middleware配置中。仓库内测试插件 ci/tests/plugin-compiler/testdata/test-plugin/main.go 展示了插件代码的最小形态——一个导出的AddFooBarHeader(rw http.ResponseWriter, r *http.Request)函数通过r.Header.Add(Foo, Bar)向请求注入自定义头package main import ( html/template net/http github.com/Masterminds/sprig/v3 github.com/kr/pretty github.com/TykTechnologies/tyk/ctx github.com/TykTechnologies/tyk/log ) var logger log.Get() // AddFooBarHeader adds custom Foo: Bar header to the request // //nolint:deadcode func AddFooBarHeader(rw http.ResponseWriter, r *http.Request) { r.Header.Add(Foo, Bar) logger.Info(Test) api : ctx.GetDefinition(r) if api ! nil { logger.Info(API Definition, pretty.Sprint(api)) } // Set up variables and template. tpl : Hello {{.Name | trim | lower}} // Get the Sprig function map. template.Must(template.New(test).Funcs(sprig.FuncMap()).Parse(tpl)) } func main() {}该插件的 go.mod 依赖了Masterminds/sprig、kr/pretty以及github.com/TykTechnologies/tyk含一条replace指令是一个能真实检验共享依赖版本对齐能力的测试用例。在 API 定义中注册插件时通过custom_middleware的post钩子挂载参考测试套件中的 API 定义与 loadtest-gate.sh 生成的示例{ custom_middleware: { pre: [], post: [ { name: AddFooBarHeader, path: /gate/plugin.so, require_session: false } ], post_key_auth: [], auth_check: {}, response: [], driver: goplugin } }其中driver必须为gopluginpath指向 Gateway 可访问的.so文件位置name为插件中导出的函数名。四、测试镜像端到端验证插件原文档给出了完整的镜像测试流程核心思想是用插件编译器构建测试插件 → 启动一个运行了该插件的 Gateway → 发起 HTTP 请求验证插件行为。4.1 原文档的测试流程% export tagv2.9.5 % rm -v testplugin/*.so % docker run --rm -v pwd/testplugin:/plugin-source tykio/tyk-plugin-compiler:${tag} testplugin.so % docker-compose -f test.yml up ....启动后在 Gateway 日志中查找msgAPI Loaded api_id api_nameGoplugin test确认插件 API 加载成功。然后发起请求验证插件行为% curl http://localhost:8080/goplugin/headers { headers: { Accept: */*, Accept-Encoding: gzip, Foo: Bar, Host: httpbin.org, User-Agent: curl/7.68.0, X-Amzn-Trace-Id: Root1-606f4317-18581ac0164b5496739a5b32 } }响应头中出现了Foo: Bar说明插件成功执行并注入了自定义头。还可以用jq做自动化断言% curl http://localhost:8080/goplugin/headers | jq .headers.Foo Bar true4.2 仓库中的自动化测试套件仓库在 ci/tests/plugin-compiler/ 下提供了完整的自动化测试套件其说明文档 ci/tests/plugin-compiler/README.md 明确指出插件兼容性要求极其严格并引用 Go plugin 包的官方警告。该测试套件可验证以下步骤本地构建 plugin compiler 镜像插件编译plugin compilation插件加载tyk load -f -s即tyk plugin load。测试脚本ci/tests/plugin-compiler/test.sh 的逻辑# 拉取对应 tag 的 Gateway 与编译器镜像可用环境变量覆盖 export GATEWAY_IMAGE${GATEWAY_IMAGE:-tykio/tyk-gateway:${tag}} export PLUGIN_COMPILER_IMAGE${PLUGIN_COMPILER_IMAGE:-tykio/tyk-plugin-compiler:${tag}} docker pull -q $GATEWAY_IMAGE docker pull -q $PLUGIN_COMPILER_IMAGE # 编译 amd64 插件 docker run --rm -v $PLUGIN_SOURCE_PATH:/plugin-source $PLUGIN_COMPILER_IMAGE plugin.so # 交叉编译 arm64 插件 docker run --rm -e GOARCHarm64 -v $PLUGIN_SOURCE_PATH:/plugin-source $PLUGIN_COMPILER_IMAGE plugin.so # 启动 Gateway 并验证 docker compose up -d --wait --force-recreate curl http://localhost:8080/goplugin/headers | jq -e .headers.Foo Bar其中GATEWAY_IMAGE与PLUGIN_COMPILER_IMAGE环境变量支持测试未发布到 Docker Hub 的本地镜像这正是 CI 在发布流水线中对构建产物做冒烟测试时使用的机制。Taskfile 方式基于 taskfile.dev测试套件目录下的 Taskfile.yml# 列出可用目标 task -l # 针对某个发布镜像运行插件子测试 task test:qa-plugin imagetykio/tyk-plugin-compiler:v5.3.9-rc4 # 对整个 tag 运行冒烟测试 ./test.sh v5.2.1Taskfile 的默认变量变量名默认值tagv0.0.0basetykio/golang-cross:1.22-bullseyedockerfileci/images/plugin-compiler/Dockerfileimageinternal/plugin-compilersha$(git rev-parse HEAD)root$(git rev-parse --show-toplevel)五、构建插件编译器镜像原文档指出构建镜像本身仅供信息参考正常使用者直接拉取官方镜像即可但仓库内保留了完整的构建方式。5.1 原文档给出的历史构建命令docker build --build-arg TYK_GW_TAGv2.8.4 -t tykio/tyk-plugin-compiler:v2.8.4 -f images/plugin-compiler/Dockerfile .其中TYK_GW_TAG可以是任意 GitHub ref。需要说明的是这是早期版本的参数。在当前仓库中插件编译器的构建参数已演进为GITHUB_TAG/GITHUB_SHA详见下文TYK_GW_TAG属于历史用法。5.2 当前仓库的 Dockerfile 与构建参数当前镜像定义在 ci/images/plugin-compiler/Dockerfile要点ARG BASE_IMAGEtykio/golang-cross:1.26-bullseye FROM ${BASE_IMAGE} ENV TYK_GW_PATH/go/src/github.com/TykTechnologies/tyk ENV GO111MODULEon ENV PLUGIN_SOURCE_PATH/plugin-source RUN mkdir -p $TYK_GW_PATH $PLUGIN_SOURCE_PATH # 移除可能引入 CVE 的工具 RUN apt-get purge -y --allow-remove-essential --auto-remove wget curl automake cmake python* docker* libsqlite* qemu* \ rm -f /usr/bin/passwd /usr/sbin/adduser /usr/bin/goreleaser ADD go.mod go.sum $TYK_GW_PATH WORKDIR $TYK_GW_PATH RUN --mounttypecache,mode0755,target/go/pkg/mod \ --mounttypecache,mode0755,target/root/.cache/go-build \ go mod download ADD . $TYK_GW_PATH ARG GITHUB_SHA ARG GITHUB_TAG ENV GITHUB_SHA${GITHUB_SHA} ENV GITHUB_TAG${GITHUB_TAG} ARG BUILD_TAG ENV BUILD_TAG${BUILD_TAG} ARG GOFIPS140 ENV GOFIPS140${GOFIPS140} # 构建一个用于测试插件加载的 Gateway 测试二进制 RUN --mounttypecache,mode0755,target/go/pkg/mod \ --mounttypecache,mode0755,target/root/.cache/go-build \ GOBIN/usr/local/bin go install -tagsgoplugin${BUILD_TAG:,$BUILD_TAG} -trimpath . COPY ci/images/plugin-compiler/data/build.sh /build.sh RUN chmod x /build.sh ENTRYPOINT [/build.sh]关键设计基础镜像tykio/golang-cross带交叉编译能力的 Go 工具链镜像且版本与 Gateway 发布所用工具链一致这是插件 ABI 兼容的根基内置 Gateway 源码与依赖镜像把整个 Tyk 仓库源码ADD到$TYK_GW_PATH并预下载全部模块依赖挂载 BuildKit 缓存加速使插件在 workspace 中直接对齐 Gateway 的依赖图预装 Gateway 测试二进制go install -tagsgoplugin ...生成的tyk二进制用于tyk plugin load自测见下文第六节的验证方法入口即构建脚本ENTRYPOINT [/build.sh]所以docker run时直接传入插件名参数即可。5.3 用 Taskfile 构建仓库提供了 [ci/images/plugin-compiler/Taskfile.yml]ci/images/plugin-compiler/Taskfile.yml封装了两种构建方式# 标准构建amd64 task build # 无缓存构建输出完整日志便于排查 task build-nocache # 以 bash 交互式进入镜像调试 task test其内部等价于以tag、sha变量注入docker build --build-arg GITHUB_TAG{{.tag}} --build-arg GITHUB_SHA{{.sha}} \ --platformlinux/amd64 --rm -t internal/plugin-compiler \ -f ci/images/plugin-compiler/Dockerfile .5.4 发布流水线中的镜像构建在官方发布流水线配置 ci/goreleaser/goreleaser-5.0.yml 中plugin-compiler 镜像随 Gateway 一起发布标签规则为tykio/tyk-plugin-compiler:{{.Tag}}与tykio/tyk-plugin-compiler:v{{.Major}}.{{.Minor}}{{.Prerelease}}构建时注入- --build-argBASE_IMAGEtykio/golang-cross:{{ .Env.GOLANG_CROSS }} - --build-argGITHUB_SHA{{ .Env.GITHUB_SHA }} - --build-argGITHUB_TAG{{ .Tag }}这印证了镜像标签与 Gateway 版本一一对应的发布约定——选择哪个标签的编译器镜像就必须把它用于哪个版本的 Gateway。六、加载验证与兼容性排查6.1 用 Gateway 自测二进制验证插件可加载镜像内置的 Gateway 测试二进制支持tyk plugin load命令无需启动完整 Gateway 即可验证插件能否被加载。官方开发流程文档 docs/plugins/go-development-flow.md 给出./tyk-release-5.3.6/tyk plugin load -f plugins/testplugin.so -s AuthCheck成功输出类似timeOct 14 13:39:55 levelinfo msg--- Go custom plugin init success! ---- [fileplugins/testplugin.so, symbolAuthCheck] loaded ok, got 0x76e1aeb52140测试套件 ci/tests/plugin-compiler/README.md 中的加载验证正是tyk load -f -s步骤下一代镜像的发布门禁 loadtest-gate.sh 也以tyk plugin load -f /gate-plugin.so -s AddFooBarHeader的输出中出现loaded ok作为通过条件并以curl断言响应体等于Bar作为最终门禁——与本文第四节的验证思路完全一致。6.2 常见构建标志不一致导致的错误从 docs/plugins/go-development-flow.md 可以提取最典型的失败场景插件与 Gateway 的构建标志不一致时plugin.Open会报错例如tyk: error: unexpected error: plugin.Open(plugins/testplugin): plugin was built with a different version of package internal/goarch, try --help官方文档给出的排查原则-trimpath、-race等构建标志必须一致Go 工具链 / 构建环境必须完全一致交叉编译时CCCGO必须与运行时一致CGO_ENABLED1、GOOS、GOARCH必须与运行环境匹配。排查手段用go version -m分别查看 Gateway 与插件的构建信息并逐项比对go version -m tyk go version -m plugin.so重点比对build段的-buildmode、-compiler、-race、-tags、-trimpath、CGO_ENABLED、GOARCH、GOOS等条目。另外可用nm -gD testplugin.so列出插件导出的符号确认AddFooBarHeader、AuthCheck等函数确实被编译进.so。6.3 依赖相关兼容性问题官方文档还总结了三类依赖场景Gateway 的依赖没有go.mod构建时生成 pseudo version插件加载时报版本不匹配。解决移除该依赖或改用带go.mod的版本。Gateway 与插件共享依赖插件必须使用与 Gateway完全相同的版本并保持同步。插件需要共享依赖的不同版本若为/v4这种主版本差异Go 视作独立包可共存若仅为 minor/patch 差异插件很可能加载失败。6.4 下一代编译器镜像plugin-compiler-ng仓库中还维护了下一代插件编译器镜像 ci/images/plugin-compiler-ng/它把镜像拆为稳定基础层Dockerfile.base含 glibc 链接 sysroot、交叉工具链、build.sh与validate-plugin.sh刻意不携带 Go 工具链与 Gateway 源码与随版本发布层Dockerfile.release叠加与 Gateway 完全一致的 Go 工具链与源码。其入口脚本 data/build.sh 与旧版参数完全兼容并新增了基于固定 glibc sysroot默认 2.17即 RHEL7/CentOS7 ABI 底限选择CC与--sysroot保证插件 glibc 符号下限与旧镜像一致构建后自动校验validate-plugin.sh用file/readelf检查 ELF 架构、用go version -m核对工具链与依赖、用readelf --version-info检查 GLIBC 符号上限、校验ee/ee-fips版本的构建标签与 FIPS 证据任何一项不匹配都会在构建时给出可操作的错误信息可用VALIDATE0关闭EDITIONce|ee|ee-fips版本选择及基于发布清单数据驱动的架构门禁。七、总结围绕 ci/images/README.md 及其仓库源码可以归纳出使用 Tyk 插件编译器的完整心智模型镜像选择tykio/tyk-plugin-compiler:tag的 tag 必须与目标 Gateway 版本一致构建插件docker run --rm -v $(pwd):/plugin-source tykio/tyk-plugin-compiler:vX.Y.Z myplugin.so产物出现在当前目录参数扩展可传plugin_id规避重复加载、隔离 module、GOOS/GOARCH交叉编译验证tyk plugin load -f xxx.so -s Symbol验证可加载启动 Gateway 后curl断言插件行为如Foo: Bar头重建镜像信息用途docker build --build-arg GITHUB_TAG... --build-arg GITHUB_SHA... -f ci/images/plugin-compiler/Dockerfile .或用仓库 Taskfile / 发布流水线goreleaser自动完成兼容性红线工具链版本、构建标志-trimpath、-tagsgoplugin、CGO_ENABLED1与共享依赖版本必须与 Gateway 逐项一致这也是整个插件编译器存在的最根本理由。相关仓库资源索引镜像说明文档ci/images/README.md镜像 Dockerfileci/images/plugin-compiler/Dockerfile构建入口脚本ci/images/plugin-compiler/data/build.sh构建 Taskfileci/images/plugin-compiler/Taskfile.yml测试套件ci/tests/plugin-compiler/README.md、ci/tests/plugin-compiler/test.sh测试插件源码ci/tests/plugin-compiler/testdata/test-plugin/main.go发布流水线ci/goreleaser/goreleaser-5.0.yml下一代镜像ci/images/plugin-compiler-ng/Go 插件开发流程含调试与排错docs/plugins/go-development-flow.md赞分享API网关后端云原生【免费下载链接】tykOpen Source API and AI Gateway supporting REST, GraphQL, TCP, gRPC and MCP (Model Context Protocol)项目地址https://gitcode.com/gh_mirrors/ty/tyk点击查看免费下载相关推荐Pixelle-Video深度解析5大技术优势打造全自动AI短视频创作引擎Pixelle Video深度解析5大技术优势打造全自动AI短视频创作引擎 Pixelle Video是一款开源的AI全自动短视频引擎它正在重新定义内容创作人工智能AI 应用音视频媒体生成Tyk Gateway跨平台编译为不同架构构建可执行文件Tyk Gateway跨平台编译为不同架构构建可执行文件 Tyk Gateway作为开源API网关解决方案支持REST、GraphQL、TCP和gRPC协议API网关后端云原生Super Productivity 插件 API 包发布指南super-productivity/plugin-api 的构建、测试与 npm 发布全流程Super Productivity 插件 API 包发布指南super productivity/plugin api 的构建、测试与 npm 发布全流程前端UI组件设计系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表