開発環境をデプロイして、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 ロールは必要ありません。ロールが付与されているプロジェクトであれば、どのプロジェクトでも選択できます。
-
プロジェクトを作成する: プロジェクトを作成するには、
resourcemanager.projects.create権限を含むプロジェクト作成者ロール(roles/resourcemanager.projectCreator)が必要です。詳しくは、ロールを付与する方法をご覧ください。
Artifact Registry API と Kubernetes Engine API を有効にします。
API を有効にするために必要なロール
API を有効にするには、
serviceusage.services.enable権限を含む Service Usage 管理者 IAM ロール(roles/serviceusage.serviceUsageAdmin)が必要です。詳しくは、ロールを付与する方法をご覧ください。-
Google Cloud コンソールで Cloud Shell をアクティブにします。
- このガイドを完了するために必要な権限があることを確認します。
- Agent Sandbox 機能が有効になっている GKE クラスタが必要です。ない場合は、GKE でエージェント Sandbox を有効にするの手順に沿って、新しいクラスタを作成するか、既存のクラスタを更新します。
必要なロール
サンドボックスの作成と管理に必要な権限を取得するには、プロジェクトに対する Kubernetes Engine 管理者 (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 です。この事前初期化により、新しいサンドボックスを 1 秒以内に作成できるようになり、通常のサンドボックスの起動時のレイテンシを回避できます。
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-templateSandboxTemplateマニフェストと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.yamlSandbox Router のデプロイが正しく実行されていることを確認します。
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ディレクトリに、次の内容の Python スクリプトをtest_sandbox.pyという名前で作成します。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!」というメッセージが表示されます。
これで完了です。安全なサンドボックス内でシェルコマンドが正常に実行されました。sandbox.run() メソッドを使用すると、任意のシェルコマンドを実行できます。Agent Sandbox は、クラスタのノードや他のワークロードを信頼できないコードから保護する安全なバリア内でコマンドを実行します。これにより、AI エージェントや自動化されたワークフローがタスクを実行するための安全で信頼性の高い方法が提供されます。
スクリプトの実行時に、SandboxClient によってすべての手順が処理されます。SandboxClaim リソースを作成してサンドボックスを起動し、サンドボックスの準備が整うまで待機してから、sandbox.run() メソッドを使用して安全なコンテナ内で bash シェルコマンドを実行します。クライアントは、そのコマンドから stdout をキャプチャして出力します。サンドボックスは、プログラムの実行後に自動的に削除されます。
SandboxClaim リソースが作成されると、使用可能な Pod がウォームプールから Sandbox オブジェクトに割り当てられ、クレームが準備完了とマークされます。その後、SandboxWarmPool は構成されたレプリカ数を維持するために自動的に補充されます。
特定のサンドボックスが要求されているか、使用可能かどうかを確認するには、サンドボックス Pod のメタデータの ownerReferences を確認します。kind フィールドの値が Sandbox の場合、Pod は使用中です。kind フィールドの値が SandboxWarmPool の場合、Pod はアイドル状態で、要求されるのを待っています。
本番環境でサンドボックスを実行する
このドキュメントでは、Cloud Shell を使用してクラスタの外部からサンドボックスを操作します。Python クライアントは、ユーザー認証情報を使用してクラスタに対する認証を行い、サンドボックス リソースを管理します。また、kubectl port-forward コマンドを使用してサンドボックスとの接続を確立します。これらの手順は、開発シナリオに適しています。
本番環境のシナリオでは、コントローラ アプリケーション(AI オーケストレータなど)がサンドボックス リソースの作成と管理を行います。本番環境でエージェント サンドボックスを使用するには、次の点を考慮してください。
認証: コントローラ アプリケーションは、サンドボックスを実行するためにクラスタ API サーバーに対して認証する必要があります。認証の構成方法は、コントローラ アプリケーションの実行場所によって異なります。
- コントローラ アプリケーションが同じクラスタ内の Pod として実行されている場合は、Kubernetes RBAC または Workload Identity Federation for GKE と IAM ポリシーを使用して、Pod の Kubernetes ServiceAccount にサンドボックスのモニタリングやネットワーク エンドポイントの検出に必要な権限を付与します。
- コントローラ アプリケーションがクラスタの外部で実行されている場合は、Workload Identity 連携または IAM サービス アカウントを使用して、許可ポリシーで参照できる ID をアプリケーションに付与します。
ルーティング: コントローラ アプリケーションの Python クライアントからのリクエストは、クラスタ内のサンドボックス ルーターに到達する必要があります。本番環境では、次のいずれかの方法でネットワーク接続を確立します。
- コントローラ アプリケーションが同じクラスタで実行されている場合は、
SandboxDirectConnectionConfig関数を使用して、Sandbox Router サービスが使用する URL とポートをターゲットにします。 - コントローラ アプリケーションがクラスタの外部で実行されている場合は、GKE Gateway API を使用して内部ロードバランサまたは外部ロードバランサを作成します。クライアント コードで、
SandboxGatewayConnectionConfig関数を使用して Gateway を参照します。
これらのルーティング方法の詳細については、GitHub の使用例とルーターのゲートウェイ デプロイ手順をご覧ください。
- コントローラ アプリケーションが同じクラスタで実行されている場合は、
Google Cloud リソースへのサンドボックス アクセス: サンドボックス コードが Cloud Storage などの Google Cloud API にリクエストを送信する必要がある場合は、Workload Identity Federation for GKE を使用して IAM ポリシーを作成し、サンドボックス Pod が使用する Kubernetes ServiceAccount に、そのアクセスに必要な権限を付与します。デフォルトのネットワーク ポリシーでは Google Cloud メタデータ サーバー(
169.254.169.254)へのアクセスがブロックされるため、このトラフィックを許可するようにネットワーク ポリシーをカスタマイズする必要があります。ネットワーク ポリシーの制限: デフォルトでは、Agent Sandbox は厳格な Secure-by-Default ネットワーク ポスチャー(
networkPolicyManagement: Managed)を適用します。このポスチャーでは、次の制限が適用されます。- 指定されたサンドボックス ルーター以外のすべての送信元からの Ingress がブロックされます。
- 公共のインターネットへの上り(外向き)は許可されますが、プライベート LAN 範囲(RFC 1918)、内部クラスタ DNS(CoreDNS)、Cloud プロバイダ メタデータ サーバー(
169.254.0.0/16)への上り(外向き)は明示的にブロックされます。
Workload Identity Federation for GKE を使用するか、他のプライベート リソースにアクセスするには、
SandboxTemplateでカスタム ネットワーク ポリシーを定義する必要があります。構成の詳細とカスタマイズ可能なテンプレート(エアギャップ サンドボックスや Workload Identity Federation for GKE 統合など)については、エージェント サンドボックス ネットワーク ポリシー管理をご覧ください。
サンドボックス セキュリティ ポリシー
デフォルトで安全な環境を確保するために、GKE Agent Sandbox アドオンは Kubernetes 検証アドミッション ポリシー(VAP)を使用して、Sandbox リソースと SandboxTemplate リソースにセキュリティ制約を適用します。これらのポリシーは自動的に適用されます。
このアドオンは、セキュリティの適用を 2 段階のポリシー モデルに分割して、柔軟性を高めます。以降のセクションでは、厳密に管理されるコアポリシーとカスタマイズ可能な強化ポリシーについて説明します。
コア セキュリティ ポリシー(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 を使用する際の既知の問題と、その解決方法または回避策について説明します。
サービス メッシュを使用するとセキュリティ ポリシーが機能をブロックする
サービス メッシュ サイドカー(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.
- 原因: サービス メッシュ サイドカーは、
istio-initやproxy-initなどの init コンテナをよく使用します。これらの init コンテナでは、透過的な下り(外向き)ルーティングのiptablesルールを構成するために、NET_ADMINやNET_RAWなどの機能が必要です。デフォルトでは、GKEsandbox-hardening-policyはすべてのコンテナ タイプで機能の追加をすべてブロックします。 - 回避策: GKE 強化ポリシーは
EnsureExistsモードでデプロイされるため、ValidatingAdmissionPolicyを変更して、特定の信頼できる init コンテナがNET_ADMIN機能とNET_RAW機能をリクエストできるようにします。これらの強化制約を変更または削除する手順については、強化制約を変更または削除するをご覧ください。たとえば、ポリシーの検証式または変数を更新して、信頼できるコンテナ名を機能ルールから除外できます。
IPv6 経由で Google API に接続する際の下り(外向き)レイテンシまたはタイムアウト
サンドボックス内のワークロードが外部リソースまたは Google API(Vertex AI や Cloud Storage など)に接続しようとすると、接続タイムアウトやレイテンシの増加(最大 2 分)が発生することがあります。
- 原因: GKE クラスタでデュアルスタック IPv6 が有効になっている場合、Google API の DNS 解決は IPv4(A)アドレスと IPv6(AAAA)アドレスの両方を返します。Node.js などのランタイム エンジンのアルゴリズムでは、まず IPv6 経由で接続しようとします。GKE VPC に有効な IPv6 下り(外向き)ルート(IPv6 用の Cloud NAT やインターネット ゲートウェイなど)がない場合、TCP SYN タイムアウトが切れるまで TCP 接続が応答しなくなります(詳細については、https://developers.google.com/style/word-list#hang をご覧ください)。その後、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 環境を保存して復元する方法を学習する。
- Agent Sandbox オープンソース プロジェクトの詳細については、GitHub をご覧ください。
- オープンソースの Kata Containers と Agent Sandbox を使用する方法を確認する。Kata Containers は Google Cloud プロダクトではありません。このソフトウェアをインストールして使用する場合は、管理とトラブルシューティングはユーザーの責任となります。Google のサポートと SLA は Kata Containers には適用されません。
- ワークロードのセキュリティ分離を提供する基盤となるテクノロジーについては、GKE Sandbox をご覧ください。
- クラスタとワークロードのセキュリティ強化の詳細については、GKE セキュリティの概要をご覧ください。