:把 Helm Chart 存入容器镜像仓库的设计与落地)
云原生CI/CD容器编排DevOps【免费下载链接】flux2Open and extensible continuous delivery solution for Kubernetes. Powered by GitOps Toolkit.项目地址https://gitcode.com/gh_mirrors/fl/flux2点击查看免费下载本篇基于 Flux 官方设计文档 RFC-0002讲解 Flux Source API 如何扩展HelmRepository以从容器镜像仓库OCI Registry拉取 Helm Chart包括type: oci字段的 API 设计、私有仓库的 Basic/OIDC 认证方式、Cosign 签名验证方案以及静态对象这一关键设计决策在 source-controller 与 flux CLI 中的实现体现。读完本文你将能够用oci://仓库地址配置 Flux Chart 源、打通私有仓库认证并利用 Flux 镜像自动化能力实现 Chart 版本的自动升级。背景与动机Helm v3.8 开始原生支持将 Chart 作为 OCI artifact 发布到容器镜像仓库。Flux 的 RFC-0002创建于 2022-03-30状态标记为partially implemented最后一次更新于 2023-11-28提出将这一能力引入 Flux 的 Source API使得 Helm Chart 也能像容器镜像一样被 Flux 持续观察并自动更新到 Git。RFC 明确列出了三个目标以最小化 API 变更的方式支持从 OCI Registry 拉取 Helm Chart支持验证用 Cosign 签名的 Helm OCI Chart 的真实性让用户能方便地从 HTTP/S Helm 仓库迁移到 OCI 仓库。同时明确了一条非目标不为 OCI Chart 引入新的 API Kind而是复用现有的HelmRepository。这一取舍正是后文 API 设计的核心。API 设计type字段与oci://URL 前缀RFC 提出的方案是给HelmRepository.spec增加两个可选字段spec.type不指定时默认为default保持原有HelmRepository行为不变设为oci时spec.url必须以oci://为前缀遵循 Helm 官方约定。对oci://URLsource-controller 会借助 Helm SDK 和oras库连接远端 OCI 存储。spec.provider用于面向 AWS、Azure、GCP 的基于上下文workload identity的授权。当spec.type为default时该字段被忽略未指定时默认为generic。RFC 原文给出的最小示例apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmRepository metadata: name: repo-name spec: type: oci provider: azure版本说明RFC 示例使用的是source.toolkit.fluxcd.io/v1beta2apiVersion这是 2022 年特性首发时的版本。当前仓库中 flux CLI 生成的清单已使用source.toolkit.fluxcd.io/v1见下文黄金测试文件实际使用时请以所部署版本支持的 apiVersion 为准。为什么没有引入HelmRegistry新 KindRFC 的 Alternatives 一节否决了新增HelmRegistryKind 来承载 OCI 仓库与认证信息的备选方案理由是对用户而言一个专用 Kind 相比在现有HelmRepository上加type字段没有任何收益。type字段的设计也与 FluxBucketAPI 一脉相承——同一个 Kind 通过type区分 S3、Azure Blob、GCS 等不同实现。这一同 Kind 多实现的思路贯穿了整个特性。flux CLI 对 OCI 仓库的处理在本仓库的 CLI 端flux create source helm命令直接实现了上述 API 约定是 RFC 设计落地的第一手证据。见 cmd/flux/create_source_helm.goURL 解析后只允许http、https和oci三种 scheme其他 scheme 直接报错url scheme %s not supported, can be: http, https and oci当 scheme 为oci时CLI 自动将spec.type置为oci并把--oci-provider参数写入spec.provider认证信息通过--username/--password生成 secret或--secret-ref引用已有 secret传入同时支持--pass-credentials控制凭据是否传递给所有域名。命令帮助文本内置了 OCI 示例create_source_helm.go# Create a source for an OCI Helm repository flux create source helm podinfo \ --urloci://ghcr.io/stefanprodan/charts/podinfo \ --usernameusername \ --passwordpassword # Create a source for an OCI Helm repository using an existing secret flux create source helm podinfo \ --urloci://ghcr.io/stefanprodan/charts/podinfo \ --secret-refdocker-config对应的单元测试与黄金文件验证了 CLI 的输出结果包括 scheme 校验、OCI 仓库生成、带 Secret 引用的 OCI 仓库三种场景create_source_helm_test.go。生成的 OCI 清单如下oci.goldenapiVersion: source.toolkit.fluxcd.io/v1 kind: HelmRepository metadata: name: podinfo namespace: {{ .fluxns }} spec: interval: 5m0s type: oci url: oci://ghcr.io/stefanprodan/charts/podinfo当指定--secret-refcreds时生成的清单会带上spec.secretRefoci-with-secret.golden与 RFC 中通过 secret 引用私有仓库凭据的设计一致。从私有仓库拉取 ChartBasic authdockerconfigjson Secret对于托管在 GitHub、Quay、自托管 Docker Registry 等处的私有仓库凭据存放在与HelmRepository同命名空间的 Kubernetes Secret 中且 Secret 类型必须是kubernetes.io/dockerconfigjsonapiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmRepository metadata: name: repo-name spec: type: oci secretRef: name: regcredkubectl create secret docker-registry regcred \ --docker-serveryour-registry-server \ --docker-usernameyour-name \ --docker-passwordyour-pwordOIDC auth面向云厂商的上下文授权当 Flux 运行在 AKS、EKS 或 GKE 上时可以给source-controller绑定一个对 ACR、ECR 或 GCR 具有只读权限的 IAM 角色通过spec.provider声明云厂商spec: type: oci provider: azure从源码看provider 的取值集合在 internal/flags/source_oci_provider.go 中定义为generic、aws、azure、gcp四种分别对应 source-controller API 中的GenericOCIProvider、AmazonOCIProvider、AzureOCIProvider、GoogleOCIProvider常量CLI 侧对非法取值会直接拒绝source OCI provider %s is not supported。RFC 还明确了一条认证优先级规则当spec.secretRef与一个非 generic 的 provider 同时存在时控制器优先使用 secret 中的静态凭据而不是云厂商的工作负载身份。用 Cosign 验证 Helm Chart 签名为保证从 OCI 仓库拉取的 Chart 未被篡改Flux 使用 Sigstore Go SDK 实现验证支持两种签名方式Cosign 密钥签名以及 Cosign 无密钥keyless签名。密钥签名提供公钥 Secret在HelmChart或HelmRelease内联 chart spec的spec.verify中启用验证apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmChart metadata: name: chart-name spec: verify: provider: cosign secretRef: name: cosign-public-keys承载 Cosign 公钥的 Kubernetes Secret 有一条硬性要求键名必须带.pub扩展名apiVersion: v1 kind: Secret metadata: name: cosign-public-keys type: Opaque stringData: key1.pub: pub-key-1 key2.pub: pub-key-2无密钥签名Rekor 透明度日志对于用 keyless 方法签名的公开 Chart省略spec.verify.secretRef即可spec: verify: provider: cosign此时 Flux 会在 Rekor 透明度日志中验证签名。实战案例一GHCR 上的 Chart HelmRelease以开发者希望在HelmRelease中引用 GitHub Container Registry 里的 OCI Chart为目标完整流程分三步。第一步用允许访问 GHCR 的 GitHub token 创建 docker-registry Secretkubectl create secret docker-registry ghcr-charts \ --docker-serverghcr.io \ --docker-username$GITHUB_USER \ --docker-password$GITHUB_TOKEN第二步定义 type 为oci的HelmRepository并引用该 SecretapiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmRepository metadata: name: ghcr-charts namespace: default spec: type: oci url: oci://ghcr.io/my-org/charts/ secretRef: name: ghcr-charts第三步在HelmRelease中引用该仓库。注意 chart 的interval可设为较短周期以更高频地检查仓库中新发布的 OCI artifactapiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: my-app namespace: default spec: interval: 60m chart: spec: chart: my-app version: 1.0.x sourceRef: kind: HelmRepository name: ghcr-charts interval: 1m # check for new OCI artifacts every minute实战案例二基于 Semver 区间自动升级 Chart 版本第二个用户故事面向平台管理员当镜像仓库中出现新的 patch 版本 Chart 时希望 Flux 直接修改 Git 中HelmRelease清单里的版本号并提交 PR。由于 Chart 本质上存放在容器镜像仓库里Flux 的镜像自动化组件ImageRepository / ImagePolicy可以原样复用——把 Chart 当作镜像来观察和打标签。第一步为 Chart artifact 定义镜像仓库和 Semver 策略apiVersion: image.toolkit.fluxcd.io/v1beta1 kind: ImageRepository metadata: name: my-app namespace: default spec: image: ghcr.io/my-org/charts/my-app interval: 1m0s --- apiVersion: image.toolkit.fluxcd.io/v1beta1 kind: ImagePolicy metadata: name: my-app namespace: default spec: imageRepositoryRef: name: my-app policy: semver: range: 1.0.x第二步在 Git 中的HelmRelease清单上添加策略标记version字段被替换为 policy 标记后Flux 就会在发现新版本时自动改写该字段并推送 PRapiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: my-app namespace: default spec: interval: 60m chart: spec: chart: my-app version: 1.0.0 # {$imagepolicy: default:my-app:tag} sourceRef: kind: HelmRepository name: ghcr-charts interval: 1m这是 RFC 动机部分Flux 用户可以用今天自动化容器镜像更新的同样方式来自动化 Chart 更新的具体落地形态也解释了为什么 OCI Chart 复用镜像自动化的基础设施是天然契合的。设计细节OCI 类型的 HelmRepository 是静态对象RFC 的 Design Details 一节描述了该特性对 source-controller 的改造理解它对排查问题很有帮助与默认的HelmRepository不同OCI 类型的HelmRepository不需要下载任何仓库索引文件。关联的HelmChart可以基于HelmRepository中携带的 registry 信息直接从 OCI 仓库拉取 Chart。因此type: oci的HelmRepository是静态的——它不承载一个向期望状态收敛的 reconciler而是一个关于 OCI Registry 的数据容器。source-controller 中的HelmRepositoryReconciler会检查.spec.type若为oci则不做索引拉取动作HelmChartReconciler则被扩展为同时处理两种类型。这个静态对象定位在 flux CLI 中留下了清晰的实现痕迹。在 create_source_helm.go 中创建 HelmRepository 后的等待逻辑按类型分叉readyConditionFunc : isObjectReadyConditionFunc(kubeClient, namespacedName, helmRepository) if helmRepository.Spec.Type sourcev1.HelmRepositoryTypeOCI { // HelmRepository type OCI is a static object. readyConditionFunc isStaticObjectReadyConditionFunc(kubeClient, namespacedName, helmRepository) } ... if helmRepository.Spec.Type sourcev1.HelmRepositoryTypeOCI { // OCI repos dont expose any artifact so we just return early here return nil }对应的isStaticObjectReadyConditionFuncreadiness.go用objectStatusStatic判定就绪而非默认的动态 status 判定。代码注释直白地说明了原因OCI 仓库不产生 artifactStatus.Artifact为空因此 CLI 在确认对象就绪后直接返回而不会像 HTTPS 仓库那样去打印fetched revision。这与 RFCOCI 型 HelmRepository 是静态数据容器的设计一一对应。该特性默认启用无需额外的 feature gate。实现时间线与当前状态RFC 的 Implementation History 记录了特性的演进节点时间里程碑2022-05-19source-controller 侧部分实现PR #6902022-06-06首个完整实现随 flux2 v0.31.0 发布2022-08-11支持从 OCI 解析 Chart 依赖随 flux2 v0.32.0 发布2022-08-29AWS、Azure、GCP 上下文登录contextual login随 flux2 v0.33.0 发布2022-10-21Cosign Chart 签名验证随 flux2 v0.36.0 发布2023-11-28OCI 型 HelmRepository 重构为静态对象设计随 flux2 v2.2.0 发布状态标记为implemented (partially)文档尾部留下的主要 TODO 是支持使用自签名 TLS 证书自签名 CA的容器镜像仓库。结合当前仓库依赖 go.mod 中github.com/fluxcd/source-controller/api v1.9.5的 API 版本CLI 生成的清单已是v1说明该特性从 RFC 撰写时的v1beta2一路演进到了现行 API 版本。小结RFC-0002 用一个可选的spec.type字段而非新 Kind以最小的 API 代价把容器镜像仓库引入 Flux 的 Helm 生态oci://URL 声明仓库、dockerconfigjsonSecret 或云厂商工作负载身份解决认证、Cosign 公钥/Rekor 解决完整性、镜像自动化复用解决版本升级而静态对象的重新定位则让 OCI 型HelmRepository免去了索引拉取的复杂性。以上设计均可在本仓库的 CLI 实现、就绪判定逻辑与测试黄金文件中找到对应佐证可作为阅读 source-controller 侧实现的入口。赞分享云原生CI/CD容器编排DevOps【免费下载链接】flux2Open and extensible continuous delivery solution for Kubernetes. Powered by GitOps Toolkit.项目地址https://gitcode.com/gh_mirrors/fl/flux2点击查看免费下载相关推荐OpenTofu 通过 OCI 镜像仓库分发与安装 Provider 与 Module从 RFC 设计到落地实现OpenTofu 通过 OCI 镜像仓库分发与安装 Provider 与 Module从 RFC 设计到落地实现 本文基于 rfc/20241206 oci云原生DevOps基础设施cert-manager 将 Helm Chart 推送至 OCI Registry 的设计与实践cert manager 将 Helm Chart 推送至 OCI Registry 的设计与实践 导读 本文基于 cert manager 官方设计文档 de云原生网络安全认证鉴权ArduPilot不写C也能加飞行逻辑Lua脚本引擎上手实录ArduPilot不写C也能加飞行逻辑Lua脚本引擎上手实录 你的飞机需要到特定高度自动悬停拍照但官方固件没这个功能。改C源码重刷固件至少折腾一天其实嵌入式无人机自动驾驶机器人固件上一篇N_m3u8DL-RE 流媒体下载完整指南3 条命令搞定 DASH、HLS 点播与直播录制下一篇Boss Show Time终极指南5个技巧掌握招聘时间提升求职成功率创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考