Files
pikasTech-unidesk/docs/plan/d601-k3s-dev-environment.md
2026-05-18 06:59:51 +00:00

352 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# D601 k3s 开发环境建设计划
> 状态:本过程计划的环境分支方案已废弃。长期权威规则以 `docs/reference/deploy.md` 和 `docs/reference/ci.md` 为准:dev/prod 期望状态统一写在 `master` 分支的根目录 `deploy.json`,通过 `environments.dev` 和 `environments.prod` 区分,不再以 `deploy/dev` 或 `deploy/prod` 分支作为环境事实源。本文件保留为阶段性历史计划,不作为新实现依据。
## 目标
在现有 D601 原生 k3s 集群内建设一套与生产隔离的 UniDesk 开发环境,让以 LLM 为主力的开发流程可以部署、破坏、重建和验证 backend-core、frontend、Code Queue 及其数据库依赖,而不打断生产主 server。
第一版必须支持通过 GitHub commit id 部署。长期控制点是 GitHub 托管的 `deploy.json`:部署某个环境时,自动读取对应 GitHub 环境分支里的 `deploy.json`,并应用其中声明的 commit id。
初始环境分支:
- `deploy/dev`:D601 k3s 开发环境的期望状态。
- `deploy/prod`:生产环境的期望状态。分支保护可以后续补上;第一版仍必须把 prod 部署命令和凭据与 dev 隔离。
## 非目标
- 第一版不创建第二套物理 k3s 控制平面。先复用现有 D601 原生 k3s 集群,通过 namespace 做隔离。
- 第一版不把生产主 server 的 backend-core/frontend 迁入 k3s。
- dev 环境不得共享生产 PostgreSQL 表、Provider 身份、Provider token、Code Queue 任务状态或部署 worktree 路径。
- `deploy/dev``deploy/prod` 不是普通源码开发分支的别名,只是环境期望状态分支。
## 目标开发拓扑
第一版 dev 环境运行在 D601 的 `unidesk-dev` namespace
- `postgres-dev`dev 独立 PostgreSQL StatefulSet,或等价的持久化数据库。
- `backend-core-dev`:从 `deploy/dev:deploy.json` 声明的 commit id 构建。
- `frontend-dev`:从 `deploy/dev:deploy.json` 声明的 commit id 构建,并且只代理到 `backend-core-dev`
- `code-queue-mgr-dev`:轻量 Code Queue 控制面,使用 dev 数据库。
- `code-queue-read-dev``code-queue-write-dev``code-queue-scheduler-dev`Code Queue k3s 执行组件,使用 dev 数据库、dev 日志、dev state 路径和 dev Code Queue 配置。
- 第一阶段访问方式可选:SSH port-forward 或 D601 私有 ingress。阶段 1 不要求公网暴露。
所有 dev 服务的 `/health` 必须输出环境身份:
- `environment=dev`
- namespace 名称
- 数据库名称
- service id
- GitHub repo 和 commit id
- 部署 ref,预期为 `origin/deploy/dev`
## 核心隔离规则
1. dev 服务只能使用 `unidesk-dev` namespace。
2. dev 服务必须使用 dev PostgreSQL 实例或 dev 数据库,不能连接生产 PostgreSQL。
3. dev Provider 身份必须独立,例如 `D601-dev`,不能复用生产 `D601` 的 provider id 或 provider token。
4. dev Code Queue 的 task、queue、attempt、notification 和 trace state 不能写入生产表;除非表名已经显式 namespace 化并经过安全验证。第一版优先使用独立 dev 数据库。
5. dev manifest 不得挂载生产部署根目录,例如主 server 的 `/root/unidesk` 或 D601 生产部署路径;除非只读挂载且确实用于诊断。
6. dev Code Queue 必须使用 dev workdir、dev log dir 和 dev state dir。
7. 生产部署不能读取本地 dirty `deploy.json`;必须从配置好的 GitHub 生产环境 ref 读取生产期望状态。
8. LLM/Code Queue 开发任务默认只获得 dev 部署凭据。
## 部署清单模型
环境 manifest 使用同一套 schema
```json
{
"schemaVersion": 1,
"environment": "dev",
"services": [
{
"id": "backend-core",
"repo": "https://github.com/pikasTech/unidesk",
"commitId": "<commit>"
},
{
"id": "frontend",
"repo": "https://github.com/pikasTech/unidesk",
"commitId": "<commit>"
},
{
"id": "code-queue",
"repo": "https://github.com/pikasTech/unidesk",
"commitId": "<commit>"
},
{
"id": "code-queue-mgr",
"repo": "https://github.com/pikasTech/unidesk",
"commitId": "<commit>"
}
]
}
```
环境到 ref 的映射必须固定在代码或权威配置中:
- `dev` 映射到 `origin/deploy/dev`
- `prod` 映射到 `origin/deploy/prod`
部署命令应接收环境名,而不是让生产部署任意指定分支。debug 或 admin-only 命令可以查看任意 ref,但普通 prod 部署必须走固定映射。
## 阶段 0:设计与护栏
目的:在加入第二套运行环境前,把目标行为说清楚。
实现项:
- 定义环境 manifest schema 和校验规则。
- 给 deploy manifest 增加 `environment` 字段,并拒绝环境不匹配的 manifest。
- 定义固定环境映射:`dev -> deploy/dev``prod -> deploy/prod`
- 记录 dev 的目标 namespace、数据库、Provider 身份和 service id。
- 增加 CLI dry-run plan 输出:
- 选中的环境
- GitHub ref
- 解析到的 manifest commit
- services 和 commit id
- 目标 namespace
- 目标数据库指纹
- 目标 Provider 身份
验收标准:
- `deploy plan --env dev` 可以读取并校验 dev manifest,且不修改集群。
- `deploy plan --env prod` 可以读取并校验 prod manifest,且不使用本地 worktree 的 `deploy.json`
- `environment=prod` 的 manifest 必须被 `--env dev` 拒绝,反向也必须拒绝。
## 阶段 1:GitHub 环境分支作为部署源
目的:让 GitHub 里的环境期望状态 ref 成为部署真相源。
实现项:
- 创建或初始化 `deploy/dev`,包含有效的 `deploy.json`
- 创建或初始化 `deploy/prod`,包含有效的 `deploy.json`
- 增加 CLI 支持:fetch 环境 ref,并从该 ref 读取 `deploy.json`
- 现有本地 `deploy.json` 只保留为显式本地/管理员流程的兼容模式。
- 校验 manifest 中列出的 commit id 存在于声明的 repo。
- 确保 dev/prod 部署不依赖本地 dirty working tree。
验收标准:
- `deploy plan --env dev` 读取 `origin/deploy/dev:deploy.json`
- `deploy plan --env prod` 读取 `origin/deploy/prod:deploy.json`
- 修改本地 `deploy.json` 不影响 `--env dev``--env prod`
- plan 输出包含实际使用的 Git ref 和 manifest blob/commit。
## 阶段 2D601 开发 Namespace 与数据库
目的:创建 dev backend 和 Code Queue state 的最小隔离底座。
实现项:
- 增加 `unidesk-dev` namespace 的 k8s manifest。
- 增加 dev PostgreSQL StatefulSet/Service/PVC,或等价持久化 DB。
- 增加 dev DB init 和 migration 流程,用于 backend-core 和 Code Queue 表。
- 增加 dev secrets/config
- 数据库凭据
- provider token
- auth/session secret
- 必要时的 Code Queue model secrets
- 增加资源 requests/limits,避免 dev DB 挤占 D601 生产 k3s workload。
技术决策:
- 优先使用独立 dev PostgreSQL 实例,而不是共享生产 PostgreSQL 的不同数据库名。独立实例的故障边界最清晰。
- 如果临时使用共享 PostgreSQL serverCLI 和服务启动时必须硬校验数据库名和连接目标。
验收标准:
- `kubectl -n unidesk-dev get pods,svc,pvc` 显示 dev DB ready。
- dev DB 在 Pod 重启后数据仍存在。
- dev 服务误连生产数据库 URL 时,必须启动失败。
## 阶段 3backend-core-dev 与 frontend-dev
目的:做出一套可用的 UniDesk dev 控制面,不依赖生产主 server Compose。
实现项:
- 增加 `backend-core-dev``frontend-dev` 的 k8s manifest。
-`deploy/dev:deploy.json` 声明的 commit id 构建镜像。
- 向 backend-core 注入 dev-only config
- `UNIDESK_ENV=dev`
- dev `MICROSERVICES_JSON`
- dev database URL
- dev provider token
- dev log paths
- 注入 frontend 配置,使其代理到 `backend-core-dev`,不能代理生产 backend-core。
- 增加 service health 和 readiness probe。
- 通过 port-forward 或私有 dev ingress 暴露 dev frontend。
技术决策:
- 第一版可以不做公网暴露。验证隔离时使用 port-forward 即可。
- dev frontend 必须有明显 DEV 环境标记,避免操作员混淆。
验收标准:
- dev backend-core `/health` 返回 ok,并包含 `environment=dev`
- dev frontend `/health` 返回 ok,并且只代理到 dev backend-core。
- dev backend/frontend 重部署期间,生产 `bun scripts/cli.ts server status` 仍健康。
- 重建 dev backend/frontend 不触碰主 server Docker Compose 容器。
- 当前实施切片:`deploy apply --env dev --service backend-core|frontend` 先支持 dev core 两个服务;`deploy/dev` 只保存 `deploy.json`,不保存 k8s manifest 或源码。
## 阶段 4code-queue-mgr-dev
目的:提供 dev 队列管理和提交路径,同时不写生产 Code Queue 表。
实现项:
- 增加 `code-queue-mgr-dev` k8s manifest。
- 配置它只使用 dev 数据库。
- 配置 dev backend-core service catalog,使 dev 稳定 `code-queue` 控制/读取路径路由到 `code-queue-mgr-dev`
- 确保 `code-queue-mgr-dev` 可以提交、列出、汇总和更新 dev queue state。
- health 输出必须证明:
- role 是 `master-control-plane``dev-control-plane`
- database 是 dev
- schema ready
- no runner dependencies
验收标准:
- dev UI/CLI 可以向 dev DB 提交 dry-run 或 queued task。
- dev 提交不会改变生产 Code Queue task list。
- `code-queue-mgr-dev` 内存占用保持在轻量控制面预算内。
## 阶段 5code-queue-dev 执行组件
目的:在 `unidesk-dev` 内运行 dev Code Queue 执行面,不干扰生产 Code Queue。
实现项:
- 增加 Code Queue manifest 的 dev 变体:
- `code-queue-read-dev`
- `code-queue-write-dev`
- `code-queue-scheduler-dev`
- 所有 dev 组件使用 dev 数据库、dev 日志和 dev state 路径。
- 使用 dev service name 和 label,避免生产 k3s adapter 混淆 dev/prod 服务。
- 决定第一版支持真实 Codex 执行,还是只支持 smoke-only 执行。
- 如果启用真实执行:
- 隔离 workdir 路径
- 隔离 Codex/OpenCode XDG/state 路径
- 隔离通知
- 限制并发和内存
- 默认不写生产 OA Event Flow,除非显式配置为 dev
技术决策:
- 第一版采用真实 Code Queue 进程和 dev PostgreSQL,但部署验收先以执行面可部署、`/health` 通过和 dev DB 隔离为准。
- dev scheduler 使用 `D601-dev` 作为本机 Provider 标识,默认工作目录为 `/workspace-dev`,远程工作目录为 `/home/ubuntu/unidesk-dev-workspace`
- 默认禁用生产 ClaudeQQ 通知,不使用生产 `d601-tcp-egress-gateway` 或生产 PostgreSQL 入口。
- dev frontend/backend-core 的稳定 `code-queue` 业务路由需要等 `code-queue-mgr-dev` 和 dev service catalog 完成后再接入,本阶段不把 dev 执行面伪装成完整业务入口。
验收标准:
- dev Code Queue `/health` 返回 ok,并包含 `environment=dev`
- `deploy apply --env dev --service code-queue` 可以根据 `origin/deploy/dev:deploy.json` 构建 `unidesk-code-queue:dev`,部署 `code-queue-scheduler-dev``code-queue-read-dev``code-queue-write-dev`,并验证 health commit。
- 后续接入 `code-queue-mgr-dev` 后,dev scheduler 可以拾取 dev queued task,并推进到终态。
- 重启 dev scheduler 不影响生产 running task。
- dev Code Queue rollout 期间,生产 `code-queue` health 仍健康。
## 阶段 6Dev 部署执行
目的:让 `deploy/dev:deploy.json` 端到端驱动 dev 环境。
实现项:
- 增加 `deploy apply --env dev`
- 对 dev manifest 中的每个服务:
- fetch 声明的 repo 和 commit
- 在 D601 上构建镜像,或复用既有 target-side build 路径
- 用环境和 commit 给镜像打 tag
- apply dev k8s manifest
- 等待 rollout
-`/health` 或 Deployment annotation 验证 live commit
- 部署记录包含 environment、ref、service id、commit id、image tag、namespace 和 rollout 状态。
- 增加 `deploy status --env dev` 或等价 drift check。
验收标准:
- 更新 `deploy/dev:deploy.json` 到新 commit 后,运行 `deploy apply --env dev` 会更新 dev backend-core/frontend/code-queue 组件。
- live `/health` commit 与 manifest commit 一致。
- dev 部署不会修改任何生产 Deployment、Service、Secret、PVC、DB table 或 Docker Compose 容器。
## 阶段 7:生产部署 Ref 兼容
目的:让生产部署从 `deploy/prod` 读取期望状态,同时保持生产运行方式不变。
实现项:
- 增加 `deploy plan --env prod``deploy apply --env prod`,读取 `origin/deploy/prod:deploy.json`
- 初期保持现有生产 executor:
- 生产 backend-core/frontend 和 direct sidecar 继续使用主 server Compose。
- 生产 Code Queue 执行面继续使用 D601 k3s。
- 强化生产命令护栏:
- 只能在权威根目录执行
- 生产凭据只存在主 server
- manifest 必须声明 `environment=prod`
- 目标 namespace 和 Provider 身份必须匹配生产
- 建议后续给 `deploy/prod` 增加 branch protection;第一版可暂缓。
验收标准:
- 生产部署不再依赖本地 `deploy.json`
- 生产部署报告实际使用的 Git ref 和 manifest commit。
- 生产部署 rollout 后仍校验 live commit。
## 阶段 8:操作员与 LLM 安全
目的:降低 LLM agent 和人工操作员混淆环境的概率。
实现项:
- 每次 deploy 的 CLI 输出都清晰显示:
- environment
- ref
- namespace
- DB 指纹
- provider id
- services 和 commits
- dev frontend 增加明确 DEV 标记。
- 增加硬启动检查:
- dev service 拒绝生产 DB
- dev service 拒绝生产 provider id/token
- prod service 拒绝 dev namespace/DB
- 确保 LLM task container 默认只拿到 dev deploy 凭据,拿不到 prod 凭据。
- 增加 smoke check:故意尝试不安全组合,并验证它们失败。
验收标准:
- dev 服务使用生产 DB 配置启动时,在监听端口前失败。
- 从非权威上下文运行 prod deploy 时失败。
- LLM/Code Queue 默认环境可以部署 dev,但没有独立生产凭据路径时不能部署 prod。
## 风险与缓解
- 风险:namespace 不能隔离节点级 CPU、内存、Docker socket、hostPath 或 containerd 压力。
- 缓解:资源 requests/limits、独立 dev workdir、不挂载生产路径,并限制 Code Queue 并发。
- 风险:dev Code Queue 误写生产 task 表。
- 缓解:独立 dev DB、启动时 DB 指纹检查、health 输出 DB 身份。
- 风险:dev frontend 看起来像 prod,或代理到 prod backend-core。
- 缓解:可见 DEV 标记、`CORE_INTERNAL_URL` 固定到 dev service、proxy target health check。
- 风险:deploy 命令误读本地 manifest,而不是 GitHub 环境 ref。
- 缓解:`--env` 模式必须只读取 remote ref,并报告实际使用的 ref/blob。
- 风险:D601 k3s 控制面故障同时影响 dev 和生产 k3s workload。
- 缓解:Phase 1 接受该风险;只有 namespace 隔离被证明不足后,再考虑独立物理节点或节点级 dev 集群。
- 风险:`deploy/prod` 初期未开启 branch protection。
- 缓解:即使没有 branch protection,生产部署仍必须要求权威主 server 凭据,并报告用于审计的 ref。
## 建议实现顺序
1. Phase 0 和 Phase 1:建立 GitHub 环境分支期望状态和 dry-run planning。
2. Phase 2 和 Phase 3:创建 dev namespace、dev DB、backend-core-dev 和 frontend-dev。
3. Phase 4 和 Phase 5:增加 dev Code Queue 控制面和执行组件。
4. Phase 6:让 `deploy apply --env dev` 按 commit id 部署完整第一版 dev stack。
5. Phase 7:把生产部署迁移到 `deploy/prod`
6. Phase 8:强化操作员和 LLM 安全检查。
第一个完整里程碑完成条件:`deploy apply --env dev` 可以根据 `origin/deploy/dev:deploy.json` 声明的 commit id,把 backend-core、frontend、code-queue-mgr 以及 Code Queue read/write/scheduler 部署进 `unidesk-dev`;反复 dev redeploy 不改变生产主 server status,也不改变生产 Code Queue state。阶段 3 的阶段性里程碑先以 `--service backend-core``--service frontend` 分别部署成功为准。