接入 Agent 平台
本页介绍怎样把 Agent 平台接入 Kibotos:Operator 身份放在哪里、Agent 会话怎样对应到 Workspace 与 Volume,以及平台怎样处理失败。代码使用 Go SDK,其他语言的程序经原生 API 做同样的调用。
概述
平台后端位于 Agent 与 Kibotos 之间。它经 ctrl 管理 Workspace,并用短期凭证访问运行各 Workspace 的 node:
flowchart LR Agent[Agent 运行环境] -->|工具调用| Backend[平台后端] Backend -->|mTLS 与 Operator 身份| Ctrl[ctrl] Backend -->|会话凭证| Node[node 数据面] Node --> Workspace[Workspace]
一次典型的会话按下面的顺序进行:
- 找到或创建项目的 Volume。
- 创建绑定这个 Volume 的 Workspace,并设置到期时间。
- 经数据面会话执行 Agent 的工具调用。
- 会话结束时删除 Workspace,Volume 留给下一次会话。
保留项目的编码 Agent 是按这些步骤写的完整程序。
身份与访问
警告
Operator 拥有集群管理权限,能操作部署内的所有 Workspace。把身份留在后端,不要复制到 Workspace 里,也不要交给 Agent。
- 平台自己为用户授权。 Kibotos 没有租户,每个 Operator 都能看到所有 Workspace,所以由后端决定哪个用户能访问哪个 Workspace。
- labels 不是访问控制。 用它查找资源,见 labels 与 annotations。
- 每个后端实例用各自的身份目录。 ctrl 只接受一个身份的当前与上一张证书,两个程序续期同一个身份会互相锁死。用
kibo enrollment create --operator为每个实例生成一把注册密钥(enrollment key),见连接 ctrl。
Agent 访问 Workspace 的方式
选择 Agent 的工具调用怎样到达 Workspace:
| 方式 | 做法 | 适用情形 |
|---|---|---|
| 后端执行工具 | 后端持有 dataplane.Session 并执行每次工具调用,Agent 拿不到凭证 | 默认选择。后端能检查、记录、限制每次调用 |
| 后端下发凭证 | 后端申请会话凭证(session credential),交给 Workspace 外的 Agent 运行环境,由它直接调用 node | Agent 运行环境需要直连,例如读取长时间的输出流 |
下发凭证时,只申请 Agent 需要的权限范围,并设置较短的有效期:
response, err := client.DataPlaneSessions().CreateDataPlaneSession(ctx, connect.NewRequest(&ctrlv1.CreateDataPlaneSessionRequest{
Metadata: &ctrlv1.CommandMetadata{CommandId: kibotos.NewCommandID("platform")},
WorkspaceId: workspaceID,
RequestedScopes: []ctrlv1.DataPlaneScope{ctrlv1.DataPlaneScope_DATA_PLANE_SCOPE_PROCESS},
RequestedTtl: durationpb.New(5 * time.Minute),
}))
if err != nil {
log.Fatal(err)
}
endpoint := response.Msg.GetSession().GetEndpoint()
credential := response.Msg.GetCredential()- 凭证只对一个 Workspace 与它列出的权限范围有效,不能创建、停止或删除 Workspace。
- 默认有效 5 分钟,最长 15 分钟,由后端签发下一张。
- Agent 运行环境要能访问 node 地址,并信任身份里的
server-ca.pem,见访问 node。 - 把凭证当作密钥对待。要一次切断对某个 Workspace 的全部访问,调用
RevokeWorkspaceDataPlane。
会话与 Kibotos 对象的对应
| 平台上的对象 | Kibotos 对象 | 说明 |
|---|---|---|
| 项目或用户目录 | Volume | 一直存在,直到你删除它。创建 Workspace 时绑定 |
| Agent 会话 | Workspace | 绑定项目的 Volume。删除 Workspace 时,这样绑定的 Volume 会保留 |
| 会话或请求 ID | 幂等键(command ID) | kibotos.DeriveCommandID 由你的 ID 得出,后端重启后重放同一条命令,不会多创建一个 Workspace |
| 所有者、项目或批次 | labels | 重启后用 label_selector 查找资源 |
| 会话的最长时间 | 到期时间 | 后端再也不回来时,ctrl 也会停止或删除 Workspace |
一个 Volume 同一时间只绑定一个 Workspace。绑定到新的 Workspace 之前,删除旧的 Workspace,并用 Client.WaitWorkspaceDeleted 等删除命令完成。
空闲的会话
Kibotos 不能保存内存状态,所以按继续时需要什么来选择:
| 两轮对话之间 | CPU 与内存 | 保留什么 | 怎样继续 |
|---|---|---|---|
| 保持运行 | 占用 | 全部,包括进程 | 用原来的数据面会话 |
| 停止 | 释放 | Volume,以及尽力保留的可写层 | StartWorkspace,再打开新的数据面会话并重新启动进程 |
| 删除 | 释放 | 只有按上面的方式绑定的 Volume | 新建 Workspace |
Agent 必须保留的文件放在 Volume 上,见保证与边界。
失败处理
| 现象 | 含义 | 处理 |
|---|---|---|
| 写操作没有应答或超时 | 结果未知 | 用同一个幂等键重发,kibotos.Settle 会这样做。带 command_settled 的失败已确定,要重试就换新的幂等键。见写操作与错误 |
创建或启动失败,返回 resource_exhausted | 没有 node 放得下 | 把任务排队后重试。Workspace 仍然存在,之后可以启动或删除 |
Workspace 处于 UNKNOWN | 某个 node 暂时不可达 | 等待,或用原来的幂等键重发。先不要另建替代的 Workspace,原来的可能还在运行 |
Workspace 处于 FAILED | 这次执行失败 | 先强制停止,再启动,见从 FAILED 恢复 |
Workspace 是 AVAILABLE,但 guest 不回应 | guest 卡住了 | 见 guest 回应情况 |
| 进程流中断 | 与 node 的连接断开 | dataplane.Session 会自动续上,Gap 事件报告无法找回的输出 |
| 操作因缺少能力而失败 | 服务端比这个功能旧 | 在操作前调用 Client.Require,只让这个功能失败,见先查询能力 |
网络访问
新建的 Workspace 不能访问网络,这对多数 Agent 是合适的起点。
- 任务需要时再打开公网访问,并用目的地规则收窄,见网络策略。
- 要让流量经自己的代理离开,或使用固定的出站地址,使用 Egress,要求
v0.3.0或更新版本。 - 要把 Workspace 里的服务展示给用户,创建公开 URL,用完后撤销。拿到地址的人都能访问。