在Agent Sandbox 运维场景中,为解决预热池与已分配实例的版本升级问题,可通过 SandboxSet 滚动更新策略或创建 SandboxUpdateOps 资源执行升级任务,配合 Lifecycle 钩子完成数据备份与恢复,可有效保障环境升级过程中的业务连续性与数据完整性。
前提条件
已完成Agent Sandbox的基础环境搭建,具体操作,请参见创建Agent Sandbox。
在集群组件管理中,确认
ack-agent-sandbox-controller组件版本在v0.5.12-release.2及以上。
升级说明
集群中的 Sandbox 资源分为以下两种类型:
未分配 Sandbox:SandboxSet 预热池中的 Sandbox。
已分配 Sandbox(Claimed Sandbox):通过 E2B Create API或 SandboxClaim 获取的 Sandbox 资源。
SandboxSet 内置了升级能力,支持直接升级预热池中的 Sandbox。针对 Claimed Sandbox,需要使用 SandboxUpdateOps 资源进行升级。
升级 SandboxSet 预热池中的 Sandbox
直接修改 SandboxSet 的配置即可触发预热池中 Sandbox 的滚动升级。以下示例将容器镜像升级到新版本:
升级期间,若 SandboxSet 触发扩容,新增的 Sandbox 实例将统一采用新版本;若触发缩容,系统将优先移除旧版本的 Sandbox 实例。
apiVersion: agents.kruise.io/v1alpha1 kind: SandboxSet metadata: name: openclaw-sbs namespace: default spec: replicas: 10 updateStrategy: maxUnavailable: 10% runtimes: - name: agent-runtime - name: csi template: metadata: labels: app: openclaw alibabacloud.com/acs: "true" # 使用 ACS 算力 spec: containers: - name: gateway image: ghcr.io/openclaw/openclaw:2026.4.11 # 替换成您的新版本镜像字段说明:
spec.template:template 下任何字段的修改都会触发 Sandbox 升级,包括但不限于容器镜像版本。updateStrategy.maxUnavailable:控制升级过程中允许的最大不可用 Sandbox 数量。上述示例按 10% 的步长灰度升级预热池中的 Sandbox,默认值为20%。
可通过查看 SandboxSet 的状态(Status)来观测升级进度。
当
updatedAvailableReplicas的数值与replicas相等时,表示升级流程已完成,预热池中的所有 Sandbox 均已更新为新版本。kubectl get sandboxsets openclaw-sbsNAME REPLICAS AVAILABLE UPDATEDREPLICAS UPDATEDAVAILABLEREPLICAS UPDATEREVISION AGE openclaw-sbs 10 9 2 2 6b6b77848c 4d23h# 查看详细状态 (YAML) kubectl get sandboxsets openclaw-sbs -o yamlapiVersion: agents.kruise.io/v1alpha1 kind: SandboxSet status: availableReplicas: 9 observedGeneration: 5 replicas: 10 selector: agents.kruise.io/sandbox-claimed=false,agents.kruise.io/sandbox-pool=openclaw-sbs updateRevision: 6b6b77848c updatedAvailableReplicas: 2 updatedReplicas: 2在
status字段中,相关参数的具体含义如下:replicas:预热池中 Sandbox 的总副本数。availableReplicas:预热池中处于可用(Available)状态的 Sandbox 数量。updatedReplicas:预热池中已升级至新版本的 Sandbox 数量。updatedAvailableReplicas:预热池中已升级至新版本且处于可用状态的 Sandbox 数量。
通过 SandboxUpdateOps 升级 Claimed Sandbox
SandboxUpdateOps 只能升级 Phase 为 Running 或 Upgrading 的 Sandbox,不支持升级处于休眠或唤醒状态的 Sandbox。
升级过程不保留容器 rootfs(可写层)、内存和 IP。如果需要保留特定目录的数据,可以通过 Lifecycle 钩子进行备份和恢复。
同一个命名空间下只能存在一个状态为 Updating 的 SandboxUpdateOps。需等待前一个 SandboxUpdateOps 完成或删除后,才能创建新的 SandboxUpdateOps。
升级过程中 Sandbox 内部的服务会中断,请提前评估升级风险和所需时间。
创建 SandboxUpdateOps
以下示例创建一个 SandboxUpdateOps,将容器镜像升级到新版本,并通过 Lifecycle 钩子在升级前后备份和恢复数据。以下示例为备份OpenClaw工作空间(.openclaw)到/backup(动态挂载的OSS目录),进而在升级后进行恢复,可根据实际情况调整备份和恢复命令:
建议将工作目录打包压缩,避免 OSS 小文件 I/O 性能问题。
apiVersion: agents.kruise.io/v1alpha1
kind: SandboxUpdateOps
metadata:
name: upgrade-demo
spec:
selector:
matchLabels:
agents.kruise.io/sandbox-template: openclaw-sbs
updateStrategy:
maxUnavailable: 10%
patch:
spec:
containers:
- name: gateway
image: ghcr.io/openclaw/openclaw:2026.4.11 # 替换成您的新版本镜像
lifecycle:
preUpgrade:
exec:
command:
- /bin/bash
- -c
- |
set -e
cd /root/
tar -czf openclaw-state-v1.tgz .openclaw
mv openclaw-state-v1.tgz /backup
echo 'preUpgrade success'
timeoutSeconds: 600
postUpgrade:
exec:
command:
- /bin/bash
- -c
- |
set -e
rm -rf /root/.openclaw
cp /backup/openclaw-state-v1.tgz /root/openclaw-state-v1.tgz
tar -xzvf /root/openclaw-state-v1.tgz -C /root
rm -rf /root/openclaw-state-v1.tgz
timeoutSeconds: 600字段说明:
selector:通过 Label 选择需要升级的 Sandbox,支持matchLabels和matchExpressions两种方式。详情请参见 Kubernetes Labels and Selectors。patch:JSON 或 YAML 格式的补丁内容,以 Strategic Merge Patch(策略合并补丁)的方式应用到 Sandbox 的 template。lifecycle:升级生命周期钩子。preUpgrade:升级前执行的备份命令。上述示例将工作目录文件备份到动态挂载的 OSS 目录。postUpgrade:升级后执行的恢复命令。上述示例将 OSS 目录中的备份数据恢复到工作目录。
以下示例展示了 patch 的三种常见操作:更新容器镜像、增加 Volume 和删除 Volume。
apiVersion: agents.kruise.io/v1alpha1
kind: SandboxUpdateOps
spec:
patch:
spec:
containers:
- name: test-container
# 更新容器镜像
image: mirrors-ssl.aliyuncs.com/centos:8
volumeMounts:
# 删除原有的 Volume 挂载点 (根据 mountPath 定位)
- $patch: delete
mountPath: /mnt/volume2
# 增加新的 Volume 挂载点
- name: volume3
mountPath: /mnt/volume3
volumes:
# 删除 Pod 级别的 Volume 定义 (根据 name 定位)
- name: volume2
$patch: delete
# 增加 Pod 级别的 Volume 定义
- name: volume3
emptyDir: {}上述示例完成三项修改:
更新:将容器
test-container的镜像更新为mirrors-ssl.aliyuncs.com/centos:8。增加:添加 Volume
volume3及对应的 volumeMount。删除:通过
$patch: delete删除 Volumevolume2及对应的 volumeMount。
查看升级状态
查看 SandboxUpdateOps 的升级状态(
suo是 SandboxUpdateOps 的简写):kubectl get suo upgrade-demoNAME PHASE TOTAL UPDATED UPDATING FAILED AGE upgrade-demo Updating 1000 66 100 0 2m32s输出字段说明:
PHASE:升级任务的整体状态。取值:Pending:尚未开始升级,等待控制器调度执行。Updating:正在升级。Completed:升级完成,所有 Sandbox 升级成功。Failed:升级完成,但部分 Sandbox 升级失败。
TOTAL:本次升级涉及的 Sandbox 总数。UPDATED:已完成升级且升级成功的 Sandbox 数量。UPDATING:正在升级的 Sandbox 数量,由 maxUnavailable 控制。FAILED:升级失败的 Sandbox 数量。
查看正在升级或已完成升级的 Sandbox 列表:
kubectl get sandbox -l agents.kruise.io/update-ops='upgrade-demo'NAME STATUS AGE CLAIMED SHUTDOWN_TIME PAUSE_TIME MESSAGE openclaw-sbs-22df6 Running 45m true openclaw-sbs-22n57 Running 45m true openclaw-sbs-22s7h Running 45m true openclaw-sbs-m4srn Upgrading 22m true openclaw-sbs-m4z74 Upgrading 23m true openclaw-sbs-m5646 Upgrading 45m true openclaw-sbs-m5bmh Upgrading 45m true openclaw-sbs-m5h68 Upgrading 45m true其中
agents.kruise.io/update-ops的值为 SandboxUpdateOps 的名称。STATUS取值:Upgrading:正在升级。Running:已完成升级且升级成功。
查看处于 Upgrading 状态的 Sandbox 详细信息:
kubectl get sandbox openclaw-sbs-x56r5 -o yamlstatus: conditions: - lastTransitionTime: "2026-05-01T02:50:33Z" message: "" reason: UpgradePod status: "False" type: Upgrading nodeName: virtual-kubelet-cn-hangzhou-h observedGeneration: 2 phase: Upgrading关键字段说明:
phase:当前为 Upgrading(升级中),升级完成后变为 Running。message:升级任务失败时的错误信息。conditions[type=Upgrading].reason:表示升级所处的阶段。PreUpgrade:正在执行lifecycle.preUpgrade脚本。UpgradePod:正在根据新模板重建 Sandbox 底层 Pod 实例。PostUpgrade:正在执行lifecycle.postUpgrade脚本。PreUpgradeFailed:lifecycle.preUpgrade脚本执行失败。UpgradePodFailed:新模板启动 Pod 失败。PostUpgradeFailed:lifecycle.postUpgrade脚本执行失败。
常见问题
通过 SandboxUpdateOps 升级失败如何排查处理?
SandboxUpdateOps 升级过程请参考工作原理。
步骤一:定位失败阶段
查看Sandbox当前的状态,status.conditions 中的 reason表示当前升级所处阶段,message显示脚本报错信息:
kubectl get sandbox <name> -o yamlapiVersion: agents.kruise.io/v1alpha1
kind: Sandbox
status:
conditions:
- lastTransitionTime: "2026-05-01T08:27:51Z"
message: 'hook execution error: process error: exit status 1'
reason: PreUpgradeFailed
status: "False"
type: Upgrading
nodeName: virtual-kubelet-cn-hangzhou-i
observedGeneration: 2
phase: UpgradingPreUpgradeFailed:前置脚本执行报错。
UpgradePodFailed:新 Pod 重建失败(镜像拉取、启动超时)。
PostUpgradeFailed:后置恢复脚本报错。
步骤二:继续升级或进行回滚
可根据Sandbox所处的升级失败阶段及实际业务场景选择继续升级或回滚。
PreUpgrade阶段失败
继续升级:修正
spec.lifecycle.preUpgrade脚本逻辑后,删除原 SandboxUpdateOps 并重新创建即可。回滚:由于此时底层容器尚未重建,数据不会丢失。将SandboxUpdateOps的
spec.patch配置回滚,且无需配置 Lifecycle(preUpgrade、postUpgrade)。
UpgradePod阶段失败
继续升级:修正主容器错误,如镜像拉取失败(替换SandboxUpdateOps
spec.patch中的镜像)。注意:上一阶段中preUpgrade已经执行成功,需剔除preUpgrade配置(避免重复执行)。回滚:
方式一(推荐):如果升级前对 Sandbox 进行了 Checkpoint 备份,推荐使用Checkpoint功能克隆Agent Sandbox方式恢复。
方式二:将SandboxUpdateOps的
spec.patch配置回滚。注意:上一阶段中preUpgrade已经执行成功,需剔除preUpgrade配置(避免重复执行)。
PostUpgrade阶段失败
继续升级:修正
spec.lifecycle.postUpgrade脚本逻辑,剔除preUpgrade配置(上一阶段中preUpgrade已经执行成功,避免重复执行),然后删除原 SandboxUpdateOps 并重新创建即可。回滚:请参考UpgradePod阶段失败回滚方式。