feat: extend k3s artifact consumers

This commit is contained in:
Codex
2026-05-20 02:58:41 +00:00
parent 15a1a8b21a
commit 595de3d320
28 changed files with 1003 additions and 76 deletions
+8 -3
View File
@@ -158,7 +158,7 @@ Baidu Netdisk 在 UniDesk 语境中按纯后端服务管理:不得暴露百度
D601 开发环境底座只允许创建 `unidesk-dev` namespace 与 dev 专用对象,manifest 固定为 `src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-foundation.k8s.yaml`。该 manifest 包含 `postgres-dev` 独立 PostgreSQL StatefulSet/Service/PVC、dev-only secret/config 模板、dev DB 初始化 SQL 和迁移 Job、ResourceQuota/LimitRange,以及 `unidesk-dev-db-guard`。它不得修改生产 `unidesk` namespace、生产 PostgreSQL、生产 PVC、生产 Deployment/Service/Secret 或主 server Docker Compose。
`postgres-dev` 是 dev backend-core 与未来 dev Code Queue 状态的默认唯一数据库。dev 运行时必须使用 `postgres-dev.unidesk-dev.svc.cluster.local:5432/unidesk_dev` 和 dev Provider 身份 `D601-dev`;不得共享生产 `d601-tcp-egress-gateway.../unidesk`。Persistent dev backend-core target-side rollout, frontend artifact rollout, public dev frontend port and Rust build boundary are defined in `docs/reference/dev-environment.md`; Code Queue dev rollout remains future work.
`postgres-dev` 是 dev backend-core 与 dev Code Queue 状态的默认唯一数据库。dev 运行时必须使用 `postgres-dev.unidesk-dev.svc.cluster.local:5432/unidesk_dev` 和 dev Provider 身份 `D601-dev`;不得共享生产 `d601-tcp-egress-gateway.../unidesk`。Persistent dev backend-core target-side rollout, frontend/Decision Center/MDTODO/ClaudeQQ artifact rollout, dev-only Code Queue artifact rollout, public dev frontend port and Rust build boundary are defined in `docs/reference/dev-environment.md`.
验收入口:先运行 `bun scripts/cli.ts dev-env validate` 做静态资源与 DB URL 护栏检查;具备 D601 kubeconfig 时运行 `bun scripts/cli.ts dev-env validate --kubectl-dry-run` 做 Kubernetes client dry-run。首次或镜像缓存不确定时,先运行 `bun scripts/cli.ts dev-env prewarm-images`,把 `postgres:16-alpine` 和 local-path helper 所需的 `rancher/mirrored-library-busybox:1.36.1` 导入 D601 原生 k3s containerd;否则 D601 的 Docker 代理/缓存正常也不能保证 k3s/containerd 能实时拉到外部镜像。若实际 apply,只能 apply 到 `unidesk-dev`,随后用 `kubectl -n unidesk-dev get pods,svc,pvc` 验证 dev DB ready,并对比 apply 前后的 `kubectl -n unidesk get deploy,sts,svc,secret,pvc -o name` 证明生产 workload 未变化。
@@ -172,12 +172,15 @@ D601 上必须显式使用原生 k3s kubeconfig`KUBECONFIG=/etc/rancher/k3s/k
`unidesk-dev-core.k8s.yaml` 当前使用 placeholder image/commit;正式 rollout 需要 `deploy apply --env dev` executor 从 `origin/master:deploy.json#environments.dev` 替换 commit 并构建镜像。当前验收只做静态校验和 Kubernetes client dry-run,不能把 placeholder manifest 当成已上线。
`unidesk-dev-mdtodo.k8s.yaml``unidesk-dev-claudeqq.k8s.yaml``unidesk-dev-code-queue.k8s.yaml` 是 D601 registry artifact consumer 的 dev manifests。它们只能创建 `unidesk-dev` 内的 ClusterIP Service/Deployment 对象,不得修改生产 `unidesk` namespace、主 server Compose 或新增 NodePort/hostPort。受控 rollout 必须使用 commit-pinned registry artifact、stamp `UNIDESK_DEPLOY_*` metadata,并通过 Kubernetes API service proxy 检查服务健康。
### Code Queue k3s-Managed
当前对外 `id=code-queue` 是稳定用户服务 ID,实际按 master 控制面与 D601 执行面拆分。队列管理、提交、历史摘要、已读状态和轻量 Trace 读取默认由主 server `code-queue-mgr` 直管 PostgreSQLD601 k3s Code Queue 作为执行面代管,负责 scheduler/runner、dev-container、active run steer/interrupt、judge、输出/attempt/通知写回,并接入统一 `oa-event-flow` 发布 Trace/STEP 事实事件与读取统计中心:
- Orchestrator:稳定 `code-queue` ID 的控制/读取路径由 backend-core 分流到 `deployment.mode=internal-sidecar``code-queue-mgr`D601 执行面仍登记为 `deployment.mode=k3sctl-managed``deployment.adapterServiceId=k3sctl-adapter``deployment.k3sServiceId=code-queue``backend.proxyMode=k3sctl-adapter-http``backend.nodeBaseUrl=k3s://code-queue`。对外登记的 `code-queue` ID 保持稳定,frontend/CLI 不需要知道内部拆分。
- Direct path ban`code-queue` 不得再登记 `http://code-queue:4222``http://host.docker.internal:4222`、NodePort 或 provider-gateway `microservice.http` 作为业务代理目标;frontend 也不得使用旧 `/api/code-queue-direct` 兼容别名作为 Code Queue 页面数据源。provider-gateway 只允许用于维护 D601/D518、部署 adapter、部署 k3s/k8s 节点或诊断节点本机容器。
- Artifact consumer boundary`code-queue` 只支持 dev artifact consumer。`--env dev --service code-queue` 可从 D601 registry 消费 `unidesk/code-queue:<commit>` 并更新 `unidesk-dev` 的 scheduler/read/write/provider-egress-proxy dev Deployments`--env prod --service code-queue` 必须明确 unsupported,不得执行 production artifact deploy、rollout 或 manifest 变更。
- Claim/move consistencymaster `code-queue-mgr` 和 D601 scheduler 都必须以 PostgreSQL 状态为权威;move 只允许未 claim 的 `queued`/`retry_wait` 行,merge 在 source/target queue 存在 `running`/`judging` 或 claim marker 时整体返回 409。稳定 `code-queue` 代理可用 `/api/queue-claim-move/self-test` 验证 claimed task move 会被拒绝且数据库仍保持 running/source queue 状态。
- D601 Service boundaryD601 内部可以继续保留 `code-queue-read``code-queue-write``code-queue-scheduler` 三个 Kubernetes Service 作为执行面兼容和过渡对象,但普通提交、queue CRUD、history、readAt 和轻量 overview 不得依赖 `code-queue-write` 或 D601 egress 可用;`code-queue-write` 不 ready 时,主 server `code-queue-mgr` 仍应保证 CLI/WebUI 的提交、列表和历史读取可用。需要 active run、dev-container、judge 或执行面健康的路径才进入 D601 scheduler。
- 服务拆分语义:`code-queue-read` 只承载 GET/HEAD 查询、overview、任务详情、Trace/output/transcript、统计和只读健康,可多副本滚动更新;它必须设置 `CODE_QUEUE_SERVICE_ROLE=read``CODE_QUEUE_SCHEDULER_ENABLED=false`,且不得接受入队、queue 变更、已读、重试、移动、追加 prompt 或打断这类 mutation。`code-queue-write` 承载入队、queue 创建/合并/更新、已读、手动重试、移动等命令写入,初期保持单副本和 `CODE_QUEUE_SERVICE_ROLE=write`,只把命令和任务状态写入 PostgreSQL,不启动 agent 子进程。`code-queue-scheduler` 是唯一拥有 scheduler 和 active run 的执行服务,设置 `CODE_QUEUE_SERVICE_ROLE=scheduler``CODE_QUEUE_SCHEDULER_ENABLED=true`,负责从 PostgreSQL 热任务集轮询新写入任务、推进队列、启动 Codex/OpenCode、处理 running task 的 steer/interrupt、发送终态通知和暴露执行端 `/health`。普通 Service 负载均衡不得把 mutation 打到 read,也不得把 running task 控制打到 write。
@@ -224,10 +227,11 @@ D601 上必须显式使用原生 k3s kubeconfig`KUBECONFIG=/etc/rancher/k3s/k
当前 ClaudeQQ 作为 `id=claudeqq``k3sctl-managed` 用户服务登记在 `config.json`,业务实例由 D601 k3s 控制面代管:
- Orchestrator`deployment.mode=k3sctl-managed``deployment.adapterServiceId=k3sctl-adapter``deployment.k3sServiceId=claudeqq``backend.proxyMode=k3sctl-adapter-http``backend.nodeBaseUrl=k3s://claudeqq`backend-core 对 ClaudeQQ 的正式链路只能是 `frontend -> backend-core -> k3sctl-adapter -> Kubernetes API service proxy -> Kubernetes Service claudeqq:3290`
- 部署引用:ClaudeQQ 业务源码来自 `https://gitee.com/lyon1998/agent_skills``claudeqq` 子目录;镜像构建 Dockerfile 和 `0.0.0.0:3290` API 适配器由 UniDesk 仓库 `src/components/microservices/claudeqq/` 作为 k3s 部署资产注入,不能依赖 D601 未提交工作树文件。Kubernetes 运行清单为 `src/components/microservices/k3sctl-adapter/k3s/claudeqq.k8s.yaml``config.json` 对外记录 k3s manifest `src/components/microservices/k3sctl-adapter/k3s/claudeqq.k3s.json`。旧 `docker-compose.unidesk.yml` 只作为迁移/本地诊断参考,不是正式运行入口。
- 部署引用:ClaudeQQ 业务源码来自 `https://gitee.com/lyon1998/agent_skills``claudeqq` 子目录;镜像构建 Dockerfile 和 `0.0.0.0:3290` API 适配器由 UniDesk 仓库 `src/components/microservices/claudeqq/` 作为 k3s 部署资产注入,不能依赖 D601 未提交工作树文件。Kubernetes 运行清单为 `src/components/microservices/k3sctl-adapter/k3s/claudeqq.k8s.yaml``config.json` 对外记录 k3s manifest `src/components/microservices/k3sctl-adapter/k3s/claudeqq.k3s.json`dev 环境使用 `src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-claudeqq.k8s.yaml``unidesk-dev-claudeqq.k3s.json`,服务名为 `claudeqq-dev``docker-compose.unidesk.yml` 只作为迁移/本地诊断参考,不是正式运行入口。
- 运行对象:ClaudeQQ Pod 在 D601 上以同 Pod 双容器运行 `claudeqq``napcat`,仅通过 ClusterIP Service 暴露 `claudeqq:3290` 给 UniDesk 代理和 Code Queue 通知链路;NapCat 的 `3000/3001/6099` 只在 Pod 内可达,不得作为 NodePort、hostPort 或 provider-gateway 业务直连目标。
- 持久化路径:NapCat 登录态保存在 D601 hostPath `/home/ubuntu/.agents/skills/claudeqq/napcat/qq`,NapCat 配置和二维码缓存分别保存在 `napcat/config``napcat/cache`;ClaudeQQ 后端挂载同一业务目录中的 `config.json``bot_workspace``logs``.state` 和只读 `napcat`。这些路径不得改成匿名 volume,避免重建 Pod 后 QQ 登录态和事件/订阅状态丢失。
- 代理/API:只允许 `/health``/logs``/api/` 前缀;允许方法为 `GET``HEAD``POST``DELETE``POST /api/push/text` 接受 `userId``groupId``message`,由 ClaudeQQ 通过同 Pod NapCat HTTP API 发送 QQ 消息;NapCat 不可用时必须快速返回 `status=napcat_offline` 或可解释错误。
- Dev/prod CDClaudeQQ 的 dev/prod rollout 都必须走 D601 registry artifact consumer。CI 从 Gitee commit 导出 `claudeqq/` 源码并 overlay UniDesk Dockerfile/adapterCD 验证同一个 commit-pinned artifact contractdev 落到 `unidesk-dev/claudeqq-dev`prod 落到 `unidesk/claudeqq`,健康检查通过 Kubernetes API service proxy 完成;不得回退到维护通道直连或 NodePort/hostPort。
- UniDesk 前端:`用户服务 / ClaudeQQ` React 页面负责展示 D601、仓库引用、私有 k3s 后端映射、NapCat 登录二维码、NapCat HTTP/WS 状态、事件缓存、订阅表、订阅创建表单、消息推送表单、主用户私聊账号 `645275593`、最近 QQ 事件和已发送记录;完整原始 JSON 只能通过显式 `查看原始JSON` 打开。浏览器只能通过 UniDesk frontend 同源代理访问 ClaudeQQ,不得直接访问 D601 `3290/3000/3001/6099`,也不得 iframe ClaudeQQ 旧 WebUI。
### Decision Center k3s-Managed
@@ -251,10 +255,11 @@ D601 上必须显式使用原生 k3s kubeconfig`KUBECONFIG=/etc/rancher/k3s/k
当前 MDTODO 作为 `id=mdtodo``k3sctl-managed` 用户服务登记在 `config.json`,用于把 D601 Windows 工作区 `F:\Work\vscode-mdtodo` 从 VS Code 扩展形态拆成 UniDesk 可代理的后端服务:
- Orchestrator`deployment.mode=k3sctl-managed``deployment.adapterServiceId=k3sctl-adapter``deployment.k3sServiceId=mdtodo``backend.proxyMode=k3sctl-adapter-http``backend.nodeBaseUrl=k3s://mdtodo`;正式链路只能是 `frontend -> backend-core -> k3sctl-adapter -> Kubernetes API service proxy -> Kubernetes Service mdtodo:4267`
- 代码与部署引用:后端源码位于 UniDesk 仓库 `src/components/microservices/mdtodo`Dockerfile 为 `src/components/microservices/mdtodo/Dockerfile`k3s manifest 为 `src/components/microservices/k3sctl-adapter/k3s/mdtodo.k3s.json`Kubernetes 运行清单为 `src/components/microservices/k3sctl-adapter/k3s/mdtodo.k8s.yaml`,镜像名固定为 `unidesk-mdtodo:d601`
- 代码与部署引用:后端源码位于 UniDesk 仓库 `src/components/microservices/mdtodo`Dockerfile 为 `src/components/microservices/mdtodo/Dockerfile`k3s manifest 为 `src/components/microservices/k3sctl-adapter/k3s/mdtodo.k3s.json`Kubernetes 运行清单为 `src/components/microservices/k3sctl-adapter/k3s/mdtodo.k8s.yaml`,镜像名固定为 `unidesk-mdtodo:d601`dev 环境使用 `src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-mdtodo.k8s.yaml``unidesk-dev-mdtodo.k3s.json`,服务名为 `mdtodo-dev`
- 持久化边界:D601 的 `F:\Work\vscode-mdtodo` 先同步到 k3s 可见的 WSL hostPath `/home/ubuntu/cq-deploy/.state/mdtodo-workspace`Pod 将该目录挂载为 `/workspace`,后端直接读写 Markdown TODO 文件;`.state/mdtodo/logs` 只保存 JSONL 日志,不作为任务权威状态。该服务不得把原 VS Code webview 前端或 VSIX 构建产物作为浏览器入口。
- API`GET /health``GET /live``GET /logs``GET /api/files``GET /api/tasks?file=...``GET|PATCH|DELETE /api/tasks/{id}``POST /api/tasks``GET|PUT /api/content``POST /api/execute-command``/health` 必须证明 hostPath 可读并至少能扫描到 TODO Markdown 文件。
- 代理路径:只允许 `/health``/live``/logs``/api/` 前缀;允许方法为 `GET``HEAD``POST``PUT``PATCH``DELETE`。业务请求不得退化为 provider-gateway 直连、NodePort 或 D601 本机端口。
- Dev/prod CDMDTODO 的 dev/prod rollout 都必须走 D601 registry artifact consumer。dev manifest 在 `unidesk-dev` 中创建最小 ClusterIP Service/Deployment 并种子化一个 dev Markdown TODO 文件,保证 `/health` 可以真实扫描任务文件;prod 使用生产 `mdtodo` manifest。两边都要通过 Kubernetes API service proxy 验证 health/live deploy metadata,不能用 NodePort、hostPort 或 provider-gateway 业务直连替代。
- UniDesk 前端:`用户服务 / MDTODO` React 页面负责展示文件列表、任务树、任务状态、标题/正文编辑、新增/删除任务、执行命令生成和显式原始 JSON 按钮;默认页面不得裸铺完整 Markdown 或 JSON。
## D601 User Services