帮你快速理解、总结文档立即下载
文档中心>Agent Runtime>Agent 集群>高阶能力>验证 Agent 集群的 Cube 安全隔离能力

验证 Agent 集群的 Cube 安全隔离能力

最近更新时间:2026-10-12 16:42:01
我的收藏
当多个用户的 Agent 共用一个集群执行代码或调用工具时,应将不同信任来源的任务放入不同沙箱。本文模拟用户 A 和用户 B 的两个任务,在同一节点创建两个 Cube Pod,验证它们的运行环境、进程和工作文件是否隔离,以及一个任务异常退出时另一个任务能否继续运行。
Cube 为每个 Pod 创建独立虚拟机和 Guest 内核。同一 Pod 内的业务容器、初始化容器和 sidecar 共用一个沙箱;如果需要隔离两个用户,应创建两个 Pod,不能只创建同一 Pod 中的两个容器。

本文验证什么

检查项
操作
结果如何判断
运行环境
核对 RuntimeClass、实际运行时记录和两个 Pod 的内核启动标识
确认实际使用 Cube。
进程可见性
分别查看两个 Pod 内的进程
能看到自己的任务进程,看不到对方的任务进程。
文件隔离
在相同目录分别写入不同文件
两个 Pod 各自保留自己的内容,不能通过本地目录看到对方文件。
异常退出影响
让 A 的测试任务以非零退出码结束
A 失败,B 的同一个容器继续处理文件,未发生重启。
这些检查用于验收配置及有限场景下的隔离行为,不是漏洞安全测试。Cube 增加的边界是每 Pod 独立虚拟机及 Guest 内核。

开始前准备

1. 在 Agent Runtime 控制台 准备专用测试集群和节点池,确认一个支持 Cube 的节点已就绪。创建方式请参见 创建集群和节点池。
2. 为本次测试创建专用命名空间,例如 cube-isolation-check。下文使用这个名称;若已存在同名资源,换用新的测试命名空间并同步修改清单和命令。
3. 通过控制台获取访问配置,连接集群。执行命令的账号需要在测试命名空间读取 Pod、事件、日志和执行容器命令的权限。
4. 准备节点可拉取的 BusyBox 1.36 工具镜像,包含 sh、ps、cat、tr、sleep 和 touch。建议使用已审核镜像的固定 digest;私有镜像同时配置拉取凭证。
5. 确认目标节点能同时容纳两个测试 Pod。每个容器请求 100m CPU、128Mi 内存,上限为 500m CPU、256Mi 内存;还需计入目标 RuntimeClass 的额外资源开销。本测试不创建持久卷或负载均衡器。
下文通过控制台创建和删除资源,用 kubectl 采集结果。节点有污点时,仅添加管理员确认过的必要容忍配置,不移除节点已有污点。
在同一终端配置连接并查询环境:
export KUBECONFIG='/absolute/path/to/agc-kubeconfig'
export AGC_NAMESPACE='cube-isolation-check'
kubectl config current-context
kubectl version -o yaml
kubectl get runtimeclass -o yaml
kubectl get nodes -L kubernetes.io/hostname
保存测试日期、集群 Kubernetes 版本、节点内核版本、Cube 版本、RuntimeClass 名称与配置、镜像 digest。

第一步:通过控制台创建两个测试 Pod

在目标集群进入工作负载的 YAML 创建入口,选择测试命名空间。控制台跳转到关联 TKE 集群时,先核对集群 ID。将下面两份清单分别提交,并替换以下内容:
runtimeClassName: cube:使用 Cube 运行时,保留此值。
REPLACE_WITH_NODE_HOSTNAME:同一个目标节点的 kubernetes.io/hostname 标签值,不一定等于节点名称。
REPLACE_WITH_BUSYBOX_IMAGE:准备好的完整镜像地址及 digest。
两个 Pod 必须使用同一个节点标签值。这样验证的是共享物理节点时的隔离,避免把不同节点带来的分离当成 Cube 的效果。

用户 A 的任务

apiVersion: v1
kind: Pod
metadata:
name: cube-isolation-a
namespace: cube-isolation-check
labels:
app: cube-isolation-check
spec:
runtimeClassName: cube
nodeSelector:
kubernetes.io/hostname: REPLACE_WITH_NODE_HOSTNAME
restartPolicy: Never
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: task
image: REPLACE_WITH_BUSYBOX_IMAGE
command: ["/bin/sh", "-c"]
args:
- |
echo 'agent-a ready'
while [ ! -f /work/stop ]; do sleep 1; done
echo 'test task exits with code 42'
exit 42
- agc-isolation-a
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: work
mountPath: /work
volumes:
- name: work
emptyDir:
sizeLimit: 16Mi

