GKE で Agent Sandbox を有効にする

このドキュメントでは、Google Kubernetes Engine(GKE)クラスタで Agent Sandbox 機能を有効にする方法について説明します。また、信頼できないコードを安全に実行するために、クラスタにサンドボックス環境を作成する方法についても説明します。

Agent Sandbox 機能が信頼できない AI 生成コードを分離する方法の概要については、 GKE Agent Sandbox についてをご覧ください。

費用

Agent Sandbox は GKE で追加料金なしで利用できます。 GKE の料金 は、作成したリソースに適用されます。

不要な料金が発生しないように、このドキュメントの完了後に GKE を無効にするか、プロジェクトを削除してください。

始める前に

  1. コンソールの Google Cloud プロジェクト セレクタページで、 Google Cloud プロジェクトを選択または作成します。

    プロジェクトを選択または作成するために必要なロール

    • プロジェクトを選択する: プロジェクトの選択には特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトを選択できます。
    • プロジェクトを作成する: プロジェクトを作成するには、プロジェクト作成者ロール (roles/resourcemanager.projectCreator)が必要です。これには resourcemanager.projects.create 権限が含まれています。詳しくは、ロールを付与する方法をご覧ください。

    プロジェクト セレクタに移動

  2. プロジェクトで課金が有効になっていることを確認します Google Cloud 。

  3. Artifact Registry API と Google Kubernetes Engine API を有効にします。

    API を有効にするために必要なロール

    API を有効にするには、serviceusage.services.enable 権限が必要です。プロジェクトを作成した場合は、オーナーロール(roles/owner)を通じてこの権限が付与されている可能性があります。それ以外の場合は、Service Usage 管理者ロール(roles/serviceusage.serviceUsageAdmin)を通じてこの権限を取得できます。ロールを付与する方法をご覧ください

    API を有効にする

  4. コンソール Google Cloud で Cloud Shell をアクティブにします。

    Cloud Shell をアクティブにする

  5. クラスタが GKE バージョン 1.36.3-gke.1767000 以降(v1beta1 API をサポート)を実行していることを確認します。

環境変数を定義する

このドキュメントで実行するコマンドを簡略化するために、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: 現在の Google Cloud プロジェクトの ID。この変数を定義すると、GKE クラスタなどのすべてのリソースが正しいプロジェクトに作成されます。
  • CLUSTER_NAME: GKE クラスタの名前(例: agent-sandbox-cluster)。
  • LOCATION: GKE クラスタが作成される Google Cloud リージョンまたはゾーン。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 クラスタを作成する場合にのみ必要です。

Agent Sandbox を有効にする

Agent Sandbox 機能は、新しいクラスタを作成するとき、または既存のクラスタを更新するときに有効にできます。

新しい GKE クラスタの作成時に Agent Sandbox を有効にする

フルマネージドの Kubernetes エクスペリエンスを実現するには、Autopilot クラスタを使用することをおすすめします。ワークロードに最適な GKE のオペレーション モードを選択するには、 GKE の運用モードを選択するをご覧ください。

Autopilot

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 など)に設定されていることを確認します。

標準

Agent Sandbox を有効にして新しい GKE Standard クラスタを作成するには、クラスタを作成し、gVisor を有効にしたノードプールを追加してから、Agent Sandbox 機能を有効にする必要があります。費用を節約するには、プールごとに 1 つのノードを持つゾーンクラスタを作成することをおすすめします。

  1. クラスタを作成します。

    gcloud beta container clusters create ${CLUSTER_NAME} \
        --location=${LOCATION} \
        --num-nodes=1 \
        --cluster-version=${CLUSTER_VERSION}
    

    この Standard クラスタでは、LOCATION 環境変数がゾーン(us-central1-a など)に設定されていることを確認します。

  2. 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=gvisor
    

    LOCATION は、クラスタの作成時に使用したゾーンと同じである必要があります。

  3. クラスタを更新して、Agent Sandbox 機能を有効にします。

    gcloud beta container clusters update ${CLUSTER_NAME} \
        --location=${LOCATION} \
        --enable-agent-sandbox
    

既存の GKE クラスタの更新時に Agent Sandbox を有効にする

既存のクラスタで Agent Sandbox を有効にするには、クラスタがバージョン 1.36.3-gke.1767000 以降(v1beta1 API をサポート)を実行している必要があります。

LOCATION 環境変数が、既存のクラスタがあるリージョンまたはゾーンに設定されていることを確認します。

  1. GKE Standard クラスタを使用している場合、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
    
  2. クラスタを更新して、Agent Sandbox 機能を有効にします。

    gcloud beta container clusters update ${CLUSTER_NAME} \
        --location=${LOCATION} \
        --enable-agent-sandbox
    

