1. 소개
개요
이 실습에서는 Eventarc 및 Pub/Sub 서비스를 사용하여 Cloud Run에 배포된 ADK 에이전트의 이벤트 기반 호출을 안전하게 구현하는 방법을 보여줍니다. 대부분의 경우 사용자가 직접 또는 다른 상담사가 상담사를 호출합니다. 하지만 에이전트가 기존 이벤트 기반 워크플로에 통합되는 경우 직접 호출하려면 기존 소프트웨어를 변경해야 합니다. 이벤트를 기반으로 에이전트 호출을 트리거하면 워크플로를 변경하지 않고도 기존 워크플로에 에이전트를 통합할 수 있습니다.
실습할 내용
이 실습에서는 AI 에이전트가 있고 몇 가지 도구를 사용하여 가상의 동물원에 있는 동물에 관한 정보를 제공하는 ZooKeeper 에이전트 애플리케이션을 만듭니다.

ZooKeeper 애플리케이션을 Cloud Run에 서비스로 배포합니다. Cloud Run은 Google 인프라에서 상태 비저장 컨테이너를 실행하는 완전 관리형 서버리스 컴퓨팅 플랫폼입니다. 그런 다음 Pub/Sub 주제에 게시된 메시지를 비동기적으로 처리하기 위해 서비스 엔드포인트를 호출하는 Eventarc 트리거를 설정합니다. 지정된 IAM 서비스 계정을 사용하고, 최소 권한 액세스를 부여하고, ZooKeeper 애플리케이션의 엔드포인트를 Eventarc에만 노출하여 잠재적인 공격 표면을 최소화하는 등 배포가 권장사항을 따르도록 합니다. Cloud Shell 및 Cloud 콘솔을 사용하여 이 작업을 수행합니다. Python용 ADK 및 Cloud SDK 라이브러리를 사용합니다. gcloud CLI를 사용하여 동작을 확인합니다.
학습할 내용
- Google Cloud Run에 ADK 에이전트를 배포합니다.
- Google Cloud Run에서 실행되는 ADK 에이전트와 Eventarc 트리거를 통합합니다.
- Google Cloud IAM을 사용하여 최소 권한 액세스 원칙에 따라 Eventarc를 사용하여 배포 및 통합을 보호합니다.
- Pub/Sub에서 메시지를 게시하고 가져옵니다.
- Google Cloud Run에 배포된 애플리케이션의 공개 노출을 최소화합니다.
필요한 항목
- Chrome 웹브라우저 †
- 개인 Google 계정 ‡
- 활성 결제 계정에 연결된 Google Cloud 프로젝트
계정에 리소스를 프로비저닝하고 이러한 리소스에 대한 IAM 액세스를 구성할 수 있는 프로젝트에 대한 IAM 액세스 권한이 있어야 합니다.
† 다른 브라우저를 사용하는 사용자 환경은 실습에 설명된 환경과 다를 수 있습니다.
‡ 회사 또는 학교 계정을 사용하는 경우 실습에 설명된 일부 작업을 수행하는 데 제한이 있을 수 있습니다.
2. 환경 설정
실습을 위한 완전한 기능을 갖춘 개발 환경을 보장하기 위해 필요한 모든 도구가 사전 설치된 Google Cloud Shell을 사용합니다. 안내에 따라 환경을 설정합니다.
Google 계정이 없으면 Google 계정을 만듭니다.
설정 안내
- Google 계정으로 Google Cloud 콘솔에 로그인합니다.
- 👉 상단 탐색 메뉴에서 프로젝트 선택기를 열거나('프로젝트 선택'이라고 표시되거나 기존 프로젝트 이름이 표시될 수 있음)
Ctrl+O단축키를 클릭하고 기존 프로젝트를 선택하거나 새 프로젝트를 만듭니다.새 프로젝트를 만드는 데 몇 초가 걸립니다. 준비될 때까지 기다린 후 프로젝트 선택기를 사용하여 선택합니다.
- 👉 Google Cloud 콘솔 상단에 있는 Cloud Shell 아이콘을 클릭합니다. (빨간색 사각형으로 표시됨):

