cover

部署环境:ACK Pro 集群(杭州地域),2 台 8c16g ECS + ACS Serverless 后端。 目标:在 Agent Sandbox 上运行 OpenClaw 网关,通过 ALB 从集群外部访问其 Web Control UI。 域名 openclaw-sandbox.infra,E2B API Key e2b_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 个问题及根因分析,最后附验证清单与配置速查表。

所有命令均附带原理说明,所有状态输出均为真实执行结果。目标是使读者能够在同等环境下完整复现本次部署。

参考文档:OpenClaw 企业版 - 生产级部署指南

系统架构

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: default

compute-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,将流量转发到对应沙箱 Podsandbox-gateway deployment
ack-agent-sandbox-controller (>= v0.5.14)负责沙箱 Pod 生命周期管理(调云 API 创建 serverless Pod)实测可缺失(见 6.4),不影响核心链路
ALB Ingress Controller将外部 HTTPS 流量路由到 sandbox-manager / sandbox-gateway serviceALB 实例在云上,通过 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          6h36m

sandbox-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.infrasandbox-manager:8080E2B 管理 API(创建/删除沙箱、鉴权)
*.openclaw-sandbox.infrasandbox-gateway:7788沙箱流量代理(按子域名解析 sandboxID 转发到沙箱 Pod 端口)
openclaw-sandbox.infrasandbox-manager:8080sandbox-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 UI

SDK 不直连沙箱 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.pemCA 证书公钥,E2B SDK 客户端需信任此 CA
certs/ca-privkey.pemCA 证书私钥

组件版本要求

在控制台「组件管理」中确认或升级:

  • 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.replicaCount1leader 选举,多副本仅 1 个 active,1 副本足够
sandboxManager.controller.resources.cpu2不要设为节点核数整数值(见 6.2)
sandboxManager.controller.resources.memory4Gi
sandboxManager.proxy.resources.cpu2
sandboxManager.proxy.resources.memory4Gi
sandboxManager.acsfalseACK Pro 模式(非纯 ACS 集群)
e2b.domainopenclaw-sandbox.infra
e2b.enableAuthtrue开启 API Key 鉴权
e2b.adminApiKeye2b_root591740
ingress.classNamealb
ingress.tlstrue

安装后验证:

$ 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-system

AlbConfig 添加 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

关键设计说明:

  1. runtimes: csi 注入 CSI 挂载 sidecar,agent-runtime 注入 envd 进程(提供文件读写 API,端口 49983)。E2B SDK 的 sandbox.files.write() 通过 envd API 操作沙箱内文件系统。
  2. OPENCLAW_SKIP_ONBOARDING=1: 跳过 OpenClaw 的交互式 onboarding 流程。onboarding 会要求输入 provider API key 和生成 gateway token,不适合无人值守的沙箱环境。配置由后续 E2B SDK 运行时注入(见第 5 章)。
  3. 不设 OPENCLAW_GATEWAY_TOKEN: gateway token 写在运行时注入的 openclaw.json 配置文件中,不硬编码到 env。每个沙箱实例可以使用不同的 token。
  4. 镜像: registry-cn-hangzhou-vpc 前缀走 VPC 内网拉取,速度远快于公网。地域必须与集群一致(见 6.5)。
  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          4m24s

SandboxSet 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.infra
  • E2B_API_KEY -> 请求头 Authorization: Bearer {key}
  • SSL_CERT_FILE -> Python ssl 模块的 CA 信任库,使 httpx 信任自签 CA

DNS 解析问题与解决方案

E2B SDK 的三类请求使用不同的域名格式:

请求类型域名格式示例
管理 APIapi.{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]}")

