news 2026/9/12 11:42:21

Argo CD 内部 Fork 维护实战:从自建镜像到自定义版本发布

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Argo CD 内部 Fork 维护实战:从自建镜像到自定义版本发布

Argo CD 内部 Fork 维护实战:从自建镜像到自定义版本发布

【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd

本文面向需要从自维护 fork 发布自定义 Argo CD 镜像乃至自定义版本的团队,以及希望在本仓库之外验证发布流程的维护者。文章以 maintaining-internal-argo-cd-forks.md 为骨架,结合仓库内真实工作流源码,完整讲解上游镜像的发布拓扑、fork 所需的 GitHub Actions 变量与 Secrets 配置、fork 版本发布的启用条件,以及触发发布时的关键避坑点。读完本文,你将能够把 fork 构建产物定向推送到自有镜像仓库,并在不污染上游的前提下跑通自定义版本的完整发布链路。

前置说明:绝大多数 Argo CD 贡献者并不需要本节内容,常规开发与贡献流程请直接参考常规开发者指南。本节面向两类场景:需要发布自定义镜像或自定义版本的团队,以及需要在测试环境演练发布流程的 Argo CD 维护者。

一、理解上游镜像的发布拓扑:双注册表模型

在动手配置 fork 之前,先明确 Argo CD 上游镜像"发布到哪里、以什么标签发布"。从仓库中的 image.yaml 与 release.yaml 两个工作流可以还原出完整的发布拓扑:

