您可以部署开发者环境,以便在 Google Kubernetes Engine (GKE) 集群中使用 Agent Sandbox Python 客户端。此设置有助于您通过在沙盒化的 Python 环境中隔离不受信任的代码,安全地执行和测试 AI 生成的代码。这种隔离对于保护您的系统免受 AI 生成的代码中潜在漏洞的影响、提高开发速度以及确保安全部署至关重要。如需大致了解 Agent Sandbox 功能如何隔离不受信任的 AI 生成的代码,请参阅关于 GKE Agent Sandbox。
费用
Agent Sandbox 在 GKE 中免费提供。 GKE 价格 适用于您创建的资源。
准备工作
-
在 Google Cloud 控制台的项目选择器页面上, 选择或创建一个 Google Cloud 项目。
选择或创建项目所需的角色
- 选择项目:选择项目不需要特定的 IAM 角色,您可以选择已获授角色的任何项目。
-
创建项目:如需创建项目,您需要 Project Creator 角色
(
roles/resourcemanager.projectCreator),该角色包含resourcemanager.projects.create权限。了解如何授予 角色。
-
验证是否已为您的 Google Cloud 项目启用结算功能。
启用 Artifact Registry 和 Kubernetes Engine API。
启用 API 所需的角色
如需启用 API,您需要拥有
serviceusage.services.enable权限。如果您已创建项目,则可能已通过 Owner 角色 (roles/owner) 拥有此权限。否则,您可以通过 Service Usage Admin 角色 (roles/serviceusage.serviceUsageAdmin) 获得此权限。了解如何授予角色。-
在 Google Cloud 控制台中,激活 Cloud Shell。
- 验证您是否拥有完成本文档所需的权限。
- 您必须拥有启用了 Agent Sandbox 功能的 GKE 集群。如果没有,请按照在 GKE 上启用 Agent Sandbox 中的说明创建新集群或更新现有集群。
所需的角色
如需获得创建和管理沙盒所需的权限,请让您的管理员为您授予项目的Kubernetes Engine Admin (roles/container.admin) IAM 角色。如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限。
您也可以通过自定义 角色或其他预定义 角色来获取所需的权限。
定义环境变量
为了简化您在本文档中运行的命令,您可以在 Cloud Shell 中设置环境变量。在 Cloud Shell 中,运行以下命令来定义以下有用的环境变量:
export PROJECT_ID=$(gcloud config get project)
export CLUSTER_NAME="agent-sandbox-cluster"
export LOCATION="us-central1"
export NODE_POOL_NAME="agent-sandbox-node-pool"
export MACHINE_TYPE="e2-standard-2"
以下是对这些环境变量的说明:
PROJECT_ID:当前 Google Cloud 项目的 ID。定义此变量有助于确保所有资源(例如 GKE 集群)都在正确的项目中创建。CLUSTER_NAME:GKE 集群的名称,例如agent-sandbox-cluster。LOCATION:GKE 集群所在的 Google Cloud 区域或可用区。如果您使用的是 Autopilot 集群,请将其设置为区域(例如us-central1);如果您使用的是 Standard 集群,请将其设置为可用区(例如us-central1-a)。NODE_POOL_NAME:将运行沙盒化工作负载的节点池的名称,例如agent-sandbox-node-pool。MACHINE_TYPE:节点池中节点的机器类型,例如e2-standard-2。如需详细了解不同的机器系列以及 如何在不同选项之间进行选择,请参阅 机器家族资源和比较指南。
部署沙盒化环境
本部分介绍了如何创建沙盒蓝图 (SandboxTemplate)、部署必要的网络路由器,以及安装用于与沙盒交互的 Python 客户端。
建议使用 Agentic Sandbox Python 客户端来创建沙盒并与之交互。 此客户端提供了一个界面,可简化沙盒的整个生命周期(从创建到清理)。这是一个 Python 库,可用于以程序化方式创建、使用和删除沙盒。
客户端使用沙盒路由器作为所有流量的中心入口点。在本文档所述的示例中,客户端使用命令 kubectl port-forward
创建通往此路由器的隧道,这样您就不需要公开任何公共 IP 地址。请注意,使用 kubectl port-forward
不是一种安全解决方案,其使用应仅限于开发环境。
创建 SandboxTemplate 和 SandboxWarmPool
您现在可以通过创建 SandboxTemplate 和 SandboxWarmPool 资源来定义沙盒的配置。SandboxTemplate
充当可重用的蓝图,供 Agent Sandbox 控制器用于创建一致的预配置沙盒环境。SandboxWarmPool
资源有助于确保指定数量的预热 Pod 始终处于运行状态,并随时可供声明。 预热沙盒是已初始化的正在运行的
Pod。这种预初始化功能可让您在不到一秒的时间内创建新沙盒,并避免启动常规沙盒时的启动延迟:
在 Cloud Shell 中,创建一个名为
sandbox-template-and-pool.yaml的文件,其中包含以下内容:apiVersion: extensions.agents.x-k8s.io/v1alpha1 kind: SandboxTemplate metadata: name: python-runtime-template namespace: default spec: podTemplate: metadata: labels: sandbox: python-sandbox-example spec: runtimeClassName: gvisor 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: python-runtime image: registry.k8s.io/agent-sandbox/python-runtime-sandbox:v0.1.0 ports: - containerPort: 8888 readinessProbe: httpGet: path: "/" port: 8888 initialDelaySeconds: 0 periodSeconds: 1 resources: requests: cpu: "250m" memory: "512Mi" limits: cpu: "500m" memory: "1Gi" # Required securityContext: capabilities: drop: ["ALL"] # Required restartPolicy: "OnFailure" --- apiVersion: extensions.agents.x-k8s.io/v1alpha1 kind: SandboxWarmPool metadata: name: python-sandbox-warmpool namespace: default spec: replicas: 2 sandboxTemplateRef: name: python-runtime-template应用
SandboxTemplate和SandboxWarmPool清单:kubectl apply -f sandbox-template-and-pool.yaml
部署沙盒路由器
您将用于创建沙盒环境并与之交互的 Python 客户端使用名为“沙盒路由器”的组件与沙盒进行通信。
在此示例中,您将使用客户端的开发者模式进行测试。此模式适用于本地开发,并使用 kubectl port-forward 命令在本地机器与集群中运行的沙盒路由器服务之间建立直接隧道。这种隧道方法无需使用公共 IP 地址或复杂的入站流量设置,并简化了从本地环境与沙盒的交互。
请按照以下步骤部署沙盒路由器:
在 Cloud Shell 中,创建一个名为
sandbox-router.yaml的文件,其中包含以下内容:# A ClusterIP Service to provide a stable endpoint for the router pods. apiVersion: v1 kind: Service metadata: name: sandbox-router-svc namespace: default spec: type: ClusterIP selector: app: sandbox-router ports: - name: http protocol: TCP port: 8080 # The port the service will listen on targetPort: 8080 # The port the router container listens on (from the sandbox_router/Dockerfile) --- # The Deployment to manage and run the router pods. apiVersion: apps/v1 kind: Deployment metadata: name: sandbox-router-deployment namespace: default spec: replicas: 1 selector: matchLabels: app: sandbox-router template: metadata: labels: app: sandbox-router spec: # Ensure pods are spread across different zones for HA topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: app: sandbox-router containers: - name: router image: us-central1-docker.pkg.dev/k8s-staging-images/agent-sandbox/sandbox-router:latest-main ports: - containerPort: 8080 readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 5 periodSeconds: 5 livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 10 periodSeconds: 10 resources: requests: cpu: "100m" memory: "512Mi" limits: cpu: "1000m" memory: "1Gi" securityContext: runAsUser: 1000 runAsGroup: 1000应用清单以将路由器部署到集群:
kubectl apply -f sandbox-router.yaml验证沙盒路由器部署是否正常运行:
kubectl get deployment sandbox-router-deployment等待部署在
READY列中显示 2/2 或 1/1。
安装 Python 客户端
现在,沙盒路由器等集群内组件已部署完毕, 最后一步准备工作是在您的 本地机器上安装 Agentic Sandbox Python 客户端。请注意,此客户端是一个 Python 库,可让您以程序化方式创建、使用和删除沙盒。您将在下一部分中使用它来测试环境:
创建并激活 Python 虚拟环境:
python3 -m venv .venv source .venv/bin/activate安装客户端软件包:
pip install k8s-agent-sandbox
测试沙盒
在所有设置组件就绪后,您现在可以使用 Agentic Sandbox Python 客户端创建沙盒并与之交互。
在
agent-sandbox目录中,创建一个名为test_sandbox.py的 Python 脚本,其中包含以下内容:from k8s_agent_sandbox import SandboxClient from k8s_agent_sandbox.models import SandboxLocalTunnelConnectionConfig # Automatically tunnels to svc/sandbox-router-svc client = SandboxClient( connection_config=SandboxLocalTunnelConnectionConfig() ) sandbox = client.create_sandbox(template="python-runtime-template", namespace="default") try: print(sandbox.commands.run("echo 'Hello from the sandboxed environment!'").stdout) except Exception as e: print(f"An error occurred: {e}")在终端中(虚拟环境仍处于活跃状态),运行测试脚本:
python3 test_sandbox.py
您应该会看到“Hello from the sandboxed environment!”消息,这是沙盒的输出。
恭喜!您已成功在安全沙盒内运行 shell 命令。使用 sandbox.run()
方法,您可以执行任何 shell 命令,Agent Sandbox 会在安全屏障内运行该命令,以保护集群的节点和其他工作负载免受不受信任的代码的影响。这为 AI 智能体或任何自动化工作流提供了一种安全可靠的任务执行方式。
运行脚本时,SandboxClient 会为您处理所有步骤。它会创建 SandboxClaim
资源来启动沙盒,等待沙盒准备就绪,然后使用 sandbox.run() 方法在安全容器内执行 bash shell
命令。然后,客户端会捕获并输出来自该命令的 stdout。程序运行后,沙盒会自动删除。
创建 SandboxClaim 资源后,系统会从暖池中向 Sandbox 对象分配一个可用的 Pod,并将声明标记为就绪。然后,SandboxWarmPool
会自动补充自身,以维持配置的副本数。
如需验证特定沙盒是否已声明或可用,请检查沙盒 Pod 元数据中的 ownerReferences - 如果 kind 字段的值为
Sandbox,则表示该 Pod 正在使用中。如果 kind 字段的值为 SandboxWarmPool,则表示该 Pod 处于空闲状态,等待声明。
在生产环境中运行沙盒
在本文档中,您将使用 Cloud Shell 从集群外部与沙盒交互。Python
客户端使用您的用户凭据向集群进行身份验证并管理沙盒资源,并使用 kubectl port-forward
命令与沙盒建立连接。这些步骤非常适合开发场景。
在生产场景中,控制器应用(例如 AI 编排器)负责创建和管理沙盒资源。如需在生产环境中使用 Agent Sandbox,请考虑以下事项:
身份验证:您的控制器应用必须向 集群 API 服务器进行身份验证,才能运行沙盒。如何配置身份验证取决于控制器应用的运行位置,如下所示:
- 如果控制器应用作为 Pod 在同一集群中运行,请使用 Kubernetes RBAC 或 Workload Identity Federation for GKE 和 IAM 政策向 Pod 的 Kubernetes ServiceAccount 授予观看沙盒或发现 网络端点所需的权限。
- 如果控制器应用在集群外部运行,请使用 工作负载身份联合或 IAM 服务账号为应用提供身份 ,您可以在允许政策中引用该身份。
路由:来自控制器应用中 Python 客户端的请求 必须到达集群中的沙盒路由器。在生产环境中,请使用以下方法之一建立网络连接:
- 如果控制器应用在同一集群中运行,请使用
SandboxDirectConnectionConfig函数来定位沙盒路由器服务使用的网址和端口。 - 如果控制器应用在集群外部运行,请使用
the
GKE Gateway API
创建内部或外部负载均衡器。在客户端代码中,使用
SandboxGatewayConnectionConfig函数引用您的网关。
如需详细了解这些路由方法,请参阅 GitHub 上的使用示例 以及 路由器的网关部署步骤。
- 如果控制器应用在同一集群中运行,请使用
沙盒对 Google Cloud 资源的访问权限:如果您的沙盒代码 需要向 Google Cloud API(例如 Cloud Storage)发送请求,请将 IAM 政策与 Workload Identity Federation for GKE 结合使用,向沙盒 Pod 使用的 Kubernetes ServiceAccount 授予该访问权限所需的 权限。由于默认网络策略会阻止访问 Google Cloud 元数据服务器 (
169.254.169.254),因此您必须自定义网络策略以允许此 流量。网络政策限制:默认情况下,Agent Sandbox 会强制执行严格的默认安全网络安全状况 (
networkPolicyManagement: Managed)。在这种状况下,适用以下限制:- 系统会阻止来自除指定沙盒路由器之外的所有来源的入站流量 。
- 系统允许出站流量 流向公共互联网,但会明确阻止出站流量流向专用 LAN 范围 (RFC 1918)、内部集群 DNS (CoreDNS) 和 Cloud Provider Metadata Server (
169.254.0.0/16)。
如需使用 Workload Identity Federation for GKE 或访问其他专用资源,您必须在
SandboxTemplate中定义自定义网络政策。如需了解详细的 配置详情和可自定义的模板(例如 气隙沙盒或 Workload Identity Federation for GKE 集成),请参阅 Agent Sandbox 网络政策管理。
沙盒安全政策
为了帮助确保默认安全环境,GKE Agent
Sandbox 插件使用 Kubernetes 验证准入政策 (VAP) 来对 Sandbox 和 SandboxTemplate 资源强制执行
安全限制。这些政策会自动应用。
该插件将安全强制执行分为两层政策模型,以提高灵活性。以下部分介绍了这些政策:严格管理的核心政策和可自定义的强化政策。
核心安全政策 (sandbox-core-policy)
核心安全政策会强制执行有助于保护沙盒完整性的隔离要求。此政策包含需要使用 gVisor、网络隔离(例如停用
hostNetwork)和文件系统隔离(例如阻止 hostPath)的规则。由于 GKE 通过
addonmanager.kubernetes.io/mode: Reconcile 设置管理此政策,因此您无法修改或替换这些核心规则。
强化安全政策 (sandbox-hardening-policy)
安全加固政策提供了额外的安全最佳实践和管理选项。它会强制执行以下限制:丢弃所有功能、阻止添加新功能,以及要求容器以非 root
身份运行并设置资源限制。GKE 通过 addonmanager.kubernetes.io/mode: EnsureExists 设置以 EnsureExists 模式部署此政策。此设置意味着,如果政策缺失,GKE 会创建该政策,但您可以根据需要修改或删除该政策或其绑定。
修改或移除强化限制
由于强化政策以 EnsureExists 模式部署,因此如果政策缺失,GKE 会创建该政策,但不会覆盖您的修改。如果您的工作负载需要豁免这些安全加固规则,您可以修改政策以移除特定限制,或完全删除政策绑定。
如需修改安全加固政策并移除特定限制(例如,允许容器以 root 身份运行或省略资源限制),请修改 ValidatingAdmissionPolicy 资源:
kubectl edit validatingadmissionpolicy sandbox-hardening-policy
在打开的文本编辑器中,找到 validations 部分,然后移除或修改阻止工作负载的限制表达式。
或者,如果您想完全为集群停用安全加固政策,请删除政策绑定:
kubectl delete validatingadmissionpolicybinding sandbox-hardening-binding
已知问题
本部分介绍了在 GKE 中使用 Agent Sandbox 时遇到的已知问题,以及如何解决或规避这些问题。
使用服务网格时,安全政策会阻止功能
如果您尝试部署与服务网格 Sidecar(例如 Envoy 或 Istio)集成的沙盒,则沙盒的创建可能会被安全加固安全政策阻止,并显示如下错误:
sandbox create error: sandboxes.agents.x-k8s.io "claude-cli-claim-managed" is forbidden:
ValidatingAdmissionPolicy 'sandbox-hardening-policy' with binding 'sandbox-hardening-binding'
denied request: Security Violation: Capabilities.add must be empty. You cannot add capabilities.
- 原因:服务网格 Sidecar 通常使用 init 容器,例如
istio-init或proxy-init。这些 init 容器需要NET_ADMIN或NET_RAW等功能来配置iptables规则,以实现透明的出站流量路由。 默认情况下,GKEsandbox-hardening-policy会阻止所有容器类型中的所有功能添加。 - 解决方法:由于 GKE 安全加固政策以
EnsureExists模式部署,因此您可以修改ValidatingAdmissionPolicy以 允许特定的受信任 init 容器请求NET_ADMIN和NET_RAW能力。如需了解如何修改或移除这些 强化限制,请参阅 修改或移除强化限制。 例如,您可以更新政策的验证表达式或变量,以将受信任的容器名称从功能规则中豁免。
通过 IPv6 连接到 Google API 时出现出站流量延迟或超时
沙盒中的工作负载在尝试连接到外部资源或 Google API(例如 Vertex AI 或 Cloud Storage)时,可能会遇到连接超时或高延迟(高达两分钟)。
- 原因:如果您的 GKE 集群启用了双栈 IPv6, 则 Google API 的 DNS 解析会返回 IPv4 (A) 和 IPv6 (AAAA) 地址。运行时引擎(例如 Node.js)中的某些算法会先尝试通过 IPv6 进行连接。如果您的 GKE VPC 没有有效的 IPv6 出站流量路由(例如 Cloud NAT 或 IPv6 的互联网网关),则 TCP 连接会停止响应,直到 TCP SYN 超时过期。然后,TCP 连接会回退到 IPv4。
解决方案:如需解决此问题,请执行以下某项操作:
- 配置 IPv6 出站流量:如需允许出站 IPv6 流量 返回到集群,请在 VPC 网络中配置有效的 IPv6 Cloud NAT 或 互联网网关。
在工作负载中首选 IPv4:如需首选 IPv4 DNS 解析, 请配置工作负载的运行时。例如,在 Node.js 应用中,您可以在
SandboxTemplate定义中设置以下环境变量:env: - name: NODE_OPTIONS value: "--dns-result-order=ipv4first --no-network-family-autoselection"
清理资源
为避免系统向您的 Google Cloud 账号收取费用,您应删除您创建的 GKE 集群:
gcloud container clusters delete $CLUSTER_NAME --location=$LOCATION --quiet
后续步骤
- 了解如何使用 Pod 快照保存和恢复 Agent Sandbox 环境。
- 详细了解 GitHub 上的 Agent Sandbox 开源项目。
- 了解如何将开源 Kata Containers 与 Agent Sandbox 结合使用。 Kata Containers 不是 Google Cloud 产品。如果您安装并使用此软件,则需要负责管理和问题排查。 Google 的支持和 SLA 不适用于 Kata Containers。
- 如需了解为 工作负载提供安全隔离的底层技术,请参阅 GKE Sandbox。
- 如需详细了解如何增强集群和工作负载的安全性, 请参阅 GKE 安全概览。