構成を確認する

クラスタの説明を検査することで、Agent Sandbox 機能が有効になっているかどうかを確認できます。

gcloud beta container clusters describe ${CLUSTER_NAME} \
    --location=${LOCATION} \
    --format="value(addonsConfig.agentSandboxConfig.enabled)"

Autopilot クラスタを作成した場合、ロケーションはリージョン(us-central1 など)です。Standard クラスタを作成した場合、ロケーションはゾーン(us-central1-a など)です。

機能が正常に有効になると、コマンドは True を返します。

Agent Sandbox のデプロイ要件

SandboxSandboxTemplate などのワークロードを正常にデプロイするには、 YAML マニフェストに特定のセキュリティ設定と構成設定を含める必要があります。 GKE は、検証アドミッション ポリシー(VAP)を使用してこれらの要件を適用します。これらの要件が満たされていない場合、アドミッション コントローラはデプロイを拒否します。

必要な構成

デプロイ マニフェストには、次の設定を含める必要があります。

  • runtimeClassName: gvisor: Pod が gVisor サンドボックスで実行されるようにします。
  • automountServiceAccountToken: false: Pod がデフォルトのサービス アカウント トークンを自動的にマウントしないようにします。
  • securityContext.runAsNonRoot: true: コンテナが root ユーザーとして実行されないようにします。
  • securityContext.capabilities.drop: ["ALL"]: すべての Linux 機能をコンテナから削除します。
  • resources.limits: サービス拒否(DoS)のシナリオを回避するために、CPU とメモリの上限を指定する必要があります。
  • nodeSelector: sandbox.gke.io/runtime: gvisor をターゲットにする必要があります。
  • tolerations: sandbox.gke.io/runtime=gvisor:NoSchedule taint の toleration を含める必要があります。

禁止されている構成

デプロイ マニフェストに次のいずれも含めない でください。

  • hostNetwork: truehostPID: truehostIPC: true
  • コンテナ セキュリティ コンテキストの privileged: true
  • HostPath ボリューム。
  • 追加された機能(capabilities.add)。
  • hostPort 設定。
  • カスタム sysctl。
  • サービス アカウント トークンまたは証明書のプロジェクション ボリューム。

サンドボックス環境をデプロイする

SandboxTemplate を定義し、SandboxWarmPool を使用して事前にウォームアップされたインスタンスを準備しておくことで、サンドボックス環境をデプロイすることをおすすめします。SandboxClaim を使用して、このウォーム ノードプールからインスタンスをリクエストできます。または、Sandbox を直接作成することもできますが、この方法ではウォームプールはサポートされません。

SandboxTemplate、SandboxWarmPool、SandboxClaim、Sandbox は Kubernetes のカスタム リソースです

SandboxTemplate は、再利用可能なブループリントとして機能します。SandboxWarmPool は、指定された数の事前にウォームアップされた Pod が常に実行され、要求される準備ができていることを保証します。このカスタム リソースを使用すると、起動レイテンシを最小限に抑えることができます。

SandboxTemplate と SandboxWarmPool を作成してサンドボックス環境をデプロイする手順は次のとおりです。

  1. 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
    
  2. SandboxTemplate マニフェストを適用します。

    kubectl apply -f sandbox-template.yaml
    
  3. 次の内容で 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
    
  4. SandboxWarmPool マニフェストを適用します。

    kubectl apply -f sandbox-warmpool.yaml
    

SandboxClaim を作成する

SandboxClaim は、ウォームプールからサンドボックスをリクエストします。ウォームプールを作成したため、作成された Sandbox は新しい Pod を起動するのではなく、プールから実行中の Pod を採用します。

SandboxClaim を作成してウォームプールからサンドボックスをリクエストする手順は次のとおりです。

  1. 次の内容で 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
    
  2. SandboxClaim マニフェストを適用します。

    kubectl apply -f sandbox-claim.yaml
    
  3. サンドボックス、申請、ウォームプールの準備ができていることを確認します。

    kubectl get sandboxwarmpool,sandboxclaim,sandbox,pod
    

代替方法: Sandbox を直接作成する

ウォームプールによる高速起動が必要ない場合は、テンプレートを使用せずに Sandbox を直接デプロイできます。

Sandbox を直接作成してサンドボックス環境をデプロイする手順は次のとおりです。

  1. 次の内容で 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
    
  2. Sandbox マニフェストを適用します。

    kubectl apply -f sandbox.yaml
    
  3. サンドボックスが実行されていることを確認します。

    kubectl get sandbox
    

Agent Sandbox を v1alpha1 から v1beta1 に移行する

