本文档介绍了如何在集群中的 Google Kubernetes Engine (GKE) 上启用 Agent Sandbox。此外,还介绍了如何在集群上创建沙盒环境,以便安全地执行不受信任的代码。
如需大致了解 GKE 上的 Agent Sandbox 如何隔离 不受信任的 AI 生成代码,请参阅 GKE 上的 Agent Sandbox 简介。
费用
GKE 上的 Agent Sandbox 免费提供。 GKE 定价 适用于您创建的资源。
为避免产生不必要的费用,请务必在完成本文档后停用 GKE 或删除项目。
准备工作
-
在 Cloud de Confiance 控制台的项目选择器页面上, 选择或创建 Cloud de Confiance 项目。
选择或创建项目所需的角色
- 选择项目:选择项目不需要特定的 IAM 角色,您可以选择已获授角色的任何项目。
-
创建项目:如需创建项目,您需要 Project Creator 角色
(
roles/resourcemanager.projectCreator),该角色包含resourcemanager.projects.create权限。了解如何授予 角色。
启用 Artifact Registry 和 Google Kubernetes Engine API(如果尚未启用)。
启用 API 所需的角色
如需启用 API,您需要拥有
serviceusage.services.enable权限。如果您已创建项目,则可能已通过 Owner 角色 (roles/owner) 拥有此权限。否则,您可以通过 Service Usage Admin 角色 (roles/serviceusage.serviceUsageAdmin) 获得此权限。了解如何授予角色。-
在 Cloud de Confiance 控制台中,激活 Cloud Shell。
- 确保您的集群运行的是 GKE 1.36.3-gke.1767000 版或更高版本(支持
v1beta1API)。
定义环境变量
为了简化您在本文档中运行的命令,您可以在 Cloud Shell 中设置环境变量。在 Cloud Shell 中,运行以下命令来定义以下有用的环境变量:
export PROJECT_ID=$(gcloud config get project)
export CLUSTER_NAME="agent-sandbox-cluster"
export LOCATION="us-central1"
export CLUSTER_VERSION="1.36.3-gke.1767000"
export NODE_POOL_NAME="agent-sandbox-pool"
export MACHINE_TYPE="e2-standard-2"
以下是这些环境变量的说明:
PROJECT_ID:当前 Cloud de Confiance by S3NS 项目的 ID。定义此变量有助于确保所有资源(例如 GKE 集群)都在正确的项目中创建。CLUSTER_NAME:GKE 集群的名称,例如agent-sandbox-cluster。LOCATION:GKE 集群创建所在的 Cloud de Confiance by S3NS 区域或可用区。如果您创建的是 Autopilot 集群,请将其设置为区域(例如us-central1);如果您创建的是 Standard 集群,请将其设置为可用区(例如us-central1-a)。CLUSTER_VERSION:集群将运行的 GKE 版本(1.36.3-gke.1767000或更高版本)。NODE_POOL_NAME:将运行沙盒化工作负载的节点池的名称,例如agent-sandbox-pool。只有在创建 GKE Standard 集群时,才需要此变量。MACHINE_TYPE:节点池中节点的机器类型,例如e2-standard-2。如需详细了解不同的机器系列以及 如何在不同选项之间进行选择,请参阅 机器家族资源和比较指南。 只有在创建 GKE Standard 集群时,才需要此变量。
在 GKE 上启用 Agent Sandbox
您可以在创建新集群或更新现有集群时在 GKE 上启用 Agent Sandbox。
在创建新集群时在 GKE 上启用 Agent Sandbox
我们建议您使用 Autopilot 集群获得全代管式 Kubernetes 体验。如需选择最适合您的工作负载的 GKE 操作模式,请参阅 选择 GKE 操作模式。
Autopilot
如需创建已启用 GKE 上的 Agent Sandbox 的新 GKE Autopilot 集群,请添加 --enable-agent-sandbox 标志:
gcloud beta container clusters create-auto ${CLUSTER_NAME} \
--location=${LOCATION} \
--cluster-version=${CLUSTER_VERSION} \
--enable-agent-sandbox
对于 Autopilot 集群,请确保将 LOCATION 环境变量设置为区域(例如 us-central1)。
标准版
如需创建已启用 GKE 上的 Agent Sandbox 的新 GKE Standard 集群,您必须先创建集群,然后添加启用了 gVisor 的节点池,最后在 GKE 上启用 Agent Sandbox。为节省费用,我们建议您创建可用区级集群,且每个池只有一个节点:
创建集群:
gcloud beta container clusters create ${CLUSTER_NAME} \ --location=${LOCATION} \ --num-nodes=1 \ --cluster-version=${CLUSTER_VERSION}对于此 Standard 集群,请确保将
LOCATION环境变量设置为可用区(例如us-central1-a)。创建单独的节点池并启用 gVisor:
gcloud container node-pools create ${NODE_POOL_NAME} \ --cluster=${CLUSTER_NAME} \ --machine-type=${MACHINE_TYPE} \ --location=${LOCATION} \ --num-nodes=1 \ --image-type=cos_containerd \ --sandbox=type=gvisorLOCATION必须与您在创建集群时使用的可用区相同。更新集群以在 GKE 上启用 Agent Sandbox:
gcloud beta container clusters update ${CLUSTER_NAME} \ --location=${LOCATION} \ --enable-agent-sandbox
在更新现有集群时在 GKE 上启用 Agent Sandbox
如需在现有集群中启用 GKE 上的 Agent Sandbox,集群必须运行 1.36.3-gke.1767000 版或更高版本,该版本支持 v1beta1 API。
确保将 LOCATION 环境变量设置为现有集群所在的区域或可用区。
如果您使用的是 GKE Standard 集群,则 GKE 上的 Agent Sandbox 依赖于 gVisor。如果您的 Standard 集群没有启用 gVisor 的节点池,您必须先创建一个:
gcloud container node-pools create ${NODE_POOL_NAME} \ --cluster=${CLUSTER_NAME} \ --machine-type=${MACHINE_TYPE} \ --location=${LOCATION} \ --image-type=cos_containerd \ --sandbox=type=gvisor更新集群以在 GKE 上启用 Agent Sandbox:
gcloud beta container clusters update ${CLUSTER_NAME} \ --location=${LOCATION} \ --enable-agent-sandbox
验证配置
您可以通过检查集群说明来验证是否已启用 GKE 上的 Agent Sandbox。
gcloud beta container clusters describe ${CLUSTER_NAME} \
--location=${LOCATION} \
--format="value(addonsConfig.agentSandboxConfig.enabled)"
如果您创建的是 Autopilot 集群,则位置是区域(例如 us-central1)。如果您创建的是 Standard 集群,则位置是可用区(例如 us-central1-a)。
如果该功能已成功启用,此命令会返回 True。
GKE 上的 Agent Sandbox 部署要求
如需成功部署工作负载(例如 Sandbox 或 SandboxTemplate),
您的 YAML 清单必须包含特定的安全和配置设置。
GKE 使用验证准入政策 (VAP) 来强制执行这些要求。如果不满足这些要求,准入控制器会拒绝部署。
所需的配置
您的部署清单必须包含以下设置:
runtimeClassName: gvisor:确保 Pod 在 gVisor 沙盒中运行。automountServiceAccountToken: false:阻止 Pod 自动装载默认服务帐号令牌。securityContext.runAsNonRoot: true:确保容器不会以根用户身份运行。securityContext.capabilities.drop: ["ALL"]:从容器中删除所有 Linux 功能 。resources.limits:您必须指定 CPU 和内存限制,以防止潜在的拒绝服务 (DoS) 场景。nodeSelector:必须以sandbox.gke.io/runtime: gvisor为目标。tolerations:必须包含对sandbox.gke.io/runtime=gvisor:NoSchedule污点的容忍设置。
禁止的配置
您的部署清单不得包含以下任何内容:
hostNetwork: true、hostPID: true或hostIPC: true。- 容器安全上下文中的
privileged: true。 HostPath卷。- 添加的功能 (
capabilities.add)。 hostPort设置。- 自定义 sysctl。
- 用于服务帐号令牌或证书的投影卷。
部署沙盒环境
我们建议您通过定义 SandboxTemplate 并使用 SandboxWarmPool 保持预热实例就绪来部署沙盒环境。然后,您可以使用 SandboxClaim 从此预热节点池请求实例。或者,您也可以直接创建 Sandbox,但此方法不支持预热池。
SandboxTemplate、SandboxWarmPool、SandboxClaim 和 Sandbox 是 Kubernetes 自定义资源。
推荐:创建 SandboxTemplate 和 SandboxWarmPool
SandboxTemplate 充当可重用的蓝图。SandboxWarmPool 有助于确保指定数量的预热 Pod 始终处于运行状态,并随时可供声明。使用此自定义资源可最大限度地缩短启动延迟时间。
如需通过创建 SandboxTemplate 和 SandboxWarmPool 来部署沙盒环境,请完成以下步骤:
在 Cloud Shell 中,创建一个名为
sandbox-template.yaml的文件,其中包含以下内容:apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxTemplate metadata: name: python-runtime-template namespace: default spec: podTemplate: metadata: labels: sandbox-type: python-runtime spec: runtimeClassName: gvisor # Required automountServiceAccountToken: false # Required securityContext: runAsNonRoot: true # Required nodeSelector: sandbox.gke.io/runtime: gvisor # Required tolerations: - key: "sandbox.gke.io/runtime" value: "gvisor" effect: "NoSchedule" # Required containers: - name: runtime image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0 ports: - containerPort: 8888 resources: requests: cpu: "250m" memory: "512Mi" limits: cpu: "500m" memory: "1Gi" # Required securityContext: capabilities: drop: ["ALL"] # Required restartPolicy: OnFailure应用
SandboxTemplate清单:kubectl apply -f sandbox-template.yaml创建一个名为
sandbox-warmpool.yaml的文件,其中包含以下内容:apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxWarmPool metadata: name: python-runtime-warmpool namespace: default labels: app: python-runtime-warmpool spec: replicas: 2 sandboxTemplateRef: # This must match the name of the SandboxTemplate. name: python-runtime-template应用
SandboxWarmPool清单:kubectl apply -f sandbox-warmpool.yaml
创建 SandboxClaim
SandboxClaim 从预热池请求沙盒。由于您创建了预热池,因此创建的 Sandbox 会采用池中正在运行的 Pod,而不是启动新的 Pod。
如需通过创建 SandboxClaim 从预热池请求沙盒,请完成以下步骤:
创建一个名为
sandbox-claim.yaml的文件,其中包含以下内容:apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxClaim metadata: name: sandbox-claim namespace: default spec: warmPoolRef: # This must match the name of the SandboxWarmPool. name: python-runtime-warmpool应用
SandboxClaim清单:kubectl apply -f sandbox-claim.yaml验证沙盒、声明和预热池是否已准备就绪:
kubectl get sandboxwarmpool,sandboxclaim,sandbox,pod
替代方案:直接创建 Sandbox
如果您不需要预热池提供的快速启动时间,可以直接部署 Sandbox,而无需使用模板。
如需通过直接创建 Sandbox 来部署沙盒环境,请完成以下步骤:
创建一个名为
sandbox.yaml的文件,其中包含以下内容:apiVersion: agents.x-k8s.io/v1beta1 kind: Sandbox metadata: name: sandbox-example-2 spec: replicas: 1 podTemplate: metadata: labels: sandbox: sandbox-example spec: runtimeClassName: gvisor restartPolicy: OnFailure automountServiceAccountToken: false # Required securityContext: runAsNonRoot: true # Required runAsUser: 1000 # Required if image defaults to root (e.g. busybox) nodeSelector: sandbox.gke.io/runtime: gvisor tolerations: - key: "sandbox.gke.io/runtime" value: "gvisor" effect: "NoSchedule" # Required containers: - name: my-container image: busybox command: ["/bin/sh", "-c"] args: ["sleep 3600000; echo 'Container finished successfully'; exit 0"] securityContext: capabilities: drop: ["ALL"] # Required allowPrivilegeEscalation: false resources: limits: cpu: "100m" memory: "128Mi" # Required应用
Sandbox清单:kubectl apply -f sandbox.yaml验证沙盒是否正在运行:
kubectl get sandbox
将 GKE 上的 Agent Sandbox 从 v1alpha1 迁移到 v1beta1
如果您的集群是使用 v1alpha1 自定义资源部署的旧版 GKE 上的 Agent Sandbox,您可以升级到 GKE 1.36.3-gke.1767000 版或更高版本,且工作负载停机时间接近于零。
注意:此迁移过程适用于使用托管式 GKE 上的 Agent Sandbox 功能 (
--enable-agent-sandbox) 的集群。如果您 使用开源清单部署了 Agent Sandbox,请参阅 上游迁移指南。
v1alpha1 和 v1beta1 之间的主要 API 差异
| 概念 | v1alpha1 行为 |
v1beta1 行为 |
迁移影响 |
|---|---|---|---|
| SandboxClaim 目标 | 允许直接引用 SandboxTemplate,而无需预热池(冷启动)。 |
需要引用 SandboxWarmPool (spec.warmPoolRef.name)。 |
冷启动声明必须映射到影子预热池 (replicas: 0)。 |
| Sandbox 运行模式 | 从副本或状态字段推断。 | spec.operatingMode 字段的显式值(例如 Running 或 Suspended)。 |
转换 webhook 会自动映射并设置此字段。 |
| CustomResourceDefinition 存储版本 | v1alpha1 存储在 etcd 中 (storage: true)。 |
v1beta1 存储在 etcd 中 (storage: true)。 |
Webhook 会动态转换;升级后步骤会重新保留 etcd 对象。 |
| 转换 webhook | 无。 | 在 /convert(端口 9447)上处于活跃状态。 |
v1alpha1 和 v1beta1 之间的双向转换。 |
使用迁移工具进行迁移
如需自动创建影子预热池并重新保留永久性存储,请使用 Agent Sandbox 代码库 中的规范迁移脚本。
下载并准备脚本:
curl -LO https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/v0.5.6/helm/files/migrate.sh
chmod +x migrate.sh
分步迁移运行手册
如需迁移现有集群,且工作负载停机时间接近于零,请按顺序完成以下三个阶段:
第 1 阶段:升级前引导阶段
备份现有资源 :保存声明式 GKE 上的 Agent Sandbox 资源(
sandboxtemplates、sandboxwarmpools和sandboxclaims)的 YAML 备份:kubectl get sandboxtemplates,sandboxwarmpools,sandboxclaims \ --all-namespaces -o yaml > agent-sandbox-v1alpha1-backup.yaml验证模板安全性合规性:确保现有
SandboxTemplate资源满足 GKE 上的 Agent Sandbox 部署要求。 在第 3 阶段的存储迁移期间,准入控制器会拒绝更新任何不符合这些安全政策的模板。预览要创建的影子池:
./migrate.sh --phase=bootstrap --dry-run执行引导阶段:
./migrate.sh --phase=bootstrap验证创建的影子池:
kubectl get sandboxwarmpools --all-namespaces \ -o custom-columns="NAMESPACE:.metadata.namespace,NAME:.metadata.name,REPLICAS:.spec.replicas,SHADOW:.metadata.annotations.agents\.x-k8s\.io/migration-shadow"
第 2 阶段:升级 GKE 控制平面
将 GKE 控制平面升级到 1.36.3-gke.1767000 版或更高版本:
gcloud container clusters upgrade ${CLUSTER_NAME} \
--location=${LOCATION} \
--master \
--cluster-version=1.36.3-gke.1767000
在控制平面推出期间,请注意以下事项:
- Pod 不会重新启动或停机。
- 新控制器和
/convertwebhook 端点部署在控制平面上。
第 3 阶段:升级后存储迁移
控制平面升级完成后,刷新凭据并通过运行存储迁移阶段来重写存储的 etcd 对象:
./migrate.sh --phase=migrate
迁移后验证核对清单
| 检查项 | 命令 | 预期结果 |
|---|---|---|
| CustomResourceDefinition 存储版本 | kubectl get crd sandboxes.agents.x-k8s.io sandboxclaims.extensions.agents.x-k8s.io sandboxtemplates.extensions.agents.x-k8s.io sandboxwarmpools.extensions.agents.x-k8s.io -o jsonpath='{range .items[*]}{.metadata.name}{": storedVersions="}{.status.storedVersions}{"\n"}{end}' |
所有 4 个 CustomResourceDefinition 都显示:storedVersions=["v1beta1"] |
| Pod 连续性 | kubectl get pods -n default -o wide |
Status: 1/1 RunningRestarts: 0(适用于具有活跃运行沙盒的集群) |
| 声明绑定 | kubectl get sandboxclaims -n default -o yaml |
spec.warmPoolRef.name: shadow-pool-...status.conditions: Ready=True (需要模板符合准入要求) |
| v1alpha1 兼容性 | kubectl get sandboxes.v1alpha1.agents.x-k8s.io |
显示弃用警告并返回资源 |
| v1beta1 原生 CRUD | kubectl apply -f sandbox-claim.yaml |
应用时出现 0 个警告 |
如果 CustomResourceDefinition 在迁移阶段完成后继续在 ["v1alpha1", "v1beta1"] 中列出 .status.storedVersions
,这是预期的 Kubernetes 行为。
迁移脚本会将 etcd 中的所有现有记录重写为 v1beta1,但 Kubernetes 不会自动从 status.storedVersions 列表中移除已弃用的版本。
确认所有资源都已迁移后,您可以选择从存储的版本中剪除 v1alpha1:
for crd in \
sandboxes.agents.x-k8s.io \
sandboxclaims.extensions.agents.x-k8s.io \
sandboxtemplates.extensions.agents.x-k8s.io \
sandboxwarmpools.extensions.agents.x-k8s.io; do
kubectl patch crd "${crd}" --subresource=status --type=merge \
-p '{"status":{"storedVersions":["v1beta1"]}}'
done
排查迁移问题
如果您在升级控制平面或运行存储迁移后遇到问题,请向前解决这些问题,而不是尝试降级控制平面:
声明停留在
WarmPoolNotFound中:如果冷启动
v1alpha1声明已升级,但未运行./migrate.sh --phase=bootstrap,请手动创建缺少的影子预热池:apiVersion: extensions.agents.x-k8s.io/v1beta1 kind: SandboxWarmPool metadata: name: shadow-pool-TEMPLATE_NAME namespace: NAMESPACE annotations: agents.x-k8s.io/migration-shadow: "true" spec: replicas: 0 sandboxTemplateRef: name: TEMPLATE_NAME如果声明命名了不再存在的特定预热池,请使用该名称创建缺少的
SandboxWarmPool资源,或更新声明中的spec.warmPoolRef.name以引用现有预热池。
声明条件
Ready=False: 运行kubectl describe sandboxclaim以 检查声明中的事件。确保引用的SandboxTemplate满足 GKE 上的所有 Agent Sandbox 部署要求,并 根据需要重新应用模板。转换或控制器错误: 运行
kubectl get leases -n gke-managed-agentsandbox以验证控制平面领导者选举租约是否处于活跃状态。如果问题仍然存在,请与 Cloud Customer Care联系。
停用 GKE 上的 Agent Sandbox
如需停用 GKE 上的 Agent Sandbox,请使用 gcloud beta container clusters update 命令,并添加 --no-enable-agent-sandbox 标志。
gcloud beta container clusters update ${CLUSTER_NAME} \
--location=${LOCATION} \
--no-enable-agent-sandbox
如果您创建的是 Autopilot 集群,则位置是区域(例如 us-central1)。如果您创建的是 Standard 集群,则位置是可用区(例如 us-central1-a)。
清理资源
为避免系统向您的 Cloud de Confiance by S3NS 账号收取费用,请删除您创建的 GKE 集群。
gcloud container clusters delete $CLUSTER_NAME \
--location=${LOCATION} \
--quiet
如果您创建的是 Autopilot 集群,则位置是区域(例如 us-central1)。如果您创建的是 Standard 集群,则位置是可用区(例如 us-central1-a)。
后续步骤
- 了解如何使用 Pod 快照保存和恢复 GKE 上的 Agent Sandbox 环境。
- 了解 GKE 上的 Agent Sandbox 使用的基础技术。
- 详细了解 GKE 安全。
- 探索 GitHub 上的 Agent Sandbox 开源项目。
- 了解如何在 GKE 上将开源 Kata Containers 与 Agent Sandbox 结合使用。 Kata Containers 不是 Cloud de Confiance 产品。如果您安装并使用此软件,则需要负责管理和问题排查。 Google 的支持和 SLA 不适用于 Kata Containers。