werwerwer
ACP Kernel 拆解与瘦身

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.yamlModulePlugin CR,ACP 注册插件的入口、声明 affinity / appReleases / dependencieschart 能装、但 ACP 不知道有这个插件,不出现在装机流程里
chart/scripts/plugin-config.yamlPluginConfig,valuesTemplates 提供 cluster-aware 渲染(platformURL、registry、ingress、SystemNamespace 等)安装到非 global 集群、跨升级或不同 ingress 域时值缺失,渲染出错或固化成 chart 默认值
.build/build.yamlkatanomi 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 载体仓都不需要。

仓内目录布局

<chart-carrier-repo>/
├── README.md
├── .build/
│   └── build.yaml             # katanomi 流水线
└── chart/
    ├── Chart.yaml
    ├── values.yaml
    ├── module-plugin.yaml     # ModulePlugin CR,**chart 根目录、不在 templates/ 下**
    ├── templates/             # K8s 资源 template
    ├── charts/                # sub-chart 依赖(按需)
    └── scripts/
        ├── plugin-config.yaml          # 必须
        ├── manifest.yaml               # 可选,声明 install/upgrade 用的 valuesRenderer
        ├── render.sh                   # 可选,被 manifest.yaml 引用
        └── process.sh                  # 可选,render.sh 内部调用

容易踩坑的点

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):

update-module-plugin
   ↓
chart-build (push chart artifact)
   ↓
validate-chart
   ↓
pipeline build-check
finally:
   alauda-release-tag (custom / ga 版本相位)

约定

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 锚标记:

# chart/module-plugin.yaml 片段
  - name: frontend
    chartVersions:
    - name: frontend/chart-frontend
      releaseName: frontend
      version: v4.4.0-beta.10.gb4ffa677  # 外部 chart,由 ait/pipeline 的 chart-frontend.yaml 走 yq 更新
  - name: console-essentials
    chartVersions:
    - name: ait/chart-console-essentials
      releaseName: console-essentials
      version: <placeholder> # carrier            # ← 本仓 build 期 sed 命中
# .build/build.yaml 片段
sed -i "s|version: .* # carrier|version: $(params.build_git_version_short) # carrier|g" \
    ./chart/module-plugin.yaml

只有一个 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> 占位。

# .build/build.yaml 的 chart-build task 片段
- name: values
  value:
    - global.chartVersion=$(build.git.version.short)

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.yamlcarrier version: <placeholder> # carrier本仓 .build/build.yaml 的 update-module-plugin每次本仓 build
chart/Chart.yaml顶层 version:chart-build ClusterTask每次本仓 build,只改 .tgz
chart/values.yamlglobal.chartVersion: <placeholder>chart-build ClusterTask 的 values: 参数每次本仓 build,helm --set 注入
chart/values.yamlglobal.images.*.tagait/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 ← .SystemNamespace
  • global.labelBaseDomain ← .LabelBaseDomain
  • global.registry.{address,imagePullSecrets} ← .Base.Registry / .ImagePullSecrets
  • global.cluster.{name,isGlobal,type} ← .ClusterName / .ClusterType
  • global.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:

description:
  en: "Provides the core components of the platform, including fundamental APIs, CRDs and feature gates."
  zh: "提供平台的核心组件,包括基础 API、CRD 以及 FeatureGate 。"

验证 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 期 sedsed '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 + # main marker 变体)、ait/chart-console-essentials(多 appRelease + # carrier marker、含 valuesTemplates 完整字段集合)、ait/chart-console-marketplace(minimal valuesTemplates)、ait/chart-application-catalog(双 templates 子目录 captain/ + chartmuseum/,default branch master)