docs(deploy): add Kubernetes deployment guide (zh/en/ja)

Add a Kubernetes deployment page covering the Box sandbox runtime under
k8s: the langbot-box component, the same-absolute-path constraint for the
Box workspace root (hostPath + podAffinity), the explicit
BOX__RUNTIME__ENDPOINT Service name, security implications of mounting
the node Docker socket, and readiness checks. Register the page in the
Installation group for all three languages.
This commit is contained in:
RockChinQ
2026-06-07 11:19:07 -04:00
parent cc15e187ba
commit 3c950c23c3
4 changed files with 309 additions and 0 deletions
+3
View File
@@ -252,6 +252,7 @@
"pages": [
"en/deploy/langbot/package",
"en/deploy/langbot/docker",
"en/deploy/langbot/kubernetes",
"en/deploy/langbot/one-click/1panel",
"en/deploy/langbot/one-click/bt",
"en/deploy/langbot/manual",
@@ -463,6 +464,7 @@
"pages": [
"zh/deploy/langbot/package",
"zh/deploy/langbot/docker",
"zh/deploy/langbot/kubernetes",
"zh/deploy/langbot/one-click/1panel",
"zh/deploy/langbot/one-click/bt",
"zh/deploy/langbot/manual",
@@ -699,6 +701,7 @@
"pages": [
"ja/deploy/langbot/package",
"ja/deploy/langbot/docker",
"ja/deploy/langbot/kubernetes",
"ja/deploy/langbot/one-click/1panel",
"ja/deploy/langbot/one-click/bt",
"ja/deploy/langbot/manual",
+102
View File
@@ -0,0 +1,102 @@
---
title: "Kubernetes Deployment"
---
<Warning>
Before you start, you should be familiar with:
- Basic Kubernetes usage (`kubectl`, Namespace, Deployment, Service, PVC)
- How to configure inter-container networking and persistent storage
</Warning>
The LangBot repository ships a ready-to-use Kubernetes manifest at `docker/kubernetes.yaml`, together with a full [`README_K8S.md`](https://github.com/langbot-app/LangBot/blob/master/docker/README_K8S.md). This page summarizes the essentials, focusing on the **Box sandbox runtime** under Kubernetes — the part that differs most from the Docker Compose deployment.
## Components
The manifest creates the following components in the `langbot` namespace:
| Component | Description | Ports |
| --- | --- | --- |
| `langbot` | Main app (WebUI + webhooks) | 5300 / 2280-2290 |
| `langbot-plugin-runtime` | Plugin runtime | 5400 |
| `langbot-box` | Box sandbox runtime (optional) | 5410 |
Persistent storage: three PVCs (`langbot-data`, `langbot-plugins`, `langbot-plugin-runtime-data`). The Box workspace root uses a node `hostPath` (`/app/data/box`) rather than a PVC.
## Quick Start
```bash
# Clone the repository
git clone https://github.com/langbot-app/LangBot
cd LangBot/docker
# Deploy all components
kubectl apply -f kubernetes.yaml
# Check status
kubectl get all -n langbot
```
Access the WebUI via port-forward:
```bash
kubectl port-forward -n langbot svc/langbot 5300:5300
# Visit http://localhost:5300
```
For production, expose via Ingress + TLS — see `README_K8S.md`.
## Box Sandbox Runtime
`langbot-box` provides the code-sandbox capability backing the sandbox tools (`exec` / `read` / `write` / `edit` / `glob` / `grep`), the skill `activate` tool and skill add/edit, and stdio-mode MCP servers. It is **optional**: without it, LangBot still runs and the dashboard / skills list stay visible (read-only), but those features are disabled — in that case set `BOX__ENABLED=false` on `langbot`.
### How it works & the key constraint
The official LangBot image ships **only the Docker CLI** (no dockerd, no nsjail). The Box runtime therefore creates sandbox containers by talking to the node's Docker daemon over the mounted socket (`/var/run/docker.sock`) — it does not run dockerd inside the Pod.
This imposes a **key constraint**: the daemon that actually creates sandbox containers is the **node's Docker daemon**, which resolves bind-mount paths against the **node filesystem**. So the Box workspace root must be the **same absolute path** in all three places:
1. The actual path on the node
2. The mount path inside the `langbot-box` container
3. The mount path inside every sandbox container it spawns
This is exactly why the manifest uses a `hostPath` (fixed at `/app/data/box`) instead of a regular PVC: a PVC path only exists inside the Pod's mount namespace, which the node's dockerd cannot see. `langbot` and `langbot-box` are also pinned to the **same node** via `podAffinity` so they share this hostPath.
<Warning>
Because it relies on hostPath + same-node affinity, `langbot` does not support multi-replica horizontal scaling (same limitation as `ReadWriteOnce` PVCs). High availability requires a different architecture.
</Warning>
### Connection & configuration
- `langbot` connects to the Box runtime over WebSocket, using the endpoint from the ConfigMap: `BOX__RUNTIME__ENDPOINT: ws://langbot-box:5410`.
<Note>
The in-container default hostname is `langbot_box` (with an underscore), which is **not** a valid Kubernetes DNS name. The endpoint must therefore be set **explicitly** to the valid Service name `langbot-box` — you cannot rely on the in-container default.
</Note>
- The Box runtime does **not** read its own `box.local.*` / `BOX__*` environment variables; its configuration is read from `BOX__LOCAL__*` by `langbot` and pushed via the INIT RPC. So `BOX__LOCAL__HOST_ROOT` / `DEFAULT_WORKSPACE` / `SKILLS_ROOT` / `ALLOWED_MOUNT_ROOTS` are set on the `langbot` Deployment, where `HOST_ROOT` must match the `box-root` mountPath on both sides (`/app/data/box`).
### Security note
Mounting the node's Docker socket grants the Box runtime (and any code executed in the sandbox) effective root on the node. Only deploy Box on nodes you trust for this workload — ideally a dedicated node pool isolated with taints/tolerations. For a stronger isolation boundary, switch `box.backend` to `e2b` (set `E2B_API_KEY`) and drop the `docker.sock` mount + hostPath. See [Sandbox configuration](/en/usage/sandbox/config).
### Verify Box is ready
```bash
# Box runtime logs (should show the selected backend, e.g. "using backend: docker")
kubectl logs -n langbot -l app=langbot-box -f
# Confirm langbot connected to the Box runtime
kubectl logs -n langbot -l app=langbot | grep -i "box runtime"
```
## When you don't need the sandbox
If you do not need the sandbox, remove the `langbot-box` Deployment / Service from the manifest and set `BOX__ENABLED=false` on the `langbot` Deployment to avoid connection-failure warnings in the logs.
## Further reading
- [Docker Deployment](/en/deploy/langbot/docker)
- [Sandbox docs](/en/usage/sandbox/readme) and [Sandbox configuration](/en/usage/sandbox/config)
- [Skills docs](/en/usage/skills/readme)
- Full manifest and operations: [`docker/README_K8S.md`](https://github.com/langbot-app/LangBot/blob/master/docker/README_K8S.md) in the repo
+102
View File
@@ -0,0 +1,102 @@
---
title: "Kubernetes デプロイ"
---
<Warning>
事前に以下を理解しておく必要があります:
- Kubernetes クラスタの基本操作(`kubectl`、Namespace、Deployment、Service、PVC)
- コンテナ間ネットワークと永続ストレージの設定方法
</Warning>
LangBot リポジトリの `docker/` ディレクトリには、すぐに使える Kubernetes マニフェスト `kubernetes.yaml` と、完全な [`README_K8S.md`](https://github.com/langbot-app/LangBot/blob/master/docker/README_K8S.md) が用意されています。本ページはその要点をまとめたもので、Docker Compose デプロイと最も異なる部分である **Box サンドボックスランタイム** に焦点を当てます。
## コンポーネント構成
マニフェストは `langbot` ネームスペースに以下のコンポーネントを作成します:
| コンポーネント | 説明 | ポート |
| --- | --- | --- |
| `langbot` | メインアプリ(WebUI + webhook) | 5300 / 2280-2290 |
| `langbot-plugin-runtime` | プラグインランタイム | 5400 |
| `langbot-box` | Box サンドボックスランタイム(任意) | 5410 |
永続ストレージ:`langbot-data`、`langbot-plugins`、`langbot-plugin-runtime-data` の 3 つの PVC。Box ワークスペースのルートは PVC ではなくノード上の `hostPath`(`/app/data/box`)を使用します。
## クイックスタート
```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 での公開を推奨します。詳細は `README_K8S.md` を参照してください。
## 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 ワークスペースのルートは、以下の 3 か所で**同一の絶対パス**でなければなりません:
1. ノード上の実際のパス
2. `langbot-box` コンテナ内のマウントパス
3. それが作成する各サンドボックスコンテナ内のマウントパス
これがマニフェストで通常の PVC ではなく `hostPath`(`/app/data/box` に固定)を使う理由です:PVC のパスは Pod の mount namespace 内にしか存在せず、ノードの dockerd からは見えません。また `langbot` と `langbot-box` は `podAffinity` によって**同一ノード**にスケジュールされ、この hostPath を共有します。
<Warning>
hostPath + 同一ノードアフィニティに依存するため、`langbot` は複数レプリカの水平スケーリングをサポートしません(`ReadWriteOnce` PVC と同じ制約)。高可用性が必要な場合は別のアーキテクチャを検討してください。
</Warning>
### 接続と設定
- `langbot` は WebSocket で Box ランタイムに接続します。エンドポイントは ConfigMap の `BOX__RUNTIME__ENDPOINT: ws://langbot-box:5410` で指定します。
<Note>
コンテナ内のデフォルトホスト名は `langbot_box`(アンダースコア付き)ですが、アンダースコアは有効な Kubernetes DNS 名ではありません。そのためマニフェストでは、有効な Service 名 `langbot-box` を使ってエンドポイントを**明示的に**指定する必要があり、コンテナ内のデフォルト値に依存できません。
</Note>
- 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 はこのワークロードを信頼できるノードにのみデプロイし、できればテイント/トレラレーションで隔離した専用ノードプールを使用してください。より強い隔離境界が必要な場合は、`box.backend` を `e2b` に切り替え(`E2B_API_KEY` を設定)、`docker.sock` のマウントと hostPath を削除します。詳細は[サンドボックス設定](/ja/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 デプロイ](/ja/deploy/langbot/docker)
- [サンドボックスドキュメント](/ja/usage/sandbox/readme) と [サンドボックス設定](/ja/usage/sandbox/config)
- [スキルシステムドキュメント](/ja/usage/skills/readme)
- 完全なマニフェストと運用操作:リポジトリ内の [`docker/README_K8S.md`](https://github.com/langbot-app/LangBot/blob/master/docker/README_K8S.md)
+102
View File
@@ -0,0 +1,102 @@
---
title: "Kubernetes 部署"
---
<Warning>
您需要提前了解:
- Kubernetes 集群的基本使用(`kubectl`、Namespace、Deployment、Service、PVC)
- 容器间网络通信与持久化存储的配置方式
</Warning>
LangBot 仓库在 `docker/` 目录下提供了开箱即用的 Kubernetes 部署清单 `kubernetes.yaml`,以及完整的 [`README_K8S.md`](https://github.com/langbot-app/LangBot/blob/master/docker/README_K8S.md)。本页是其要点说明,重点放在 **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 对外暴露,详见 `README_K8S.md`。
## 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。
<Warning>
因为依赖 hostPath + 同节点亲和,`langbot` 不支持多副本横向扩容(与使用 `ReadWriteOnce` PVC 的限制一致)。如需高可用,需另行设计架构。
</Warning>
### 连接与配置
- `langbot` 通过 WebSocket 连接 Box 运行时,端点由 ConfigMap 中的 `BOX__RUNTIME__ENDPOINT: ws://langbot-box:5410` 指定。
<Note>
容器内默认主机名是 `langbot_box`(带下划线),而下划线不是合法的 Kubernetes DNS 名称,因此清单中**必须显式**用合法的 Service 名 `langbot-box` 指定端点,不能依赖容器内默认值。
</Note>
- 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/README_K8S.md`](https://github.com/langbot-app/LangBot/blob/master/docker/README_K8S.md)