--- title: "Kubernetes 部署" description: "在 Kubernetes 上部署 LangBot,实现可扩展、生产级的多平台 AI 机器人托管。" --- 您需要提前了解: - Kubernetes 集群的基本使用(`kubectl`、Namespace、Deployment、Service、PVC) - 容器间网络通信与持久化存储的配置方式 LangBot 仓库在 `docker/` 目录下提供了开箱即用的 Kubernetes 部署清单 [`kubernetes.yaml`](https://github.com/langbot-app/LangBot/blob/master/docker/kubernetes.yaml)。本页是该清单的部署说明,重点放在 **Box 沙箱运行时** 在 Kubernetes 下的部署方式——这是与 Docker Compose 部署差异最大的部分。 ## 组件构成 清单会在 `langbot` 命名空间下创建以下组件: | 组件 | 说明 | 端口 | | --- | --- | --- | | `langbot` | 主应用(WebUI + webhook) | 5300 / 2280-2290 | | `langbot-plugin-runtime` | 插件运行时 | 5400 | | `langbot-box` | Box 沙箱运行时(可选) | 5410 | 持久化存储:`langbot-data`、`langbot-plugins`、`langbot-plugin-runtime-data` 三个 PVC;Box 工作区根目录使用节点上的 `hostPath`(`/app/data/box`),而非 PVC。 ## 快速开始 ```bash # 克隆仓库 git clone https://github.com/langbot-app/LangBot cd LangBot/docker # 部署全部组件 kubectl apply -f kubernetes.yaml # 查看状态 kubectl get all -n langbot ``` 部署完成后,可通过端口转发访问 WebUI: ```bash kubectl port-forward -n langbot svc/langbot 5300:5300 # 浏览器访问 http://localhost:5300 ``` 生产环境推荐使用 Ingress + TLS 对外暴露(清单中已附带被注释的 Ingress / LoadBalancer / NodePort 示例,按需取消注释)。 ### 使用 SeekDB 官方镜像已经包含可选的 SeekDB 依赖,无需构建专用镜像或添加额外构建参数。将 `vdb.use` 配置为 `seekdb` 即可启用;不使用时保持默认的 `chroma`。 ## Box 沙箱运行时 `langbot-box` 为 LangBot 提供代码沙箱能力,支撑沙箱工具(`exec` / `read` / `write` / `edit` / `glob` / `grep`)、技能的 `activate` 工具与新增/编辑、以及 stdio 模式的 MCP 服务器。它是**可选组件**:不部署时 LangBot 仍可运行,仪表盘与技能列表只读可见,但上述能力会被禁用,此时请在 `langbot` 上设置 `BOX__ENABLED=false`。 ### 工作原理与关键约束 LangBot 官方镜像**只内置了 Docker CLI**(不含 dockerd,也不含 nsjail)。因此 Box 运行时通过挂载到节点的 Docker socket(`/var/run/docker.sock`)来创建沙箱容器——它本身不在 Pod 内运行 dockerd。 由此带来一个**关键约束**:真正创建沙箱容器的是**节点上的 Docker 守护进程**,它解析 bind-mount 路径时使用的是**节点文件系统**视角。所以 Box 工作区根目录必须在以下三处是**同一个绝对路径**: 1. 节点上的实际路径 2. `langbot-box` 容器内的挂载路径 3. 它创建的每个沙箱容器内的挂载路径 这正是清单使用 `hostPath`(固定在 `/app/data/box`)而非普通 PVC 的原因:PVC 路径只存在于 Pod 的 mount namespace 中,节点的 dockerd 看不到。同时 `langbot` 与 `langbot-box` 通过 `podAffinity` 被强制调度到**同一节点**以共享这个 hostPath。 因为依赖 hostPath + 同节点亲和,`langbot` 不支持多副本横向扩容(与使用 `ReadWriteOnce` PVC 的限制一致)。如需高可用,需另行设计架构。 ### 连接与配置 - `langbot` 通过 WebSocket 连接 Box 运行时,端点由 ConfigMap 中的 `BOX__RUNTIME__ENDPOINT: ws://langbot-box:5410` 指定。 容器内默认主机名是 `langbot_box`(带下划线),而下划线不是合法的 Kubernetes DNS 名称,因此清单中**必须显式**用合法的 Service 名 `langbot-box` 指定端点,不能依赖容器内默认值。 - Box 运行时**不读取**自身的 `box.local.*` / `BOX__*` 环境变量;其配置由 `langbot` 读取 `BOX__LOCAL__*` 后通过 INIT RPC 下发。因此 `BOX__LOCAL__HOST_ROOT` / `DEFAULT_WORKSPACE` / `SKILLS_ROOT` / `ALLOWED_MOUNT_ROOTS` 都配置在 `langbot` Deployment 上,其中 `HOST_ROOT` 必须与两侧的 `box-root` 挂载路径一致(`/app/data/box`)。 ### 安全提示 挂载节点的 Docker socket 会让 Box 运行时(以及在沙箱中执行的任意代码)获得对节点的**实质 root 权限**。请仅在你信任该工作负载的节点上部署 Box,最好使用专用节点池并配合污点/容忍(taint/toleration)隔离。若需要更强的隔离边界,可将 `box.backend` 切换为 `e2b`(设置 `E2B_API_KEY`),并移除 `docker.sock` 挂载与 hostPath。详见[沙箱配置](/zh/usage/sandbox/config)。 ### 验证 Box 是否就绪 ```bash # 查看 Box 运行时日志(应能看到选用的 backend,例如 "using backend: docker") kubectl logs -n langbot -l app=langbot-box -f # 在 langbot 日志中确认已连上 Box 运行时 kubectl logs -n langbot -l app=langbot | grep -i "box runtime" ``` ## 不需要沙箱时 如果你不需要沙箱能力,可以删除清单中的 `langbot-box` Deployment / Service,并在 `langbot` Deployment 上设置 `BOX__ENABLED=false`,以避免连接失败的告警日志。 ## 后续阅读 - [Docker 部署](/zh/deploy/langbot/docker) - [沙箱文档](/zh/usage/sandbox/readme) 与 [沙箱配置](/zh/usage/sandbox/config) - [技能系统文档](/zh/usage/skills/readme) - 部署清单源文件:仓库内 [`docker/kubernetes.yaml`](https://github.com/langbot-app/LangBot/blob/master/docker/kubernetes.yaml)