OpenEBS Helm Chart 容器镜像清单(helm.sh/images 注解)设计与自动化实现解析

发布时间:2026/10/5 10:22:40
OpenEBS Helm Chart 容器镜像清单(helm.sh/images 注解)设计与自动化实现解析 云原生CLI【免费下载链接】openebsA popular widely deployed Open Source Container Native Storage platform for Stateful Persistent Applications on Kubernetes.项目地址https://gitcode.com/gh_mirrors/op/openebs点击查看免费下载本文依据 OpenEBS 仓库中的设计文档 OEP 3796Expose OpenEBS HelmCharts Container Images状态为 implemented编写。该提案为 OpenEBS 伞形 Helm Chart 引入了一份单一事实来源的容器镜像清单并通过正则提取、Chart 注解存储与自动化脚本使清单能够随 Chart 演进持续保持最新。读者读完本文后将掌握离线air-gapped部署前批量获取镜像、用helm template 正则全量枚举 Chart 镜像、以及借助仓库脚本完成清单生成/回写/集群校验的完整实战方法。一、设计背景与动机为什么需要一份镜像清单OpenEBS 是一个以 Helm 伞形 Chart 形式发布的云原生存储平台。打开仓库根目录下的 charts/Chart.yaml 可以看到这个伞形 Chart 通过dependencies聚合了 8 个子 Chartopenebs-crdsCRD 安装loki、alloy可观测性来自 Grafana Helm 仓库localpv-provisionerLocal PV Hostpath 引擎zfs-localpv、lvm-localpv、rawfile-localpvLocal PV 存储引擎mayastorReplicated PV 复制引擎每个子 Chart 内部又依赖 CSI sidecarcsi-provisioner、csi-attacher、csi-resizer等、etcd、NATS 消息总线、MinIO 对象存储等一系列镜像。结果是部署 OpenEBS 到底需要拉取哪些容器镜像用户和开发者很难凭肉眼从模板树中理清。设计文档给出的动机非常直接提供一个清晰、完整的每个 OpenEBS Chart 所需全部容器镜像清单从而减少用户查找、拉取镜像的时间与精力尤其对需要预先下载镜像的离线air-gapped环境至关重要。文档还指出另一个 OEP 可以在本提案之上构建可一键下载的镜像 tar 包。1.1 目标Goals为每个 OpenEBS Chart 提供一份详细的容器镜像清单必须建立自动化机制确保清单随 Chart 的任何变更保持同步更新。1.2 非目标Non-Goals不创建所有镜像的可下载打包留给后续 OEP 处理不负责构建或维护容器镜像不做镜像与具体功能的关联映射——也就是说清单是全量的可能包含某个用户未启用的特性所对应的镜像这是刻意为之见风险一节。二、总体方案把镜像清单写进 Chart 的 annotations提案的核心设计是在每个 OpenEBS Chart 的Chart.yaml或doc.yaml中增加一个annotations字段其中存放该 Chart 所需的全部容器镜像列表该列表自动生成并随 Chart 变更自动更新。同时每个 OpenEBS Chart 会复用其依赖的子 Chart 中已声明的注解从而把生成镜像清单这件最可靠的工作下放到最了解自身的那个 Chart。文档给出了一个示意示例以 Mayastor 为例注意其中版本号仅为示意当前仓库 Chart.yaml 中的实际版本见后文project: name: OpenEBS Mayastor annotations: images: | - name: mayastor-agent-core image: docker.io/openebs/mayastor-agent-core:v2.7.1 - name: linux-utils image: docker.io/openebs/linux-utils:4.1.0 - name: promtail image: docker.io/grafana/promtail:2.8.3在仓库的当前实现中注解键名落地为helm.sh/images块标量|内是若干- name: 组件名/image: 完整镜像地址键值对见 charts/Chart.yaml。2.1 用户故事Story 1作为用户我希望 OpenEBS Chart 有一个容器镜像的单一事实来源以便轻松拉取部署所需镜像。Story 2作为用户我希望这个单一事实来源可以被自动化消费例如脚本循环拉取、镜像仓库同步而无需人工逐条翻查模板。三、实现细节可发现镜像、暴露镜像与不可发现镜像文档将镜像划分为两类处理策略截然不同。3.1 可发现镜像Discoverable images正则 helm template 枚举凡是在 Helm 模板中以image:键出现的镜像都可以通过对 Chart 执行模板化helm template后扫描输出得到。为此提案给出了一条正则表达式^[ \t]*image: \K(.*:.*)$逐段拆解如下片段含义^行首断言匹配必须从行首开始[ \t]*匹配零个或多个空格或制表符即 YAML 的缩进贪婪匹配image:字面匹配image:区分大小写\K重置匹配报告的起点此前消耗的字符不再计入最终匹配结果PCRE 特性(.*:.*)捕获组任意字符 冒号 任意字符确保抓到的值含冒号即registry/repo:tag形态$行尾断言配合helm template与grep-P启用 PCRE、-o只输出匹配部分即可提取出全部镜像helm template . --set $ENABLE_ALL_FEATURES | grep -Po ^[ \t]*image: \K(.*:.*)$ | tr -d \注意此处必须开启全部特性enable all features才能保证拿到一份完整、无遗漏的镜像清单——这正是文档对全量清单定位的直接体现。3.2 仓库中的等价实现设计文档的这条命令在仓库中已经被完整落地到 scripts/helm/images.sh 的generate流程里且分成了两条互补的扫描# ① 通过 install.sh 的 template 模式打开全部本地引擎与复制引擎 $SCRIPT_DIR/install.sh --locals --replicated --template --helm --kubeconfig $CHART_DIR/fake \ | grep -Po ^[ \t]*image: \K(.*:.*)$ | tr -d \ | LC_ALLC sort | uniq # ② 对伞形 Chart 本身执行 helm template并显式开启分析/遥测相关特性 helm template $CHART_DIR \ --set mayastor.eventing.enabledtrue,mayastor.obs.callhome.enabledtrue,mayastor.obs.callhome.sendReporttrue \ --kubeconfig $CHART_DIR/fake --is-upgrade \ | grep -Po ^[ \t]*image: \K(.*:.*)$ | tr -d \ | LC_ALLC sort | uniq其中ENABLE_ALL_FEATURES在脚本中对应变量ENABLE_ANALYTICS见 images.sh即把 Mayastor 的 eventing 与 callhome 上报功能强制打开而install.sh --locals --replicated会通过 scripts/helm/install.sh 中的参数拼装逻辑把engines.local.*与engines.replicated.mayastor.enabled全部置为true对应 values.yaml 中的引擎开关。tr -d \去掉 YAML 中可能出现的引号sort | uniq去重后得到干净的去重列表。3.3 暴露镜像Expose images写回 annotations拿到镜像列表后将其作为 annotations 写入 Chart。当前 charts/Chart.yaml 中的helm.sh/images注解实际列出了约 50 个镜像条目按用途大致可分为类别代表条目当前仓库实际值可观测性docker.io/grafana/loki:3.4.2、docker.io/grafana/alloy:v1.8.1、docker.io/kiwigrid/k8s-sidecar:1.30.2、quay.io/prometheus-operator/prometheus-config-reloader:v0.81.0消息总线NATSdocker.io/nats:2.9.17-alpine、docker.io/natsio/nats-box:0.13.8、docker.io/natsio/nats-server-config-reloader:0.10.1、docker.io/natsio/prometheus-nats-exporter:0.11.0基础设施/工具docker.io/openebs/etcd:3.6.4-debian-12-r0、docker.io/openebs/kubectl:1.25.15、docker.io/openebs/linux-utils:4.6.0、docker.io/openebs/alpine-bash:4.6.0、docker.io/openebs/alpine-sh:4.6.0、docker.io/openebs/mc:*、docker.io/openebs/minio:*Local PV 引擎驱动docker.io/openebs/provisioner-localpv:4.6.0、docker.io/openebs/provisioner-localpv:4.7.0-develop、docker.io/openebs/zfs-driver:2.12.0-develop、docker.io/openebs/lvm-driver:1.11.0-develop、docker.io/openebs/rawfile-localpv:v0.15.1Replicated PV Mayastor 系列docker.io/openebs/mayastor-agent-core:develop等 12 个mayastor-*组件agent/api-rest/csi/io-engine/eventing/obs/operator-diskpool 等升级任务docker.io/openebs/openebs-upgrade-job:v4.7.0-developCSI sidecarregistry.k8s.io/sig-storage/csi-attacher:v4.8.1、csi-provisionerv5.2.0 / v6.1.0 / v6.3.0 三个版本、csi-resizerv1.13.2 / v2.0.0 / v2.2.1、csi-node-driver-registrarv2.13.0 / v2.17.0、csi-snapshotterv8.2.0 / v8.6.0、snapshot-controllerv8.2.0 / v8.6.0可以观察到同一个组件名会出现多个版本条目如provisioner-localpv同时有 4.6.0 与 4.7.0-developcsi-provisioner有三个版本。这是各存储引擎子 Chart 各自声明依赖的 CSI sidecar 版本不同所致——伞形 Chart 把依赖子 Chart 的注解原样汇总恰好印证了文档每个 Chart 使用其所依赖 Chart 的注解的设计意图。3.4 不可发现/运行时镜像Non-Discoverable / Runtime images并非所有镜像都能从helm template中发现。凡是在运行时才被动态部署的 Pod/Job而非 Helm 渲染的静态资源其镜像就无法通过扫描模板获得文档明确指出这类镜像需要人工查找并硬编码进清单。仓库中恰好有两个典型实例实例一LocalPV 的 helper pod初始化容器localpv-provisioner在为 PVC 准备文件系统时会按需拉起一个 init podhelper pod。该镜像不会出现在 helm 渲染结果中因此 images.sh 专门实现了helm_localpv_prov_helper_image()从子 Chart 的helperPod.image.registry / repository / tag取值支持helperPod.image.registry与global.imageRegistry两级回退拼出完整镜像地址并追加进清单images.sh。对应的 values 配置见 charts/values.yaml。实例二openebs-upgrade-job升级任务OpenEBS 的升级任务由kubectl openebs upgrade插件在升级时按需创建 Job而非随 Chart 常驻部署。从插件源码 plugin/src/cli_utils/upgrade/mod.rs 可以看到镜像地址是在运行时拼装的{image_registry}/{namespace}/openebs-upgrade-job:{image_tag}。为此images.sh 中的upgrade_job_image()以 callhome 镜像的 registry/namespace 为默认来源可用--openebs-registry/--openebs-namespace覆盖结合 Chart 的.version生成openebs-upgrade-job:vX.Y.Z并写入镜像清单images.sh。脚本注释也说明了当前阶段升级任务尚未集成进 Chart故需从清单中单独提取。此外伞形 Chart 自身静态渲染的资源如 charts/templates/pre-upgrade-hook.yaml 中引用的openebs/kubectl:1.25.15升级钩子 Job属于可发现镜像会由helm template扫描覆盖。四、仓库中的自动化闭环generate / patch / verify 三命令设计文档的目标章节要求自动化机制保证清单与 Chart 同步这一要求在 scripts/helm/images.sh 中落地为一个完整的 CI 可用闭环脚本提供三个子命令4.1generate从 Chart 生成镜像清单三步流水线images.sh收集依赖注解遍历Chart.yaml中所有带repository的依赖用helm show chart读取各自.annotations.helm.sh/images中的镜像helm_dep_collect_images全量扫描模板依次执行install.sh --locals --replicated --template与helm template --set $ENABLE_ANALYTICS --is-upgrade用上文正则提取image:值补充按需镜像调用helm_on_demand_images追加 helper pod 镜像与openebs-upgrade-job镜像。最终sort | uniq后写入 charts/images.txt每行一个完整镜像地址。配合--exit-code选项脚本会执行git diff --exit-code一旦清单与 Chart 不同步即返回非零退出码——这正是文档自动化测试保证清单保持最新见缓解措施一节的具体实现可无缝接入 CI。4.2patch把清单回写为 Chart 注解patch子命令将images.txt的每一行解析出组件名按/与:切分取倒数第二段构造{ name: ..., image: ... }的 JSON 数组通过yq写回Chart.yaml的.annotations.helm.sh/images并确保其保持块标量|格式images.sh。这样charts/Chart.yaml注解与charts/images.txt互为可再生的同一份数据。4.3verify在真实集群上校验清单verify子命令把清单与实际部署做交叉验证images.sh# 从 openebs 命名空间收集所有 Pod 的容器与 initContainer 镜像 kubectl -n openebs get pods -o json \ | jq -r .items[].spec.containers[]?.image, .items[].spec.initContainers[]?.image \ | LC_ALLC sort | uniq随后将 live 镜像与images.txt、Chart.yaml注解逐条比对任何集群在用但清单缺失的镜像都会触发log_fatal报错脚本还内置了一个 sanity checklive 镜像少于 5 条视为异常防止在空命名空间上误判通过。这与设计文档 Test Plan 中提出的思路完全对应可以在集群上用镜像白名单只允许清单内的镜像被拉取或禁用镜像拉取 预加载的方式验证清单的正确性与完整性。五、测试计划与风险缓解5.1 测试计划Test Plan文档要求随项目发展持续验证镜像清单的正确性与时效性验证可在真实集群上执行两种典型做法镜像白名单配置运行时只允许清单内的镜像被拉取一旦部署请求了清单之外的镜像即失败从而暴露清单缺漏禁用镜像拉取 预加载把所有镜像预先加载进集群并禁止在线拉取模拟离线环境验证清单是否足以支撑完整部署。上述两种方式在仓库中均有可用的工具基础verify子命令提供了 live 镜像与清单的自动比对scripts/staging/mirror-images.sh 等 staging 脚本也可用于镜像的同步与校验场景。5.2 风险与缓解Risks and Mitigations文档明确列出的风险包括可能收录非必需镜像因为生成清单时启用了全部特性清单会包含某些用户配置下用不到的镜像由于镜像随用户启用的功能而异这个问题难以从清单层面根除这也正是 Non-Goals 中不做镜像-功能关联映射的原因不可发现镜像必须人工维护运行时镜像无法自动扫描必须手动加入清单。对应的缓解措施是尽可能自动化仓库已通过 generate/patch/verify 三命令实现并使用自动化测试保证清单持续更新--exit-code的 CI 接入即为此设计。六、如何消费这份清单离线部署与镜像预拉取对于读者而言消费这份清单的最直接场景是离线air-gapped部署查看清单完整的镜像地址列表在 charts/images.txt每行一个带组件名/镜像地址的注解形式在 charts/Chart.yaml。批量拉取逐行docker pull或接入镜像同步工具将镜像导入离线镜像仓库即可在无外网集群上完成 OpenEBS 部署。按需筛选需要注意清单是全量的——若只部署部分引擎例如在 values.yaml 中关闭engines.replicated.mayastor.enabled或在安装时加--set engines.replicated.mayastor.enabledfalse见 charts/README.md 的安装示例清单仍会包含 Mayastor 系列镜像请结合自己的启用项决定是否全部预拉。自定义镜像仓库清单记录的是默认 registrydocker.io、registry.k8s.io、quay.io等。若通过global.imageRegistry全局覆盖镜像仓库charts/values.yaml实际拉取地址会与清单不同预拉取时应换算为覆盖后的地址。七、局限性与替代方案文档坦诚地列出了该方案的代价与备选Drawback在无法全自动生成清单的场景下即存在不可发现镜像时需要额外的维护精力来保持清单更新Alternatives维持现状——不提供集中清单由用户在部署时手动逐个发现所需容器镜像。这显然更耗时且更容易出错也正是本提案被采纳状态为 implemented的原因。八、实施历史与展望按 OEP 流程文档经历了Summary与Motivation合并以表明 owner 接受提案的阶段当前仓库中的helm.sh/images注解、images.txt清单与images.sh自动化脚本即为该设计的最终落地形态。正如文档开篇所展望的这份单一事实来源的镜像清单还可以作为后续 OEP 的基础用于构建包含全部所需容器镜像、可一键下载的 tar 包进一步降低离线交付 OpenEBS 的门槛。延伸阅读均为仓库内文件设计文档原文designs/helm-charts/expose-container-images.md镜像清单纯镜像地址charts/images.txt镜像注解名称地址charts/Chart.yaml自动化脚本generate/patch/verifyscripts/helm/images.sh模板化安装脚本全特性开启逻辑scripts/helm/install.sh引擎开关与镜像相关 valuescharts/values.yaml升级任务镜像的运行时拼装plugin/src/cli_utils/upgrade/mod.rs赞分享云原生CLI【免费下载链接】openebsA popular widely deployed Open Source Container Native Storage platform for Stateful Persistent Applications on Kubernetes.项目地址https://gitcode.com/gh_mirrors/op/openebs点击查看免费下载相关推荐Ingress NGINX Controller v1.13.9 版本发布解析镜像清单、变更内容与 Helm Chart 配套升级Ingress NGINX Controller v1.13.9 版本发布解析镜像清单、变更内容与 Helm Chart 配套升级 Ingress NGINX后端API网关负载均衡云原生革命性交互式Go编程lgo项目完全指南革命性交互式Go编程lgo项目完全指南 lgo是一个功能强大的Go语言Jupyter Notebook内核和交互式REPL工具它彻底改变了Go语言的编程体验虚拟化桌面应用图形学Flux Helm OCI 支持RFC-0002把 Helm Chart 存入容器镜像仓库的设计与落地Flux Helm OCI 支持RFC 0002把 Helm Chart 存入容器镜像仓库的设计与落地 本篇基于 Flux 官方设计文档 RFC 0002云原生CI/CD容器编排DevOps上一篇Memray transform 子命令完全指南将内存追踪文件转换为 gprof2dot、CSV 与 speedscope 格式下一篇在 Flet 应用中集成地理定位flet-geolocator 扩展包完整指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考