v1alpha1 カスタム リソースを使用して、以前のバージョンの Agent Sandbox でクラスタをデプロイした場合は、GKE バージョン 1.36.3-gke.1767000 以降にアップグレードできます。この場合、ワークロードのダウンタイムはほぼゼロになります。

注: この移行手順は、マネージド GKE Agent Sandbox 機能(--enable-agent-sandbox)を使用するクラスタに適用されます。オープンソース マニフェストを使用して Agent Sandbox をデプロイした場合は、 アップストリームの移行ガイドをご覧ください。

v1alpha1v1beta1 の主な API の違い

コンセプト v1alpha1 の動作 v1beta1 の動作 移行の影響
SandboxClaim ターゲット ウォームプール(コールド スタート)なしで SandboxTemplate を直接参照できます。 SandboxWarmPoolspec.warmPoolRef.name)への参照が必要です。 コールド スタートの申請は、シャドウ ウォームプール(replicas: 0)にマッピングする必要があります。
サンドボックスのオペレーション モード レプリカまたは状態フィールドから推測されます。 spec.operatingMode フィールドの明示的な値(RunningPaused など)。 変換 Webhook は、このフィールドを自動的にマッピングして設定します。
CRD ストレージ バージョン etcd に保存された v1alpha1storage: true)。 etcd に保存された v1beta1storage: true)。 Webhook は動的に変換します。アップグレード後の手順で etcd オブジェクトを再永続化します。
変換 Webhook なし /convert(ポート 9447)で有効。 v1alpha1v1beta1 の間の双方向変換。

移行ツールを使用して移行する

シャドウ ウォームプールを自動的に作成してストレージを再永続化するには、Agent Sandbox リポジトリの正規の移行スクリプトを使用します。

スクリプトをダウンロードして準備します。

curl -LO https://raw.githubusercontent.com/kubernetes-sigs/agent-sandbox/v0.5.6/helm/files/migrate.sh
chmod +x migrate.sh

移行手順書

ワークロードのダウンタイムをほぼゼロにして既存のクラスタを移行するには、次の 3 つのフェーズを順番に完了します。

フェーズ 1: アップグレード前のブートストラップ フェーズ

  1. 既存のリソースをバックアップする: クラスタ内のすべての Agent Sandbox カスタム リソースの YAML バックアップを保存します。

    kubectl get sandboxtemplates,sandboxwarmpools,sandboxclaims,sandboxes \
        --all-namespaces -o yaml > agent-sandbox-v1alpha1-backup.yaml
    
  2. テンプレートのセキュリティ コンプライアンスを確認します。既存の SandboxTemplate リソースが Agent Sandbox のデプロイ要件を満たしていることを確認します。 フェーズ 3 のストレージ移行中に、これらのセキュリティ ポリシーに準拠していないテンプレートの更新はアドミッション コントローラによって拒否されます。

  3. 作成するシャドウプールをプレビューします。

    ./migrate.sh --phase=bootstrap --dry-run
    
  4. ブートストラップ フェーズを実行します。

    ./migrate.sh --phase=bootstrap
    
  5. 作成されたシャドウプールを確認します。

    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 の再起動やダウンタイムは発生しません。
  • 新しいコントローラと /convert Webhook エンドポイントがコントロール プレーンにデプロイされます。

フェーズ 3: アップグレード後のストレージ移行

コントロール プレーンのアップグレードが完了したら、認証情報を更新し、ストレージ移行フェーズを実行して保存されている etcd オブジェクトを書き換えます。

./migrate.sh --phase=migrate

移行後の検証チェックリスト

商品アイテムのチェックをオン コマンド 期待される結果
CRD ストレージ バージョン 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 つの CRD すべてに次の内容が表示されます:
storedVersions=["v1beta1"]
Pod の継続性 kubectl get pods -n default -o wide Status: 1/1 Running
Restarts: 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 警告なしで適用されます

Agent Sandbox を無効にする

Agent Sandbox 機能を無効にするには、--no-enable-agent-sandbox フラグを指定して gcloud beta container clusters update コマンドを使用します。

gcloud beta container clusters update ${CLUSTER_NAME} \
    --location=${LOCATION} \
    --no-enable-agent-sandbox

Autopilot クラスタを作成した場合、ロケーションはリージョン(us-central1 など)です。Standard クラスタを作成した場合、ロケーションはゾーン(us-central1-a など)です。

リソースのクリーンアップ

アカウント Google Cloud に課金されないようにするには、作成した GKE クラスタを削除します。

gcloud container clusters delete $CLUSTER_NAME \
    --location=${LOCATION} \
    --quiet

Autopilot クラスタを作成した場合、ロケーションはリージョン(us-central1 など)です。Standard クラスタを作成した場合、ロケーションはゾーン(us-central1-a など)です。

次のステップ