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

16 KiB
Raw Blame History

D601 k3s 开发环境建设计划

状态:本过程计划的环境分支方案已废弃。长期权威规则以 docs/reference/deploy.mddocs/reference/ci.md 为准:dev/prod 期望状态统一写在 master 分支的根目录 deploy.json,通过 environments.devenvironments.prod 区分,不再以 deploy/devdeploy/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/devdeploy/prod 不是普通源码开发分支的别名,只是环境期望状态分支。

目标开发拓扑

第一版 dev 环境运行在 D601 的 unidesk-dev namespace

  • postgres-devdev 独立 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-devcode-queue-write-devcode-queue-scheduler-devCode 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

{
  "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/devprod -> 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-devfrontend-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-planedev-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-devcode-queue-read-devcode-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 proddeploy 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 分别部署成功为准。