构建来源推送目标标签形态用途
官方 release 标签(vX.Y.Z*quay.io/argoproj/argocd(主注册表,fork 可用IMAGE_*变量改写)v<MAJOR>.<MINOR>.<PATCH>-rc<X>预发布正式发布版本镜像 + 对应的 provenance 证明
上游 master 分支 push主注册表quay.io/argoproj/argocdlatest持续刷新最新标签
上游 master 分支 pushghcr.io/argoproj/argo-cd/argocd<VERSION>-<commit SHA8>(提交标签)cd.apps.argoproj.io固定精确 SHA 使用,同时附带 provenance

也就是说,上游采用"Quay 主镜像 + GHCR 提交级镜像"双通道:Quay 承载latest与 release 标签,GHCR 承载按提交哈希打标的镜像与签名证明,避免用大量提交标签污染 Quay。

fork 的关键区别在于:

  • fork 继承完全相同的发布行为,但所有目标指向你自定义的 registry/namespace;
  • fork 构建不会部署到cd.apps.argoproj.io(该部署 job 在 image.yaml 中显式以github.repository == 'argoproj/argo-cd'为条件);
  • GHCR 的推送目标默认就是 fork 自己的 GitHub 仓库 Packages 命名空间。

二、从 fork 的 master 分支发布自定义镜像

fork 的每次 master push 都会触发Image工作流(见 image.yaml 的on.push触发条件)。要让构建产物进入你的私有仓库,只需把工作流变量从argoproj指到你的 registry/namespace——其中IMAGE_NAMESPACE是必改项,因为它把工作流从"上游模式"切换到"fork 模式"。

2.1 配置 GitHub Actions Variables(仓库级变量)

在 fork 仓库的Settings → Secrets and variables → Actions → Variables中配置下表变量:

变量名默认值是否需要覆盖说明
IMAGE_NAMESPACEargoproj必须覆盖Quay 主镜像的命名空间;覆盖它即切换到 fork 模式
IMAGE_REPOSITORYargocd视需要Quay 主镜像的仓库名
GHCR_NAMESPACE${{ github.repository }}(即<你的GitHub用户名>/<fork仓库名>极少需要覆盖GHCR 镜像的命名空间
GHCR_REPOSITORYargocd视需要GHCR 镜像的仓库名

这些变量在 image.yaml 的set-varsjob 中通过${VAR:-default}语法读取,最终推导出的完整镜像名为:

quay.io/$IMAGE_NAMESPACE/$IMAGE_REPOSITORY ghcr.io/$GHCR_NAMESPACE/$GHCR_REPOSITORY

一个值得注意的源码细节set-vars中还有一层 GHCR 发布护栏——只有当GITHUB_REPOSITORY == 'argoproj/argo-cd',或者GHCR_NAMESPACE不以argoproj/开头时,才允许向 GHCR 推送(image.yaml)。这意味着 fork 若把GHCR_NAMESPACE误设成argoproj/xxx,工作流会拒绝推送并打印提示。这正是文档要求"fork 需覆盖 GHCR_* 或保持默认"的原因:默认值指向 fork 自身仓库,天然满足护栏条件。

2.2 完整示例:推到 Quay 个人命名空间

假设你的 GitHub 账号是my-user,fork 仓库名为my-argo-cd-fork,希望 release 镜像推到quay.io/my-quay-user/argocd,那么只需配置一个变量:

IMAGE_NAMESPACE = my-quay-user

效果:

  • master 构建镜像发布到quay.io/my-quay-user/argocd:latest
  • 提交级标签镜像及其 attestation 发布到 fork 仓库的 GitHub Packages(GHCR)下,即ghcr.io/my-user/my-argo-cd-fork/argocd:<VERSION>-<SHA8>

2.3 fork 模式下的构建平台与推送条件

Image工作流对构建平台做了区分(image.yaml):

  • master分支的 push:构建linux/amd64, linux/arm64, linux/s390x, linux/ppc64le四平台多架构镜像;
  • 对 PR:默认仅构建linux/amd64(除非 PR 带有test-multi-image标签)。

同时,build-onlybuild-and-publish两个 job 都以(github.repository == 'argoproj/argo-cd' || image_namespace != 'argoproj')作为执行条件(image.yaml、image.yaml)——这再次印证:fork 只要覆盖IMAGE_NAMESPACE即可正常触发构建与推送,且 push 事件走build-and-publish,PR 事件走build-only

2.4 配置 GitHub Actions Secrets(凭据)

仅配置变量还不够,工作流还需要主注册表的推送凭据。在 fork 仓库的Settings → Secrets and variables → Actions → Secrets中配置:

Secret 名称用途
RELEASE_QUAY_USERNAME推送到 Quay 的账号
RELEASE_QUAY_TOKEN推送到 Quay 的令牌(具有仓库写入权限)

在 image.yaml 中,这两个 Secret 被透传给可复用的 image-reuse.yaml,后者负责docker login quay.io、Buildx 多平台构建、推送以及 cosign 签名(image-reuse.yaml)。GHCR 一侧则无需额外配置——它复用secrets.GITHUB_TOKENgithub.actor即可完成认证。

提示:若 fork 只想构建不推送(例如仅做 CI 校验),build-onlyjob 不需要任何推送凭据;但 master push 触发的build-and-publish必须备齐上述 Quay 凭据。

三、启用 fork 版本发布(自定义 release)

发布自定义版本比发布 master 镜像多一个开关:在 fork 仓库的 Actions 变量中设置:

ENABLE_FORK_RELEASES: true

3.1 源码层面的启用条件

release.yaml 的setup-variablesjob 中,allow_fork_release需要同时满足四个条件才会置为true

GITHUB_REPOSITORY_OWNER != "argoproj" # 仓库 owner 不是 argoproj ENABLE_FORK_RELEASES == "true" # 显式开启 fork 发布 IMAGE_NAMESPACE != "argoproj" # 镜像命名空间已指向自定义目标 GITHUB_REF == refs/tags/* # 由推送 tag 触发

而整个Publish ArgoCD Release工作流的各 job(镜像构建、provenance、GoReleaser、SBOM、post-release 等)都统一以github.repository == 'argoproj/argo-cd' || allow_fork_release == 'true'作为执行门槛(如 release.yaml、release.yaml、release.yaml)。因此"仅设ENABLE_FORK_RELEASES: trueIMAGE_NAMESPACE仍为argoproj"不会生效。

同时注意setup-variablesjob 的顶层门槛(release.yaml):

if: github.repository == 'argoproj/argo-cd' || (github.repository_owner != 'argoproj' && vars.ENABLE_FORK_RELEASES == 'true' && vars.IMAGE_NAMESPACE && vars.IMAGE_NAMESPACE != 'argoproj')

即:fork 场景下IMAGE_NAMESPACE必须已设置且不等于argoproj,否则连变量计算都不会执行。

3.2 为什么必须拉取全部上游标签

setup-variablesjob 的第一步就是执行git fetch --prune --tags --force(release.yaml),GoReleaser job 也执行git fetch --force --tags(release.yaml)。原因是:

  • 发布工具需要历史标签来计算 changelog diff 与"上一个版本"(GORELEASER_PREVIOUS_TAG,见 release.yaml,由 hack/get-previous-release 计算);
  • 需要判断当前 tag 是否为最新发布(is_latest_release),决定是否移动stable标签(release.yaml)。

因此文档强调:启用 fork 发布时务必确保所有上游标签都被拉取。实践上建议 fork 时不要浅克隆,或定期同步上游 tags。

3.3 复用镜像变量与 Secrets

fork 发布完全复用第一节中的镜像变量(IMAGE_NAMESPACEIMAGE_REPOSITORY)与 Secrets(RELEASE_QUAY_USERNAMERELEASE_QUAY_TOKEN)。从 release.yaml 可见,release 镜像名直接拼接为quay.io/$IMAGE_NAMESPACE/$IMAGE_REPOSITORY:${GITHUB_REF_NAME}(即以版本 tag 为镜像标签),provenance 则指向去掉 tag 后的仓库地址。

3.4 触发发布:务必指向 fork remote

启用 fork 发布后,其余步骤与标准发布流程完全一致,但有一处关键调整:

[!WARNING] 调用hack/trigger-release.sh时,第二参数必须指向你的 fork remote(通常是origin),不能指向 upstream,否则脚本可能向官方仓库推送正式 tag。

./hack/trigger-release.sh v2.7.2 origin

这一点在 trigger-release.sh 源码中有双重保护逻辑:

  1. 脚本首先校验参数与 tag 格式:必须形如v<MAJOR>.<MINOR>.<PATCH>v<MAJOR>.<MINOR>.<PATCH>-rc<X>(trigger-release.sh);
  2. 校验当前分支必须是推导出的release-<MAJOR>.<MINOR>分支(trigger-release.sh);
  3. 若检测到目标 remote 的 URL 包含argoproj/argo-cd,会打印大段警告并强制要求 30 秒内输入y确认,否则中止(trigger-release.sh);
  4. 随后确保 release 分支与远程同步、检查本地与远程均不存在同名 tag,最后创建 tag 并 push 到指定 remote(trigger-release.sh)。

推送 tag 成功后,Publish ArgoCD Release工作流即被触发,可在 Actions 页跟踪执行。

3.5 fork 发布流程全景(对应标准发布步骤)

将以上配置串起来,fork 完成一次自定义发布共四步:

  1. 更新版本与 manifest:运行 init-release.yaml(手动触发),填写TARGET_BRANCHTARGET_VERSION(不带v前缀),该工作流会更新VERSION文件、通过make manifests-local重新生成 manifests(此时同样读取IMAGE_REGISTRY/IMAGE_NAMESPACE/IMAGE_REPOSITORY变量,见 init-release.yaml),并自动创建 PR;
  2. 合并 PR,确保CHANGELOG.mdgoreleaser.yaml等发布前置内容已就绪(参见发布流程);
  3. 在 release 分支上执行./hack/trigger-release.sh <vX.Y.Z> origin
  4. 验证产物:检查工作流状态、GitHub Release 附件、Quay 上的镜像与 provenance 是否如预期落在自定义命名空间。

fork 场景下,发布工作流的post-releasejob 中更新stable标签、创建gitops-engine/前缀 tag、在 master 分支 bumpVERSION等行为同样以github.repository == 'argoproj/argo-cd'allow_fork_release为门槛(release.yaml),因此 fork 发布是完整闭环的,产物全部归属 fork 自身仓库。

四、与发布流程相关的关键文件索引

无论是排查 fork 发布问题,还是进一步研读,以下文件是必查清单:

文件作用
docs/developer-guide/releasing.md标准发布流程(fork 发布在此基础上只改 remote 指向)
.github/workflows/image.yamlmaster 镜像构建/发布工作流,IMAGE_*/GHCR_*变量的读取处
.github/workflows/image-reuse.yaml可复用镜像构建、推送、cosign 签名工作流
.github/workflows/release.yaml版本发布工作流,ENABLE_FORK_RELEASESallow_fork_release的计算处
.github/workflows/init-release.yaml版本号与 manifests 初始化工作流
hack/trigger-release.sh发布触发脚本,含官方仓库防误推保护

实用提示:发布失败时不要删除重建同名 tag——Argo CD 的一次发布会同时产出 GitHub Release、stable 标签、Go 依赖包、镜像与 SBOM 等多类产物,删除重建不安全。正确做法是修复问题后发布下一个补丁版本(如3.2.4失败则发布3.2.5),并将失败版本标记为无效(详见 releasing.md 的 "If something went wrong" 一节)。此外,手动发布流程不被支持——镜像签名与 provenance 必须由 GitHub Actions 生成,这保证了 fork 与上游发布的供应链证明能力一致。

【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 11:42:04

Linux进程组织:从进程组到会话管理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 11:38:32

Kali Linux 2026渗透测试指令速查与实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 11:37:13

C++字符串反转:双指针法与STL实现对比

1. 反转字符串的核心思路与实现字符串反转是算法学习中最基础的练习之一&#xff0c;但恰恰是这种基础操作&#xff0c;能帮助我们理解计算机处理数据的底层逻辑。在C中&#xff0c;字符串本质上是一个字符数组&#xff0c;这意味着我们可以通过指针或索引直接访问和修改其中的…

作者头像 李华
网站建设 2026/9/12 11:32:27

DeepSeek Harness本地模型服务化实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华