脚本流程说明:

  1. Sandbox.create("openclaw") 调用 sandbox-manager 的 POST /sandboxes API,从预热池领取一个 state=available 的沙箱,使其变为 state=running。返回 sandbox_id。metadata 中的 e2b.agents.kruise.io/never-timeout: "true" 防止沙箱因空闲超时被回收。
  2. sandbox.files.write() 通过 envd API(端口 49983)将渲染后的 openclaw.json 写入沙箱内 /home/node/.openclaw/openclaw.json。OpenClaw 的 config watcher 检测到配置文件变化后自动重启 gateway 进程,使新配置(包括 gateway.bind: "lan")生效。
  3. sandbox.get_host(18789) 返回 18789-{sandboxID}.{domain} 格式的主机名,该主机名通过 ALB -> sandbox-gateway 路由到沙箱的 18789 端口。
  4. 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.bindlan监听所有网卡(0.0.0.0),使 sandbox-gateway 能从外部访问沙箱 18789 端口。默认 loopback 只监听 127.0.0.1,导致 503 Connection refused(见 6.8)
gateway.auth.modetoken使用 token 认证,token 通过 URL 参数 ?token=xxx 传递
controlUi.allowedOrigins["*"]允许任意来源的跨域请求
controlUi.dangerouslyAllowHostHeaderOriginFallbacktrue允许通过 Host 头进行 origin fallback(sandbox-gateway 转发时 Host 头会被改写)
controlUi.allowInsecureAuthtrue允许通过 HTTP 传 token(ALB 做 TLS 终止后,后端是 HTTP)
controlUi.dangerouslyDisableDeviceAuthtrue禁用设备认证(无人值守环境无法完成设备配对)
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 可达。

check

5.6 手动验证(不使用 E2B SDK)

如需绕过 E2B SDK 直接验证链路,可通过 kubectl + curl 完成:

  1. 写入配置文件(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'
  1. 验证 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
  1. 领取沙箱(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"}
  1. 通过 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):

  1. 创建 TLS secret
  2. patch AlbConfig 添加 443/HTTPS listener
  3. 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-hangzhouregistry-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'
200

127.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.bindlan,使 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 foundecho $PATH 显示 PATH 变成了循环的最后一个值。

根因:在 zsh 中,pathPATH 的绑定数组变量(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 Keye2b_root591740
ALB 域名alb-1pzfz2ohlimwzmn3xx.cn-hangzhou.alb.aliyuncsslb.com
ALB 公网 IP121.xx.128.121 / 47.xx.94.70 / 120.xx.92.115
TLS Secretsandbox-manager-tls(sandbox-system)
Ingresssandbox-manager(sandbox-system),className=alb
Ingress Hostsopenclaw-sandbox.infra, api.openclaw-sandbox.infra, *.openclaw-sandbox.infra
SandboxSetopenclaw(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
kubeconfigkubeconfig
E2B SDK 版本e2b==2.10.2, e2b-code-interpreter==2.4.1
sandbox-manager servicesandbox-manager:8080(E2B 管理 API)
sandbox-gateway servicesandbox-gateway:7788(沙箱流量代理)
Gateway Tokenopenclaw-sandbox-token
DashScope API Keysk-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:文件清单

文件用途
kubeconfigACK 集群 kubeconfig
generate-certificates.sh自签证书生成脚本
certs/fullchain.pem服务器证书
certs/privkey.pem服务器私钥
certs/ca-fullchain.pemCA 证书(客户端信任)
openclaw-sandboxset.yamlSandboxSet 定义
openclaw-claim.yamlSandboxClaim 定义
openclaw.jsonOpenClaw 配置文件(注入用)
e2b-test/.envE2B SDK 环境变量
e2b-test/create_openclaw.pyE2B SDK 完整脚本
e2b-test/openclaw_template.jsonOpenClaw 配置模板
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.infra

ALB Ingress 的 *.openclaw-sandbox.infra 通配规则覆盖所有端口前缀,无需为每个端口单独配置路由。

OpenClaw on 阿里云ACK Agent Sandbox:部署
转载前请阅读本站 版权协议,文章著作权归 饼铛 所有,转载请注明出处。
评论

目录