部署环境:ACK Pro 集群(杭州地域),2 台 8c16g ECS + ACS Serverless 后端。 目标:在 Agent Sandbox 上运行 OpenClaw 网关,通过 ALB 从集群外部访问其 Web Control UI。 域名
openclaw-sandbox.infra,E2B API Keye2b_root591740。
引言
AI Agent 的落地离不开一个安全、隔离、按需弹性的代码执行环境。在企业级万虾部署的场景下:阿里云 ACS Agent Sandbox 正是为此而生的一套 Serverless 沙箱方案,相比于传统k8s工作负载部署方式更加节省计算资源且更易于维护 -- 它在 ACK 集群中以 virtual-kubelet 虚拟节点的形式注册,当 Pod 被调度到虚拟节点时,背后并无物理机器,而是由 ACS Serverless 后端按需拉起容器实例,按用量秒级计费。沙箱之间相互隔离,适合运行不可信代码、Agent 工具调用等场景。
Agent Sandbox 同时兼容 E2B SDK 的 API 协议。这意味着凡是面向 E2B 编写的 Agent 应用,理论上只需修改域名和 API Key,即可无缝迁移到 ACS 沙箱上运行——无需改动业务代码。
OpenClaw 是一个开源的 AI Agent 网关与运行时平台,提供 Web Control UI、多模型 Provider 接入(兼容 OpenAI API 格式)、配置热加载等能力。将 OpenClaw 部署到 ACS Agent Sandbox 中,可以让每个沙箱实例成为一个独立的 Agent 运行环境:用户通过 E2B SDK 领取沙箱、注入配置,再经由 ALB 从集群外部访问沙箱内的 Web UI。
这个设想听起来直接,实际落地却涉及多个层面的打通工作:
- 基础设施层:virtual-kubelet 虚拟节点的调度机制、SandboxSet 预热池模型、Sandbox/SandboxClaim 生命周期管理;
- 网络层:ALB Ingress 的 HTTPS 监听器配置、sandbox-gateway 的子域名路由转发、自签证书体系;
- 应用层:OpenClaw 在容器环境中的监听地址配置(
gateway.bind)、配置文件运行时注入、config watcher 热重启机制; - 客户端层:E2B SDK 的 DNS 解析问题(macOS
/etc/hosts不支持通配符)及猴子补丁方案。
本文记录了在 ACK Pro 集群上完成上述全链路部署的完整过程。内容组织如下:第 1 章拆解系统架构与端到端数据流,第 2–3 章覆盖前置准备与组件部署,第 4 章创建 OpenClaw 沙箱预热池,第 5 章给出 E2B SDK 接入的完整脚本与最佳实践,第 6 章按时间顺序记录部署过程中遇到的 11 个问题及根因分析,最后附验证清单与配置速查表。
所有命令均附带原理说明,所有状态输出均为真实执行结果。目标是使读者能够在同等环境下完整复现本次部署。
系统架构
ACS Serverless 与虚拟节点
ACK Pro 集群中存在两类节点。理解二者的区别是后续所有操作的前提。
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP OS-IMAGE
cn-hangzhou.10.89.190.188 Ready <none> 6h v1.36.2-aliyun.1 10.89.190.188 Alibaba Cloud Linux 4.0.5
cn-hangzhou.10.89.190.189 Ready <none> 6h v1.36.2-aliyun.1 10.89.190.189 Alibaba Cloud Linux 4.0.5
virtual-kubelet-cn-hangzhou-i Ready agent 7h v1.36.2-aliyun.1 10.203.175.118 <unknown>
virtual-kubelet-cn-hangzhou-j Ready agent 7h v1.36.2-aliyun.1 10.203.175.118 <unknown>
virtual-kubelet-cn-hangzhou-k Ready agent 7h v1.36.2-aliyun.1 10.203.175.118 <unknown>| 节点类型 | 对应实体 | 承载工作负载 | 计费模式 |
|---|---|---|---|
| 普通节点(ECS) | 真实 ECS 机器 | 管理组件:sandbox-manager、sandbox-gateway | 按 ECS 实例 |
| 虚拟节点(virtual-kubelet) | 非真实机器,是 serverless 后端的入口 | 业务沙箱 Pod(OpenClaw 等) | 按 Pod 用量秒级计费 |
virtual-kubelet 向 Kubernetes 注册了一个 Node 对象,但其背后没有物理机器。当 Pod 被调度到虚拟节点时,virtual-kubelet 将创建请求转发给 ACS serverless 后端(类似 ECI / Fargate),由云按需拉起容器实例。三个虚拟节点共享同一个 INTERNAL-IP(10.203.175.118),说明它们是同一 serverless 入口的多副本。
虚拟节点带有 taint type=virtual-kubelet:NoSchedule,阻止普通 Pod 调度。Agent Sandbox 的沙箱 Pod 由 sandbox-manager 自动注入 toleration 和以下 labels:
alibabacloud.com/acs: "true"
alibabacloud.com/compute-class: agent-sandbox
alibabacloud.com/compute-qos: defaultcompute-class: agent-sandbox 告诉 serverless 后端按沙箱规格计费并走沙箱链路。普通业务 Pod 不带这些 labels 和 toleration,不会调度到虚拟节点。
Agent Sandbox 组件体系
| 组件 | 职责 | 集群内 Pod |
|---|---|---|
| acs-virtual-node (>= v2.17.0) | 提供 virtual-kubelet 虚拟节点,沙箱 Pod 调度到 serverless 的前提 | virtual-node controller |
| ack-sandbox-manager (>= v0.6.0) | 核心组件。controller 负责 watch SandboxSet/Sandbox CR、管理预热池、leader 选举;proxy 提供 E2B 兼容 API server,处理 SDK 的创建/连接/操作沙箱请求 | sandbox-manager deployment(controller + proxy 两容器) |
| sandbox-gateway | 流量代理层。memberlist 组网,按子域名解析 sandboxID,将流量转发到对应沙箱 Pod | sandbox-gateway deployment |
| ack-agent-sandbox-controller (>= v0.5.14) | 负责沙箱 Pod 生命周期管理(调云 API 创建 serverless Pod) | 实测可缺失(见 6.4),不影响核心链路 |
| ALB Ingress Controller | 将外部 HTTPS 流量路由到 sandbox-manager / sandbox-gateway service | ALB 实例在云上,通过 AlbConfig CR + Ingress 配置 |
组件部署后的实际状态:
$ kubectl get po -n sandbox-system
NAME READY STATUS RESTARTS AGE
sandbox-gateway-7d789f4f69-44s6v 1/1 Running 0 7h
sandbox-gateway-7d789f4f69-qk5wq 1/1 Running 0 7h
sandbox-manager-76f7c7cd57-jjf4n 2/2 Running 0 6h36msandbox-manager Pod 有 2 个容器(controller + proxy),sandbox-gateway 有 1 个容器。leader 选举机制下 sandbox-manager 只需 1 副本。
流量路由模型
Ingress 配置了三条路由规则,按 Host 头分发:
$ kubectl get ingress -n sandbox-system
NAME CLASS HOSTS ADDRESS PORTS
sandbox-manager alb api.openclaw-sandbox.infra,*.openclaw-sandbox.infra,openclaw-sandbox.infra alb-1pzfz2ohlimwzmn3xx.cn-hangzhou.alb.aliyuncsslb.com 80, 443| Host 匹配 | 后端 service | 用途 |
|---|---|---|
api.openclaw-sandbox.infra | sandbox-manager:8080 | E2B 管理 API(创建/删除沙箱、鉴权) |
*.openclaw-sandbox.infra | sandbox-gateway:7788 | 沙箱流量代理(按子域名解析 sandboxID 转发到沙箱 Pod 端口) |
openclaw-sandbox.infra | sandbox-manager:8080 | sandbox-manager 直接访问 |
sandbox-gateway 使用 Envoy 的 ORIGINAL_DST 集群类型,从子域名中解析出 {port}-{sandboxID} 格式,然后将流量转发到对应沙箱 Pod 的指定端口。同时通过 ext_proc(端口 9002)进行前置处理(鉴权、健康检查)。
沙箱生命周期
沙箱生命周期由三个自定义资源(CR)驱动:
| CR | 定义 | 作用 |
|---|---|---|
| SandboxSet | 预热池定义:镜像、副本数、runtimes、资源规格 | sandbox-manager watch 它,自动维持副本数 |
| Sandbox | 单个沙箱实例 | state: available(预热池中) -> running(被领取后) |
| SandboxClaim | 领取声明 | 声明式地从预热池领取沙箱,使 state 变为 running |
关键机制:sandbox-gateway 只转发 state=running 的沙箱流量。预热池中的沙箱 state=available,不转发(返回 "healthy sandbox not found")。必须通过 SandboxClaim 或 E2B SDK 的 Sandbox.create() 领取后,state 变为 running,gateway 才会转发。
端到端数据流
完整链路如下:
[E2B SDK (Python)]
| HTTPS, Host: api.openclaw-sandbox.infra
| Sandbox.create() / files.write() / get_host()
v
[ALB] 443/HTTPS, TLS 终止
| 按 Host 路由
v
[Ingress]
|- api.openclaw-sandbox.infra -> sandbox-manager:8080 (E2B 管理 API)
|- *.openclaw-sandbox.infra -> sandbox-gateway:7788 (沙箱流量代理)
v
[sandbox-manager proxy] API Key 鉴权 -> 领取预热池沙箱 (state: available -> running)
v
[sandbox-manager controller] watch SandboxSet/Sandbox CR, reconcile
| 创建 Sandbox CR + Pod (注入 csi/agent-runtime sidecar)
v
[Pod 调度到 virtual-kubelet 节点]
| virtual-kubelet 转发到 ACS serverless 后端
v
[ACS serverless] 拉起容器实例 -> Pod Running
| sandbox-manager 设置路由到此沙箱
v
[sandbox-gateway] 按子域名解析 sandboxID -> 转发到沙箱 Pod:port
| envd (port 49983) -> 文件读写
| openclaw (port 18789) -> Web UISDK 不直连沙箱 Pod。所有操作经 sandbox-manager proxy(管理 API)或 sandbox-gateway(流量代理)转发。沙箱 Pod 在 serverless 网络中,外部不可直达。
前置准备
集群环境
- ACK Pro 集群(杭州地域),Kubernetes v1.36.2-aliyun.1
- 2 台 8c16g ECS 普通节点(运行管理组件)
- 3 个 virtual-kubelet 虚拟节点(运行沙箱 Pod)
- kubeconfig 保存至
/Users/feichi/gopath/src/Sandbox/kubeconfig
域名与证书
使用 generate-certificates.sh 生成自签名证书(730 天有效期):
bash generate-certificates.sh -d openclaw-sandbox.infra -D 730原理:脚本生成一个 CA 根证书,再用该 CA 签发服务器证书(覆盖 openclaw-sandbox.infra 和 *.openclaw-sandbox.infra)。产出文件:
| 文件 | 用途 |
|---|---|
certs/fullchain.pem | 服务器证书公钥链,挂载到 ALB/Ingress |
certs/privkey.pem | 服务器证书私钥,挂载到 ALB/Ingress |
certs/ca-fullchain.pem | CA 证书公钥,E2B SDK 客户端需信任此 CA |
certs/ca-privkey.pem | CA 证书私钥 |
组件版本要求
在控制台「组件管理」中确认或升级:
- acs-virtual-node >= v2.17.0
- Kube Scheduler 升级到对应集群版本的最低要求(v1.36 需 >= v1.36.0-aliyun-1.x)
部署过程
以下步骤均可通过控制台或 kubectl 复现。所有 kubectl 命令使用统一的 kubeconfig 路径。
安装 ALB Ingress Controller
控制台「组件管理」安装 ALB Ingress Controller。安装后自动创建:
- 一个公网 ALB 实例(域名形如
alb-xxx.cn-hangzhou.alb.aliyuncsslb.com) - AlbConfig CR(名称默认为
alb) - IngressClass(名称为
alb)
kubectl get albconfig alb -n kube-system
kubectl get ingressclass alb安装 ack-agent-sandbox-controller
控制台安装。首次安装需授权 RAM 角色 AliyunCSManagedAgentSandboxRole。
该组件的 controller pod 实测可能不在集群中(见 6.4),但不影响核心链路。不要尝试卸载它(sandbox-manager 声明了对它的依赖,卸载会报错)。
安装 ack-sandbox-manager(关键配置)
控制台安装 ack-sandbox-manager,配置参数:
| 参数 | 值 | 说明 |
|---|---|---|
| sandboxManager.replicaCount | 1 | leader 选举,多副本仅 1 个 active,1 副本足够 |
| sandboxManager.controller.resources.cpu | 2 | 不要设为节点核数整数值(见 6.2) |
| sandboxManager.controller.resources.memory | 4Gi | |
| sandboxManager.proxy.resources.cpu | 2 | |
| sandboxManager.proxy.resources.memory | 4Gi | |
| sandboxManager.acs | false | ACK Pro 模式(非纯 ACS 集群) |
| e2b.domain | openclaw-sandbox.infra | |
| e2b.enableAuth | true | 开启 API Key 鉴权 |
| e2b.adminApiKey | e2b_root591740 | |
| ingress.className | alb | |
| ingress.tls | true |
安装后验证:
$ kubectl get deploy -n sandbox-system
NAME READY UP-TO-DATE AVAILABLE AGE
sandbox-gateway 2/2 2 2 7h
sandbox-manager 1/1 1 1 6h36m
$ kubectl get po -n sandbox-system
NAME READY STATUS RESTARTS AGE
sandbox-gateway-7d789f4f69-44s6v 1/1 Running 0 7h
sandbox-gateway-7d789f4f69-qk5wq 1/1 Running 0 7h
sandbox-manager-76f7c7cd57-jjf4n 2/2 Running 0 6h36m
$ kubectl get ingress -n sandbox-system
NAME CLASS HOSTS PORTS AGE
sandbox-manager alb api.openclaw-sandbox.infra,*.openclaw-sandbox.infra,openclaw-sandbox.infra 80, 443 7h创建 TLS Secret
将自签证书挂载到 Ingress / ALB。ALB 从 Ingress 的 TLS secret 自动注册证书到 AlbConfig。
kubectl create secret tls sandbox-manager-tls \
--cert=certs/fullchain.pem \
--key=certs/privkey.pem \
-n sandbox-systemAlbConfig 添加 443/HTTPS 监听器
ALB 默认只有 80/HTTP 监听器。HTTPS 需手动添加。
kubectl patch albconfig alb -n kube-system --type='json' -p='[
{"op":"add","path":"/spec/listeners/-","value":{"port":443,"protocol":"HTTPS"}}
]'原理:patch 操作在 AlbConfig 的 spec.listeners 数组末尾追加一个 HTTPS:443 监听器。ALB Ingress Controller watch AlbConfig 变更并同步到 ALB 实例。证书 ID 从 Ingress TLS secret 自动填充。
验证:
kubectl get albconfig alb -n kube-system -o jsonpath='{.status.loadBalancer.listeners[*]}'
# 预期:80/HTTP + 443/HTTPS,certId 非空Ingress 关联 TLS
kubectl patch ingress sandbox-manager -n sandbox-system --type='json' -p='[
{"op":"add","path":"/spec/tls","value":[{"hosts":["openclaw-sandbox.infra","*.openclaw-sandbox.infra","api.openclaw-sandbox.infra"],"secretName":"sandbox-manager-tls"}]},
{"op":"add","path":"/metadata/annotations/alb.ingress.kubernetes.io~1listen-ports","value":"[{\"HTTP\": 80}, {\"HTTPS\": 443}]"}
]'原理:spec.tls 声明 Ingress 使用的 TLS secret 和覆盖的 hostnames;listen-ports annotation 指示 ALB 同时监听 80 和 443 端口。二者配合后 ALB 对 443 端口的 HTTPS 请求做 TLS 终止,再以 HTTP 转发到后端 service。
域名解析配置
openclaw-sandbox.infra 使用 .infra 非真实 TLD,公网 DNS 无法解析。测试阶段使用 /etc/hosts 手动指向 ALB 公网 IP。
ALB 公网 IP 查询:
$ kubectl get ingress sandbox-manager -n sandbox-system \
-o jsonpath='{range .status.loadBalancer.ingress[*]}{.hostname}{"\n"}{end}'
alb-1pzfz2ohlimwzmn3xx.cn-hangzhou.alb.aliyuncsslb.com
$ nslookup alb-1pzfz2ohlimwzmn3xx.cn-hangzhou.alb.aliyuncsslb.com
# 解析得到多个 A 记录:121.xx.128.121, 47.xx.94.70, 120.xx.92.115在 /etc/hosts 中添加(任选一个 ALB IP):
121.xx.128.121 openclaw-sandbox.infra
121.xx.128.121 api.openclaw-sandbox.infra注意:sandbox-gateway 的流量代理使用 {port}-{sandboxID}.openclaw-sandbox.infra 格式的子域名。macOS 的 /etc/hosts 不支持通配符,无法预先添加所有子域名。此问题在 6.10 中详述。
生产环境应使用真实域名 CNAME 到 ALB 域名,并申请正式证书。
3.8 验证 ALB 到 sandbox-manager 链路
curl -k --resolve openclaw-sandbox.infra:443:121.xx.128.121 \
https://openclaw-sandbox.infra/
# 返回 404 = 流量已到达 sandbox-manager 后端(无匹配路由,符合预期)--resolve 参数绕过 DNS 解析,直接将指定域名解析到指定 IP。-k 跳过自签证书验证。返回 404 说明 ALB -> Ingress -> sandbox-manager 链路畅通。
创建 OpenClaw 沙箱预热池
SandboxSet 定义
apiVersion: agents.kruise.io/v1alpha1
kind: SandboxSet
metadata:
name: openclaw
namespace: default
spec:
runtimes:
- name: csi # 注入 CSI 挂载 sidecar
- name: agent-runtime # 注入 envd 环境管理工具
replicas: 1 # 预热实例数
template:
metadata:
labels:
alibabacloud.com/acs: "true"
alibabacloud.com/compute-class: agent-sandbox
alibabacloud.com/compute-qos: default
spec:
automountServiceAccountToken: false
containers:
- image: registry-cn-hangzhou-vpc.ack.aliyuncs.com/ack-demo/openclaw:2026.3.23-2
imagePullPolicy: IfNotPresent
name: openclaw
ports:
- containerPort: 18789
name: http-ui
env:
- name: OPENCLAW_SKIP_ONBOARDING
value: "1"
- name: OPENCLAW_TZ
value: "Asia/Shanghai"
resources:
limits:
cpu: "2"
memory: 4Gi
requests:
cpu: "2"
memory: 4Gi
ephemeral-storage: 30Gi
terminationGracePeriodSeconds: 30关键设计说明:
- runtimes:
csi注入 CSI 挂载 sidecar,agent-runtime注入 envd 进程(提供文件读写 API,端口 49983)。E2B SDK 的sandbox.files.write()通过 envd API 操作沙箱内文件系统。 - OPENCLAW_SKIP_ONBOARDING=1: 跳过 OpenClaw 的交互式 onboarding 流程。onboarding 会要求输入 provider API key 和生成 gateway token,不适合无人值守的沙箱环境。配置由后续 E2B SDK 运行时注入(见第 5 章)。
- 不设 OPENCLAW_GATEWAY_TOKEN: gateway token 写在运行时注入的
openclaw.json配置文件中,不硬编码到 env。每个沙箱实例可以使用不同的 token。 - 镜像:
registry-cn-hangzhou-vpc前缀走 VPC 内网拉取,速度远快于公网。地域必须与集群一致(见 6.5)。 - ephemeral-storage: 30Gi: 沙箱需要足够的临时存储空间。
kubectl apply -f openclaw-sandboxset.yaml验证沙箱就绪
$ kubectl get sandboxset
NAME REPLICAS AVAILABLE UPDATEDREPLICAS UPDATEDAVAILABLEREPLICAS UPDATEREVISION AGE
openclaw 1 1 1 1 5576855fd5 22m
$ kubectl get sandbox
NAME STATUS AGE CLAIMED SHUTDOWN_TIME PAUSE_TIME RECYCLEDCOUNT MESSAGE
openclaw-7rx55 Running 22m true
openclaw-dnstc Running 5m41s true
openclaw-t8lrj Running 15m true
openclaw-w9fn4 Running 4m24s false
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
openclaw-w9fn4 4/4 Running 0 4m24sSandboxSet AVAILABLE 1/1 表示预热池有 1 个可用沙箱。沙箱 Pod 有 4 个容器(openclaw 主容器 + csi sidecar + agent-runtime/envd sidecar + pause),调度到 virtual-kubelet 节点。CLAIMED=false 的沙箱是预热池中待领取的实例。
E2B SDK 接入与最佳实践
环境准备
cd e2b-test
python3 -m venv .venv && source .venv/bin/activate
pip install e2b==2.10.2 e2b-code-interpreter==2.4.1 python-dotenv==1.0.1 requests.env 文件内容:
E2B_DOMAIN=openclaw-sandbox.infra
E2B_API_KEY=e2b_root591740
SSL_CERT_FILE=/Users/feichi/gopath/src/Sandbox/certs/ca-fullchain.pem原理:E2B SDK 通过以下环境变量构造 API 地址:
E2B_DOMAIN-> API URL 构造为https://api.{domain},即https://api.openclaw-sandbox.infraE2B_API_KEY-> 请求头Authorization: Bearer {key}SSL_CERT_FILE-> Python ssl 模块的 CA 信任库,使 httpx 信任自签 CA
DNS 解析问题与解决方案
E2B SDK 的三类请求使用不同的域名格式:
| 请求类型 | 域名格式 | 示例 |
|---|---|---|
| 管理 API | api.{domain} | api.openclaw-sandbox.infra |
| 文件操作(envd) | {envd_port}-{sandboxID}.{domain} | 49983-default--openclaw-xxx.openclaw-sandbox.infra |
| 沙箱端口访问 | {port}-{sandboxID}.{domain} | 18789-default--openclaw-xxx.openclaw-sandbox.infra |
sandboxID 在 Sandbox.create() 返回后才知道,无法预先在 /etc/hosts 中添加所有子域名。macOS 的 /etc/hosts 不支持通配符(*.openclaw-sandbox.infra)。
解决方案:在脚本中用 socket.getaddrinfo 猴子补丁拦截 DNS 解析,将所有包含 openclaw-sandbox.infra 的域名解析到 ALB IP。
import socket
_orig_getaddrinfo = socket.getaddrinfo
_ALB_IP = os.getenv("ALB_IP", "121.xx.128.121")
def _patched_getaddrinfo(host, port, *args, **kwargs):
if host and "openclaw-sandbox.infra" in host:
host = _ALB_IP
return _orig_getaddrinfo(host, port, *args, **kwargs)
socket.getaddrinfo = _patched_getaddrinfo原理:Python 的网络库(httpx、requests、urllib3)底层都通过 socket.getaddrinfo 进行 DNS 解析。替换该函数后,所有匹配 openclaw-sandbox.infra 的域名查询都会被重定向到 ALB IP,等效于通配符 DNS。此补丁仅在脚本进程内生效,不影响系统全局 DNS。
完整脚本
import os
import time
import socket
import requests
from string import Template
from dotenv import load_dotenv
from e2b_code_interpreter import Sandbox
# --- DNS 通配符解析补丁 ---
# macOS /etc/hosts 不支持通配符,用 socket 补丁拦截 *.openclaw-sandbox.infra
_orig_getaddrinfo = socket.getaddrinfo
_ALB_IP = os.getenv("ALB_IP", "121.xx.128.121")
def _patched_getaddrinfo(host, port, *args, **kwargs):
if host and "openclaw-sandbox.infra" in host:
host = _ALB_IP
return _orig_getaddrinfo(host, port, *args, **kwargs)
socket.getaddrinfo = _patched_getaddrinfo
# 关闭 SSL 警告(自签名证书)
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
load_dotenv(override=True)
GATEWAY_TOKEN = os.environ.get("GATEWAY_TOKEN", "openclaw-sandbox-token")
DASHSCOPE_API_KEY = os.environ.get("DASHSCOPE_API_KEY", "sk-fake-test-key-12345")
# 步骤 1: 创建 sandbox(从预热池领取)
print("[1/4] 通过 E2B SDK 创建 sandbox (template=openclaw)...")
start = time.monotonic()
sandbox = Sandbox.create(
"openclaw",
metadata={"e2b.agents.kruise.io/never-timeout": "true"},
)
print(f" Sandbox ID: {sandbox.sandbox_id} 耗时: {time.monotonic() - start:.2f}s")
# 步骤 2: 写入 openclaw.json 配置文件
# OpenClaw 的 config watcher 检测到文件变化后自动重启 gateway
print("[2/4] 写入 openclaw.json 配置...")
with open("openclaw_template.json", "r") as f:
template = Template(f.read())
rendered = template.safe_substitute(
GATEWAY_TOKEN=GATEWAY_TOKEN,
DASHSCOPE_API_KEY=DASHSCOPE_API_KEY,
)
sandbox.files.write("/home/node/.openclaw/openclaw.json", rendered, user="node")
print(" 配置已写入 /home/node/.openclaw/openclaw.json")
# 步骤 3: 等待 gateway 重启(config watcher 检测到文件变化后自动重启)
print("[3/4] 等待 30s 让 gateway 重启...")
time.sleep(30)
# 步骤 4: 通过 sandbox-gateway 访问 Web UI
print("[4/4] 测试外部访问...")
host = sandbox.get_host(18789)
base_url = f"https://{host}"
print(f" 访问地址: {base_url}/?token={GATEWAY_TOKEN}")
resp = requests.get(f"{base_url}/?token={GATEWAY_TOKEN}", verify=False, timeout=10)
print(f" HTTP {resp.status_code}, body 长度: {len(resp.text)} bytes")
if resp.status_code == 200:
print(" E2B SDK 全链路验证通过")
else:
print(f" 返回非 200: {resp.text[:200]}")脚本流程说明:
Sandbox.create("openclaw")调用 sandbox-manager 的POST /sandboxesAPI,从预热池领取一个 state=available 的沙箱,使其变为 state=running。返回 sandbox_id。metadata中的e2b.agents.kruise.io/never-timeout: "true"防止沙箱因空闲超时被回收。sandbox.files.write()通过 envd API(端口 49983)将渲染后的openclaw.json写入沙箱内/home/node/.openclaw/openclaw.json。OpenClaw 的 config watcher 检测到配置文件变化后自动重启 gateway 进程,使新配置(包括gateway.bind: "lan")生效。sandbox.get_host(18789)返回18789-{sandboxID}.{domain}格式的主机名,该主机名通过 ALB -> sandbox-gateway 路由到沙箱的 18789 端口。requests.get()通过 HTTPS 访问 OpenClaw Web UI,?token=参数传递 gateway token 进行认证。
配置模板
openclaw_template.json:
{
"agents": {
"defaults": {
"model": {
"primary": "bailian/qwen3.5-plus"
},
"workspace": "/home/node/.openclaw/workspace"
}
},
"models": {
"mode": "merge",
"providers": {
"bailian": {
"baseUrl": "https://dashscope.aliyuncs.com/compatible-mode/v1",
"apiKey": "${DASHSCOPE_API_KEY}",
"api": "openai-completions",
"models": [
{
"id": "qwen3.5-plus",
"name": "通义千问",
"input": ["text"],
"contextWindow": 1000000,
"maxTokens": 65536
}
]
}
}
},
"commands": {
"native": "auto",
"nativeSkills": "auto",
"restart": true,
"ownerDisplay": "raw"
},
"gateway": {
"port": 18789,
"bind": "lan",
"controlUi": {
"allowedOrigins": ["*"],
"dangerouslyAllowHostHeaderOriginFallback": true,
"allowInsecureAuth": true,
"dangerouslyDisableDeviceAuth": true
},
"auth": {
"mode": "token",
"token": "${GATEWAY_TOKEN}"
}
}
}关键配置项说明:
| 配置项 | 值 | 作用 |
|---|---|---|
gateway.bind | lan | 监听所有网卡(0.0.0.0),使 sandbox-gateway 能从外部访问沙箱 18789 端口。默认 loopback 只监听 127.0.0.1,导致 503 Connection refused(见 6.8) |
gateway.auth.mode | token | 使用 token 认证,token 通过 URL 参数 ?token=xxx 传递 |
controlUi.allowedOrigins | ["*"] | 允许任意来源的跨域请求 |
controlUi.dangerouslyAllowHostHeaderOriginFallback | true | 允许通过 Host 头进行 origin fallback(sandbox-gateway 转发时 Host 头会被改写) |
controlUi.allowInsecureAuth | true | 允许通过 HTTP 传 token(ALB 做 TLS 终止后,后端是 HTTP) |
controlUi.dangerouslyDisableDeviceAuth | true | 禁用设备认证(无人值守环境无法完成设备配对) |
models.providers.bailian | - | 百炼(DashScope)模型 provider 配置,兼容 OpenAI API 格式 |
模板使用 Python string.Template 的 ${VAR} 语法进行变量替换,safe_substitute 在变量缺失时保留原值而不报错。
运行结果
$ python3 create_openclaw.py
[1/4] 通过 E2B SDK 创建 sandbox (template=openclaw)...
Sandbox ID: default--openclaw-dnstc 耗时: 0.11s
[2/4] 写入 openclaw.json 配置...
配置已写入 /home/node/.openclaw/openclaw.json
[3/4] 等待 30s 让 gateway 重启...
[4/4] 测试外部访问...
访问地址: https://18789-default--openclaw-dnstc.openclaw-sandbox.infra/?token=openclaw-sandbox-token
HTTP 200, body 长度: 2732 bytes
E2B SDK 全链路验证通过各步骤验证:
- 步骤 1:
Sandbox.create()在 0.11s 内完成。API key 鉴权通过,从预热池领取沙箱。此前曾出现 401 "Invalid API Key"(见 6.9),根因是 DNS 解析失败导致请求异常,非 key 格式问题。 - 步骤 2:
files.write()通过 envd API(端口 49983)成功写入配置文件。 - 步骤 3:30s 等待后 OpenClaw config watcher 检测到
openclaw.json变化,gateway 进程自动重启,加载新配置(gateway.bind: "lan")。 - 步骤 4:通过
sandbox.get_host(18789)获取的外部地址访问,HTTP 200,返回 2732 字节的 HTML(含<openclaw-app>标签),Web UI 可达。

