ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Argo CD 原生 OCI 支持:从提案到落地——基于 OCI Registry 的 Kubernetes 清单存储与检索实践

2026/9/13 16:41:05 拓冰建站 浏览量
Argo CD 原生 OCI 支持:从提案到落地——基于 OCI Registry 的 Kubernetes 清单存储与检索实践 Argo CD 原生 OCI 支持从提案到落地——基于 OCI Registry 的 Kubernetes 清单存储与检索实践【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd导读本文围绕 Argo CD 的 first-class OCI 支持native OCI support展开系统讲解 Argo CD 如何将 OCI Registry 作为除 Git 仓库、Helm Chart 仓库之外的第三种资源来源既包含设计提案docs/proposals/native-oci-support.md中的动机、目标、媒体类型定义与安全考量也结合当前仓库中已落地的实现util/oci/client.go、reposerver/repository/repository.go与实战文档docs/user-guide/oci.md给出可复制、可运行的配置示例。读完本文你将掌握如何在 Application 中以oci://声明式消费 OCI 镜像中的 Kubernetes 清单、如何用 ORAS 打包并推送兼容 Argo CD 的 OCI 制品、如何配置私有 OCI 仓库的认证与自定义媒体类型以及其底层实现原理。一、背景为什么需要 first-class OCI 支持提案 native-oci-support.md 指出在原生支持落地之前Argo CD 获取清单只有三条途径Git 仓库、远程 Helm Chart 仓库、以及存储在 OCI Registry 中的 Helm Chart该能力由 Helm 及其底层 ORAS 库提供而非 Argo CD 自身。随着 OCI Artifacts 被业界广泛采纳用于存储镜像之外的内容将 OCI Registry 提升为一等资源来源具有直接价值。1.1 依赖削减Dependency Reduction大多数企业级 Kubernetes 环境已经具备 OCI Registry如 Docker Hub、ECR、GHCR、GCR作为镜像内容的主要载体。如果资源清单同样存放在 OCI Registry 中就无需额外搭建 Git 或 Helm 仓库基础设施从而简化开始完整使用 Argo CD 的依赖要求。1.2 市场相关性Market RelevanceGitOps 生态中的其他工具已经率先支持将 OCI Artifacts 作为 GitOps 资源的存储与检索来源。作为行业中最流行的 GitOps 工具之一Argo CD 跟进这一趋势是必要且及时的。1.3 明确的目标与非目标Goals支持从 OCI Registry 检索以任意受支持格式Kustomize、Jsonnet、Helm、plain-manifest、CMP 等存储的资源制品定义一套可被 Argo CD 消费的 OCI Artifact 存储格式包括内容构成与媒体类型Media Types支持使用自定义 / 自签名 TLS 证书访问 OCI Registry支持对需要认证的 OCI Registry 进行访问。Non-Goals不在本提案范围内不提供用于打包并向 OCI Registry 发布资源的 CLI 集成不向 OCI artifact manifest 附加描述内容的元数据如原始 Git 来源 URL、revision——不过从当前实现看Argo CD 已能展示标准的 OCI 元数据注解详见本文第七章。1.4 用例Use cases发布与检索用户希望将任意受支持格式Kustomize、Jsonnet、Helm、plain-manifest 等或可通过 Config Management PluginCMP消费的内容发布到 OCI Registry 并从其中检索使用OCI Registry 认证用户希望强制执行安全控制、要求对 OCI Registry 进行认证并配置 Argo CD 与之交互CLI 集成用户希望使用 Argo CD CLI 在 OCI Registry 中生产、存储与检索push/pull资源。二、落地实现从提案到代码2.1 实现思路新增第三种客户端提案中的 Implementation Details 描述了一个关键架构决策repo-server 当时维护 Helm 与 git 两类客户端通过新增第三个客户端并在与前两者相同的位置调用它即可支持 OCI Artifacts同时建议抽象出一个统一的客户端接口根据仓库配置中的类型值实例化所需客户端。这一设想在代码中得到了印证。仓库根目录的 util/oci/client.go 定义了统一的Client接口ResolveRevision(ctx, revision, noCache)将 tag、digest 或语义化版本约束解析为具体 digest若 revision 本身是 digest 则原样返回DigestMetadata(ctx, digest)获取指定 digest 的 OCI manifestCleanCache(revision)硬刷新或 manifest 缓存过期时清理缓存的 OCI 镜像Extract(ctx, revision)按 revision 拉取并解包 OCI 镜像内容到随机临时目录TestRepo(ctx)验证仓库的可达性与可访问性GetTags(ctx, noCache)获取仓库的 tag 列表。var _ Client nativeOCIClient{}明确声明了实现关系nativeOCIClient基于oras.land/oras-go/v2ORAS 库构建。这与提案 Security Considerations 中可以复用 Helm OCI 集成所用的同一套库的判断完全一致。在 reposerver/repository/repository.go 中可以看到repo-server 通过oci.NewClient实例化 OCI 客户端并将仓库凭据q.Repo.GetOCICreds()、代理配置与允许的层媒体类型列表initConstants.OCIMediaTypes一并传入用于GetTags、ResolveRevision、Extract等操作。2.2 仓库配置模型类型识别与凭据pkg/apis/application/v1alpha1/repository_types.go 是 OCI 支持在 API 层面的数据模型几个关键字段EnableOCI是否对当前仓库启用 helm-oci 支持Type仓库凭据类型可取git、helm或oci为空时默认gitInsecureOCIForceHttp是否完全禁用 TLS仅对 OCI 仓库生效GetOCICreds()repository_types.go从仓库配置中提取 OCI 认证所需的oci.Creds包含用户名、密码、CA 路径、客户端证书、InsecureSkipVerify与InsecureHTTPOnly等字段。值得注意的是 repository_types.go当仓库 URL 以oci://前缀开头时代码会自动将仓库Type判定为oci这是类型推断的便捷入口。三、应用定义在 Application 中使用 OCI 来源3.1 基础示例OCI 镜像中的任意清单docs/user-guide/oci.md 给出了声明式用法。Argo CD 支持通过 UI 或声明式 GitOps 方式将 OCI 镜像作为应用来源apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-custom-image namespace: argocd spec: project: default source: path: . repoURL: oci://registry-1.docker.io/some-user/my-custom-image targetRevision: 1.16.1 destination: server: https://kubernetes.default.svc namespace: my-namespace3.2 示例公共 OCI Helm ChartOCI Helm Chart其mediaType为application/vnd.cncf.helm.chart.content.v1.targzip同样可以直接消费并支持通过helm.valuesObject传入 valuesapiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: nginx spec: project: default source: path: . repoURL: oci://registry-1.docker.io/bitnamicharts/nginx targetRevision: 15.9.0 helm: valuesObject: some-value: foo destination: name: in-cluster namespace: nginx3.3 三个关键字段的语义启动 OCI 来源只需关注 Application spec 中的三个组件repoURL使用oci://scheme 指定 OCI 镜像仓库 URLregistry 镜像名targetRevision指定期望的镜像 tag 或 digestpath从展开后的镜像中选择相对路径不选子路径时使用.。对于 OCI Helm Chartpath必须始终为.。3.4 版本解析的源码级细节targetRevision支持 tag、digest 与语义化版本约束SemVer constraint三种形式。util/oci/client.go 的resolveRevision展示了解析逻辑先尝试将 revision 当作精确 tag/digest 解析若失败且 revision 是 SemVer 约束则拉取全部 tags 并用versions.MaxVersion选出满足约束的最大版本再解析该版本的 digest。tag 列表会缓存在 tags cache 中GetTags支持noCache强制绕过缓存直达远端且约定将 tag 中的_替换回以还原合法 SemVer。四、私有 OCI 仓库认证与特殊场景4.1 添加类型为 oci 的仓库凭据若 OCI 仓库需要凭据需创建类型为oci的仓库凭据Repository Credential# Add a private HTTPS OCI repository named stable argocd repo add oci://registry-1.docker.io/bitnamicharts/nginx --type oci --name stable --username test --password test4.2 使用 Helm 仓库凭据 --enable-oci对于 Helm 仓库另有启用 OCI 凭据的方式# Add a private HTTPS OCI Helm repository named stable argocd repo add registry-1.docker.io/bitnamicharts/nginx --type helm --name stable --username test --password test --enable-oci4.3 两个关键注意点[!NOTE] 仓库 URL 不应包含oci://scheme 前缀同时应将路径从仓库 URL 中剥离改由path属性定义。apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: my-custom-image namespace: argocd spec: project: default source: path: bitnamicharts/nginx repoURL: registry-1.docker.io targetRevision: 1.16.1 destination: server: https://kubernetes.default.svc namespace: my-namespace[!NOTE] 上述简化方式仅在使用 Helm 仓库凭据时适用。4.4 相关 CLI 参数从 cmd/argocd/commands/repo.go 与 cmd/argocd/commands/repocreds.go 可以看到配套命令选项--type oci声明仓库类型为 oci--enable-oci指定是否对该仓库启用 helm-oci 支持布尔 flag默认 false--insecure-skip-server-verification跳过服务端 TLS 证书校验--insecure-oci-force-http强制使用 HTTP完全禁用 TLS仅对 OCI 仓库适用代码中通过cmdutil.ValidateInsecureOCIForceHTTP校验其与仓库类型、EnableOCI 的组合是否合法。对应地repository_types.go 中的InsecureOCIForceHttp字段注释明确该 flag 仅对 OCI 仓库适用。这些能力正是提案 Goals 中支持自定义 / 自签名 TLS 证书与支持需要认证的 Registry的落地形态——util/oci/client.go 的newTLSConfig支持注入自定义 CA 证书池CAPath与客户端证书CertData/KeyData并依据InsecureSkipVerify决定是否跳过校验。五、打包与发布制作兼容 Argo CD 的 OCI 制品5.1 使用前提首先需要一个 OCI 合规的 Registry例如 Docker Hub、ECR、GHCR、GCR 均满足要求。其次Argo CD 期望 OCI 镜像只包含单个层且该层的媒体类型需被 repo-server 接受。默认情况下Argo CD 接受以下两种镜像层媒体类型application/vnd.oci.image.layer.v1.targzipapplication/vnd.cncf.helm.chart.content.v1.targzip自定义媒体类型可通过在 repo-server 部署中设置环境变量ARGOCD_REPO_SERVER_OCI_LAYER_MEDIA_TYPES配置。在代码中该列表通过initConstants.OCIMediaTypes传入oci.NewClient见 reposerver/repository/repository.go在拉取时对每个内容层做白名单校验不在允许列表内的媒体类型会被拒绝并报错oci layer media type %s is not in the list of allowed media types。5.2 用 ORAS 打包目录推送制作兼容制品的方式很多官方文档以 ORAS 为例。在存放清单的目录中执行oras push registry-url/guestbook:latest .ORAS 会自动将目录打包为单层并把媒体类型设置为application/vnd.oci.image.layer.v1.targzip。5.3 用压缩归档推送也可以先制作 gzip 压缩的 tar 归档再推送# Create a tarball of the directory containing your manifests. If you are not in the current directory, please ensure # that you are setting the correct parent of the directory (that is what the -C flag does). tar -czvf archive.tar.gz -C manifests .# In the case of tarballs, you currently need to set the media type manually. oras push registry-url/guestbook:latest archive.tar.gz:application/vnd.oci.image.layer.v1.targzip5.4 内容与媒体类型的源码约束提案 native-oci-support.md 的 Format of OCI Artifact 章节提出了制品格式设想资源以 gzip 压缩 tar 归档.tar.gz作为 OCI 层存储并利用 OCI Image Specification 的 annotations 附加属性化元数据如 Git 仓库 URL、分支/版本以满足 Argo CD 追踪内容的需求同时定义两种新的媒体类型application/vnd.cncf.argoproj.argocd.content.v1.targzipOCI 制品内的主资产gzip 压缩的 Argo CD 资源 tar 归档application/vnd.cncf.argoproj.argocd.config.v1jsonOCI Image Configuration。落地实现与提案的对应关系清晰可见util/oci/client.go 在提取时检查 manifest层数超过 10 会被拒绝内容层content layer数量必须恰好为 1会跳过 provenance/attestation 等额外层对于 Helm Chartconfig 媒体类型为application/vnd.cncf.helm.config.v1json时只匹配application/vnd.cncf.helm.chart.content.v1.targzip内容层。isContentLayer/isCompressedLayerutil/oci/client.go判断层是否为targzip、tar.gzip或tar结尾的压缩层解包时依据后缀选择files.Untgz或files.Untar并对 Helm Chart 做仅允许单个子目录的校验。此外WithManifestMaxExtractedSize/WithDisableManifestMaxExtractedSize两个 ClientOpts 提供了对解包体积上限的约束能力防止恶意超大归档耗尽磁盘。六、安全考量与风险缓解6.1 安全考量Security Considerations提案指出Argo CD 核心子系统直接与外部端点集成会引入安全考量。值得注意的是Argo CD 此前对 OCI Registry 中 Helm Chart 的拉取是由 Helm 及其底层 ORAS 库完成的而非 Argo CD 自身本提案的能力可以复用同一套库。这一判断已在实现中兑现——util/oci/client.go 的客户端正是基于oras.land/oras-go/v2构建。6.2 凭据CredentialsOCI Registry 可能强制客户端认证。为引入针对目标系统的额外认证机制超出本提案范围但复用现有能力如从 repository 凭据中取值是必要前提。实现上GetOCICreds()将仓库配置转换为oci.Creds用户名/密码、CA、客户端证书、TLS 选项并在 util/oci/client.go 中通过auth.StaticCredential注入 HTTP 客户端代理则通过proxy.GetCallback(proxyURL, noProxy)支持对应仓库配置中的Proxy/NoProxy字段。6.3 风险与缓解与现有 Helm OCI 集成重叠Argo CD 已支持从 OCI Registry 拉取 Helm Chart且拉取行为委托给 Helm。因此需要区分用户意图是消费包含 Argo CD 资源的 OCI Artifact还是Helm Chart。提案给出的一个方法是检查 OCI artifact 的mediaType。实现中通过 manifest 的Config.MediaType helmOCIConfigType判断是否为 Helm Chartutil/oci/client.go从而走不同的层匹配与解包路径正是这一思路的工程化落地。6.4 升级 / 降级策略与 Drawbacks提案要求把升级/降级策略纳入测试计划需明确存量集群为保持既有行为在升级时需做的变更invocations、配置、API 使用以及为使用新增强功能需做的变更。同时提案坦诚地记录了潜在缺点从 OCI Registry 获取内容可能被质疑违背 GitOps 原则内容非源自 Git 仓库。缓解方式是为内容附加原始来源细节如 Git URL、revision但提案也指出GitOps 原则仅要求事实来源可版本化、不可变而 OCI Registry 完全满足这两点。6.5 备选方案Config Management Plugin一个不修改 Argo CD 核心能力即可消费 OCI Artifacts 的替代方案是通过 Config Management PluginCMP。但提案明确指出这种方式比较 hacky且无法在 Argo CD UI 中原生呈现区别于一等支持。七、OCI 元数据注解在 UI 中展示镜像信息除了核心拉取能力Argo CD 还能识别并展示标准 OCI 元数据注解为 OCI 镜像提供额外上下文直接在 Argo CD UI 中可见。支持的注解包括org.opencontainers.image.titleorg.opencontainers.image.descriptionorg.opencontainers.image.versionorg.opencontainers.image.revisionorg.opencontainers.image.urlorg.opencontainers.image.sourceorg.opencontainers.image.authorsorg.opencontainers.image.created结合前面 ORAS 的示例可通过-a参数在推送时写入注解oras push -a org.opencontainers.image.authorssome author \ -a org.opencontainers.image.urlhttp://some-url \ -a org.opencontainers.image.versionsome-version \ -a org.opencontainers.image.sourcehttp://some-source \ -a org.opencontainers.image.descriptionsome description \ registry-url/guestbook:latest .八、实践小结从提案到落地Argo CD 的原生 OCI 支持已经形成完整闭环声明式使用在 Application 的source.repoURL中使用oci://scheme配合targetRevisiontag / digest / SemVer 约束与path子路径选择Helm Chart 固定为.私有仓库接入argocd repo add ... --type oci或 Helm 仓库凭据 --enable-oci配合--insecure-skip-server-verification/--insecure-oci-force-http处理 TLS 场景制品打包用 ORAS 将清单目录或tar.gz归档指定application/vnd.oci.image.layer.v1.targzip媒体类型推送到任意 OCI 合规 Registry约束认知镜像需为单内容层、层媒体类型需在允许列表内默认两类可通过ARGOCD_REPO_SERVER_OCI_LAYER_MEDIA_TYPES扩展、Helm Chart 与普通清单通过 config 媒体类型自动分流可观测性通过标准 OCI annotations 为 UI 提供镜像来源、版本、作者等上下文信息。如需继续深入可查阅实现主体 util/oci/client.go 及其测试 util/oci/client_test.go、repo-server 集成点 reposerver/repository/repository.go 与 OCI 指标埋点 reposerver/metrics/ocihandlers.go以及 API 数据模型 pkg/apis/application/v1alpha1/repository_types.go。【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考