docs: streamline onboarding execution rules

This commit is contained in:
xiaobing.wang 2026-04-01 11:14:37 +08:00
parent 71b39b6bf3
commit ab2698f7c9
2 changed files with 257 additions and 277 deletions

View File

@ -21,14 +21,13 @@
执行时会遵守这些平台规则: 执行时会遵守这些平台规则:
- 需要公网 HTTP 入口的应用使用 nginx + 单一 `NodePort` 作为平台接入层 - 明确列出应用仓库必须产出的文件、GitOps 导出结果和 CI 处理顺序
- 百智云用户鉴权是平台必填接入项,需要逐项补齐 `app_id` 与证书材料 - 只允许应用仓库 CI 同步当前应用自己的 release 结果与 `Application.targetRevision`
- 平台 shared 之外的私有依赖必须明确来源,不能只写不存在的连接参数 - `deploy/release/secret.yaml` 是唯一作者源CI 只导出 `releases/<app>/manifests/secret.yaml`
- 应用自带私有依赖的内部口令优先自动生成;外部集成凭据再向用户逐项索取 - 如果保留 `releases/<app>/manifests/` source就必须保留固定模板的 `kustomization.yaml`
- 只允许应用仓库 CI 向 GitOps 仓库同步当前应用自己的 release 结果与版本引用;如果当前应用的 chart 版本由 GitOps 仓库中的 `Application` 维护,则只同步更新 `apps/<app-name>/application.yaml` 里的 `targetRevision` - 需要公网 HTTP 入口时固定使用 nginx + 单一 `NodePort`,不改成 Ingress
- 如果运行时资源通过 `releases/<app>/manifests/` 提供,就必须同步维护这个 path 与 `Application` 中对应的 source不能只删目录不删引用 - 百智云用户鉴权是必填项,按固定顺序逐项补齐 `app_id` 与证书材料
- 第三方镜像保持真实来源;只有当前应用 CI 实际发布的镜像才写到 `registry.baizhi.cloud/<app-name>/...` - 平台 shared 之外的私有依赖必须明确来源;第三方镜像保持真实来源
- 镜像内自带的 nginx / 反向代理 upstream 必须和 Chart 渲染出来的 Service 名一致,不能混用裸服务名和 fullname 前缀
不适合处理: 不适合处理:

View File

