)
Grafana Loki 版本发布流程如何安全补丁升级 Go 版本Patch Go version【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki导读当上游 Go 官方发布安全修复版本后使用受影响 Go 工具链构建的 Grafana Loki 二进制文件同样存在风险维护者需要及时将易受攻击的 Go 版本升级为非易受攻击版本。本文基于 Loki 仓库中 patch-go-version.md 官方流程完整讲解从定位目标版本、修改 Makefile、重新生成发布工作流到提交 Pull Request 的全过程并深入到 Makefile 目标、go-version-bump.sh脚本与 Jsonnet 生成管线的实现细节帮助你在main或release-MAJOR.MINOR.x分支上独立完成一次 Go 版本补丁升级。背景为什么需要手动补丁 Go 版本Loki 使用 Go 工具链构建所有二进制与容器镜像。Go 官方在发现安全漏洞如标准库中的高危 CVE后会发布新的 patch 版本例如从1.20.5升级到1.20.6。由于 Go 版本在 Loki 仓库中被多处以硬编码方式维护只修改一处远远不够因此官方流程要求按固定步骤统一更新。从当前仓库Makefile可见# Ensure you run make update-go-version after changing this GO_VERSION : 1.26.6Makefile 中明确注释了「修改后必须运行make update-go-version」说明 Go 版本是一个需要联动更新的全局变量而不是一处孤立的配置。升级前置准备确认目标 Go 版本执行任何修改之前先确定要升级到的具体 Go 版本号。判定依据包括Go 官方安全公告中标注的修复版本通过漏洞扫描工具如govulncheck在当前构建工具链中检测到的受影响版本目标发布分支main或release-MAJOR.MINOR.x当前使用的版本与期望版本之间的差异。Loki 仓库本身也内置了govulncheck的 CI 检查govulncheck.yml它在 PR 涉及 Go 源码、go.mod或go.sum变更时自动运行env: GO_VERSION: 1.26.6 GOVULNCHECK_VERSION: v1.3.0并使用符号可达性分析govulncheck -modesource -showverbose ./...只报告从 main 包实际可达的漏洞可以据此判断当前 Go 版本是否存在需要立即修补的问题。第一步修改 Makefile 中的 GO_VERSION打开仓库根目录的 Makefile将GO_VERSION更新为目标版本例如GO_VERSION : 1.26.6 # 修改前1.26.5GO_VERSION在构建系统中承担着「单一事实来源」的角色其下游使用点包括BUILD_IMAGE : golang:$(GO_VERSION)Makefile所有在容器内执行的构建yacc/protobuf 生成、release 构建等使用的基础镜像OCI_BUILD_ARGS : --build-arg GO_VERSION$(GO_VERSION) --build-arg BUILD_IMAGE$(BUILD_IMAGE)MakefileDocker / Buildx 构建 OCI 镜像时传入的构建参数goversion目标echo $(GO_VERSION)Makefile用于输出当前版本号。第二步运行 make release-workflows 重新生成发布工作流Loki 的发布相关 GitHub Actions 工作流不是手写的 YAML而是由 Jsonnet 模板生成的。修改 Go 版本后必须重新生成这些工作流否则发布流水线仍会使用旧的 Go 版本构建。make release-workflows目标的定义如下Makefile.PHONY: release-workflows release-workflows: ifeq ($(BUILD_IN_CONTAINER),true) $(run_in_container) else pushd $(CURDIR)/.github jb update popd jsonnet -SJ .github/vendor -m .github/workflows -V GO_VERSION$(GO_VERSION) .github/release-workflows.jsonnet endif该目标的行为取决于BUILD_IN_CONTAINER默认true默认情况下整个生成过程在golang:$(GO_VERSION)容器内执行保证工具链一致若在本机执行BUILD_IN_CONTAINERfalse则会先运行jb update拉取 jsonnet-bundler 依赖再调用jsonnet将 release-workflows.jsonnet 渲染为.github/workflows/下的 YAML 文件并通过-V GO_VERSION$(GO_VERSION)把 Makefile 中的版本注入模板。在 release-workflows.jsonnet 中可以看到版本的注入点local goVersion std.extVar(GO_VERSION); local buildImage golang:%s % goVersion;buildImage随后被用于生成patch-release-pr.yml、minor-release-pr.yml、release.yml、check.yml、images.yml等全部发布工作流中的基础镜像与 Go 版本环境变量。仓库还提供了release-workflows-check目标Makefile它会重新生成工作流并用git diff --exit-code对比差异用于 CI 中校验生成结果与提交内容一致$(MAKE) release-workflows echo Checking diff git diff --exit-code --ignore-space-at-eol -- .github/workflows/*release* || (echo Please build release workflows by running make release-workflows false)第三步运行 make update-go-version 统一更新所有相关文件这是整个流程的核心一步。make update-go-version目标定义如下Makefileupdate-go-version: goversion release-workflows tools/go-version-bump.sh $(GO_VERSION)它依赖goversion先打印当前版本与release-workflows先重新生成发布工作流随后执行 tools/go-version-bump.sh 脚本由脚本自动批量替换仓库中所有引用 Go 版本的位置。脚本的核心逻辑tools/go-version-bump.sh会排除operator与vendor目录然后依次更新四类文件go.mod 中的 Go 指令查找所有含^go的go.mod将go x.y.z替换为目标版本当前根模块为go 1.26.6见 go.modprint_green Updating version in go.mod ${VERSION} find ${EXCLUDE_DIRS[]} -type f -name go.mod -exec grep -lE ^go {} \; | while read -r x; do ${SED} -i -re s,go [0-9\.],go ${VERSION},g ${x} doneDockerfile 中的 golang 基础镜像查找所有FROM golang:的Dockerfile*文件更新镜像标签${SED} -i -re s,golang:[0-9\.],golang:${VERSION},g ${x}工作流中的GO_VERSION:环境变量更新.github/workflows/*.yml中形如GO_VERSION: x.y.z的声明例如 build-loki-binary.yml 与 govulncheck.yml 中的GO_VERSION: 1.26.6。工作流中的go-version:配置更新actions/setup-go使用的go-version: x.y.z参数如 lint-jsonnet.yml、logql-bench.yml、logql-correctness.yml、querytee-images.yml、verify-release-workflow.yaml 等。macOS 注意事项脚本使用 GNU sed 语法BSD 版sed无法兼容。若在 macOS 上执行请先通过brew install gnu-sed安装脚本会自动检测并使用gsedtools/go-version-bump.sh。脚本做了什么与没做什么值得注意该脚本不修改.github/release-workflows.jsonnet模板本身模板始终从std.extVar(GO_VERSION)读取版本也不触碰operator/与vendor/目录下的 go.mod 或 Dockerfile——这些目录由 Operator 项目独立维护其 Go 工具链。因此升级后应使用git status与git diff核对变更范围确认根目录与各子模块的go.mod均已更新所有Dockerfile*的golang:基础镜像已更新.github/workflows/下所有GO_VERSION与go-version已更新由release-workflows重新生成的发布工作流 diff 符合预期。第四步提交 Pull Request 与目标分支选择完成上述修改后将所有变更提交并打开 Pull Request。目标分支的选择取决于补丁性质main分支适用于常规的安全补丁升级后续会随下一次发布Weekly / Minor Release合入release-MAJOR.MINOR.x分支适用于需要为已发布的维护版本立即修复漏洞的场景。Loki 的补丁发布工作流 patch-release-pr.yml 恰好针对release-[0-9].[0-9].x分支运行见 release-workflows.jsonnet支持always-bump-patch版本策略配合升级后的 Go 版本构建并发布补丁版本。提交 PR 时可在 PR 描述中注明升级前后版本与对应的 Go 安全公告PR 通过后CI 中的govulncheck、重新生成的发布工作流检查release-workflows-check会自动验证新工具链的安全性。常见问题与排查现象可能原因处理方式make release-workflows在本地报错缺少 jsonnet / jsonnet-bundler使用默认的容器内执行保持BUILD_IN_CONTAINERtrue脚本在 macOS 上 sed 报错BSD sed 语法不兼容安装 gnu-sed脚本会自动使用gsed发布工作流 diff 与预期不一致未重新生成或 jsonnetfile 依赖过期重新运行make release-workflows必要时运行make update-loki-release-sha更新 loki-release 依赖 SHA提交后 CI 报「Please build release workflows」生成结果与提交内容不一致重新运行make release-workflows并提交生成结果小结补丁 Go 版本是 Loki 发布维护流程中的高频安全操作核心在于「一个变量、两级生成、一次脚本」在 Makefile 修改GO_VERSIONmake release-workflows基于 Jsonnet 模板重新生成全部发布工作流make update-go-version通过 go-version-bump.sh 批量更新 go.mod、Dockerfile 基础镜像与 CI 工作流中的版本声明向main或release-MAJOR.MINOR.x分支提交 PR交由 CI 校验。掌握这套流程后你可以在 Go 安全公告发布后第一时间为 Loki 完成工具链升级确保发布产物不再受已知漏洞影响。【免费下载链接】lokiLike Prometheus, but for logs.项目地址: https://gitcode.com/GitHub_Trending/lok/loki创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考