554 lines
25 KiB
Markdown
554 lines
25 KiB
Markdown
---
|
||
name: gitops-app-onboarding
|
||
description: 面向当前 Baizhi GitOps 平台的项目接入工作流,只适用于 `deploy.baizhi.cloud`、`registry.baizhi.cloud`、GitLab + Argo CD 这套固定交付模型。只要用户提到“给当前平台接入新项目”“恢复 .gitlab-ci.yml / deploy 目录”“补齐当前平台的 Helm chart / release bundle”“修当前平台的发版链路”“让应用仓库在发版时推送自己的 release 结果”,就应优先使用这个 skill;如果只是通用 CI、通用 Helm 或通用 GitOps 任务而未指向当前平台,不应触发。
|
||
---
|
||
|
||
# GitOps 项目接入 Skill
|
||
|
||
## 目标
|
||
|
||
让 agent 能独立完成下面四件事:
|
||
|
||
- 生成或修复 `.gitlab-ci.yml`
|
||
- 生成或修复 `deploy/helm/<app>/`
|
||
- 生成或修复 `deploy/release/`
|
||
- 让发版链路把当前应用的发布结果同步到固定 GitOps 仓库
|
||
|
||
## 平台固定常量
|
||
|
||
除非用户明确要求修改,否则固定使用:
|
||
|
||
- GitOps 主机:`deploy.baizhi.cloud`
|
||
- Registry 主机:`registry.baizhi.cloud`
|
||
- Helm OCI 仓库:`oci://registry.baizhi.cloud/helm`
|
||
- GitOps 仓库地址:`https://deploy.baizhi.cloud/gitops-admin/argodeploy.git`
|
||
- Registry 用户名:`registry-ci`
|
||
- 共享 pull secret:`registry-pull-secret`
|
||
- GitOps 控制器:Argo CD
|
||
- 代码托管:GitLab
|
||
|
||
GitLab CI 默认依赖这些变量:
|
||
|
||
- `GITEA_USER`
|
||
- `GITEA_TOKEN`
|
||
- `REGISTRY_PASSWORD`
|
||
|
||
## 开始前先做什么
|
||
|
||
先按这个顺序读仓库:
|
||
|
||
1. `README.md`
|
||
2. Dockerfile、包管理文件、构建脚本、已有 deploy 文件
|
||
3. 用户提供的额外设计文档
|
||
|
||
在动手前先确定:
|
||
|
||
- 组件列表
|
||
- 每个组件的构建上下文与入口
|
||
- 对外暴露方式
|
||
- 运行时配置结构
|
||
- 平台共享依赖与应用私有依赖
|
||
- 是否检测到私有 Git 依赖(例如 `git.in.chaitin.net/ai/baizhiyun/opensdk`)
|
||
|
||
应用仓库自己的 `README.md` 是应用运行架构的真相来源;本 skill 只定义平台接入规则。
|
||
|
||
## 边界
|
||
|
||
- 只处理应用仓库侧接入
|
||
- 不修改与当前应用无关的 GitOps 清单
|
||
- 对 GitOps 的唯一动作,是在应用仓库 CI 中同步当前应用自己的 release 结果与版本引用
|
||
- 如果当前应用的 `Application` 已存在,只允许更新 `apps/<app>/application.yaml` 中当前应用 chart source 的 `targetRevision`
|
||
- 不修改 `AppProject`、bootstrap、其他应用的 `Application`
|
||
|
||
## 应用仓库必须产出哪些文件
|
||
|
||
### CI
|
||
|
||
- `.gitlab-ci.yml`
|
||
|
||
### Chart
|
||
|
||
- `deploy/helm/<app>/Chart.yaml`
|
||
- `deploy/helm/<app>/values.yaml`
|
||
- `deploy/helm/<app>/templates/*`
|
||
|
||
### release 作者源
|
||
|
||
- `deploy/release/metadata.yaml`
|
||
- `deploy/release/values.yaml`
|
||
- `deploy/release/secret.yaml`
|
||
|
||
## GitOps 仓库里最终应该有哪些文件
|
||
|
||
CI 导出结果固定为:
|
||
|
||
- `deploy/release/metadata.yaml` -> `releases/<app>/metadata.yaml`
|
||
- `deploy/release/values.yaml` -> `releases/<app>/values.yaml`
|
||
- `deploy/release/secret.yaml` -> `releases/<app>/manifests/secret.yaml`
|
||
- `apps/<app>/application.yaml` -> 只更新 chart source 的 `targetRevision`
|
||
|
||
固定规则:
|
||
|
||
- 不导出 `releases/<app>/secret.yaml`
|
||
- 不生成或覆盖 `db-secret.yaml`、 `kustomization.yaml` 这类 GitOps 仓库里已有的文件
|
||
|
||
## GitLab CI 规则
|
||
|
||
### 私有 Git 依赖判定口径
|
||
|
||
下文中的“检测到私有 Git 依赖”统一指:仓库在 `go.mod`、`go.sum`、源码 import、构建脚本或 Dockerfile 构建流程中,实际引用了需要认证访问的私有 Git 仓库(例如 `git.in.chaitin.net/ai/baizhiyun/opensdk`)。
|
||
|
||
只有在检测到这类依赖时,才启用 `.netrc`、私有仓库认证,以及 `GOPRIVATE`、`GONOSUMDB`、`GONOPROXY`、`GOINSECURE`、`GIT_SSL_NO_VERIFY` 这一组私有 Go 变量;否则不要添加这些配置。
|
||
|
||
### stages
|
||
|
||
固定使用:
|
||
|
||
- `test`
|
||
- `build`
|
||
- `release`
|
||
|
||
### runner tags
|
||
|
||
只要 job 使用 Docker、DinD 或 `docker buildx`,就必须带:
|
||
|
||
- `docker`
|
||
- `network`
|
||
|
||
### test job
|
||
|
||
用途:只做测试,不改 GitOps,不推镜像。
|
||
|
||
要求:
|
||
|
||
- 运行在分支和 MR 上,打 `vX.Y.Z` 发布 tag 时不运行 test job
|
||
- 安装当前语言栈的最小依赖
|
||
- 只有检测到私有 Git 依赖时才补齐认证;否则不要引入 `.netrc`
|
||
- 使用项目原生测试入口
|
||
|
||
Go 项目默认变量写在 `.gitlab-ci.yml` 的 `variables:`:
|
||
|
||
- `GOPROXY=https://goproxy.cn,direct`
|
||
- `GOSUMDB=sum.golang.google.cn`
|
||
|
||
只有检测到私有 Git 依赖时,才额外设置这些变量:
|
||
|
||
- `GOPRIVATE=git.in.chaitin.net`
|
||
- `GONOSUMDB=git.in.chaitin.net`
|
||
- `GONOPROXY=git.in.chaitin.net`
|
||
- `GOINSECURE=git.in.chaitin.net`
|
||
- `GIT_SSL_NO_VERIFY="true"`
|
||
|
||
### release 触发条件
|
||
|
||
只在 `vX.Y.Z` tag 上触发发布链路。
|
||
|
||
### image build jobs
|
||
|
||
输入:源码、Dockerfile、单组件构建上下文。
|
||
|
||
输出:分别推送到 `registry.baizhi.cloud/<app>/<component>:<version>` 的运行时镜像。
|
||
|
||
设计原则:不同服务的镜像必须独立构建,避免一个组件改动或失败拖慢所有组件发布。
|
||
|
||
要求:
|
||
|
||
- 不要生成一个串行构建所有镜像的单体 `build-images` job;每个需要构建镜像的服务使用独立 job,例如 `build-backend-image`、`build-frontend-image`、`build-nginx-image`
|
||
- 如果多个组件构建脚本完全一致,可以使用 `parallel:matrix`,但矩阵中的每个组件仍必须是 GitLab 可独立调度、独立失败、独立重试的构建单元
|
||
- 每个镜像构建 job 只负责一个组件的 Dockerfile、构建上下文、tag 与 push
|
||
- release 链路必须等待所有应用自建镜像构建成功;优先用 `needs:` 精确声明,而不是只依赖 stage 顺序
|
||
- 登录 `registry.baizhi.cloud`
|
||
- 优先使用 `docker buildx`
|
||
- 只有检测到私有 Git 依赖时,才通过 `.netrc` 和 build secret 传入;否则不要生成 `.netrc` 相关步骤
|
||
- 如需额外 CA,也通过 build secret 传入
|
||
- 如果 Dockerfile 中使用 Docker Hub 源作为 `FROM` 基础镜像或其他拉取来源,需改写为 `registry-mirrors.dev.in.chaitin.net` 对应镜像源;不要保留对 Docker Hub 的直接拉取
|
||
- 如果 Dockerfile 中使用 `apk`,需要将 apk 软件源切换为中科大源后再安装依赖
|
||
- 如果 Dockerfile 内会执行 `go mod download`、`go build` 等 Go 构建命令,必须通过 `--build-arg` 透传 Go 构建变量,不要只写在 `.gitlab-ci.yml` 的 `variables:` 里
|
||
- 无论是否检测到私有 Git 依赖,至少透传:`GOPROXY`、`GOSUMDB`
|
||
- 只有检测到私有 Git 依赖时,才额外透传:`GOPRIVATE`、`GONOSUMDB`、`GONOPROXY`、`GOINSECURE`
|
||
- Dockerfile 中对应变量必须有 `ARG`,并让构建命令实际使用传入值,而不是退回默认值
|
||
|
||
禁止:
|
||
|
||
- `http://registry...`
|
||
- `--plain-http`
|
||
- `--insecure-skip-tls-verify`
|
||
- 不要假设 `.gitlab-ci.yml` 中的环境变量会自动进入 `docker build` / `docker buildx build`
|
||
|
||
### GitLab CI YAML 与脚本合法性
|
||
|
||
生成或修复 `.gitlab-ci.yml` 时要优先保证 GitLab CI 配置本身可解析、可执行、可维护。
|
||
|
||
要求:
|
||
|
||
- 不要在 CI 脚本里用 Python 临时解析或改写 YAML;优先使用 `yq`、`helm`、`git`、`install`、`mkdir`、`cp`、`rsync` 这类明确的 CLI
|
||
- 修改 `Chart.yaml` 的 `version` / `appVersion` 使用 `yq -i`,不要用 Python heredoc 或内联脚本
|
||
- 修改 Argo CD `Application` 的 `targetRevision` 时,按当前平台的 `spec.sources` 多 source 结构定位当前 chart source;推荐使用类似 `(.spec.sources[] | select(.chart == strenv(CHART_NAME))).targetRevision = strenv(VERSION)` 的简单 yq selector
|
||
- yq 表达式中通过 `strenv(...)` 读取的变量必须先 `export`,例如 `export VERSION="${CI_COMMIT_TAG#v}"`;不要只做 shell 局部赋值
|
||
- CI 中通过 `apk add yq` 安装的 yq 只使用已验证的简单表达式;不要为了兼容 `.spec.source` 单 source 生成 `if ... then ... elif ... else ... end` 这类条件表达式
|
||
- 对 CI 文件做合法性自检时,至少能用 `yq e '.' .gitlab-ci.yml` 验证 YAML 语法;如果环境有 GitLab CI lint 工具或 API,再补充 GitLab 语义校验
|
||
- `.gitlab-ci.yml` 中的多行 shell 逻辑保持最小化;复杂到需要编程语言脚本时,优先把脚本提交到仓库中的可审查文件,而不是在 CI YAML 里塞内联程序
|
||
|
||
禁止:
|
||
|
||
- 在 `.gitlab-ci.yml` 中嵌入 `python - <<'PY'`、`python -c` 或临时 Python 脚本来改 YAML
|
||
- 用字符串替换方式盲改 `application.yaml` 中所有 `targetRevision`,或生成兼容 `.spec.source` 单 source 的 yq 分支表达式
|
||
- 在使用 yq `strenv(...)` 前只设置局部变量但不 `export`
|
||
|
||
### package-chart job
|
||
|
||
输入:`deploy/helm/<app>/Chart.yaml`、`deploy/helm/<app>/values.yaml`、`deploy/helm/<app>/templates/*`
|
||
|
||
输出:推送到 `oci://registry.baizhi.cloud/helm` 的 Chart 包。
|
||
|
||
要求:
|
||
|
||
- `helm registry login registry.baizhi.cloud`
|
||
- 在临时目录复制 `deploy/helm/<app>/`
|
||
- 用 `yq -i` 把复制品中的 `version` 和 `appVersion` 改成 tag 版本
|
||
- 业务镜像的默认 tag 必须跟随 `appVersion`,不要依赖 release values 覆盖业务镜像 tag
|
||
- `helm package`
|
||
- `helm push`
|
||
- 如果应用包含自建镜像,`package-chart` 必须通过 `needs:` 等待所有镜像构建 job 成功
|
||
|
||
### update-gitops-repo job
|
||
|
||
输入:`deploy/release/*`、当前 tag 版本、GitOps 仓库中的 `apps/<app>/application.yaml`
|
||
|
||
输出:
|
||
|
||
- `releases/<app>/metadata.yaml`
|
||
- `releases/<app>/values.yaml`
|
||
- `releases/<app>/manifests/` 下的发布结果
|
||
- `apps/<app>/application.yaml` 中当前应用 chart source 的 `targetRevision`
|
||
|
||
依赖关系:
|
||
|
||
- `update-gitops-repo` 必须显式依赖 `package-chart` 成功,优先写 `needs: ["package-chart"]`
|
||
- 不要让 `update-gitops-repo` 和 `package-chart` 仅靠同 stage 顺序或隐式执行顺序关联
|
||
- 如果 release stage 中还有其他准备 job,也必须保证 GitOps 仓库更新发生在 Chart 包成功推送之后
|
||
|
||
处理顺序固定为:
|
||
|
||
1. 克隆 `https://${GITEA_USER}:${GITEA_TOKEN}@deploy.baizhi.cloud/gitops-admin/argodeploy.git`
|
||
2. 确保 `releases/<app>/` 与 `releases/<app>/manifests/` 存在,不要整体清空目录
|
||
3. 将应用仓库中的 `deploy/release/metadata.yaml` 和 `deploy/release/values.yaml` 复制到 GitOps 仓库的 `releases/<app>/metadata.yaml` 与 `releases/<app>/values.yaml`,覆盖已有内容
|
||
4. 保留已有的 `releases/<app>/manifests/kustomization.yaml` 与 `releases/<app>/manifests/db-secret.yaml`
|
||
5. 将 `deploy/release/secret.yaml` 物化为 `releases/<app>/manifests/secret.yaml`
|
||
6. 替换 `releases/<app>/metadata.yaml` 中的 `__VERSION__`;只有第三方镜像、非业务版本字段或明确需要的环境配置才允许替换 `releases/<app>/values.yaml` 中的 `__VERSION__`
|
||
7. 用简单 yq selector 更新 `apps/<app>/application.yaml` 中当前应用 chart source 的 `targetRevision`,只改当前应用的 chart source
|
||
8. 只有存在 diff 时才提交并推送 `main`
|
||
|
||
禁止:
|
||
|
||
- 在 CI 中调用 `kubectl`
|
||
- 在 CI 中调用 `argocd app sync`
|
||
- 把 hard refresh 当常规发布步骤
|
||
- 在 Chart 包推送成功前更新 GitOps 仓库
|
||
|
||
## Helm Chart 规则
|
||
|
||
Chart 必须反映应用的真实运行架构。
|
||
|
||
固定要求:
|
||
|
||
- 按职责拆文件,不堆一个大模板
|
||
- 模板中不硬编码生产 tag
|
||
- 所有镜像名从 values 读取
|
||
- 应用自己构建的业务镜像 tag 默认必须来自 `.Chart.AppVersion`,values 中的 tag 只能作为显式覆盖项
|
||
- Deployment 模板必须使用类似 `{{ default .Chart.AppVersion .Values.<component>.image.tag }}` 的逻辑渲染业务镜像 tag
|
||
- `deploy/helm/<app>/values.yaml` 中业务镜像 `tag` 默认写空字符串或不写,不要写生产版本号
|
||
- 所有 Service 暴露方式从 values 读取
|
||
- nginx 对外 Service 固定使用 `NodePort`
|
||
- 后端 Service 只做集群内访问
|
||
- 不生成 Ingress 模板,也不保留 Ingress values
|
||
- `NodePort` 必须来自用户或平台已分配值,不能猜
|
||
- 设置 `enableServiceLinks: false`
|
||
- 支持 `imagePullSecrets`
|
||
- 如果应用包含需要持久化数据的服务,PVC / `volumeClaimTemplates` 必须显式使用 `storageClassName: longhorn`
|
||
- 环境变量注入保持可读
|
||
- 如果镜像内带 nginx / 反向代理配置,upstream service 名必须与 Chart 渲染出的 Service 名一致
|
||
- 生成 chart 时要确认应用是否包含需要经 nginx 转发的静态文件;如果有,必须明确静态资源目录、挂载方式和 nginx 路由,不要只配后端 upstream
|
||
- 不要依赖 Kubernetes 不支持的 `$(OTHER_ENV)` 展开
|
||
- 对 Neo4j 这类镜像,不要注入不存在的 `NEO4J_*` 配置名,例如 `NEO4J_PASSWORD`
|
||
|
||
### Argo CD sync-wave
|
||
|
||
当 Chart 或 release manifests 中存在资源依赖顺序时,使用 Argo CD sync wave 明确表达顺序,避免依赖文件名、模板渲染顺序或 Kubernetes 最终一致性碰运气。
|
||
|
||
固定规则:
|
||
|
||
- annotation 键必须写成 `argocd.argoproj.io/sync-wave`,不要写成 `rgocd.argoproj.io/sync-wave` 或其他拼写
|
||
- wave 值使用字符串,例如 `"-20"`、`"0"`、`"10"`
|
||
- 低 wave 先同步,高 wave 后同步;不要把依赖方和被依赖方放在同一个 wave
|
||
- `releases/<app>/manifests/` 下的资源也必须参与 wave 设计;不要只给 Helm Chart 模板里的资源排序
|
||
- 被 Job、Deployment、StatefulSet 或 Pod 通过 `envFrom`、`secretKeyRef`、`configMapKeyRef`、volume、`imagePullSecrets` 消费的 Secret / ConfigMap,wave 必须早于消费它们的 workload
|
||
- `registry-pull-secret`、`platform-shared-secrets` 等平台托管共享资源的 wave 已固定为 `"-1"`;不要修改它们,应用资源应围绕这个锚点排序
|
||
- `manifests/db-secret.yaml` 如果存在,必须早于所有读取 `databaseSecret` / `<app>-db` 的 migrate Job 和业务 workload;推荐使用 `"0"`
|
||
- 应用私有 Secret、应用私有 ConfigMap 必须早于所有会消费它们的 workload;推荐使用 `"0"`
|
||
- 只有确实存在跨资源启动顺序要求时才加 sync-wave,不要给所有资源机械添加 annotation
|
||
|
||
推荐顺序:
|
||
|
||
- `-1`:平台托管共享资源,例如 `registry-pull-secret`、`platform-shared-secrets`、平台共享 ConfigMap
|
||
- `0`:应用自有前置资源,例如 ServiceAccount、RBAC、`manifests/db-secret.yaml`、应用私有 Secret、应用私有 ConfigMap、PVC / `volumeClaimTemplates` 所依赖的存储前置资源
|
||
- `10`:migrate Job、应用自带的私有基础设施,例如 Neo4j、向量库、内部依赖服务的 StatefulSet / Deployment
|
||
- `15`:内部依赖的 Service,尤其是会被后续 nginx upstream 或应用启动配置引用的服务名
|
||
- `20`:后端、worker、API 等核心业务 Deployment / StatefulSet
|
||
- `25`:核心业务 Service
|
||
- `30`:nginx / frontend 入口 Deployment,以及对外 `NodePort` Service
|
||
|
||
如果 nginx 配置在容器启动时解析 upstream,必须保证 upstream 对应 Service 的 wave 早于 nginx Deployment;如果应用启动依赖 Secret / ConfigMap / PVC / imagePullSecret,必须保证这些资源的 wave 早于消费它们的 workload。尤其注意平台共享资源已经在 `"-1"`,应用自有 secret/config 应从 `"0"` 开始,migrate Job 这类消费者必须排在它们之后,例如 `"10"`,不能把消费者放到 `"-10"` 或同一个 wave 里。
|
||
|
||
生成或修复 release manifests 时,逐项核对:
|
||
|
||
- `releases/<app>/manifests/db-secret.yaml` 的 wave 早于 Chart 中所有引用该 secret 的 Job / Deployment / StatefulSet
|
||
- `releases/<app>/manifests/secret.yaml` 的 wave 早于 Chart 中所有引用该 secret 的 workload
|
||
- `registry-pull-secret` 在目标 namespace 存在,且 wave 早于所有使用私有镜像的 workload
|
||
- 共享 secret / config 如果由 release manifests 或 shared manifests 同步,也早于所有消费者
|
||
|
||
如果应用依赖平台 shared 之外的私有服务,必须明确表达依赖来源:
|
||
|
||
- 要么由 Chart 生成应用自带资源
|
||
- 要么明确引用用户提供的外部地址
|
||
|
||
不能只留一个指向不存在服务的 host。
|
||
|
||
如果应用自带依赖同时需要业务连接口令和依赖自身启动口令,Secret key 要同时表达两种消费方式,例如:
|
||
|
||
- `neo4j_password`
|
||
- `neo4j_auth`
|
||
|
||
## 对外暴露模型
|
||
|
||
固定使用:
|
||
|
||
- nginx 作为统一入口
|
||
- 对外只暴露一个 nginx `NodePort`
|
||
- 后端服务只在集群内通信
|
||
- 不生成 Ingress
|
||
|
||
`NodePort` 处理规则:
|
||
|
||
- 用户或文档已提供时直接使用
|
||
- 没提供时,在生成到这一项时立即索取
|
||
- 不要写示例端口或默认端口
|
||
|
||
## Release Bundle 规则
|
||
|
||
### `metadata.yaml`
|
||
|
||
至少包含:
|
||
|
||
- 应用名
|
||
- release 名
|
||
- namespace
|
||
- chart 名
|
||
- chart 版本
|
||
- chart 仓库
|
||
- 镜像 tag
|
||
- 源码仓库地址
|
||
|
||
### `values.yaml`
|
||
|
||
必须是可部署默认值,不是示例值。
|
||
|
||
至少满足:
|
||
|
||
- 应用自建镜像使用 `registry.baizhi.cloud/<app>/...`
|
||
- 应用自建镜像不要在 release values 中写业务版本 tag;业务镜像 tag 默认由 Chart `appVersion` 决定,以便 Argo CD UI 回滚 Chart 版本时镜像版本同步回滚
|
||
- 第三方镜像保持真实来源
|
||
- 第三方镜像 tag 必须继续显式写在 values 中,不要跟随 Chart `appVersion`
|
||
- Secret 名与 Chart 约定一致
|
||
- PostgreSQL 连接读取应用自己的 `databaseSecret`
|
||
- 私有镜像包含 `imagePullSecrets`
|
||
- 与 Chart schema 一致
|
||
- 不要包含 `backend.image.tag`、`server.image.tag`、`frontend.image.tag`、`nginx.image.tag` 等应用自建业务镜像版本覆盖,除非用户明确要求做一次性特殊覆盖
|
||
- nginx 对外入口使用 `NodePort`
|
||
- `NodePort` 值来自用户或平台分配结果
|
||
- 不包含 Ingress 配置项
|
||
|
||
### `manifests/db-secret.yaml`
|
||
|
||
这是 deploy 仓库注册应用阶段生成的数据库源,secret 名称格式为 `<app>-db` 不是应用仓库侧要生成的文件。至少包含:
|
||
|
||
- `host`
|
||
- `port`
|
||
- `database`
|
||
- `username`
|
||
- `password`
|
||
|
||
固定规则:
|
||
|
||
- chart 如果依赖 Postgres 则必须消费这个 secret
|
||
|
||
### `secret.yaml`
|
||
|
||
只放应用私有 Secret,key 名必须与 Chart 读取的 key 对齐。
|
||
|
||
规则:
|
||
|
||
- 不伪造生产值
|
||
- 外部集成凭据在生成到对应配置时逐项索取
|
||
- 应用自带私有依赖的内部口令优先自动生成
|
||
- 组合型鉴权字段优先直接写成完整 key 值
|
||
- 缺值时停在当前项继续问,不要留看似可部署的假配置
|
||
|
||
## 平台共享配置契约
|
||
|
||
`shared/` 只放平台级共享配置。
|
||
|
||
共享资源:
|
||
|
||
- `platform-runtime-config`
|
||
- `platform-shared-secrets`
|
||
- `registry-pull-secret`
|
||
|
||
`platform-runtime-config` 提供:
|
||
|
||
- `LLM_BASE_URL`
|
||
- `EMBEDDER_BASE_URL`
|
||
- `OSS_BUCKET`
|
||
|
||
`platform-shared-secrets` 提供:
|
||
|
||
- `REDIS_PASSWORD`
|
||
- `QDRANT_API_KEY`
|
||
- `OSS_ACCESS_KEY`
|
||
- `OSS_SECRET_KEY`
|
||
|
||
平台共享基础设施固定为:
|
||
|
||
- `PostgreSQL`
|
||
- `Redis`
|
||
- `Qdrant`
|
||
- `OSS`
|
||
|
||
固定 FQDN 与对象存储约定:
|
||
|
||
- `redis.infra.svc.cluster.local`
|
||
- `qdrant.infra.svc.cluster.local`
|
||
|
||
固定规则:
|
||
|
||
- 不要写成当前应用 namespace 下的裸服务名
|
||
- 不默认为 `Redis`、`Qdrant`、`OSS` 生成应用私有实例
|
||
- 如果应用当前使用的是 `MinIO` / S3 兼容配置,优先沿用现有对象存储配置结构接入平台对象存储;但不要默认假设 `MinIO` 客户端可直接连接平台 `OSS`,需根据仓库实际使用的 SDK 与平台提供的协议兼容性确认
|
||
- `Neo4j` 不属于 shared;如应用需要,由应用自己部署
|
||
- 不要把应用私有鉴权材料放进 `shared/`
|
||
- 如果 Chart 依赖的运行时资源不是由 Chart 直接创建,就必须确保 `releases/<app>/manifests/` 仍会把这些资源 apply 到目标 namespace
|
||
|
||
## 百智云用户鉴权接入
|
||
|
||
只有在检测到私有 Git 依赖,且该依赖就是 `git.in.chaitin.net/ai/baizhiyun/opensdk` 时才需要接入。
|
||
|
||
识别规则:
|
||
|
||
- 先按上文“私有 Git 依赖判定口径”检查仓库,再确认私有依赖中是否实际包含 `git.in.chaitin.net/ai/baizhiyun/opensdk`
|
||
- 只有确认包含这个依赖或导入时,才进入本节并索取百智云相关材料
|
||
- 如果仓库里没有这个包,就跳过整段,不要要求接入百智云,也不要生成对应配置
|
||
|
||
固定规则:
|
||
|
||
- 不要把鉴权材料放进 `shared/`
|
||
- 不要伪造生产值
|
||
- 按固定顺序逐项索取:`app_id` -> `app.crt` -> `app.key` -> `ca.crt` -> `public.key`
|
||
- 缺少哪一项,就停在那一项继续问
|
||
|
||
挂载规则:
|
||
|
||
- 固定挂载目录:`/app/ssl`
|
||
- 固定文件路径:`/app/ssl/app.crt`、`/app/ssl/app.key`、`/app/ssl/ca.crt`
|
||
- 不要改成其他自定义目录
|
||
- `public.key` 如果保留,应明确其用途,不要混同为 mTLS 必需文件
|
||
|
||
## 提问方式
|
||
|
||
- 只问当前步骤真正阻塞的值
|
||
- 逐项问,不要一次性要一大串
|
||
- 对外部集成字段,在写到对应配置时就问
|
||
- 对应用自带私有依赖内部口令,优先自动生成
|
||
- 如果当前正在等补值,回复重点只放当前这一项
|
||
|
||
## 执行顺序
|
||
|
||
按下面顺序推进:
|
||
|
||
1. 读 README 与构建文件
|
||
2. 梳理组件、依赖、暴露模型
|
||
3. 生成或修复 `.gitlab-ci.yml`
|
||
4. 生成或修复 Chart
|
||
5. 缺少必填值时停在当前项索取
|
||
6. 生成或修复 `deploy/release/`
|
||
7. 自检并汇报风险点
|
||
|
||
## 自检
|
||
|
||
完成后尽量执行:
|
||
|
||
- `git status --short`
|
||
- `git diff --check`
|
||
- `yq e '.' .gitlab-ci.yml`
|
||
- `helm template`(前提是 Chart 与 values 已能渲染)
|
||
|
||
至少确认:
|
||
|
||
- 接入文件齐全
|
||
- `.gitlab-ci.yml` YAML 语法合法,不包含用于改 YAML 的内联 Python
|
||
- `.gitlab-ci.yml` 包含 test、组件级独立镜像构建、Chart 发布、GitOps 同步
|
||
- test job 不在 `vX.Y.Z` 发布 tag 上运行
|
||
- 多服务应用的业务镜像不是由一个串行 `build-images` job 统一构建;每个自建镜像可被 GitLab 独立调度和重试
|
||
- `package-chart` 通过 `needs:` 等待所有必要镜像构建成功
|
||
- `update-gitops-repo` 通过 `needs:` 依赖 `package-chart` 成功
|
||
- release values 指向 `registry.baizhi.cloud`
|
||
- release values 不覆盖应用自建业务镜像 tag;业务镜像 tag 由 Chart `appVersion` 默认决定
|
||
- 第三方镜像没有被错误改写到平台 registry
|
||
- 第三方镜像仍显式固定 repository 和 tag,且没有错误跟随 Chart `appVersion`
|
||
- 如果 Dockerfile 原本使用 Docker Hub 源,已切换到 `registry-mirrors.dev.in.chaitin.net`,且未误改其他非 Docker Hub 镜像源
|
||
- 如果 Dockerfile 中使用 `apk`,已切换到中科大源
|
||
- GitOps update job 指向 `https://deploy.baizhi.cloud/gitops-admin/argodeploy.git`
|
||
- GitOps update job 用多 source yq selector 精确更新当前应用 chart source 的 `targetRevision`,且不包含单 source 兼容分支
|
||
- GitOps update job 中被 yq `strenv(...)` 读取的变量已提前 `export`
|
||
- CI 中没有直接调用 Argo
|
||
- 只使用 `deploy.baizhi.cloud` 与 `registry.baizhi.cloud`
|
||
- 没有使用不安全的 registry 访问方式
|
||
- 如果 `Application` 仍引用 `releases/<app>/manifests/`,该 path 在发布结果中实际存在
|
||
- 如果镜像内包含固定 upstream 配置,upstream service 名与 Chart 渲染结果一致
|
||
- Neo4j 一类自带依赖的启动环境变量不依赖 `$(OTHER_ENV)` 展开
|
||
- 如果应用包含需要持久化数据的服务,对应 PVC / `volumeClaimTemplates` 已显式设置 `storageClassName: longhorn`
|
||
- 如果资源存在启动顺序依赖,`argocd.argoproj.io/sync-wave` 拼写正确,wave 顺序符合依赖方向
|
||
- `releases/<app>/manifests/db-secret.yaml`、`secret.yaml`、pull secret、shared secret/config 的 wave 早于所有引用它们的 migrate Job 和业务 workload
|
||
- `registry-pull-secret`、`platform-shared-secrets` 等平台托管资源保持平台约定的 `"-1"`,应用自有前置资源围绕它排序,不要改平台资源 wave
|
||
- migrate Job 不要设置成负 wave;它依赖的应用自有 Secret / ConfigMap / DB secret 通常在 `"0"`,migrate Job 应排在更高 wave,例如 `"10"`
|
||
- 如果检测到的私有 Git 依赖中包含 `git.in.chaitin.net/ai/baizhiyun/opensdk`,缺少必填百智云私有配置时交互停在当前项继续索取
|
||
|
||
## 最终输出
|
||
|
||
默认按这个顺序汇报:
|
||
|
||
1. 修改了哪些文件
|
||
2. 关键决定
|
||
3. 最值得人工复核的点
|
||
|
||
## 常见错误
|
||
|
||
- 把应用私有鉴权材料放进 `shared/`
|
||
- 在 CI 里直接刷新 Argo
|
||
- 重新引入旧域名
|
||
- 使用 insecure registry 参数
|
||
- Chart 与应用真实组件不匹配
|
||
- 在生产 release values 中写示例地址
|
||
- 在 release values 中写应用自建业务镜像 tag,导致 Argo CD UI rollback 只回滚 Chart 但镜像仍被 `main` 上的 values 固定到新版本
|
||
- 擅自发明新的公网 host
|
||
- 在未检测到私有 Git 依赖中的 `git.in.chaitin.net/ai/baizhiyun/opensdk` 时仍强行接入百智云
|
||
- Dockerfile 明明使用了 Docker Hub / `apk` 默认源,却没有切到 `registry-mirrors.dev.in.chaitin.net` / 中科大源,或误改了原本不在 Docker Hub 的镜像源
|
||
- 用户未提供必填值时伪造占位内容
|
||
- 多个服务镜像塞进一个串行 build job,导致无法并行构建、无法单独重试、失败定位困难
|
||
- `update-gitops-repo` 没有依赖 `package-chart`,GitOps 仓库先于 Chart 推送被更新
|
||
- 在 `.gitlab-ci.yml` 中用 Python heredoc 临时改 `Chart.yaml`、release values 或 `application.yaml`
|
||
- yq 使用 `strenv(VERSION)`,但 CI 脚本只写 `VERSION="${CI_COMMIT_TAG#v}"` 而没有 `export VERSION="${CI_COMMIT_TAG#v}"`
|
||
- 为当前平台的 Application 更新逻辑生成 `.spec.sources` / `.spec.source` 双结构兼容表达式,导致 `apk add yq` 安装的 yq 解析失败
|
||
- `argocd.argoproj.io/sync-wave` 拼错为 `rgocd.argoproj.io/sync-wave`,或把依赖方放在被依赖资源之前
|
||
- 只给 Chart 模板资源设计 wave,却遗漏 `releases/<app>/manifests/db-secret.yaml`、`secret.yaml`、pull secret 等 release manifests,导致 migrate Job 先于 Secret 执行
|
||
- 不顾平台约定把 `registry-pull-secret`、`platform-shared-secrets` 等平台托管资源改成其他 wave;正确做法是保持它们在 `"-1"`,应用资源围绕 `"-1"` 排序
|