메시지가 표시되면 팝업 대화상자에서 **승인** 을 클릭하여 Cloud Shell이 계정의 사용자 인증 정보를 사용하도록 승인합니다.
- 👉💻 gcloud CLI가 선택한 (또는 만든) 프로젝트를 사용하도록 구성되어 있는지 확인합니다. 다음 명령어를 실행하여 구성된 프로젝트 ID를 확인합니다.
다음과 비슷한 출력이 표시됩니다.gcloud config get-value project 여기서Your active configuration is: [cloudshell-19597] [PROJECT_ID]
[PROJECT_ID]는 선택하거나 만든 프로젝트의 ID입니다.👉💻 다른 값이 표시되면 다음 명령어를 실행하여 프로젝트 ID를 gcloud CLI 명령어의 기본 프로젝트 ID로 구성합니다. 예를 들어 프로젝트 ID가 lab-project-id-example-123이면 명령어는 다음과 같습니다.gcloud config set project [YOUR_PROJECT_ID] 🤔💻 프로젝트 ID가 기억나지 않으면 다음 명령어를 사용하여 액세스할 수 있는 모든 프로젝트 ID를 최신순으로 나열하세요.gcloud config set project lab-project-id-example-123
gcloud projects list \ --format='value(projectId)' \ --sort-by='~createTime'
- 👉💻 환경 변수에서 리소스 프로비저닝 위치와 프로젝트 ID 및 번호를 설정합니다.
export LOCATION="us-central1" export PROJECT_ID=$(gcloud config get-value project) export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)") - 👉💻 이 실습에 필요한 Google API를 사용 설정합니다.
이 명령어는 몇 분 정도 걸릴 수 있습니다. 명령어가 성공적으로 실행되면 다음과 유사한 메시지가 표시됩니다.gcloud services enable \ aiplatform.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ pubsub.googleapis.comOperation "operations/ab12345c-6e7f-8ghi-jkl9-m0e1d23456f7" finished successfully.
3. ZooKeeper 데모 애플리케이션 배포
다음 단계에서는 에이전트 기반 AI 애플리케이션 배포를 비롯한 리소스를 프로비저닝하고 구성합니다.
Pub/Sub 리소스 설정
Pub/Sub 주제 2개를 만듭니다. 하나는 서드 파티 서비스가 에이전트 AI 애플리케이션에 이벤트를 전송하는 데 사용됩니다. 이벤트 처리 결과를 게시하는 애플리케이션용
- 👉💻 에이전트형 AI 애플리케이션을 트리거하는 데 사용되는 Pub/Sub 주제를 만듭니다.
gcloud pubsub topics create invoke_agent export INVOKE_TOPIC_ID=$(gcloud pubsub topics describe invoke_agent --format="value(name)") - 👉💻 애플리케이션이 응답을 게시할 수 있는 Pub/Sub 주제를 만듭니다.
이 명령어는 생성된 Pub/Sub 주제에 대한 구독도 만듭니다. 데모를 실행할 때 결과를 보는 방법으로 구독이 사용됩니다.gcloud pubsub topics create agent_responses export RESPONSE_TOPIC_ID=$(gcloud pubsub topics describe agent_responses --format="value(name)") gcloud pubsub subscriptions create agent_responses \ --topic=agent_responses
서비스 계정 및 프로젝트 수준 IAM 정책 설정
최소 권한 액세스 원칙에 따라 Cloud Run 서비스와 Eventarc 트리거의 액세스 범위를 최소로 제한하기 위해 서비스 계정을 두 개 만듭니다. Cloud Run 서비스에는 로그 및 트레이스를 작성하고, Google Vertex AI에서 Gemini LLM을 호출하고, 결과를 Pub/Sub 주제에 게시할 수 있는 권한이 필요합니다. Eventarc 트리거의 최소 액세스에는 Cloud Run ZooKeeper 서비스를 호출하고 게시된 이벤트를 읽기 위해 Pub/Sub에 액세스할 수 있는 권한이 필요합니다. 이 안내에서는 Pub/Sub 시스템 서비스를 가장하는 데 필요한 권한을 트리거의 서비스 계정에 부여하는 방법을 설명합니다. Eventarc 트리거 리소스를 만든 후 트리거의 서비스 계정이 Cloud Run 서비스를 호출할 수 있도록 roles/run.invoker 역할을 부여하는 명령어를 실행합니다.
- 👉💻 Cloud Run 서비스의 서비스 계정을 만듭니다.
gcloud iam service-accounts create zookeeper-cloudrun-sa export ZOOKEEPER_SA="zookeeper-cloudrun-sa@${PROJECT_ID}.iam.gserviceaccount.com" - 👉💻 로그 및 트레이스를 작성하고 Vertex AI에서 Gemini 모델을 사용할 수 있는 권한을 서비스 계정에 부여합니다.
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:${ZOOKEEPER_SA}" \ --role="roles/logging.logWriter" \ --condition=None gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:${ZOOKEEPER_SA}" \ --role="roles/cloudtrace.agent" \ --condition=None gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:${ZOOKEEPER_SA}" \ --role="roles/aiplatform.user" \ --condition=None - 👉💻 'agent_responses' 주제에 메시지를 게시할 권한이 있는 서비스 계정에 권한을 부여합니다.
gcloud pubsub topics add-iam-policy-binding agent_responses \ --member="serviceAccount:${ZOOKEEPER_SA}" \ --role="roles/pubsub.publisher" - 👉💻 Eventarc 트리거의 서비스 계정을 만듭니다.
gcloud iam service-accounts create zookeeper-trigger-sa export TRIGGER_SA="zookeeper-trigger-sa@${PROJECT_ID}.iam.gserviceaccount.com" - 👉💻 인증된 푸시 요청을 할 수 있는 권한을 Pub/Sub 시스템 서비스 계정에 부여합니다.
프로젝트가 2021년 4월 8일 이후에 생성된 경우 이 명령어는 선택사항입니다.gcloud iam service-accounts add-iam-policy-binding "${TRIGGER_SA}" \ --member="serviceAccount:service-${PROJECT_NUMBER}@gcp-sa-pubsub.iam.gserviceaccount.com" \ --role="roles/iam.serviceAccountTokenCreator"
ZooKeeper 앱을 Cloud Run에 배포
GitHub에서 데모 애플리케이션의 코드를 다운로드합니다. 코드를 Cloud Run에 배포합니다.
- 👉💻 에이전트 AI 애플리케이션 다운로드:
이 명령어는 데모 앱이 있는 폴더의 Git 스파스 체크아웃을 사용하여 다운로드 시간을 줄입니다.mkdir zoo-keeper-lab && cd zoo-keeper-lab git init git remote add origin https://github.com/GoogleCloudPlatform/devrel-demos git config set core.sparseCheckout true echo "ai-ml/agent-labs/adk_invoke_with_pubsub/" >> .git/info/sparse-checkout git pull origin main --depth 1 cd ai-ml/agent-labs/adk_invoke_with_pubsub/ - 👉💻 에이전트형 AI 애플리케이션을 Cloud Run에 배포합니다.
gcloud run deploy zookeeper-agent \ --region="${LOCATION}" \ --source="." \ --no-allow-unauthenticated \ --quiet \ --service-account="${ZOOKEEPER_SA}" \ --set-env-vars="REPLY_TOPIC_ID=${RESPONSE_TOPIC_ID}"
Eventarc 트리거 구성
모든 리소스 (Pub/Sub 주제, IAM 서비스 계정, Cloud Run 서비스)를 준비한 후에는 Eventarc 트리거 리소스를 설정할 차례입니다. Eventarc 트리거 리소스를 만들고 트리거의 서비스 계정에 Cloud Run 서비스를 호출할 권한을 부여합니다.
- 👉💻 Eventarc 트리거를 만듭니다.
gcloud eventarc triggers create invoke-agent \ --location="${LOCATION}" \ --destination-run-service="zookeeper-agent" \ --destination-run-path="/zookeeper" \ --destination-run-region="${LOCATION}" \ --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \ --transport-topic="${INVOKE_TOPIC_ID}" \ --service-account="${TRIGGER_SA}" - 👉💻 트리거의 서비스 계정에 Cloud Run 서비스를 호출할 수 있는 권한을 부여합니다.
gcloud run services add-iam-policy-binding zookeeper-agent \ --region="${LOCATION}" \ --member="serviceAccount:${TRIGGER_SA}" \ --role="roles/run.invoker"
4. 솔루션 작동 방식 검토
이제 방금 배포한 내용을 검토합니다. 다음 다이어그램은 모든 리소스와 리소스 간의 상호작용을 보여줍니다. gcloud CLI를 사용하여 'invoke_agent' 주제에 메시지를 게시합니다. 이렇게 하면 에이전트 AI 애플리케이션을 호출하기 위해 서드 파티 서비스가 메시지 서비스에 로깅하는 이벤트가 시뮬레이션됩니다.

