이 문서에서는 Google Kubernetes Engine (GKE) 클러스터에 개발자 환경을 배포하고 에이전트 샌드박스 Python 클라이언트를 사용하는 방법을 설명합니다.
에이전트 샌드박스 기능이 신뢰할 수 없는 AI 생성 코드를 격리하는 방법에 대한 개요는 GKE 에이전트 샌드박스 정보를 참고하세요.
비용
에이전트 샌드박스는 GKE에서 추가 비용 없이 제공됩니다. 생성하는 리소스에는 GKE 가격 책정이 적용됩니다.
시작하기 전에
-
Google Cloud 콘솔의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.
프로젝트를 선택하거나 만드는 데 필요한 역할
- 프로젝트 선택: 프로젝트를 선택하는 데는 특정 IAM 역할이 필요하지 않습니다. 역할이 부여된 프로젝트를 선택하면 됩니다.
-
프로젝트 만들기: 프로젝트를 만들려면
resourcemanager.projects.create권한이 포함된 프로젝트 생성자 역할(roles/resourcemanager.projectCreator)이 필요합니다. 역할 부여 방법 알아보기
Artifact Registry, Kubernetes Engine API를 사용 설정합니다.
API 사용 설정에 필요한 역할
API를 사용 설정하려면
serviceusage.services.enable권한이 포함된 서비스 사용량 관리자 IAM 역할(roles/serviceusage.serviceUsageAdmin)이 필요합니다. 역할 부여 방법 알아보기-
Google Cloud 콘솔에서 Cloud Shell을 활성화합니다.
- 이 가이드를 완료하는 데 필요한 권한이 있는지 확인합니다.
- 에이전트 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는 에이전트 샌드박스 컨트롤러가 일관된 사전 구성된 샌드박스 환경을 만드는 데 사용하는 재사용 가능한 청사진 역할을 합니다. SandboxWarmPool 리소스는 지정된 수의 사전 워밍 포드가 항상 실행되고 클레임할 준비가 되도록 합니다. 사전 워밍된 샌드박스는 이미 초기화된 실행 중인 포드입니다. 이 사전 초기화를 통해 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.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
샌드박스 테스트
모든 설정 구성요소가 준비되었으므로 이제 에이전트 샌드박스 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 Local!'").stdout) except Exception as e: print(f"An error occurred: {e}")가상 환경이 활성 상태인 터미널에서 테스트 스크립트를 실행합니다.
python3 test_sandbox.py
샌드박스에서 출력된 'Hello from the sandboxed environment!'라는 메시지가 표시됩니다.
수고하셨습니다 보안 샌드박스 내에서 셸 명령어를 실행했습니다. sandbox.run() 메서드를 사용하면 셸 명령어를 실행할 수 있으며, 에이전트 샌드박스는 클러스터의 노드와 기타 워크로드를 신뢰할 수 없는 코드로부터 보호하는 보안 장벽 내에서 명령어를 실행합니다. 이를 통해 AI 에이전트 또는 자동화된 워크플로가 작업을 실행하는 안전하고 신뢰할 수 있는 방법을 제공합니다.
스크립트를 실행하면 SandboxClient가 모든 단계를 처리합니다. 샌드박스를 시작하기 위해 SandboxClaim 리소스를 만들고 샌드박스가 준비될 때까지 기다린 다음 sandbox.run() 메서드를 사용하여 보안 컨테이너 내에서 bash 셸 명령어를 실행합니다. 그런 다음 클라이언트는 해당 명령에서 stdout를 캡처하여 출력합니다. 샌드박스는 프로그램이 실행된 후 자동으로 삭제됩니다.
SandboxClaim 리소스가 생성되면 사용 가능한 포드가 웜 풀에서 샌드박스 객체에 할당되고 클레임이 준비된 것으로 표시됩니다. 그러면 SandboxWarmPool가 구성된 복제본 수를 유지하기 위해 자동으로 자체 보충됩니다.
특정 샌드박스가 요청되었는지 또는 사용 가능한지 확인하려면 샌드박스 포드의 메타데이터에서 ownerReferences를 확인하세요. kind 필드의 값이 Sandbox이면 포드가 사용 중인 것입니다. kind 필드의 값이 SandboxWarmPool이면 포드가 유휴 상태이며 소유권 주장을 기다리고 있습니다.
프로덕션에서 샌드박스 실행
이 문서에서는 Cloud Shell을 사용하여 클러스터 외부에서 샌드박스와 상호작용합니다. Python 클라이언트는 사용자 인증 정보를 사용하여 클러스터에 인증하고 샌드박스 리소스를 관리하며 kubectl port-forward 명령어를 사용하여 샌드박스와 연결합니다. 이 단계는 개발 시나리오에 적합합니다.
프로덕션 시나리오에서 컨트롤러 애플리케이션 (예: AI 오케스트레이터)은 샌드박스 리소스를 만들고 관리할 책임이 있습니다. 프로덕션에서 에이전트 샌드박스를 사용하려면 다음 사항을 고려하세요.
인증: 컨트롤러 애플리케이션은 샌드박스를 실행하기 위해 클러스터 API 서버에 인증해야 합니다. 인증 구성 방법은 컨트롤러 애플리케이션이 실행되는 위치에 따라 다음과 같이 달라집니다.
- 컨트롤러 애플리케이션이 동일한 클러스터에서 포드로 실행되는 경우 IAM 정책과 함께 Kubernetes RBAC 또는 GKE용 워크로드 아이덴티티 제휴를 사용하여 포드의 Kubernetes ServiceAccount에 샌드박스를 모니터링하거나 네트워크 엔드포인트를 검색하는 데 필요한 권한을 부여합니다.
- 컨트롤러 애플리케이션이 클러스터 외부에서 실행되는 경우 워크로드 아이덴티티 제휴 또는 IAM 서비스 계정을 사용하여 허용 정책에서 참조할 수 있는 ID를 애플리케이션에 부여합니다.
라우팅: 컨트롤러 애플리케이션의 Python 클라이언트에서 보낸 요청이 클러스터의 샌드박스 라우터에 도달해야 합니다. 프로덕션에서는 다음 방법 중 하나를 사용하여 네트워크 연결을 설정합니다.
- 컨트롤러 애플리케이션이 동일한 클러스터에서 실행되는 경우
SandboxDirectConnectionConfig함수를 사용하여 샌드박스 라우터 서비스가 사용하는 URL과 포트를 타겟팅합니다. - 컨트롤러 애플리케이션이 클러스터 외부에서 실행되는 경우 GKE Gateway API를 사용하여 내부 또는 외부 부하 분산기를 만듭니다. 클라이언트 코드에서
SandboxGatewayConnectionConfig함수를 사용하여 게이트웨이를 참조합니다.
이러한 라우팅 방법에 관한 자세한 내용은 GitHub의 사용 예시 및 라우터의 게이트웨이 배포 단계를 참고하세요.
- 컨트롤러 애플리케이션이 동일한 클러스터에서 실행되는 경우
리소스에 대한 샌드박스 액세스 Google Cloud : 샌드박스 코드에서 Cloud Storage와 같은 Google Cloud API에 요청을 보내야 하는 경우 GKE용 워크로드 아이덴티티 제휴가 포함된 IAM 정책을 사용하여 샌드박스 포드에서 사용하는 Kubernetes ServiceAccount에 해당 액세스에 필요한 권한을 부여합니다.
리소스 삭제
Google Cloud 계정에 요금이 청구되지 않도록 하려면 만든 GKE 클러스터를 삭제해야 합니다.
gcloud container clusters delete $CLUSTER_NAME --location=$LOCATION --quiet
다음 단계
- 포드 스냅샷으로 에이전트 샌드박스 환경을 저장하고 복원하는 방법을 알아봅니다.
- GitHub에서 에이전트 샌드박스 오픈소스 프로젝트에 대해 자세히 알아보세요.
- 워크로드에 보안 격리를 제공하는 기본 기술을 알아보려면 GKE Sandbox를 참고하세요.
- 클러스터 및 워크로드의 보안 강화에 대한 자세한 내용은 GKE 보안 개요를 참고하세요.