GKE에서 에이전트 샌드박스 사용 설정

이 문서에서는 Google Kubernetes Engine (GKE) 클러스터에서 에이전트 샌드박스 기능을 사용 설정하는 방법을 설명합니다. 또한 클러스터에서 샌드박스 환경을 만들어 신뢰할 수 없는 코드를 안전하게 실행하는 방법도 설명합니다.

에이전트 샌드박스 기능이 신뢰할 수 없는 AI 생성 코드를 격리하는 방법에 대한 개요는 GKE 에이전트 샌드박스 정보를 참조하세요.

비용

에이전트 샌드박스는 GKE에서 추가 비용 없이 제공됩니다. GKE 가격 책정 은 사용자가 만드는 리소스에 적용됩니다.

불필요한 요금이 청구되지 않도록 이 문서를 완료한 후 GKE를 중지하거나 프로젝트를 삭제하세요.

시작하기 전에

  1. Google Cloud 콘솔의 프로젝트 선택기 페이지에서 프로젝트를 선택하거나 만듭니다. Google Cloud

    프로젝트를 선택하거나 만드는 데 필요한 역할

    • 프로젝트 선택: 프로젝트를 선택하는 데 특정 IAM 역할이 필요하지 않습니다. 역할이 부여된 프로젝트를 선택할 수 있습니다.
    • 프로젝트 만들기: 프로젝트를 만들려면 resourcemanager.projects.create 권한이 포함된 프로젝트 생성자 역할 (roles/resourcemanager.projectCreator)이 필요합니다. 역할 부여 방법 알아보기.

    프로젝트 선택기로 이동

  2. 프로젝트에 결제가 사용 설정되어 있는지 확인합니다 Google Cloud .

  3. Artifact Registry, Google Kubernetes Engine API를 사용 설정합니다.

    API 사용 설정에 필요한 역할

    API를 사용 설정하려면 serviceusage.services.enable 권한이 필요합니다. 프로젝트를 만든 경우 소유자 역할 (roles/owner)을 통해 이 권한을 이미 보유하고 있을 가능성이 높습니다. 그렇지 않은 경우 서비스 사용량 관리자 역할 (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 클러스터를 만드는 경우에만 필요합니다.

에이전트 샌드박스 사용 설정

새 클러스터를 만들 때 또는 기존 클러스터를 업데이트할 때 에이전트 샌드박스 기능을 사용 설정할 수 있습니다.

새 GKE 클러스터를 만들 때 에이전트 샌드박스 사용 설정

완전 관리형 Kubernetes 환경을 위해서는 Autopilot 클러스터를 사용하는 것이 좋습니다. 워크로드에 가장 적합한 GKE 작업 모드를 선택하려면 GKE 작업 모드 선택을 참조하세요.

Autopilot

에이전트 샌드박스가 사용 설정된 새 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 Standard 클러스터를 만들려면 클러스터를 만들고 gVisor가 사용 설정된 노드 풀을 추가한 후 에이전트 샌드박스 기능을 사용 설정해야 합니다. 비용을 절약하려면 풀당 노드가 하나인 영역 클러스터를 만드는 것이 좋습니다.

  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. 클러스터를 업데이트하여 에이전트 샌드박스 기능을 사용 설정합니다.

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

기존 GKE 클러스터를 업데이트할 때 에이전트 샌드박스 사용 설정

기존 클러스터에서 에이전트 샌드박스를 사용 설정하려면 클러스터가 v1beta1 API를 지원하는 버전 1.36.3-gke.1767000 이상을 실행해야 합니다.

LOCATION 환경 변수가 기존 클러스터가 있는 리전 또는 영역으로 설정되어 있는지 확인합니다.

  1. GKE Standard 클러스터를 사용하는 경우 에이전트 샌드박스는 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. 클러스터를 업데이트하여 에이전트 샌드박스 기능을 사용 설정합니다.

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

구성 확인

클러스터 설명을 검사하여 에이전트 샌드박스 기능이 사용 설정되어 있는지 확인할 수 있습니다.

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

Autopilot 클러스터를 만든 경우 위치는 리전 (예: us-central1)입니다. Standard 클러스터를 만든 경우 위치는 영역 (예: us-central1-a)입니다.

기능이 사용 설정되면 명령어에서 True를 반환합니다.

에이전트 샌드박스 배포 요구사항

Sandbox 또는 SandboxTemplate과 같은 워크로드를 성공적으로 배포하려면 YAML 매니페스트에 특정 보안 및 구성 설정이 포함되어야 합니다. GKE는 유효성 검사 승인 정책 (VAP)을 사용하여 이러한 요구사항을 적용합니다. 이러한 요구사항이 충족되지 않으면 승인 컨트롤러가 배포를 거부합니다.

필수 구성

배포 매니페스트에는 다음 설정이 포함되어야 합니다.

  • runtimeClassName: gvisor: 포드가 gVisor 샌드박스에서 실행되도록 합니다.
  • automountServiceAccountToken: false: 포드가 기본 서비스 계정 토큰을 자동으로 마운트하지 못하도록 합니다.
  • securityContext.runAsNonRoot: true: 컨테이너가 루트 사용자로 실행되지 않도록 합니다.
  • securityContext.capabilities.drop: ["ALL"]: 모든 Linux 기능을 컨테이너에서 삭제합니다.
  • resources.limits: 서비스 거부 (DoS) 시나리오를 방지하려면 CPU 및 메모리 한도를 지정해야 합니다.
  • 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을 만들어 샌드박스 환경을 배포하려면 다음 단계를 완료하세요.

  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은 웜 풀에서 샌드박스를 요청합니다. 웜 풀을 만들었으므로 생성된 샌드박스는 새 포드를 시작하는 대신 풀에서 실행 중인 포드를 채택합니다.

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
    

v1alpha1에서 v1beta1로 에이전트 샌드박스 마이그레이션

v1alpha1 커스텀 리소스를 사용하여 이전 버전의 에이전트 샌드박스로 클러스터를 배포한 경우 워크로드 다운타임이 거의 없는 GKE 버전 1.36.3-gke.1767000 이상으로 업그레이드할 수 있습니다.

참고: 이 마이그레이션 절차는 관리형 GKE 에이전트 샌드박스 기능 (--enable-agent-sandbox)을 사용하는 클러스터에 적용됩니다. 오픈소스 매니페스트를 사용하여 에이전트 샌드박스를 배포한 경우 업스트림 마이그레이션 가이드를 참조하세요.

v1alpha1v1beta1 간의 주요 API 차이점

개념 v1alpha1 동작 v1beta1 동작 마이그레이션 영향
SandboxClaim 타겟 웜 풀 (콜드 스타트) 없이 SandboxTemplate에 대한 직접 참조를 허용합니다. SandboxWarmPool (spec.warmPoolRef.name)에 대한 참조가 필요 합니다. 콜드 스타트 클레임은 섀도우 웜 풀 (replicas: 0)에 매핑되어야 합니다.
샌드박스 작동 모드 복제본 또는 상태 필드에서 유추됩니다. spec.operatingMode 필드의 명시적 값 (예: Running 또는 Paused) 변환 웹훅이 이 필드를 자동으로 매핑하고 설정합니다.
CRD 스토리지 버전 etcd에 저장된 v1alpha1 (storage: true) etcd에 저장된 v1beta1 (storage: true) 웹훅이 동적으로 변환합니다. 업그레이드 후 단계에서 etcd 객체를 다시 유지합니다.
변환 웹훅 없음 /convert (포트 9447)에서 활성 v1alpha1v1beta1 간의 양방향 변환

마이그레이션 도구를 사용하여 마이그레이션

섀도우 웜 풀을 자동으로 만들고 스토리지를 다시 유지하려면 에이전트 샌드박스 저장소의 정식 마이그레이션 스크립트를 사용하세요.

스크립트를 다운로드하고 준비합니다.

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

단계별 마이그레이션 런북

워크로드 다운타임이 거의 없는 기존 클러스터를 마이그레이션하려면 다음 세 단계를 순서대로 완료하세요.

1단계: 업그레이드 전 부트스트랩 단계

  1. 기존 리소스 백업: 클러스터의 모든 에이전트 샌드박스 커스텀 리소스의 YAML 백업을 저장합니다.

    kubectl get sandboxtemplates,sandboxwarmpools,sandboxclaims,sandboxes \
        --all-namespaces -o yaml > agent-sandbox-v1alpha1-backup.yaml
    
  2. 템플릿 보안 규정 준수 확인: 기존 SandboxTemplate 리소스가 에이전트 샌드박스 배포 요구사항을 충족하는지 확인합니다. 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

컨트롤 플레인 출시 중에 다음 사항에 유의하세요.

  • 포드에 재시작 또는 다운타임이 발생하지 않습니다.
  • 새 컨트롤러 및 /convert 웹훅 엔드포인트가 컨트롤 플레인에 배포됩니다.

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"]
포드 연속성 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 경고 없이 적용됩니다.

에이전트 샌드박스 사용 중지

에이전트 샌드박스 기능을 사용 중지하려면 --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)입니다.

다음 단계