배포는 최소 권한 액세스를 따라 보호됩니다. Cloud Run 서비스는 인증을 적용합니다 (이전 섹션의 9단계에 나오는 --no-allow-unauthenticated 인수 참고). 역할/run.invoker 또는 유사한 권한이 있는 ID만 서비스를 호출할 수 있습니다. 이 역할은 Eventarc 트리거의 서비스 계정에만 부여됩니다. 마찬가지로 'invoke_agent' 주제에 대한 액세스는 이벤트의 무단 게시를 허용하지 않도록 최소화됩니다. Pub/Sub 주제에 게시하는 것을 우회하여 ZooKeeper 에이전트를 직접 호출할 수는 있습니다. 공개 액세스에서 애플리케이션의 엔드포인트를 숨기는 방법은 섹션 6을 참고하세요.
워크플로 실행
자연어로 된 질문을 ZooKeeper에 게시하여 외부 이벤트를 에뮬레이션합니다.
👉💻 다음 명령어를 사용하여 Pub/Sub 주제에 메시지를 게시합니다.
gcloud pubsub topics publish invoke_agent \
--message='{"user_id": "important_app", "prompt": "How many animals are in the zoo?"}'
실제로 이벤트 정보는 가독성이 떨어지는 형식일 수 있습니다. 이를 처리하려면 에이전트 AI 애플리케이션에 이벤트 형식, 데이터, 에이전트가 이벤트 정보를 사용하여 해야 할 일에 관한 자세한 안내가 있어야 합니다.
에이전트가 이벤트를 수신하고 요청을 처리하고 'agent_responses' 주제에 응답을 게시했는지 확인할 수 있습니다. 응답을 읽으려면 'agent_responses' 구독을 사용합니다 (Codelab에서는 응답의 주제와 구독에 동일한 ID를 사용함).
👉💻 다음 명령어를 사용하여 Pub/Sub 구독에서 에이전트의 응답을 읽습니다.
gcloud pubsub subscriptions pull agent_responses --auto-ack
출력에는 메시지 메타데이터와 동물원에 33종이 있다는 대답이 포함된 페이로드가 있는 표가 출력됩니다. --auto-ack 플래그는 메시지가 가져온 후 자동으로 확인하므로 다시 전송되지 않습니다.
작동 방식
Cloud Shell 편집기를 열고 ~/zoo-keeper-lab 폴더 아래의 파일을 확인하여 에이전트형 AI 애플리케이션의 소스 코드를 확인합니다. GitHub에서 소스 코드를 확인할 수도 있습니다.
- main.py는 Eventarc 이벤트를 처리하는 단일 핸들러가 있는 기본 FastAPI 웹 애플리케이션을 구현합니다.
- processor.py는 이벤트의 메시지를 파싱하여 사용자 ID와 요청을 가져옵니다. 그런 다음 ADK 러너에서 새 세션을 만들고 Zookeeper 에이전트를 호출하여 요청을 처리합니다. 상담사의 응답이 'agent_responses' Pub/Sub 주제에 게시됩니다.
- zookeeper_agent 하위 폴더에는 ADK 에이전트의 소스 코드가 있습니다. 애플리케이션의 루트 폴더에서
adk run zookeeper_agent명령어를 실행하여 adk CLI를 사용하여 에이전트와 상호작용할 수 있습니다.
문제 해결 방법
이전 명령어 중 하나라도 실패하면 오류 메시지를 주의 깊게 읽으세요. Cloud Run에 배포가 실패하면 프로세스의 어느 단계에서 실패가 발생했는지 확인하는 것이 첫 번째 단계입니다.
- 'gcloud run deploy...' 명령어의 출력에 빌드가 실패했다고 보고되면 출력에서 빌드 로그 URL을 확인하고 별도의 창에서 엽니다.
- 출력에 '서비스를 시작하지 못했습니다'와 같은 메시지가 표시되면 서비스가 배포되지만 실행 시 상태 점검이 실패한 것입니다. 이 경우 로그 탐색기를 열거나 다음 단락에서 gcloud CLI 명령어를 확인하세요. 로그를 읽어 실패의 근본 원인을 찾습니다.
Pub/Sub에 메시지를 게시했지만 상담사가 응답하지 않거나 응답이 이상한 경우 어떻게 해야 하나요?
👉💻 다음 명령어를 사용하여 최근 실행에서 게시된 애플리케이션 로그를 읽습니다.
gcloud logging read \
'resource.type = "cloud_run_revision" AND \
resource.labels.service_name = "zookeeper-agent" AND \
resource.labels.location = "us-central1"'
로그는 실행을 추적하고 잘못되거나 파싱할 수 없는 메시지 페이로드, Gemini 모델의 잘못된 응답, 잘못된 환경 설정 및 기타 가능한 문제와 같은 오류를 보고합니다.
5. 배포 보안 강화
배포한 Cloud Run 서비스는 인터넷의 모든 사용자가 호출할 수 있는 공개 엔드포인트를 노출합니다. 엔드포인트는 무단 호출로부터 보호되고 요청 구조를 엄격하게 검증하지만 서비스 거부 및 지갑 거부 공격을 허용하는 이 공격 벡터는 여전히 남아 있습니다. 현재 설계에서 서비스의 유일한 호출 경로는 Eventarc 트리거를 통하는 것이므로 서비스가 인터넷에 엔드포인트를 노출할 필요가 없습니다.
👉💻 Eventarc 트리거를 비롯한 제한된 소스 모음에서만 서비스 호출이 이루어지도록 제한하여 이 공격 벡터를 차단하세요.
gcloud run services update zookeeper-agent --region=${LOCATION} --ingress=internal
이제 로컬 머신에서 서비스의 URL을 호출하려고 하면 '404 페이지를 찾을 수 없음' 오류가 표시됩니다.
👉💻 curl을 사용하여 서비스 엔드포인트에 요청을 보냅니다.
URL=$(gcloud run services describe zookeeper-agent --region=${LOCATION} --format='value(status.url)')
curl -X POST -d '{}' "${URL}/zookeeper"
다음과 비슷한 출력이 표시됩니다.
<html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>404 Page not found</title> </head> <body text=#000000 bgcolor=#ffffff> <h1>Error: Page not found</h1> <h2>The requested URL was not found on this server.</h2> <h2></h2> </body></html>
이 변경사항이 적용된 후에는 동일한 프로젝트의 VPC, 수정 버전이 트래픽을 전송하도록 구성된 공유 VPC 네트워크 또는 VPC 서비스 제어 경계에 속한 호스트에서 호출하지 않는 한 Cloud Run 서비스 엔드포인트를 호출하여 ZooKeeper를 직접 호출할 수 없습니다.
6. 요약
축하합니다. 수신 이벤트에 의해 트리거되는 에이전트형 AI 애플리케이션을 비동기식으로 호출하는 환경을 설정했습니다.
삭제
프로비저닝한 리소스를 유지하면 결제 계정에 요금이 청구될 수 있습니다. 이 환경을 추가 실험에 사용하지 않을 계획이고 향후 요금이 청구되지 않도록 하려면 이 Codelab에서 만든 리소스를 삭제하는 것이 좋습니다.
다음과 같은 두 가지 방법이 있습니다.
방법 1: 프로젝트 종료
프로젝트를 종료 (삭제)하면 프로젝트의 모든 리소스와 데이터가 해제되고 결제 계정이 연결 해제됩니다. 이 방법을 사용하면 이 Codelab에 사용된 리소스나 데이터에 대한 추가 요금이 부과되지 않습니다. 다음 명령어를 사용하여 프로젝트를 종료합니다.
gcloud projects delete $(gcloud config get-value project) --quiet
방법 2: 프로젝트에서 리소스 삭제
Cloud Run 서비스를 삭제하면 서버리스 플랫폼 사용에 대한 추가 요금이 청구되지 않습니다. 이 방법은 Cloud Build 및 애플리케이션 로그, 컨테이너 이미지 등 Codelab 중에 생성된 모든 데이터를 완전히 삭제하지 않습니다. 다음 명령어를 실행하여 서비스를 삭제하세요.
gcloud run services delete zookeeper-agent --region=${LOCATION}
Eventarc 트리거 정의 및 Pub/Sub 주제에는 관리 비용이 부과되지 않습니다 (자세한 내용은 Eventarc 가격 책정 및 Pub/Sub 가격 책정 참고).
프로젝트 종료에 대해 자세히 알아보세요.
다음 단계
- GitHub에서 데모를 검토하여 코드에 대해 자세히 알아보세요.
- 이질적인 엔터프라이즈 시스템에 대한 액세스를 오케스트레이션하는 아키텍처 검토
- Eventarc 트리거를 사용하여 Cloud Run을 트리거하는 방법 알아보기
- ADK 자세히 알아보기