策略
策略是具名的环境配置,定义了终端容器的外观:镜像、资源限制、存储、环境变量和空闲超时时间。它们允许你从单个编排器向不同团队提供不同的终端环境。
例如,你可以创建一个带有大型镜像、4 个 CPU 核心和 16 GiB 内存的 data-science 策略,同时创建一个使用默认精简镜像、1 个 CPU 和 2 GiB 内存的 development 策略。
策略工作原理
- 管理员通过 REST API 在编排器上创建策略(见下方 API 参考)。
- 管理员在 Open WebUI 中创建终端连接(位于 Settings → Connections → Open Terminal)。每个连接包含一个
policy_id字段,将其映射到编排器上的某个策略。 - 用户打开终端。 Open WebUI 通过
/p/{policy_id}/...路由请求,编排器按该策略的规格分配(或复用)容器。
每个用户每个策略各自有独立的隔离容器。如果一个用户可以访问两个使用不同策略的连接,他们会获得两个独立的终端。
策略字段
所有字段均为可选。当字段缺省时,编排器回退到全局默认值(通过环境变量设置)。
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
image | string | TERMINALS_IMAGE · ghcr.io/open-webui/open-terminal:latest | 运行的容器镜像 |
cpu_limit | string | 无限制 | 最大 CPU(例如 "2"、"500m") |
memory_limit | string | 无限制 | 最大内存(例如 "4Gi"、"512Mi") |
storage | string | 无(临时) | 持久卷大小(例如 "10Gi")。缺省时,容器使用临时存储,容器删除后数据丢失。 |
storage_mode | string | TERMINALS_KUBERNETES_STORAGE_MODE · per-user | 持久卷的分配方式:per-user、shared 或 shared-rwo。参见存储模式。仅适用于 Kubernetes 后端。 |
env | object | {} | 注入容器的键值对环境变量 |
idle_timeout_minutes | integer | TERMINALS_IDLE_TIMEOUT_MINUTES · 0(禁用) | 容器在不活动多少分钟后被停止并删除 |
存储模式
storage_mode 字段控制 Kubernetes 后端上持久卷的分配方式。对 Docker 后端无效(Docker 后端始终 bind-mount 宿主目录)。
| 模式 | 行为 | PVC 访问模式 |
|---|---|---|
per-user | 每个用户有自己的 PVC。完全隔离。 | ReadWriteOnce |
shared | 所有用户共享一个 PVC,每个用户的数据存储在以其用户 ID 为 subPath 的目录下。需要支持 ReadWriteMany 的存储类(如 NFS、EFS)。 | ReadWriteMany |
shared-rwo | 共享一个 ReadWriteOnce PVC。所有终端 Pod 通过 Pod 亲和性被调度到同一节点(Kubernetes 确保它们都落在挂载了该卷的机器上)。适用于没有 ReadWriteMany 存储的场景。 | ReadWriteOnce |
ReadWriteOnce(RWO) 意味着卷一次只能被单个节点上的 Pod 挂载。ReadWriteMany(RWX) 意味着多个节点可以同时挂载并写入该卷。
环境变量
env 字段向终端容器注入任意键值对作为环境变量。常见用途:
- API Key: 为用户提供访问 LLM API、云服务等的权限。
- 出站过滤: 设置
OPEN_TERMINAL_ALLOWED_DOMAINS以限制出站网络访问(例如"*.pypi.org,github.com")。当该变量存在时,Docker 后端会自动为容器添加NET_ADMIN能力。 - 自定义配置: 你的终端镜像支持的任何设置
策略中的环境变量对终端用户可见(他们可以在 shell 中运行 env)。不要在此处存储用户不应看到的密钥。
管理策略
策略可在 Open WebUI 管理面板的 Settings → Connections → Open Terminal 下进行管理。在那里你可以创建、编辑和删除策略,将其分配给终端连接,并按组限制访问。
更新策略不会影响正在运行的终端。新规格在该策略下次分配容器时生效(例如,旧容器因 空闲超时被清理或手动删除后)。
将策略连接到 Open WebUI
一旦策略在编排器上存在,就可以在 Open WebUI 中将其连接起来,使用户可以访问。
1. 添加终端连接
在 Open WebUI 管理面板中,进入 Settings → Connections 并添加 Open Terminal 连接:
| 字段 | 值 |
|---|---|
| URL | 编排器的 URL(例如 http://terminals-orchestrator:3000) |
| API Key | 编排器的 TERMINALS_API_KEY |
| Policy ID | 你创建的策略名称(例如 data-science) |
保存后,Open WebUI 会将该连接的所有请求通过编排器上的 /p/data-science/... 路由。
2. 通过组限制访问
每个终端连接都支持访问授权,用于控制哪些用户或组可以看到它。这让你能够向不同团队提供不同的策略:
[
{
"url": "http://orchestrator:3000",
"key": "sk-...",
"policy_id": "development",
"config": {
"access_grants": [
{ "principal_type": "group", "principal_id": "engineering", "permission": "read" }
]
}
},
{
"url": "http://orchestrator:3000",
"key": "sk-...",
"policy_id": "data-science",
"config": {
"access_grants": [
{ "principal_type": "group", "principal_id": "data-team", "permission": "read" }
]
}
}
]在此示例中,工程组只能看到 development 终端,而数据团队只能看到 data-science 终端。同时属于两个组的用户可以看到两者。
全局资源限制
管理员可以在编排器上设置全局限制,对策略值进行约束,防止任何策略超出允许的最大值。这些限制通过编排器本身的环境变量设置:
| 环境变量 | 示例 | 说明 |
|---|---|---|
TERMINALS_MAX_CPU | 8 | 任何策略可申请的最大 CPU。超出的策略会被静默约束为此值。 |
TERMINALS_MAX_MEMORY | 32Gi | 任何策略可申请的最大内存 |
TERMINALS_MAX_STORAGE | 100Gi | 任何策略可申请的最大持久存储 |
TERMINALS_ALLOWED_IMAGES | ghcr.io/open-webui/*,gcr.io/my-org/* | 逗号分隔的 glob 模式。若设置,策略的 image 必须匹配其中至少一个模式,否则请求将被拒绝(HTTP 400)。 |
这些限制在策略创建和更新时强制执行。如果策略的 cpu_limit 为 "16" 但 TERMINALS_MAX_CPU 为 "8",存储的值会被静默约束为 "8"。
全局资源限制为平台管理员提供了安全保障。他们可以将策略创建权限委派给团队负责人,同时确保没有任何单个策略会消耗过多的集群资源。
"default" 策略
如果你尚未创建任何策略,也无需创建。编排器使用其全局环境变量作为有效默认值开箱即用:
| 设置 | 环境变量 |
|---|---|
| 镜像 | TERMINALS_IMAGE |
| 空闲超时 | TERMINALS_IDLE_TIMEOUT_MINUTES |
| 存储模式 | TERMINALS_KUBERNETES_STORAGE_MODE |
当 Open WebUI 中的终端连接未设置 policy_id(或编排器收到不带 /p/ 前缀的请求)时,此零配置回退会生效。无需数据库条目;它等同于单策略部署。
如果你后续在数据库中创建了名为 default 的策略,其字段会与全局设置合并(策略值优先)。
API 参考(用于程序化访问)
所有端点均以编排器上的 /api/v1 为前缀,并需要 Authorization: Bearer {TERMINALS_API_KEY} 标头。
| 方法 | 端点 | 说明 |
|---|---|---|
GET | /policies | 列出所有策略 |
POST | /policies | 创建新策略(请求体:{ "id": "...", "data": { ... } })。若已存在则返回 409。 |
GET | /policies/{policy_id} | 获取单个策略 |
PUT | /policies/{policy_id} | 创建或更新策略(请求体:PolicyData 字段) |
DELETE | /policies/{policy_id} | 删除策略 |
请求体:PolicyData
{
"image": "ghcr.io/open-webui/open-terminal:latest",
"cpu_limit": "4",
"memory_limit": "16Gi",
"storage": "20Gi",
"storage_mode": "per-user",
"env": { "KEY": "value" },
"idle_timeout_minutes": 60
}所有字段均为可选。省略的字段继承编排器的全局默认值。
响应体:PolicyResponse
{
"id": "data-science",
"data": {
"image": "ghcr.io/open-webui/open-terminal:latest",
"cpu_limit": "4",
"memory_limit": "16Gi",
"storage": "20Gi",
"env": { "OPEN_TERMINAL_ALLOWED_DOMAINS": "*.pypi.org" },
"idle_timeout_minutes": 60
},
"created_at": "2025-06-01T12:00:00",
"updated_at": "2025-06-01T12:00:00"
}示例:多团队配置
一家公司有三个团队(工程、数据科学和实习生),希望提供不同的终端环境。
1. 在 Open WebUI 中创建策略
在管理面板的 Settings → Connections → Open Terminal 下,创建三个策略:
| 策略 | 镜像 | CPU | 内存 | 存储 | 空闲超时 |
|---|---|---|---|---|---|
engineering | 默认 | 2 | 4Gi | 10Gi | 120 分钟 |
data-science | 自定义数据科学镜像 | 8 | 32Gi | 50Gi | 60 分钟 |
intern | 默认 | 1 | 1Gi | 无 | 15 分钟 |
2. 创建终端连接
添加三个连接,每个连接指向相同的编排器 URL,但使用不同的 policy_id 值:engineering、data-science 和 intern。
3. 分配组
对每个连接使用访问授权来限制可见范围:
- 工程连接 →
engineering组 - 数据科学连接 →
data-science组 - 实习生连接 →
interns组
engineering 组的用户只能看到工程终端。数据科学家只能看到他们自己的终端。实习生获得有限的资源,并在 15 分钟不活动后自动清理。