用户 B 的任务

apiVersion: v1
kind: Pod
metadata:
name: cube-isolation-b
namespace: cube-isolation-check
labels:
app: cube-isolation-check
spec:
runtimeClassName: cube
nodeSelector:
kubernetes.io/hostname: REPLACE_WITH_NODE_HOSTNAME
restartPolicy: Never
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: task
image: REPLACE_WITH_BUSYBOX_IMAGE
command: ["/bin/sh", "-c"]
args:
- |
echo 'agent-b ready'
while [ ! -f /work/stop ]; do sleep 1; done
echo 'test task exits with code 42'
exit 42
- agc-isolation-b
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: work
mountPath: /work
volumes:
- name: work
emptyDir:
sizeLimit: 16Mi
两个 /work 分别来自各自的 emptyDir,没有共享 PVC、hostPath、Secret 或服务账号令牌。这里模拟任务临时目录;如果业务主动挂载同一个工作区或配置同一套数据凭证,相应的数据共享不能由沙箱自动消除。
确认两个 Pod 已运行:
kubectl wait -n "$AGC_NAMESPACE" --for=condition=Ready pod/cube-isolation-a pod/cube-isolation-b --timeout=180s
kubectl get pods -n "$AGC_NAMESPACE" -l app=cube-isolation-check -o wide
kubectl get pods -n "$AGC_NAMESPACE" -l app=cube-isolation-check -o yaml
核对两者的 spec.nodeName 相同、spec.runtimeClassName 为目标 Cube 运行时,容器状态正常。

第二步:核对独立运行环境

分别读取内核版本和内核启动标识:
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-a -c task -- sh -c 'uname -r; cat /proc/sys/kernel/random/boot_id'
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-b -c task -- sh -c 'uname -r; cat /proc/sys/kernel/random/boot_id'
boot_id 是内核启动标识。记录两个值并比较:两个沙箱可使用同一版本的 Guest 内核,因此 uname -r 相同是正常现象;不同的 boot_id 可以作为不同内核运行实例的辅助证据。

第三步:检查进程可见性

两个任务的主进程分别带有 agc-isolation-a 和 agc-isolation-b 标识。遍历当前可见进程,读取完整命令行,避免进程列表截断标识造成误判:
AGC_PROCESS_SCAN='
failed=0
for d in /proc/[0-9]*; do
[ -d "$d" ] || continue
printf "PID %s: " "${d##*/}"
if ! tr "\\000" " " < "$d/cmdline"; then
echo "READ_FAILED"
failed=1
fi
echo
done
exit "$failed"
'
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-a -c task -- sh -c "$AGC_PROCESS_SCAN"
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-b -c task -- sh -c "$AGC_PROCESS_SCAN"
预期 A 的完整命令行输出包含自己的 agc-isolation-a,不包含 B 的 agc-isolation-b;B 反之。还可能看到 sleep 和本次检查进程。分别检查两条命令的退出码;出现 READ_FAILED、权限错误或进程在读取期间退出时,保留输出并重新采集。
两个 Pod 都出现 PID 1 并不冲突:PID 数字属于各自可见的进程空间。不要用另一个 Pod 的 PID 数字在当前 Pod 执行 kill,这可能终止当前 Pod 中恰好同号的进程,无法证明跨沙箱访问。
此项证明本次任务的进程可见性分离。

第四步:检查工作文件隔离

分别向相同路径写入不同内容,再创建各自独有的文件:
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-a -c task -- sh -c 'echo agent-a > /work/owner.txt; echo only-a > /work/a-only.txt'
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-b -c task -- sh -c 'echo agent-b > /work/owner.txt; echo only-b > /work/b-only.txt'
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-a -c task -- sh -c 'cat /work/owner.txt; cat /work/a-only.txt; test ! -e /work/b-only.txt && echo peer-file-absent'
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-b -c task -- sh -c 'cat /work/owner.txt; cat /work/b-only.txt; test ! -e /work/a-only.txt && echo peer-file-absent'
A 应输出 agent-a、only-a、peer-file-absent;B 应输出 agent-b、only-b、peer-file-absent。命令退出码也应为 0。
此项验证两个独立临时目录未串用。

第五步:验证单个任务异常退出的影响