5.6 手动验证(不使用 E2B SDK)
如需绕过 E2B SDK 直接验证链路,可通过 kubectl + curl 完成:
- 写入配置文件(kubectl exec):
cat openclaw.json | kubectl exec -i openclaw-7rx55 -c openclaw -- \
bash -c 'cat > /home/node/.openclaw/openclaw.json && chown node:node /home/node/.openclaw/openclaw.json'- 验证 gateway.bind 生效:
$ kubectl exec openclaw-7rx55 -c openclaw -- openclaw config get gateway.bind
lan
$ kubectl exec openclaw-7rx55 -c openclaw -- \
bash -c 'curl -s -o /dev/null -w "%{http_code}" http://10.175.70.240:18789/healthz'
200- 领取沙箱(SandboxClaim):
$ kubectl apply -f openclaw-claim.yaml
sandboxclaim.agents.kruise.io/openclaw-claim created
$ kubectl get sandboxclaim openclaw-claim -o jsonpath='{.status}'
{"claimStartTime":"2026-08-20T09:39:01Z","claimedReplicas":1,
"conditions":[{"message":"Successfully claimed all 1 sandboxes",
"reason":"AllReplicasClaimed","status":"True","type":"Completed"}],
"message":"Successfully claimed 1/1 sandboxes","phase":"Completed"}- 通过 ALB 测试外部访问(curl --resolve):
$ curl --resolve "18789-default--openclaw-7rx55.openclaw-sandbox.infra:443:121.43.128.121" \
-k -s -w "\nHTTP %{http_code}, size: %{size_download} bytes\n" \
"https://18789-default--openclaw-7rx55.openclaw-sandbox.infra/healthz"
HTTP 200, size: 15 bytes
$ curl --resolve "18789-default--openclaw-7rx55.openclaw-sandbox.infra:443:121.43.128.121" \
-k -s -w "\nHTTP %{http_code}, size: %{size_download} bytes\n" \
"https://18789-default--openclaw-7rx55.openclaw-sandbox.infra/?token=openclaw-sandbox-token"
<openclaw-app></openclaw-app>
</body>
</html>
HTTP 200, size: 2732 bytes--resolve 参数等效于在 /etc/hosts 中添加一条记录,但仅对当前 curl 命令生效。-k 跳过自签证书验证。
踩坑记录
以下记录部署过程中遇到的全部问题,按发现时间排序。每条包含现象、根因、修复方案和原理分析。
Kubeconfig 私钥与证书不配对
现象:kubectl 连接集群报 tls: failed to parse private key。
误判:以为是 PKCS#1(BEGIN RSA PRIVATE KEY)与 PKCS#8(BEGIN PRIVATE KEY)格式不兼容。kubectl v1.36.0 要求 PKCS#8 格式。
根因:kubectl 实际支持两种私钥格式。真实问题是 kubeconfig 中 client-key-data 的私钥与 client-certificate-data 的证书不配对——在编辑 kubeconfig 时密钥被替换成了另一把。
验证方法:对比 key 和 cert 的 modulus(RSA 公钥的核心参数),两者必须一致:
# 私钥的 modulus
echo "<client-key-data base64>" | base64 -d | openssl rsa -modulus -noout | openssl md5
# 证书的 modulus
echo "<client-certificate-data base64>" | base64 -d | openssl x509 -modulus -noout | openssl md5
# 两个 md5 必须相同修复:重新从 ACK 控制台下载正确的 kubeconfig,确保 key 和 cert 来自同一对。
教训:报 "parse private key" 不一定是格式问题。优先验证 key/cert 配对关系,再考虑格式。
sandbox-manager controller Pod Pending(资源 requests 设太大)
现象:sandbox-manager 的 controller Pod 一直 Pending,2 台 8c16g 节点均无法调度。
根因:配置时将 controller.resources.cpu 设为 "8"(8000m)。节点的 Capacity 是 8 核,但 Allocatable 永远小于 8 核(kube-reserved + system-reserved 预留约 90m)。因此 8000m > 7910m,永远调度不上。加再大的节点,只要 requests 等于核数整数值,就放不下。
修复:
kubectl set resources deployment sandbox-manager -n sandbox-system \
-c controller --requests=cpu=2,memory=4Gi --limits=cpu=2,memory=4Gi
kubectl scale deploy sandbox-manager -n sandbox-system --replicas=1
kubectl scale deploy sandbox-gateway -n sandbox-system --replicas=2原理:Kubernetes 调度器根据 Pod 的 resources.requests 与节点的 Allocatable(而非 Capacity)做匹配。节点 Allocatable = Capacity - kube-reserved - system-reserved - eviction-threshold。Pod QoS 为 Guaranteed(requests=limits)时,requests 必须 < Allocatable。
教训:requests.cpu 不要设为节点核数的整数值。看到 Pod Pending,第一时间 kubectl describe po 查看 Events 中的 FailedScheduling 原因。
ALB 缺少 443/HTTPS 监听器和证书
现象:AlbConfig alb 只有 80/HTTP 监听器,certificateId 为空。Ingress PORTS 只有 80。
根因:ALB Ingress Controller 安装后默认只创建 80/HTTP 监听器。HTTPS 需要手动配置 AlbConfig listener + Ingress TLS secret。
修复:三步操作(见 3.4-3.6):
- 创建 TLS secret
- patch AlbConfig 添加 443/HTTPS listener
- patch Ingress 关联 TLS secret + listen-ports annotation
证书从 Ingress TLS secret 自动注册到 ALB,certId 自动填充。
教训:ALB 的 HTTPS 不是装了 Ingress Controller 就有。需要同时配置 AlbConfig listener 和 Ingress TLS。
ack-agent-sandbox-controller 组件 Pod 缺失
现象:ack-agent-sandbox-controller 的 Deployment/Pod 不在集群中。尝试卸载报 Dependencies of addons are not met: ack-sandbox-manager depends on ack-agent-sandbox-controller。
根因:组件层面已安装 v0.5.24(满足 sandbox-manager 依赖),但 controller 的 Deployment/Pod 不在集群中。webhook service 有指向失效 IP 的残留 endpoints。
实测验证:创建测试 SandboxSet,沙箱 Pod 成功创建并 Running。证明 sandbox-manager 能独立完成 SandboxSet -> Sandbox CR -> ACS Pod 创建的完整链路,agent-sandbox-controller 的集群内 pod 不是核心必需的。
处理:不要卸载(依赖系统会牵连 sandbox-manager)。忽略即可。如要彻底修复,需先卸 sandbox-manager -> 再卸 agent-sandbox-controller -> 重装两者,但没有必要。
教训:ACK 组件依赖系统会阻止卸载被依赖组件。"组件 pod 缺失"不等于"功能不可用",需用实测验证。
镜像地域不匹配
现象:官方文档示例镜像地址是 registry-cn-zhangjiakou-vpc.ack.aliyuncs.com/acs/code-interpreter:v1.6(张家口地域)。集群在杭州,拉取缓慢。
修复:将地域改为 cn-hangzhou:registry-cn-hangzhou-vpc.ack.aliyuncs.com/ack-demo/openclaw:2026.3.23-2。-vpc 后缀走 VPC 内网拉取,速度远快于公网。
教训:镜像地址中的地域要和集群所在地域一致。去掉 -vpc 走公网也可,但内网更快。
域名使用非真实 TLD
现象:openclaw-sandbox.infra 的 .infra 不是真实顶级域名,公网 DNS 无法解析,E2B SDK 和浏览器无法连接。
修复:测试阶段在 /etc/hosts 中手动指向 ALB 公网 IP。生产环境使用真实域名 CNAME 到 ALB 域名。
教训:自签证书 + 非真实域名仅适用于测试。生产环境必须使用真实域名和正式 CA 签发的证书。
sandbox-gateway 返回 "healthy sandbox not found"
现象:通过 sandbox-gateway 访问沙箱时返回:
502 Bad Gateway
healthy sandbox not found: default--openclaw-7rx55根因:预热池中的沙箱 state=available(未被领取)。sandbox-gateway 的过滤器只转发 state=running 的沙箱流量。state=available 的沙箱不转发,直接返回 "healthy sandbox not found"。
验证:
$ kubectl get sandbox
NAME STATUS CLAIMED
openclaw-7rx55 Running false # state=available,未领取
$ # 查看 sandbox-gateway 日志
$ kubectl logs -n sandbox-system deploy/sandbox-gateway | grep openclaw-7rx55
"Sandbox is not running","sandboxID":"default--openclaw-7rx55","state":"available"注意:kubectl get sandbox 显示的 STATUS=Running 是 Pod 的运行状态,不等于 sandbox-gateway 的 state=running。sandbox-gateway 的 state 取决于沙箱是否被领取(CLAIMED)。
修复:通过 SandboxClaim 或 E2B SDK 的 Sandbox.create() 领取沙箱:
kubectl apply -f openclaw-claim.yaml # templateName: openclaw, replicas: 1领取后 CLAIMED=true,sandbox-gateway state 变为 running,不再返回 "not found"。
原理:sandbox-gateway 维护一个沙箱路由表,仅包含 state=running 的沙箱。领取操作通知 sandbox-gateway 将沙箱加入路由表。预热池沙箱未被领取时不在路由表中。
OpenClaw 18789 绑定 loopback
现象:sandbox-gateway 不再返回 "not found",但返回 503 Connection refused。沙箱 Pod 在运行,18789 端口在监听,但 sandbox-gateway 连不上。
排查过程:在沙箱内测试不同 IP 的连通性:
$ kubectl exec openclaw-7rx55 -c openclaw -- \
bash -c 'curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:18789/healthz'
200
$ kubectl exec openclaw-7rx55 -c openclaw -- \
bash -c 'curl -s -o /dev/null -w "%{http_code}" http://10.175.70.240:18789/healthz'
000 # Connection refused
$ kubectl exec openclaw-7rx55 -c openclaw -- \
bash -c 'curl -s -o /dev/null -w "%{http_code}" http://0.0.0.0:18789/healthz'
200127.0.0.1 返回 200,pod IP 返回 000(refused),0.0.0.0 返回 200。证明 OpenClaw gateway 默认绑定 127.0.0.1(loopback),不接受外部连接。
根因:OpenClaw 的 gateway.bind 默认值为 loopback。在容器环境中,loopback 只有沙箱内部可访问,sandbox-gateway 从外部连 pod IP:18789 被拒绝。
修复:设置 gateway.bind 为 lan,使 gateway 监听 0.0.0.0。
两种方式:
方式 A(热修复,临时):kubectl exec 进沙箱执行 openclaw config set,然后重启 gateway 进程。
方式 B(推荐,可复现):通过 E2B SDK 的 sandbox.files.write() 写入包含 "bind": "lan" 的 openclaw.json 配置文件,OpenClaw config watcher 自动检测并重启 gateway。
验证:
$ kubectl exec openclaw-7rx55 -c openclaw -- openclaw config get gateway.bind
lan
$ kubectl exec openclaw-7rx55 -c openclaw -- \
bash -c 'curl -s -o /dev/null -w "%{http_code}" http://10.175.70.240:18789/healthz'
200 # pod IP 现在可达教训:容器化部署 OpenClaw 时,gateway.bind 必须设为 lan。默认 loopback 会导致所有外部流量被拒。
E2B SDK 401 "Invalid API Key"
现象:E2B SDK 调用 Sandbox.create() 时返回 401 Invalid API Key。
误判:怀疑 API key 格式问题。sandbox-manager 使用 hash+pepper 机制存储 key(secret e2b-key-store 中存的是哈希值,不是明文)。尝试了 <id>.<key> 等组合格式均 401。
根因:DNS 解析失败。当时 /etc/hosts 中没有 api.openclaw-sandbox.infra 条目,SDK 无法解析 API 地址。请求实际未到达 sandbox-manager,返回的 401 是误导性的。
证据:添加 /etc/hosts 条目后,同样的 API key e2b_root591740 鉴权通过,Sandbox.create() 在 0.11s 内成功。
教训:遇到 401 不要只盯着 key 格式。先确认 DNS 解析是否正常、请求是否真正到达后端。可用 curl -v 查看连接过程。
macOS /etc/hosts 不支持通配符
现象:sandbox-gateway 的流量代理使用 {port}-{sandboxID}.openclaw-sandbox.infra 格式的子域名。sandboxID 在沙箱创建后才知道,无法预先在 /etc/hosts 中添加所有子域名。macOS 的 /etc/hosts 不支持 *.openclaw-sandbox.infra 通配符语法。
修复:在 Python 脚本中用 socket.getaddrinfo 猴子补丁拦截 DNS 解析(见 5.2)。所有匹配 openclaw-sandbox.infra 的域名查询被重定向到 ALB IP。
替代方案:
- 安装 dnsmasq 提供本地通配符 DNS
- 运行在集群内 Pod 中(CoreDNS 可解析)
- 使用
curl --resolve参数(仅适用于 curl,不适用于 SDK)
教训:macOS /etc/hosts 的局限性需要在客户端代码中补偿。socket 补丁是最轻量的方案,仅影响当前进程。
zsh 中 path 变量污染 PATH
现象:在 zsh 中执行 for path in / /health ... 循环后,所有命令报 command not found。echo $PATH 显示 PATH 变成了循环的最后一个值。
根因:在 zsh 中,path 是 PATH 的绑定数组变量(tied array)。对 path 赋值会同步修改 PATH。在 for 循环中使用 path 作为循环变量,每次迭代都会覆盖 PATH。
修复:
# 恢复 PATH
export PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
# 后续避免使用 path 作为变量名,改用 p 或 item教训:在 zsh 中不要使用 path 作为循环变量名。如已发生 PATH 污染,可通过 export PATH=... 恢复,或使用 bash -c '...' 在干净的子 shell 中执行命令。
验证清单
部署完成后,按以下清单逐项确认。
export KUBECONFIG=/Users/feichi/gopath/src/Sandbox/kubeconfig
# 1. 节点(含 virtual-kubelet)
kubectl get nodes
# 预期:2 个普通节点 + 3 个 virtual-kubelet 节点
# 2. 管理组件 Running
kubectl get po -n sandbox-system
# 预期:sandbox-manager 2/2 Running, sandbox-gateway 1/1 Running
# 3. ALB + Ingress
kubectl get ingress -n sandbox-system
# 预期:PORTS 为 80, 443,ADDRESS 为 ALB 域名
kubectl get albconfig alb -n kube-system -o jsonpath='{.status.loadBalancer.listeners[*]}'
# 预期:80/HTTP + 443/HTTPS,certId 非空
# 4. 预热池就绪
kubectl get sandboxset
# 预期:AVAILABLE 1/1
kubectl get sandbox
# 预期:至少 1 个 Running, CLAIMED false(预热池待领取)
kubectl get pod
# 预期:沙箱 Pod 4/4 Running
# 5. sandbox-manager 日志无异常
kubectl logs -n sandbox-system deploy/sandbox-manager -c controller --tail=50 | grep -i error
# 6. ALB 到 sandbox-manager 链路
curl -k --resolve openclaw-sandbox.infra:443:121.xx.128.121 https://openclaw-sandbox.infra/
# 预期:404(到达后端,无匹配路由)
# 7. E2B SDK 全链路
cd e2b-test && python3 create_openclaw.py
# 预期:HTTP 200, E2B SDK 全链路验证通过关键配置参数速查
| 项 | 值 |
|---|---|
| 域名 | openclaw-sandbox.infra |
| E2B API Key | e2b_root591740 |
| ALB 域名 | alb-1pzfz2ohlimwzmn3xx.cn-hangzhou.alb.aliyuncsslb.com |
| ALB 公网 IP | 121.xx.128.121 / 47.xx.94.70 / 120.xx.92.115 |
| TLS Secret | sandbox-manager-tls(sandbox-system) |
| Ingress | sandbox-manager(sandbox-system),className=alb |
| Ingress Hosts | openclaw-sandbox.infra, api.openclaw-sandbox.infra, *.openclaw-sandbox.infra |
| SandboxSet | openclaw(default) |
| 沙箱镜像 | registry-cn-hangzhou-vpc.ack.aliyuncs.com/ack-demo/openclaw:2026.3.23-2 |
| OpenClaw 端口 | 18789(Web UI / healthz) |
| envd 端口 | 49983(文件读写 API) |
| CA 证书 | certs/ca-fullchain.pem |
| kubeconfig | kubeconfig |
| E2B SDK 版本 | e2b==2.10.2, e2b-code-interpreter==2.4.1 |
| sandbox-manager service | sandbox-manager:8080(E2B 管理 API) |
| sandbox-gateway service | sandbox-gateway:7788(沙箱流量代理) |
| Gateway Token | openclaw-sandbox-token |
| DashScope API Key | sk-fake-test-key-12345(测试用,非真实 key) |
清理与运维
清理预热池(避免 ACS 沙箱持续计费):
kubectl delete sandboxclaim openclaw-claim -n default
kubectl delete sandboxset openclaw -n default
kubectl delete sandbox --all -n default常用调试命令:
# sandbox-manager reconcile 日志
kubectl logs -n sandbox-system deploy/sandbox-manager -c controller --tail=200 | grep -iE "sandboxset|reconcile|error"
# 单个沙箱状态/事件
kubectl describe sandbox <sandbox-name>
# 沙箱 Pod 详情(sidecar 注入、调度、镜像拉取)
kubectl describe pod <sandbox-pod-name>
# sandbox-gateway 日志(流量转发)
kubectl logs -n sandbox-system deploy/sandbox-gateway --tail=200 | grep <sandboxID>
# 沙箱内进程状态
kubectl exec <sandbox-pod> -c openclaw -- ps aux
# 沙箱内 OpenClaw 配置
kubectl exec <sandbox-pod> -c openclaw -- openclaw config get gateway.bind
kubectl exec <sandbox-pod> -c openclaw -- cat /home/node/.openclaw/openclaw.json
# 沙箱内端口连通性
kubectl exec <sandbox-pod> -c openclaw -- bash -c 'curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:18789/healthz'
kubectl exec <sandbox-pod> -c openclaw -- bash -c 'curl -s -o /dev/null -w "%{http_code}" http://<podIP>:18789/healthz'附录 A:文件清单
| 文件 | 用途 |
|---|---|
kubeconfig | ACK 集群 kubeconfig |
generate-certificates.sh | 自签证书生成脚本 |
certs/fullchain.pem | 服务器证书 |
certs/privkey.pem | 服务器私钥 |
certs/ca-fullchain.pem | CA 证书(客户端信任) |
openclaw-sandboxset.yaml | SandboxSet 定义 |
openclaw-claim.yaml | SandboxClaim 定义 |
openclaw.json | OpenClaw 配置文件(注入用) |
e2b-test/.env | E2B SDK 环境变量 |
e2b-test/create_openclaw.py | E2B SDK 完整脚本 |
e2b-test/openclaw_template.json | OpenClaw 配置模板 |
DEPLOYMENT-GUIDE.md | 本文档 |
附录 B:sandbox-gateway 路由格式
sandbox-gateway 通过子域名解析 sandboxID 和端口号,格式为:
{port}-{namespace}--{sandboxset}-{podSuffix}.{E2B_DOMAIN}示例:
18789-default--openclaw-7rx55.openclaw-sandbox.infra
| | | | |
| | | | E2B_DOMAIN
| | | pod 名后缀(sandbox 名的一部分)
| | SandboxSet 名
| namespace
目标端口sandbox-gateway 从子域名中提取 port=18789 和 sandboxID=default--openclaw-7rx55,查询沙箱路由表(仅含 state=running 的沙箱),将流量转发到沙箱 Pod 的 18789 端口。
envd 的文件操作 API 使用同样的路由格式,但端口前缀为 49983:
49983-default--openclaw-dnstc.openclaw-sandbox.infraALB Ingress 的 *.openclaw-sandbox.infra 通配规则覆盖所有端口前缀,无需为每个端口单独配置路由。


