agent_launcher:新增一等 kubernetes 后端(每 agent 一 Pod,key 经 Secret 引用不内联)(Refs #16)
回应「我们跑在 k8s pods 上」——此前 launcher 只有 dev 的 subprocess + 通用 command hook, 未把 k8s 作为一等后端,且把 OPENAI_API_KEY 内联进 env(在 k8s 会落 etcd)。本次: - 新增 AGENT_LAUNCH_BACKEND=kubernetes:每 agent 一个 Pod(build_pod_manifest)——资源 requests/limits、标签 heicode-swarm-id/heicode-user-id(GC/teardown)、restartPolicy OnFailure、 serviceAccountName;非敏感 env 内联,**OPENAI_API_KEY 经 secretKeyRef 引用每-swarm k8s Secret (build_secret_manifest,via kubectl apply -f - stdin),绝不内联进 PodSpec(不落 etcd/argv)**。 - stop_launched:k8s 按标签 kubectl delete pod,secret;subprocess 仍 terminate。 - config:AGENT_POD_IMAGE/NAMESPACE/SERVICE_ACCOUNT/CPU|MEM_REQUEST|LIMIT;ORCHESTRATOR_URL= 集群内 Service DNS。文档注明前置(kubectl + 最小 RBAC ServiceAccount + NetworkPolicy)与 硬化替代(azkv CSI SecretProviderClass,编排器全程不碰明文)。 文档:runtime-contract §3.3 后端列表加 kubernetes(含密钥/RBAC/Service DNS/CSI); security-boundary §6 增 K8s pod 边界(Secret 引用不内联、最小 RBAC、NetworkPolicy、CSI 硬化)。 测试:test-agent-launcher 增 k8s manifest 断言(标签、secretKeyRef 非内联、原文不在 Pod manifest、 资源限额、无 secret 则省略 key)。 影响范围:仅 agent_swarm(launcher + 文档 + 测试)。默认仍 backend=none,CI/e2e 不变。 Refs #16 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
ad343e6404
commit
af26455a8b
@@ -59,7 +59,8 @@
|
||||
- **Swarm 模型**:Agent 主动出站连编排器 WebSocket(`/ws/{agent_id}`),**不**对公网暴露每 Agent 子域名。AM 单 Agent 模型里的「客户端↔agent 直连 + `AGENT_ACCESS_TOKEN` 本地校验」**不适用于** swarm(无直连回路)。
|
||||
- 服务间鉴权:HM→Swarm 用 `AGENT_RUNTIME_SERVICE_TOKEN`(Bearer);回调 HMAC 签名。
|
||||
- **每用户并发 Agent 配额**:一个 `user_id` 同时连接的 Agent 数上限为 `MAX_AGENTS_PER_USER`(env,默认 10)。注册(WS `register` 消息携带 `user_id`)超额即被拒绝(回 `registration_rejected` 并关闭,code 1008),断开后释放名额。归因主轴仍为 `user.id`/`channelId`。未带 `user_id` 的 Agent 为 unbound,不计入该配额。实现:`ConnectionManager.can_bind_user/bind_user/unbind` + 注册处强制;测试 `scripts/test-max-agents-per-user.py`。
|
||||
- **Swarm 拉起 agent + 服务端解析 key(team 决议,runtime-contract §3.3)**:由 **Swarm 运行时**(`orchestrator/agent_launcher.py`)拉起专家 agent 池(拉起数 `min(池大小, MAX_AGENTS_PER_USER − 已连)`,与上面的注册兜底一致)。模型 key 由 **Swarm 从 `billing_context.secret_ref`(`azkv://`)服务端解析**后注入被拉起 agent 的 env——**不入** create 请求体 / 回调 / 日志 / argv(`command` 后端的密钥经进程 env 传入,不上命令行)。azkv 真实解析为部署侧 SecretResolver;dev/CI 用 `HEICODE_SECRET_<name>`。解析不到即 keyless 启动并明确报错(不伪造)。
|
||||
- **Swarm 拉起 agent + 服务端解析 key(team 决议,runtime-contract §3.3)**:由 **Swarm 运行时**(`orchestrator/agent_launcher.py`)拉起专家 agent 池(拉起数 `min(池大小, MAX_AGENTS_PER_USER − 已连)`,与上面的注册兜底一致)。模型 key 由 **Swarm 从 `billing_context.secret_ref`(`azkv://`)服务端解析**后注入被拉起 agent——**不入** create 请求体 / 回调 / 日志 / argv。azkv 真实解析为部署侧 SecretResolver;dev/CI 用 `HEICODE_SECRET_<name>`。解析不到即 keyless 启动并明确报错(不伪造)。
|
||||
- **K8s pod 边界(`AGENT_LAUNCH_BACKEND=kubernetes`,生产)**:**每 agent 一个 Pod**,带 CPU/内存 requests+limits、标签(`heicode-swarm-id`/`heicode-user-id`)。模型 key 经**每-swarm k8s Secret**(manifest via stdin 应用)由 Pod `secretKeyRef` 引用,**绝不内联进 PodSpec env**(否则暴露于 etcd / `kubectl get pod -o yaml`)。编排器需 `kubectl` + 一个仅对 `AGENT_POD_NAMESPACE` 有 pod/secret 权限的 **ServiceAccount(最小 RBAC)**;Pod 出网由 NetworkPolicy 限定到 HM `/v1` + git;停止/删除按标签 `kubectl delete pod,secret`。**更硬化(推荐 Infra 评估)**:azkv **CSI SecretProviderClass** 让 Pod 直接从 Key Vault 挂载密钥,编排器**全程不接触明文**。代码执行沙箱仍按 §8.1 在 Pod 层强制。
|
||||
- 🟡 待接入:多租户运行时隔离(命名空间/网络/配额)由 Agent 平台(AKS Workload Identity)承载,非本仓编排器;归因主轴为 `user.id`/`channelId`(见 `usage-billing-schema.md`),不引入 tenant 概念。
|
||||
|
||||
## 7. 外部 API 与传输
|
||||
|
||||
Reference in New Issue
Block a user