Chart 载体仓内部布局
ACP 完整插件的最小闭包、chart 载体仓目录约定、.build 流水线模板与 carrier marker、plugin-config 维护边界
Chart 载体仓内部布局
背景
ACP Kernel L4 拆分会把若干前端 / 控制面镜像从 Kernel chart 摘出,落到独立的 chart 载体仓(如 ait/chart-console-essentials、ait/chart-console-marketplace、ait/chart-application-catalog)。source-repo-mapping.md 决定每个载体仓归属哪些 image,pipeline-adaptation.md 决定 ait/pipeline 在 image build 完后怎么把版本写回载体仓。
这篇补两者中间的洞:载体仓内部应该长什么样——一个 chart 载体仓要被认为「迁移完成、能作为 ACP 插件交付」,最少需要哪几件文件、各自承担什么角色。
完整 ACP 插件 = 四件套
把 chart 装进 chartmuseum / harbor 不等于「完成一个 ACP 插件」。ACP 通过 ModulePlugin CR 注册插件、PluginConfig 渲染 cluster-aware 值、ModulePlugin install UI 用 descriptor 提示用户配置——光给 Helm chart 缺其中任何一个,部署都会在不同环节失败。
| 文件 | 角色 | 缺了会怎样 |
|---|---|---|
chart/(Chart.yaml + values.yaml + templates/) | Helm chart 本身 | helm install 不能跑 |
chart/module-plugin.yaml | ModulePlugin CR,ACP 注册插件的入口、声明 affinity / appReleases / dependencies | chart 能装、但 ACP 不知道有这个插件,不出现在装机流程里 |
chart/scripts/plugin-config.yaml | PluginConfig,valuesTemplates 提供 cluster-aware 渲染(platformURL、registry、ingress、SystemNamespace 等) | 安装到非 global 集群、跨升级或不同 ingress 域时值缺失,渲染出错或固化成 chart 默认值 |
.build/build.yaml | katanomi Build,串 chart-build → validate → release-tag | 没流水线,tag push 不产 chart artifact,下游 ait/pipeline 写版本也无处可写 |
可选第五件 chart/scripts/{manifest.yaml, render.sh, process.sh} ——仅当需要 动态 values rendering(如 chart-auth-manager-central 的 legacy CRD 迁移、marketplace cluster 的 bundle 探测)才加。base/charts/central 与本期两个 L4 载体仓都不需要。
仓内目录布局
容易踩坑的点
module-plugin.yaml 放 chart/ 根目录、不在 templates/ 下。 看起来像 K8s 资源,但 Helm 并不渲染它——chart-build ClusterTask 会单独把这个文件跟 chart artifact 一起 push 到 chartmuseum / harbor,由 ACP 控制面取出来注册。如果误放进 templates/,会作为普通模板渲染进 release manifest,引发各种重复部署 / RBAC 报错。
.build/build.yaml 模板与 # carrier marker
单 chart 载体仓的标准 task 链(参照 ait/chart-auth-manager-central/.build/build.yaml):
约定
chart artifact 命名空间
ait/chart-console-* 与 ait/chart-application-catalog 三个载体仓的 chart push 到 ait/ 命名空间(如 ait/chart-console-essentials、ait/chart-console-marketplace、ait/chart-application-catalog);其余既有 ait/* chart 仓保持原命名空间约定。source-repo-mapping.md 的 chart-carrier 表里 Owned OCI Artifacts 列已对齐。
ait/chart-application-catalog 与两个 console 载体仓的关键差别:其 default branch 沿用 ait/* 历史约定为 master(不是 main),chart/templates/ 下分 captain/ 与 chartmuseum/ 两组子目录承载两套控制面 / 后端资源;其余四件套布局与下文一致。
# carrier marker
当 module-plugin.yaml 出现多个 version: 行(自家 carrier chart + 引用的外部 chart),用 # carrier 标记自家那行,build 时 sed 锚标记:
只有一个 appRelease 时不加 marker 也能用裸 s|version: .*|...|g,但一旦未来要加第二个 appRelease 引外部 chart,裸 sed 会静默把外部 chart 版本也覆盖掉。所有载体仓建议从一开始就加 marker,零额外成本、把这条隐患直接关掉。和 ait/chart-base-cluster 的 # main marker 是同类思路、不同语义(那个是「分支固化」用)。
version placeholder
仓内 module-plugin.yaml 的 carrier version: 写 <placeholder>(不写 refer-to-productbase 或 v0.0.0 等真实版本号假象),明确告诉读代码的人这一行不是 source of truth、build 期会被改写。
values: 注入 global.chartVersion
如果 chart/values.yaml 声明了 global.chartVersion(被任何 template 引用),chart-build task 要带 values: - global.chartVersion=$(build.git.version.short),否则 chart artifact 出去的 global.chartVersion 是 placeholder 字符串。values.yaml 里写 chartVersion: <placeholder> 占位。
Chart.yaml version: 留 0.1.0 占位
不用动 source。chart-build 通过 chart-version=$(build.git.version.short) 参数走 helm package --version,只改打包出来的 .tgz,源码 Chart.yaml 不变更。
构建期替换矩阵
下表把「placeholder 在哪里、谁在什么时候替换」整理清楚——避免每加一个载体仓都重新推一遍。
| 文件 | 字段 | 替换者 | 触发条件 |
|---|---|---|---|
chart/module-plugin.yaml | carrier version: <placeholder> # carrier | 本仓 .build/build.yaml 的 update-module-plugin | 每次本仓 build |
chart/Chart.yaml | 顶层 version: | chart-build ClusterTask | 每次本仓 build,只改 .tgz |
chart/values.yaml | global.chartVersion: <placeholder> | chart-build ClusterTask 的 values: 参数 | 每次本仓 build,helm --set 注入 |
chart/values.yaml | global.images.*.tag | ait/pipeline 的对应 <image>.yaml | 上游 image build 完后回写本仓 |
chart/module-plugin.yaml | 外部 chart appRelease version:(不带 # carrier) | ait/pipeline 的对应 <chart>.yaml | 上游 chart build 完后回写本仓 |
ait/pipeline 那条线的口径见 pipeline-adaptation.md。
plugin-config.yaml 的 valuesTemplates 维护边界
valuesTemplates 是 chart 载体仓「cluster-aware 值渲染逻辑」的入口。key 是 harbor chart 名(ait/chart-console-essentials、ait/chart-base-central 等),value 是 ACP PluginConfig 渲染引擎吃的模板字符串,渲染产物注入到 helm chart 的 --values 里。
必装常见字段(cluster-aware)
global.namespace←.SystemNamespaceglobal.labelBaseDomain←.LabelBaseDomainglobal.registry.{address,imagePullSecrets}←.Base.Registry/.ImagePullSecretsglobal.cluster.{name,isGlobal,type}←.ClusterName/.ClusterTypeglobal.ingress.{host,ingressClassName,annotations}←.Base.Ingress.*(global cluster 走业务域名,非 global 走 SystemNamespace)global.globalInfo.{platformURL,oidcIssuer,registryAddress,...}←.Base.PlatformURL等global.nodeSelector/global.tolerations←.MiConfig.*(用户在装机界面填的)
L4 拆分专属维护点
老的 chart-base-cluster / chart-auth-manager-central / marketplace 的 plugin-config.yaml 里有专属于 console / marketplace-ui 的 valuesTemplates 片段(如 alauda-cluster-base.alaudaConsole.allowedRedirectHosts)——这些片段要随 image-load 模板一起搬到新载体仓。
L4 carve-out MR(chart-base-cluster!23、chart-auth-manager-central!44、marketplace 那笔)只动了 templates 和 values.yaml,没动 plugin-config.yaml,所以老仓里现在残留了一些已经渲染不到任何 template 的 dead 片段。这不是 bug、不影响运行,但下一次清理 plugin-config 时要意识到该删。
ModulePlugin description 文本
spec.description.{en,zh} 是 ACP 装机界面对用户展示的文本——不要写「L4 插件」「carve-out」之类内部架构术语。用一句声明性话讲清楚这个插件做什么,命名风格对齐 base/charts/central/module-plugin.yaml:
验证 checklist
新建或调整一个 chart 载体仓后,建议依次跑:
| 检查 | 命令 / 操作 |
|---|---|
| YAML 语法 | python3 -c "import yaml; yaml.safe_load(open('chart/module-plugin.yaml'))" 等 |
| Helm 包结构 | helm lint chart/ |
| values 渲染 | helm template chart/ --set global.chartVersion=vTEST 看关键路径段是否替换正确 |
| build 期 sed | sed 's|version: .* # carrier|version: vTEST # carrier|g' chart/module-plugin.yaml | grep version: 确认只命中 carrier 行 |
| 四件套齐备 | ls chart/module-plugin.yaml chart/scripts/plugin-config.yaml .build/build.yaml |
参考
- 镜像归属:source-repo-mapping.md
- 流水线写版本回本仓:pipeline-adaptation.md
- L4 插件拆分目标:l4-plugin-plan.md
- 实现参照:
ait/chart-auth-manager-central(单 chart 载体最干净的样板)、ait/chart-base-cluster(多 appRelease +# mainmarker 变体)、ait/chart-console-essentials(多 appRelease +# carriermarker、含valuesTemplates完整字段集合)、ait/chart-console-marketplace(minimalvaluesTemplates)、ait/chart-application-catalog(双 templates 子目录captain/+chartmuseum/,default branchmaster)