先记录 B 的 Pod UID、容器 ID、启动时间、重启次数和内核启动标识:
kubectl get pod -n "$AGC_NAMESPACE" cube-isolation-b -o yaml
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-b -c task -- cat /proc/sys/kernel/random/boot_id
让 A 的测试进程检测到停止文件后以退出码 42 结束:
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-a -c task -- touch /work/stop
kubectl wait -n "$AGC_NAMESPACE" --for=jsonpath='{.status.phase}'=Failed pod/cube-isolation-a --timeout=60s
kubectl get pod -n "$AGC_NAMESPACE" cube-isolation-a -o jsonpath='{.status.containerStatuses[0].state.terminated.exitCode}{"\\n"}'
kubectl logs -n "$AGC_NAMESPACE" cube-isolation-a -c task
随后验证 B 仍能连续处理文件:
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-b -c task -- sh -c 'i=0; while [ "$i" -lt 6 ]; do cat /work/owner.txt || exit 1; echo "$i" >> /work/progress.txt || exit 1; i=$((i+1)); sleep 5; done; cat /work/progress.txt'
kubectl get pod -n "$AGC_NAMESPACE" cube-isolation-b -o yaml
kubectl exec -n "$AGC_NAMESPACE" cube-isolation-b -c task -- cat /proc/sys/kernel/random/boot_id
通过条件:A 的退出码为 42;B 在约 30 秒观察期间完成六次文件处理,仍为 Running,且 Pod UID、容器 ID、启动时间、重启次数和启动标识与操作前一致。命令超时、重启或检查缺失需要记录原因。
此项仅验证一次应用进程异常退出没有使另一任务停止,不代表 Guest 内核崩溃、内存耗尽、CPU 争抢或宿主机故障已完成验证。本文不执行这些压力或破坏性测试。

记录结果

检查项
实际结果
应保留的证据
两个 Pod 使用 Cube 且位于同一节点
按本次观察填写
Pod YAML、RuntimeClass、节点名称、镜像 ID。
两个 Pod 对应独立运行实例
按本次观察填写
启动标识、Pod UID 与运行时侧 sandbox / VM 实例对应记录。
进程可见性
按本次观察填写
两侧完整可见进程命令行及采集退出码。
临时工作文件隔离
按本次观察填写
两侧文件内容、对方文件不存在及命令退出码。
A 异常退出后 B 继续运行
按本次观察填写
A 的退出码;B 前后身份、重启次数及文件处理输出。
可以填写“通过、失败、未验证”,并注明判断依据。不要把预期输出当作实测结果,也不要用整套 Kubernetes E2E 的通过数量代替这些隔离检查。
沙箱隔离不等于网络互相断开。两个 Pod 仍可能按集群网络配置互访;限制跨用户访问需要网络策略或其他访问控制,并另行验证。本文也未验证 RBAC、共享工作区授权、外部服务凭证隔离或侧信道防护。

一次实测结果

在 Agent 集群的同一个原生节点上,通过 TKE 控制台 YAML 入口创建测试命名空间及 Pod。使用本文的安全配置和资源规格,两个 Pod 均以非 root 用户运行,未挂载服务账号令牌、共享持久卷或宿主机目录。
环境项
本次配置
节点系统
TencentOS Rainbow 1;宿主内核 6.6.110-42.45.pvm.host.cpu.002.tl4.x86_64
容器运行时
containerd 2.2.5-tke.2;RuntimeClass cube
实际 VMM 版本
4b3b20937d41259a-trace-0,从运行中进程路径核对
Guest 内核
6.6.110-42.45.pvm.guest.cpu.002.tl4.x86_64
工具镜像
BusyBox 1.36.1;digest sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662
单容器资源
requests:100m CPU / 128Mi;limits:500m CPU / 256Mi
RuntimeClass overhead
每 Pod 250m CPU / 256Mi 内存
检查项
本次结果
实际观察
同节点使用 Cube
通过
两个 Pod 位于同一节点,RuntimeClass 为 cube,CRI 中实际 runtimeHandler 也为 cube。
独立运行实例
通过
两个 Pod UID 分别关联不同 sandbox、runtime lease、Shim 和 VMM worker;两个 Guest 的 boot_id 不同,且不同于宿主机。
进程可见性
通过
A、B 的完整进程命令行各自包含本方任务标识,没有对方任务标识;采集退出码均为 0。
临时工作文件隔离
通过
相同路径 owner.txt 分别读到 agent-a 和 agent-b;两侧都未发现对方独有文件。
A 异常退出后 B 继续运行
通过
A 以退出码 42 结束;B 在约 30 秒内完成六次文件处理,Pod UID、容器 ID、启动时间、重启次数和 boot_id 均保持不变。

清理测试资源

1. 保存本次结果和必要日志,导出时去除凭证及不应公开的环境信息。
2. 在控制台删除本次创建的 cube-isolation-a 和 cube-isolation-b。只删除实际创建成功的资源。
3. 核对测试 Pod 均已消失。如果命名空间只用于本次测试且没有其他资源,再删除该命名空间。