@ -5,180 +5,170 @@ description: 面向当前 Baizhi GitOps 平台的项目接入工作流,只适
# GitOps 项目接入 Skill # GitOps 项目接入 Skill
这个 skill 是 Baizhi GitOps 平台的接入入口与执行摘要。 ## 目标
执行不应依赖用户重复解释平台规则;按本 skill 与当前仓库约定直接推进即可。 让 agent 能独立完成下面四件事:
目标是让 agent 能独立完成以下工作: - 生成或修复 `.gitlab-ci.yml`
- 生成或修复 `deploy/helm/<app>/`
- 为应用仓库补齐或恢复 `.gitlab-ci.yml` - 生成或修复 `deploy/release/`
- 生成或修复 `deploy/helm/<app>/` Chart - 让发版链路把当前应用的发布结果同步到固定 GitOps 仓库
- 生成或修复 `deploy/release/` release bundle
- 在发版链路中将当前应用自己的 release 结果推送到固定 GitOps 仓库
## 平台固定常量 ## 平台固定常量
除非用户明确要求修改,否则默认使用以下常量 除非用户明确要求修改,否则固定使用
- GitOps 仓库主机:`deploy.baizhi.cloud` - GitOps 主机:`deploy.baizhi.cloud`
- OCI Registry 主机:`registry.baizhi.cloud` - Registry 主机:`registry.baizhi.cloud`
- Helm OCI 仓库:`oci://registry.baizhi.cloud/helm` - Helm OCI 仓库:`oci://registry.baizhi.cloud/helm`
- GitOps 仓库克隆地址:`https://deploy.baizhi.cloud/gitops-admin/argodeploy.git` - GitOps 仓库地址:`https://deploy.baizhi.cloud/gitops-admin/argodeploy.git`
- Registry 用户名:`registry-ci` - Registry 用户名:`registry-ci`
- 共享镜像拉取 Secret`registry-pull-secret` - 共享 pull secret`registry-pull-secret`
- GitOps 控制器Argo CD - GitOps 控制器Argo CD
- Chart 分发方式OCI Registry - 代码托管GitLab
- 源代码托管GitLab
应用仓库 CI 默认依赖以下 GitLab 变量: GitLab CI 默认依赖这些变量:
- `GITEA_USER` - `GITEA_USER`
- `GITEA_TOKEN` - `GITEA_TOKEN`
- `REGISTRY_PASSWORD` - `REGISTRY_PASSWORD`
通常直接把 `REGISTRY_USER` 写成 `registry-ci` ## 开始前先做什么
## 真相来源与读取顺序 先按这个顺序读仓库:
开始改代码前,按下面顺序建立上下文: 1. `README.md`
2. Dockerfile、包管理文件、构建脚本、已有 deploy 文件
3. 用户提供的额外设计文档
1. 先读目标应用仓库 `README.md` 在动手前先确定:
2. 再读 Dockerfile、包管理文件、构建脚本、现有 deploy 文件
3. 如果用户给了额外设计文档,一并读取
判断规则:
- 目标应用仓库自己的 `README.md` 是应用运行架构的真相来源
- 本 skill 定义平台接入流程、约束和执行重点
- 如果应用 README 与平台约定冲突,优先识别是“应用设计差异”还是“平台硬约束”
- 如果冲突会直接改变最终实现且无法安全推断,再问用户;否则优先按已有代码和文档做最小偏差实现
在生成任何文件前,先推断出:
- 组件列表 - 组件列表
- 每个组件的构建上下文 - 每个组件的构建上下文与入口
- 容器入口 - 对外暴露方式
- 对外暴露模型
- 运行时配置结构 - 运行时配置结构
- 哪些依赖属于平台共享,哪些是应用私有 - 平台共享依赖与应用私有依赖
不要假设每个项目都长得和现有项目一样 应用仓库自己的 `README.md` 是应用运行架构的真相来源;本 skill 只定义平台接入规则。
## 先判断修改范围 ## 边界
先区分任务属于哪一种: - 只处理应用仓库侧接入
- 不修改与当前应用无关的 GitOps 清单
1. 补齐或修复应用仓库中的 CI、Chart、release 模板
2. 修复应用仓库中的发版链路,使其在发版时推送当前应用自己的 release 结果
边界约束:
- 本 skill 只处理应用仓库侧接入
- 不读取、不判断、不修改与当前应用无关的 GitOps 发布侧清单
- 对 GitOps 的唯一动作,是在应用仓库 CI 中同步当前应用自己的 release 结果与版本引用 - 对 GitOps 的唯一动作,是在应用仓库 CI 中同步当前应用自己的 release 结果与版本引用
- 如果当前应用的 Argo CD `Application` 已存在且 chart 版本引用由 GitOps 仓库维护,只允许同步更新 `apps/<app-name>/application.yaml` 中当前应用 chart source 的 `targetRevision` - 如果当前应用的 `Application` 已存在,只允许更新 `apps/<app>/application.yaml` 中当前应用 chart source 的 `targetRevision`
- 不修改 `AppProject`、bootstrap、其他应用的 `Application`,也不要改动当前应用 `Application` 中除 chart `targetRevision` 以外的字段 - 不修改 `AppProject`、bootstrap、其他应用的 `Application`
## 交付模型 ## 应用仓库必须产出哪些文件
平台采用两个仓库协同交付: ### CI
- 应用仓库负责源码、Docker 构建、`.gitlab-ci.yml`、Helm Chart 源码、release bundle 模板
- 当前 GitOps 仓库负责 Argo CD `Application`、`AppProject`、平台 bootstrap、已发布 release bundle、共享配置
标准发布流程:
1. 分支或 MR 只跑测试
2. 打 `vX.Y.Z` tag 后构建并推送镜像
3. 打 `vX.Y.Z` tag 后打包并推送 Helm Chart
4. 打 `vX.Y.Z` tag 后更新当前 GitOps 仓库中该应用的版本引用,包括当前应用 `Application` 中 chart source 的 `targetRevision`
5. 推送当前 GitOps 仓库提交
6. Argo CD 感知当前 GitOps 仓库变更后自动同步
关键约束:
- CI 不能直接调用 `kubectl`
- CI 不能调用 `argocd app sync`
- CI 不能把 hard refresh 当常规步骤
- 当前 GitOps 仓库的提交才是 Argo 的同步信号
如果线上故障需要 hard refresh那是运维例外不属于通用模板。
## 应用仓库通常需要生成什么
通常需要创建或修复:
- `.gitlab-ci.yml` - `.gitlab-ci.yml`
- `deploy/helm/<app-name>/Chart.yaml`
- `deploy/helm/<app-name>/values.yaml` ### Chart
- `deploy/helm/<app-name>/templates/*`
- `deploy/helm/<app>/Chart.yaml`
- `deploy/helm/<app>/values.yaml`
- `deploy/helm/<app>/templates/*`
### release 作者源
- `deploy/release/metadata.yaml` - `deploy/release/metadata.yaml`
- `deploy/release/values.yaml` - `deploy/release/values.yaml`
- `deploy/release/secret.yaml` - `deploy/release/secret.yaml`
如果应用还有不适合放进 Chart 的静态清单,可以在后续发布结果中导出到当前 GitOps 仓库的 `releases/<app>/manifests/` 如果 `Application` 仍引用 `releases/<app>/manifests/`,还必须生成:
- 如果 Chart 运行时依赖的 `Secret`、`ConfigMap` 或 shared 资源并不是由 Chart 自己创建,而是通过 `deploy/release/secret.yaml` 或 GitOps 仓库中的 `shared/` 提供,就必须保留一个最小的 `releases/<app>/manifests/` 输出,并让当前应用的 `Application` 持续引用这个 path - `deploy/release/manifests/kustomization.yaml`
- 如果某次发布不再导出 `releases/<app>/manifests/`,就必须同时移除当前应用 `Application` 中对应的 manifests source不要留下一个指向不存在路径的 source
默认模板固定为:
```yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: <app-name>
resources:
- secret.yaml
- ../../../shared
```
只有在确实需要额外静态资源时,才往 `resources:` 追加内容。
如果 `Application` 不再引用 `releases/<app>/manifests/`,就不要保留 `deploy/release/manifests/`
## GitOps 仓库里最终应该有哪些文件
CI 导出结果固定为:
- `deploy/release/metadata.yaml` -> `releases/<app>/metadata.yaml`
- `deploy/release/values.yaml` -> `releases/<app>/values.yaml`
- `deploy/release/manifests/kustomization.yaml` -> `releases/<app>/manifests/kustomization.yaml`
- `deploy/release/secret.yaml` -> `releases/<app>/manifests/secret.yaml`
- `apps/<app>/application.yaml` -> 只更新 chart source 的 `targetRevision`
固定规则:
- 不导出 `releases/<app>/secret.yaml`
- `releases/<app>/manifests/kustomization.yaml` 默认只维护 `secret.yaml``../../../shared`
- 不要依赖 `../secret.yaml` 这类位于当前 source path 外的裸资源文件
- 如果不再导出 `releases/<app>/manifests/`,必须同时移除 `Application` 中对应的 manifests source
## GitLab CI 规则 ## GitLab CI 规则
runner 约束:
- 只要某个 job 需要使用 Docker、DinD 或 `docker buildx`,就必须显式带上 GitLab runner tags`docker`、`network`
### stages ### stages
使用这三个 stage 固定使用:
- `test` - `test`
- `build` - `build`
- `release` - `release`
### runner tags
只要 job 使用 Docker、DinD 或 `docker buildx`,就必须带:
- `docker`
- `network`
### test job ### test job
test job 应运行在分支和 MR 上,并执行目标项目自己的标准测试命令。 用途:只做测试,不改 GitOps不推镜像
要求: 要求:
- 安装该语言栈所需的最小依赖 - 运行在分支和 MR 上
- 如果依赖私有代码仓库,补齐认证 - 安装当前语言栈的最小依赖
- 使用项目本身的标准测试入口,不要擅自发明新的测试命令 - 如依赖私有仓库,补齐认证
- 使用项目原生测试入口
Go 项目额外要求: Go 项目默认变量写在 `.gitlab-ci.yml``variables:`
- 如果项目使用 Go并且依赖公共模块下载默认在 GitLab CI variables 中加入:`GOPROXY=https://goproxy.cn,direct`、`GOSUMDB=sum.golang.google.cn` - `GOPROXY=https://goproxy.cn,direct`
- 如果项目使用 `git.in.chaitin.net` 私有 Go 模块,默认同时加入:`GOPRIVATE=git.in.chaitin.net`、`GONOSUMDB=git.in.chaitin.net`、`GONOPROXY=git.in.chaitin.net`、`GOINSECURE=git.in.chaitin.net` - `GOSUMDB=sum.golang.google.cn`
- 如果项目通过 GitLab 私有仓库拉取依赖且当前平台环境需要跳过证书校验,默认加入:`GIT_SSL_NO_VERIFY="true"` - `GOPRIVATE=git.in.chaitin.net`
- 这类 Go 代理与私有仓库变量应放在 `.gitlab-ci.yml``variables:` 中,而不是分散写进单个命令 - `GONOSUMDB=git.in.chaitin.net`
- `GONOPROXY=git.in.chaitin.net`
示例: - `GOINSECURE=git.in.chaitin.net`
- `GIT_SSL_NO_VERIFY="true"`
- Go`go mod download`、`go test ./...`
- Node`npm ci`、`npm test`
### release 触发条件 ### release 触发条件
发布链路`vX.Y.Z` 这种语义化 tag 上触发。 只在 `vX.Y.Z` tag 上触发发布链路
### build-images job ### build-images job
这个 job 必须: 输入源码、Dockerfile、多组件构建上下文。
输出:推送到 `registry.baizhi.cloud/<app>/<component>:<version>` 的运行时镜像。
要求:
- 登录 `registry.baizhi.cloud` - 登录 `registry.baizhi.cloud`
- 构建项目所有需要发布的运行时镜像 - 优先使用 `docker buildx`
- 将镜像推送到 `registry.baizhi.cloud/<app-name>/<component>:<version>` - 私有 Git 依赖通过 `.netrc` 和 build secret 传入
- 如需额外 CA也通过 build secret 传入
如果仓库已经使用 BuildKit 或多构建上下文,优先使用 `docker buildx` 禁止:
如果镜像构建依赖私有 Git 仓库:
- 用 CI 凭据生成 `.netrc`
- 通过 Docker build secret 传入
- 如需额外 CA 证书,也通过 build secret 传入
- 如果私有 GitLab 仓库位于 `git.in.chaitin.net` 且当前平台环境需要跳过证书校验,可配合 `GOINSECURE=git.in.chaitin.net``GIT_SSL_NO_VERIFY="true"`
不要使用:
- `http://registry...` - `http://registry...`
- `--plain-http` - `--plain-http`
@ -186,107 +176,104 @@ Go 项目额外要求:
### package-chart job ### package-chart job
这个 job 必须: 输入:`deploy/helm/<app>/Chart.yaml`、`deploy/helm/<app>/values.yaml`、`deploy/helm/<app>/templates/*`
- 执行 `helm registry login registry.baizhi.cloud` 输出:推送到 `oci://registry.baizhi.cloud/helm` 的 Chart 包。
- 将 Chart 的 `version``appVersion` 更新为 tag 去掉前缀 `v` 后的版本号
- 执行 `helm package` 要求:
- 推送到 `oci://registry.baizhi.cloud/helm`
- `helm registry login registry.baizhi.cloud`
- 在临时目录复制 `deploy/helm/<app>/`
- 把复制品中的 `version``appVersion` 改成 tag 版本
- `helm package`
- `helm push`
### update-gitops-repo job ### update-gitops-repo job
这个 job 必须: 输入:`deploy/release/*`、当前 tag 版本、GitOps 仓库中的 `apps/<app>/application.yaml`
- 克隆 `https://${GITEA_USER}:${GITEA_TOKEN}@deploy.baizhi.cloud/gitops-admin/argodeploy.git` 输出:
- 只同步当前应用自己的 release 结果或版本引用
- 提交并推送到 `main`
通常需要更新: - `releases/<app>/metadata.yaml`
- `releases/<app>/values.yaml`
- `releases/<app>/manifests/` 下的发布结果
- `apps/<app>/application.yaml` 中当前应用 chart source 的 `targetRevision`
- `releases/<app-name>/values.yaml` 处理顺序固定为:
- `releases/<app-name>/metadata.yaml`
- `releases/<app-name>/manifests/` 下由当前应用导出的发布结果
- `apps/<app-name>/application.yaml` 中当前应用 chart source 的 `targetRevision`
不要在这个 job 中加入集群部署逻辑。 1. 克隆 `https://${GITEA_USER}:${GITEA_TOKEN}@deploy.baizhi.cloud/gitops-admin/argodeploy.git`
2. 清空并重建 `releases/<app>/`
3. 复制 `deploy/release/``releases/<app>/`
4. 删除 `releases/<app>/secret.yaml`
5. 如果仍保留 manifests source
- 保留 `releases/<app>/manifests/kustomization.yaml`
- 将 `deploy/release/secret.yaml` 物化为 `releases/<app>/manifests/secret.yaml`
6. 替换 `releases/<app>/metadata.yaml``releases/<app>/values.yaml` 中的 `__VERSION__`
7. 更新 `apps/<app>/application.yaml` 中当前应用 chart source 的 `targetRevision`
8. 只有存在 diff 时才提交并推送 `main`
禁止:
- 在 CI 中调用 `kubectl`
- 在 CI 中调用 `argocd app sync`
- 把 hard refresh 当常规发布步骤
## Helm Chart 规则 ## Helm Chart 规则
Chart 必须反映应用的真实运行架构。 Chart 必须反映应用的真实运行架构。
推荐结构: 固定要求
```text - 按职责拆文件,不堆一个大模板
deploy/helm/<app-name>/ - 模板中不硬编码生产 tag
├── Chart.yaml - 所有镜像名从 values 读取
├── values.yaml - 所有 Service 暴露方式从 values 读取
└── templates/
├── _helpers.tpl
├── deployment-<component>.yaml
├── service-<component>.yaml 或 services.yaml
└── 按职责拆分的其他资源
```
规则:
- 按职责拆文件,不要堆成一个巨大模板
- 模板中不要硬编码生产镜像 tag
- 所有镜像名都从 values 读取
- 所有 Service 暴露方式都从 values 读取
- nginx 对外 Service 固定使用 `NodePort` - nginx 对外 Service 固定使用 `NodePort`
- 后端 Service 默认使用集群内访问类型,不对外暴露 `NodePort` - 后端 Service 只做集群内访问
- 如果应用运行时依赖某个不属于平台 shared 的私有服务Chart / release bundle 必须把该依赖的来源表达清楚:要么生成应用自带资源,要么明确引用用户已提供的外部地址;不要只留下一个指向不存在服务的 host - 不生成 Ingress 模板,也不保留 Ingress values
- 应用自带的私有依赖如果同时需要应用口令和依赖自身启动口令Secret key 设计要把两种消费方式都表达清楚;例如既保留 `neo4j_password` 供业务容器连接使用,也额外提供 `neo4j_auth` 这类组合值供 Neo4j 自身启动使用 - `NodePort` 必须来自用户或平台已分配值,不能猜
- `NodePort` 必须来自用户或平台已分配值agent 不得自行猜测或默认分配端口
- 不要生成 Ingress 模板或 Ingress values
- 设置 `enableServiceLinks: false` - 设置 `enableServiceLinks: false`
- 支持 `imagePullSecrets` - 支持 `imagePullSecrets`
- 环境变量注入保持可读 - 环境变量注入保持可读
- 如果镜像内自带 nginx / 反向代理配置upstream service 名必须与 Chart 实际渲染出来的 Service 名一致;如果 Chart 使用 `fullname` 前缀,就不要在镜像配置里写裸服务名 `server`、`mcp`、`frontend` - 如果镜像内带 nginx / 反向代理配置upstream service 名必须与 Chart 渲染出的 Service 名一致
- Kubernetes `env.value` 不会展开 `$(OTHER_ENV)` 这种 shell 变量引用;不要生成 `NEO4J_AUTH=neo4j/$(NEO4J_PASSWORD)` 这类写法并假设容器启动时会自动拼接 - 不要依赖 Kubernetes 不支持的 `$(OTHER_ENV)` 展开
- 对像 Neo4j 这类会把 `NEO4J_*` 解析为配置项的镜像,不要额外注入并不存在的配置名,例如 `NEO4J_PASSWORD` - 对 Neo4j 这类镜像,不要注入不存在的 `NEO4J_*` 配置名,例如 `NEO4J_PASSWORD`
- 健康检查要符合真实应用行为
`_helpers.tpl` 一般至少提供 如果应用依赖平台 shared 之外的私有服务,必须明确表达依赖来源:
- chart name - 要么由 Chart 生成应用自带资源
- fullname - 要么明确引用用户提供的外部地址
- namespace
- labels
- selector labels
只有当项目本身确实有 path 推导的 URL 时,才增加 URL helper。 不能只留一个指向不存在服务的 host。
如果应用自带依赖同时需要业务连接口令和依赖自身启动口令Secret key 要同时表达两种消费方式,例如:
- `neo4j_password`
- `neo4j_auth`
## 对外暴露模型 ## 对外暴露模型
对外暴露模型使用固定方式。 固定使用:
- 固定使用 nginx 作为统一入口,代理前端与后端路径 - nginx 作为统一入口
- 对外只暴露 nginx 入口,并通过 `NodePort` 提供入口访问 - 对外只暴露一个 nginx `NodePort`
- 后端服务默认只在集群内通信 - 后端服务只在集群内通信
- 每个应用对外只保留一个 nginx `NodePort` 入口 - 不生成 Ingress
- 不生成 Ingress 资源,也不要在 values 中保留 Ingress 开关
- 不要因为应用有多个内部服务,就擅自发明多个公网 host
如果项目当前没有现成的前端代理层,也应按这个固定模型为对外入口预留 nginx 代理方案,而不是改成 Ingress。
`NodePort` 处理规则: `NodePort` 处理规则:
- 如果用户或项目文档已经提供了分配好的 `NodePort`,直接使用 - 用户或文档已提供时直接使用
- 如果没有提供,在生成到这一项时立即停下来索取该端口 - 没提供时,在生成到这一项时立即索取
- 不要擅自写入示例端口或看起来顺手的默认值,例如 `30080`、`30081` - 不要写示例端口或默认端口
- 如果用户暂时没有提供,就停在这一项等待补值,不要擅自填入
## Release Bundle 规则 ## Release Bundle 规则
应用仓库中的 `deploy/release/` 是导出给当前 GitOps 仓库的标准模板。
### `metadata.yaml` ### `metadata.yaml`
至少包含: 至少包含:
- 应用名 - 应用名
- Kubernetes release 名 - release 名
- namespace - namespace
- chart 名 - chart 名
- chart 版本 - chart 版本
@ -296,40 +283,34 @@ deploy/helm/<app-name>/
### `values.yaml` ### `values.yaml`
必须是可用于部署默认值,不是示例值。 必须是可部署默认值,不是示例值。
至少满足: 至少满足:
- 应用自己构并发布的运行时镜像使用 `registry.baizhi.cloud/<app-name>/...` - 应用自建镜像使用 `registry.baizhi.cloud/<app>/...`
- 第三方基础镜像或官方镜像如果并未由当前应用 CI 同步到平台 registry保持真实来源,不要擅自改写成 `registry.baizhi.cloud/library/...` - 第三方镜像保持真实来源
- Secret 名符合平台约定 - Secret 名与 Chart 约定一致
- 私有镜像拉取时包含 `imagePullSecrets` - 私有镜像包含 `imagePullSecrets`
- 与 Chart schema 保持一致 - 与 Chart schema 一致
- nginx 对外入口使用 `NodePort` - nginx 对外入口使用 `NodePort`
- `NodePort` 值来自用户或平台分配结果,而不是模板内置默认值 - `NodePort` 值来自用户或平台分配结果
- 不包含 Ingress 配置项 - 不包含 Ingress 配置项
### `secret.yaml` ### `secret.yaml`
用于放应用私有 Secret 模板key 名必须与 Chart 读取的 key 对齐。 只放应用私有 Secretkey 名必须与 Chart 读取的 key 对齐。
规则: 规则:
- 不要为了“看起来完整”而伪造假的生产值 - 不伪造生产值
- 先区分“外部集成凭据”和“应用自带私有依赖的内部口令” - 外部集成凭据在生成到对应配置时逐项索取
- 如果是外部集成凭据,应在生成到对应配置时主动向用户索取 - 应用自带私有依赖的内部口令优先自动生成
- 如果是应用自带私有依赖的内部口令,优先由生成流程一次性生成并写入 release secret而不是要求用户手填 - 组合型鉴权字段优先直接写成完整 key 值
- 如果某个工作负载需要组合型鉴权字段,例如 `username/password` 形式的单个环境变量,优先在 Secret 中直接写出完整值,再由 workload 直接读取该 key - 缺值时停在当前项继续问,不要留看似可部署的假配置
- 如果用户暂时没有提供,不要造占位内容冒充可部署配置
- 对部署阻塞项,按最小必要粒度逐项提问,优先直接问“这一项应填什么”
- 在交互会话中,如果当前步骤需要某个必填项才能继续,就先向用户索取当前顺序中的下一项
- 可以只保留结构,或暂不生成具体 secret 内容,但不要用伪造值把未完成配置包装成已完成
release bundle 只负责导出当前应用自己的发布结果,不负责维护 GitOps 仓库中的其他对象。
## 平台共享配置契约 ## 平台共享配置契约
`shared/` 目录只放平台级共享配置。 `shared/` 只放平台级共享配置。
共享资源: 共享资源:
@ -337,12 +318,12 @@ release bundle 只负责导出当前应用自己的发布结果,不负责维
- `platform-shared-secrets` - `platform-shared-secrets`
- `registry-pull-secret` - `registry-pull-secret`
当前 `platform-runtime-config` 提供: `platform-runtime-config` 提供:
- `LLM_BASE_URL` - `LLM_BASE_URL`
- `EMBEDDER_BASE_URL` - `EMBEDDER_BASE_URL`
当前 `platform-shared-secrets` 提供: `platform-shared-secrets` 提供:
- `POSTGRES_USER` - `POSTGRES_USER`
- `POSTGRES_PASSWORD` - `POSTGRES_PASSWORD`
@ -351,104 +332,104 @@ release bundle 只负责导出当前应用自己的发布结果,不负责维
- `MINIO_ACCESS_KEY` - `MINIO_ACCESS_KEY`
- `MINIO_SECRET_KEY` - `MINIO_SECRET_KEY`
shared 边界 平台共享基础设施固定为
- shared 只负责共享基础设施和通用运行时地址 - `PostgreSQL`
- 平台共享基础设施包括 `PostgreSQL`、`Redis`、`Qdrant`、`MinIO` - `Redis`
- 应用 Chart / release bundle 默认应引用这些 shared 组件的既有服务地址与 shared Secret不要重复生成这些工作负载 - `Qdrant`
- 这些 shared 组件默认使用以下固定 FQDN`postgres.infra.svc.cluster.local`、`redis.infra.svc.cluster.local`、`qdrant.infra.svc.cluster.local`、`minio.infra.svc.cluster.local` - `MinIO`
- 不要默认写成当前应用 namespace 下的裸服务名,例如 `postgres`、`redis`、`qdrant`、`minio`
- 只有当用户明确要求该应用自带独立实例时,才为 `PostgreSQL`、`Redis`、`Qdrant`、`MinIO` 生成应用私有资源 固定 FQDN
- 平台共享基础设施不包含 `Neo4j`;如应用需要图数据库,应由应用自己部署和维护
- 只要应用运行时配置仍引用某个应用私有依赖,就应在应用 Chart / release bundle 中把它一并表达出来,而不是只在 values 里保留连接参数 - `postgres.infra.svc.cluster.local`
- 不要把某个厂商的客户端证书、私钥、应用专属 `app_id`、tenant id、client id、namespace id、应用独有 webhook 签名密钥放进 `shared/` - `redis.infra.svc.cluster.local`
- 镜像拉取默认使用 `registry-pull-secret`,不要随便为每个应用再造一个 pull secret除非平台模型发生变化 - `qdrant.infra.svc.cluster.local`
- 如果 Chart 通过 `imagePullSecrets`、`platform-runtime-config`、`platform-shared-secrets` 或应用私有 release secret 引用运行时资源,而这些资源不是由 Chart 直接创建,就必须确保 `releases/<app>/manifests/` 仍然会把它们应用到目标 namespace - `minio.infra.svc.cluster.local`
固定规则:
- 不要写成当前应用 namespace 下的裸服务名
- 不默认为 `PostgreSQL`、`Redis`、`Qdrant`、`MinIO` 生成应用私有实例
- `Neo4j` 不属于 shared如应用需要由应用自己部署
- 不要把应用私有鉴权材料放进 `shared/`
- 如果 Chart 依赖的运行时资源不是由 Chart 直接创建,就必须确保 `releases/<app>/manifests/` 仍会把这些资源 apply 到目标 namespace
## 百智云用户鉴权接入 ## 百智云用户鉴权接入
平台接入要求百智云用户鉴权。 这是平台必填接入项
处理规则: 固定规则:
- 不要把这类鉴权材料当成平台共享配置 - 不要把鉴权材料放进 `shared/`
- 不要擅自生成生产值 - 不要伪造生产值
- 鉴权材料均为必填项 - 按固定顺序逐项索取:`app_id` -> `app.crt` -> `app.key` -> `ca.crt` -> `public.key`
- 鉴权材料按固定顺序向用户索取:`app_id` -> `app.crt` -> `app.key` -> `ca.crt` -> `public.key` - 缺少哪一项,就停在那一项继续问
- 如果用户还没提供完整值,不要写伪造占位内容
opensdk 读取与挂载规则: 挂载规则:
- 当前接入只要求提供 `app_id` 与证书文件挂载 - 固定挂载目录:`/app/ssl`
- opensdk 会从固定路径读取证书文件,而不是从环境变量读取路径 - 固定文件路径:`/app/ssl/app.crt`、`/app/ssl/app.key`、`/app/ssl/ca.crt`
- 固定文件路径是:`/app/ssl/app.crt`、`/app/ssl/app.key`、`/app/ssl/ca.crt` - 不要改成其他自定义目录
- 因此在 Chart / workload 中,应把百智云 Secret 以文件名不变的方式挂载到目录 `/app/ssl` - `public.key` 如果保留,应明确其用途,不要混同为 mTLS 必需文件
- 不要把证书挂到其他自定义目录后期待 opensdk 自动发现,例如 `/.tls/baizhi`
- `public.key` 不属于当前 opensdk 建立 mTLS 连接时的必读文件;如果平台或应用仍要求保留它,应明确说明它的用途,不要把它和 mTLS 必需挂载文件混为一谈
提问方式要求: ## 提问方式
- 只在真正阻塞最终可部署结果时才问 - 只问当前步骤真正阻塞的值
- 按必填项收集百智云配置 - 逐项问,不要一次性要一大串
- 按固定顺序逐项索取 `app_id`、`app.crt`、`app.key`、`ca.crt`、`public.key` - 对外部集成字段,在写到对应配置时就问
- 对外部集成字段,在生成到对应配置时逐项索取 - 对应用自带私有依赖内部口令,优先自动生成
- 如果当前正在等待用户补值,就把回复重点放在“当前要补的这一项” - 如果当前正在等补值,回复重点只放当前这一项
- 对应用自带私有依赖内部口令,优先自动生成;只有用户明确要求自定义时才向用户索取
- 不要用“把需要的都给我”这种模糊问法
- 缺少任一必填项时,要明确指出当前卡在哪一项
## 执行流程 ## 执行顺序
建议按下面顺序推进: 按下面顺序推进:
1. 读取应用 README 与构建文件,梳理组件和暴露模型 1. 读 README 与构建文件
2. 判断任务是补齐应用仓库接入,还是修复发版链路 2. 梳理组件、依赖、暴露模型
3. 生成或修复 `.gitlab-ci.yml` 3. 生成或修复 `.gitlab-ci.yml`
4. 生成或修复 Chart 与 values 4. 生成或修复 Chart
5. 在遇到必填值缺失时,停在当前项并向用户补值 5. 缺少必填值时停在当前项索取
6. 生成或修复 release bundle 6. 生成或修复 `deploy/release/`
7. 自检并在最终输出中说明风险点 7. 自检并汇报风险点
## 自检要求 ## 自检
完成后尽量执行: 完成后尽量执行:
- `git status --short` - `git status --short`
- `git diff --check` - `git diff --check`
- `helm template`,前提是 Chart 与 values 已能渲染 - `helm template`(前提是 Chart 与 values 已能渲染)
至少确认: 至少确认:
- 应用仓库接入文件齐全 - 接入文件齐全
- `.gitlab-ci.yml` 包含 test、镜像构建、chart 发布、release 结果同步逻辑 - `.gitlab-ci.yml` 包含 test、镜像构建、Chart 发布、GitOps 同步
- release values 指向 `registry.baizhi.cloud` - release values 指向 `registry.baizhi.cloud`
- 非当前应用自行发布的第三方镜像仍保持真实来源,不会被错误改写到平台 registry - 第三方镜像没有被错误改写到平台 registry
- GitOps 仓库更新 job 指向 `https://deploy.baizhi.cloud/gitops-admin/argodeploy.git` - GitOps update job 指向 `https://deploy.baizhi.cloud/gitops-admin/argodeploy.git`
- CI 中没有直接调用 Argo - CI 中没有直接调用 Argo
- 使用 `deploy.baizhi.cloud``registry.baizhi.cloud` - 使用 `deploy.baizhi.cloud``registry.baizhi.cloud`
- 没有使用不安全的 HTTP registry 访问方式 - 没有使用不安全的 registry 访问方式
- 如果 `Application` 仍引用 `releases/<app>/manifests/`,该 path 在发布结果中实际存在且能渲染;如果发布结果不再包含该 path`Application` 中也不会残留这个 source - 如果 `Application` 仍引用 `releases/<app>/manifests/`,该 path 在发布结果中实际存在
- 如果镜像内包含固定 upstream 配置upstream service 名与当前 Chart 渲染的 Service 名保持一致,不会出现 `host not found in upstream` 这类启动错误 - 如果镜像内包含固定 upstream 配置upstream service 名与 Chart 渲染结果一致
- Neo4j 一类自带依赖的启动环境变量不依赖 Kubernetes 不支持的 `$(OTHER_ENV)` 展开 - Neo4j 一类自带依赖的启动环境变量不依赖 `$(OTHER_ENV)` 展开
- 如果存在用户未提供的必填私有配置,交互会话会继续停在当前必填项上索取补值 - 缺少必填私有配置时,交互停在当前项继续索取
## 最终输出要求 ## 最终输出
默认按下面结构汇报: 默认按这个顺序汇报:
1. 修改了哪些文件 1. 修改了哪些文件
2. 关键设计决策 2. 关键决定
3. 最值得人工复核的 3 个 3. 最值得人工复核的点
## 常见错误 ## 常见错误
以下都属于接入错误:
- 把应用私有鉴权材料放进 `shared/` - 把应用私有鉴权材料放进 `shared/`
- 在 CI 里直接刷新 Argo - 在 CI 里直接刷新 Argo
- 重新引入已废弃的旧域名 - 重新引入旧域名
- 使用 insecure registry 参数 - 使用 insecure registry 参数
- 生成的 Chart 与应用真实组件不匹配 - Chart 与应用真实组件不匹配
- 在生产 release values 中写 `registry.example.com` 这类示例地址 - 在生产 release values 中写示例地址
- 应用没有这个设计却擅自发明新的公网 host - 擅自发明新的公网 host
- 在用户没有提供必填私有值时,仍然伪造占位内容并假装可以直接部署 - 用户未提供必填值时伪造占位内容