
신뢰할 수 없는 코드, 신뢰할 수 있는 클러스터: GKE Agent Sandbox를 통한 보안 AI 에이전트 워크스페이스 확장
요약
AI 에이전트가 생성한 코드를 안전하게 실행하기 위한 GKE Agent Sandbox 기술을 소개합니다. gVisor를 활용한 커널 레벨 격리를 통해 프롬프트 인젝션이나 컨테이너 탈출 위협으로부터 클러스터를 보호하는 방법을 다룹니다.
핵심 포인트
- gVisor 기반 커널 레벨 격리로 LLM 생성 코드 보안 강화
- 1초 미만의 빠른 샌드박스 프로비저닝 지원
- Kubernetes 네이티브 환경에서의 확장성 및 보안성 확보
- 멀티 테넌트 에이전트 시스템을 위한 안전한 워크로드 실행
gVisor 기반의 샌드박스가 어떻게 커널 레벨에서 AI가 생성한 코드를 격리하는지, 그리고 이것이 왜 멀티 테넌트 (multi-tenant) 에이전트 시스템의 모든 것을 바꾸는지 알아봅니다.
이 기사에서는 아래의 사항들에 대해 논의할 것입니다.
AI 에이전트가 코드를 작성할 때 발생하는 문제
GKE Agent Sandbox란 무엇인가?
gVisor가 커널을 가로채는 방식
아키텍처 심층 분석 (Architecture deep dive)
설정 방법: 단계별 가이드
프로덕션 패턴 (Production patterns)
결론
AI 에이전트를 실행하는 모든 엔지니어가 결국 직면하게 되는 순간이 있습니다. LLM (Large Language Model)이 매우 그럴듯한 subprocess.run() 호출을 생성하고, 이를 bash -c로 파이프 연결하는 것을 보고, 단 한 번의 프롬프트 인젝션 (prompt injection)만으로 컨테이너 탈출 (container escape)이 일어날 수 있음을 깨닫는 순간입니다. 코드는 합리적으로 보입니다. 에이전트는 자신을 신뢰합니다. 그리고 클러스터의 폭발 반경 (blast radius)은 방금 모두의 문제가 되었습니다.
이것이 에이전트 시대의 결정적인 보안 문제입니다. 언어 모델은 더 이상 텍스트만 생성하지 않습니다. 이들은 긴밀한 피드백 루프 내에서 코드를 작성하고, 실행하며, 반복합니다. 이들을 유용하게 만드는 능력(제한 없는 Python, 쉘 접근, 파일 I/O)은 공유 클러스터 내에서 이들을 위험하게 만드는 바로 그 능력입니다.
Google의 해답 — GKE Agent Sandbox
GKE Agent Sandbox는 높은 수준의 확장성, 확장성 및 보안이 필요한 에이전트 워크로드(agentic workloads)를 위해 구축되었습니다. 주요 이점은 다음과 같습니다:
커널 레벨 격리 (Kernel-level isolation): GKE Sandbox와 같은 내장된 GKE 기능을 사용하여 신뢰할 수 없는 LLM 생성 코드에 대해 강력한 커널 레벨 격리를 제공합니다. Agent Sandbox는 오픈 소스인 Kata Containers 소프트웨어도 지원합니다.
초 단위 미만의 프로비저닝 (Sub-second provisioning): 표준 Kubernetes Pod 스케줄링이 허용하는 것보다 훨씬 빠른(통상적으로 1초 미만) 샌드박스를 제공하는 즉시 사용 가능한 메커니즘을 제공합니다.
클라우드 네이티브 확장성 (Cloud-native extensibility): Kubernetes 패러다임의 강력함과 GKE의 관리형 인프라를 활용합니다.
GKE Agent Sandbox는 선언적이고 표준화된 API를 제공함으로써, 완전히 Kubernetes 기본 요소(Primitives)를 기반으로 구축되었으면서도 가상 머신 (VM)과 유사한 격리 및 지속성 특성을 제공하는 단일 컨테이너 경험을 제공합니다.
AI 에이전트의 코드 작성 문제
LangGraph, AutoGen, Claude의 도구 사용(tool-use) API를 사용하여 구축하든, 직접 구현하든 상관없이 에이전트형 AI (Agentic AI) 시스템은 공통된 아키텍처 패턴을 공유합니다. 즉, 모델이 코드를 생성하고, 런타임(Runtime)이 이를 실행하며, 결과가 모델로 다시 전달되는 루프가 지속되는 방식입니다. 각 반복 과정에서 모델은 무엇이 성공하고 무엇이 실패했는지에 대해 더 넓은 문맥(Context)을 갖게 됩니다. 이는 복잡한 작업을 자동화하는 데 엄청난 위력을 발휘합니다.
하지만 이는 기존의 Kubernetes 보안이 처리하도록 설계되지 않았던 공격 표면(Attack surface)을 생성하기도 합니다.
컨테이너 탈출 (Container escape)
LLM이 생성한 코드는 알려진 커널 취약점이나 잘못 설정된 권한(Capabilities)을 악용하여 컨테이너 경계를 벗어납니다.
코드 출력을 통한 프롬프트 인젝션 (Prompt injection via code output)
검색된 데이터 내의 악성 콘텐츠는 에이전트가 공격자가 제어하는 페이로드(Payload)를 실행하도록 조작하는 명령을 삽입합니다.
측면 네트워크 이동 (Lateral network movement)
네트워크 접근 권한이 있는 에이전트는 합법적인 것처럼 보이는 Python 요청을 통해 내부 서비스를 열거하고, 자격 증명(Credentials)을 추출하며, 클러스터 전체로 피벗(Pivot)할 수 있습니다.
파일 시스템 데이터 유출 (Filesystem exfiltration)
마운트 제한이 없다면, 에이전트는 서비스 계정 토큰, 볼륨으로 마운트된 Kubernetes 비밀(Secrets), 그리고 호스트 경로 데이터를 읽을 수 있습니다.
표준 컨테이너 보안인 securityContext, 네트워크 정책(Network policies), Pod 보안 승인(Pod Security Admission)은 심층 방어(Defense in depth)를 제공하지만 근본적인 문제는 해결하지 못합니다. 바로 컨테이너가 호스트 커널을 공유한다는 점입니다. 커널에 취약점이 있다면, 충분한 동기를 가진 공격자(또는 충분한 능력을 갖춘 LLM)는 네임스페이스 격리(Namespace isolation)와 관계없이 이를 악용할 수 있습니다.
GKE Agent Sandbox란 무엇인가?
GKE Agent Sandbox는 에이전트형 AI (Agentic AI) 워크로드에 특화되어 조정된 gVisor 기반 컨테이너 샌드박싱 (Sandboxing)을 적용하는 Google 관리형 노드 풀 (Node pool) 구성입니다.
그 핵심은 다음 세 가지를 결합한 것입니다:
기본 OCI 런타임으로서의 gVisor 런타임 (runsc)
샌드박스 노드 풀의 모든 컨테이너는 표준 runc 대신 runsc 하에서 실행됩니다. 이는 Sentry라고 불리는 사용자 공간 커널 (User-space kernel) 구현을 통해 모든 시스템 호출 (Syscalls)을 가로챕니다.
에이전트 전용 리소스 격리 프로필
AI 에이전트가 흔히 생성하는 Python/Node.js/컨테이너 인 컨테이너 (Container-in-container) 워크로드에 최적화된 사전 구성된 seccomp 및 AppArmor 프로필을 제공합니다. 일반적인 사용 사례를 위해 시스템 호출 허용 목록 (Allowlists)을 수동으로 조정할 필요가 없습니다.
Cloud Monitoring을 통한 통합 관찰성 (Observability)
시스템 호출 감사 로그 (Syscall audit logs), 샌드박스 위반 이벤트
gVisor를 사용하면, 동일한 시스템 호출 (syscalls)들이 사용자 공간 (user space)에서 완전히 실행되는 Linux 커널의 Go 구현체인 Sentry에 의해 가로채집니다. Sentry는 Linux ABI를 처음부터 구현합니다. 에이전트 코드가 execve()를 호출하면, 호스트 커널이 아닌 Sentry가 이를 처리합니다. 그런 다음 Sentry는 메모리 매핑 (memory mapping) 및 스케줄링 (scheduling)과 같은 작업을 처리하기 위해 "플랫폼 (platform)"이라고 불리는 제한된 인터페이스를 통해 실제 호스트 커널에 훨씬 더 작은 집합의 호출을 보냅니다.
엔드 투 엔드 아키텍처 청사진 (End-to-End Architectural Blueprint)
높은 응답성을 가진 관리 평면 (management plane)을 유지하면서 신뢰할 수 없는 코드 실행을 격리하기 위해, 아키텍처는 클러스터를 두 개의 별개이며 특화된 노드 풀 (node pools)로 분리합니다.
표준 노드 풀 (Standard Node Pool, The Brain)
- 이 풀은 신뢰할 수 있고 수명이 긴 오케스트레이션 (orchestration) 서비스들을 실행합니다. 이 코드는 팀에 의해 작성되고 감사 (audit)되었으므로, 최대 성능과 내부 클러스터 리소스에 대한 네이티브 액세스를 위해 표준 Linux 호스트 커널에서 실행됩니다.
- 에이전트 컨트롤러 (Agent Controller): AI 에이전트 작업의 생명 주기, 시작 시간 (spin-up times), 상태 추적을 관리하는 핵심 엔진입니다.
- 툴 라우터 (Tool Router): 외부 API 호출을 중재하고 에이전트에 노출되는 기능(예: 웹 검색, 데이터베이스 쿼리)을 관리합니다.
- 결과 수집기 (Result Collector): 런타임 포드 (runtime pods)로부터 출력, 로그 및 상태 변경 사항을 집계합니다.
- 상태 및 스토리지 (State & Storage, Postgres/Redis): 세션 메모리 및 에이전트 상태를 추적하는 고가용성 데이터 계층입니다.
Agent Sandbox 노드 풀 (The Muscle) - 이 노드 풀은 AI 모델이 생성한 신뢰할 수 없는 코드를 실행하는 데 전적으로 전용됩니다. 엄격한 커널 수준 격리를 강제하기 위해 runtimeClassName: gvisor 설정을 사용합니다.
- 코드 실행 Pod ($N$ Pods): 생성된 특정 코드 스니펫을 실행하기 위해 생성되고, 실행 후 즉시 종료되도록 설계된 휘발성(Ephemeral) 및 빠른 순환(Rapid-churn) Pod입니다.
- Sentry (사용자 공간 커널): gVisor의 핵심 구성 요소입니다. Python 에이전트가 표준 시스템 호출(syscall())을 통해 호스트 Linux 커널과 직접 통신하게 하는 대신, Sentry가 이를 가로챕니다. Sentry는 사용자 공간(User-space)에서 Linux 커널의 핵심 프리미티브(Primitives) 세트를 구현하여, 컨테이너 탈출(Container escape) 취약점으로부터 호스트 베어메탈(Bare-metal) 또는 VM 인프라를 보호합니다.
Workload Identity 및 RBAC 분리
Kubernetes 서비스 계정(KSA)을 분리하고 이를 별도의 Google Cloud IAM 서비스 계정에 매핑함으로써, 에이전트가 침해당하더라도 권한 상승(Privilege escalation)의 위험을 제거합니다.
관측성(Observability) 및 행동 분석
샌드박스 런타임은 본질적으로 적대적인 환경이므로, 관측성의 초점은 표준 애플리케이션 성능 모니터링(APM)에서 실시간 행동 및 보안 감사(Auditing)로 전환됩니다.
시스템 호출(Syscall) 감사 로그: gVisor는 내부 로깅 메커니즘을 통해 가로챈 시스템 호출에 대한 구조화된 로그를 제공합니다. 비정상적인 시스템 호출(예: 금지된 네트워크 프로토콜 호출 시도 또는 직접적인 raw socket 조작 등)은 즉시 Cloud Logging으로 스트리밍됩니다.
위반 이벤트 (Violation Events): 샌드박스 처리된 컨테이너가 Sentry를 우회하거나 유효하지 않은 작업을 실행하려는 모든 시도는 즉각적인 격리 이벤트 (containment event)를 트리거하며, 이는 Google Cloud Security Command Center에 직접 표시됩니다.
Cloud Monitoring: 컨테이너 수준의 메트릭 (CPU, Memory, Churn rate)을 집계합니다. 이는 AI 에이전트 작업으로 위장한 악성 무한 루프 또는 리소스 고갈 (DDoS) 시도를 탐지하는 데 매우 중요합니다.
Cloud Trace: 엔드 투 엔드 분산 트레이싱 (End-to-end distributed tracing)을 통해 요청이 Tool Router를 통해 라우팅되는 데 걸리는 시간과 gVisor 샌드박스 내부에서 실행되는 데 걸리는 시간을 정확하게 매핑하여, 사용자 공간 컨텍스트 스위칭 (user-space context switching)으로 인해 발생하는 성능 오버헤드를 미세 조정할 수 있습니다.
설정 방법: 단계별 안내
새로운 GKE 클러스터에서 실행 중인 샌드박스 에이전트 워크로드에 이르기까지의 전체 과정을 안내합니다. 이 과정은 프로젝트를 위해 gcloud, kubectl, Terraform이 구성되어 있다고 가정합니다.
프로덕션 패턴
패턴 1: 사전 포크된 실행기(pre-forked executors)를 포함한 웜 풀(Warm pool)
코드 실행마다 새로운 포드(pod)를 콜드 스타트(Cold-starting)하면 지연 시간 (latency)이 추가됩니다. 표준 패턴은 작업 큐 (Pub/Sub 또는 Redis Streams)를 통해 작업을 대기하는 웜 실행기 포드 (warm executor pods) 풀을 유지하는 것입니다. 컨트롤러는 유휴 상태인 실행기에 코드 스니펫을 전달하며, 완료된 실행기는 환경을 초기화하고 다시 풀로 돌아갑니다. 상태 누적을 방지하기 위해 가비지 컬렉션 사이드카 (garbage collection sidecar)가 너무 오래 웜 상태를 유지한 포드를 재시작합니다.
패턴 2: 실행 예산 강제 적용 (Execution budget enforcement)
AI 에이전트는 무한 루프 (infinite loops)에 빠질 수 있습니다. Kubernetes 리소스 제한 (resource limits)을 넘어, Python의 signal.alarm 또는 Go의 context cancellation을 사용하여 애플리케이션 수준의 타임아웃 (timeout)을 적용하십시오. 10초의 CPU 시간 예산 (CPU-time budget)을 가진 30초의 실제 시간 (wall-clock) 타임아웃은, 풀 용량 (pool capacity)을 소모하는 폭주 루프를 방지하는 동시에 거의 모든 정당한 에이전트 코드 실행 패턴을 커버할 수 있습니다.
패턴 3: 에이전트 유형별 네트워크 송신 허용 목록 (Network egress allow-listing)
서로 다른 에이전트 페르소나 (agent personas)는 서로 다른 정당한 네트워크 요구 사항을 가집니다. 데이터 분석 에이전트는 BigQuery 및 GCS에 대한 액세스가 필요합니다. 웹 리서치 에이전트는 공용 인터넷으로의 HTTP 송신 (egress)이 필요합니다. 코드 리뷰 에이전트는 둘 다 필요하지 않습니다. 에이전트 라벨 (agent label)별로 별도의 네트워크 정책 (NetworkPolicies)을 사용하여 이를 모델링하고, PodSpec 라벨을 사용하여 스케줄링 (scheduling) 시점에 에이전트를 올바른 정책에 바인딩하십시오.
결론
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기


