Eventarc 및 Cloud Run 함수를 사용하여 Cloud Storage에서 이벤트 처리 트리거

1. 개요

이 실습에서는 Cloud Storage 버킷 이벤트와 Eventarc를 사용하여 이벤트 처리를 트리거하는 방법을 알아봅니다. Cloud Run 함수를 사용하여 데이터를 분석하고 이미지를 처리합니다. 이 함수는 Google의 Vision API를 사용하고 결과 이미지를 Cloud Storage 버킷에 다시 저장합니다.

424779013ac38648.png

학습할 내용

이미지 처리 파이프라인을 빌드하는 방법

  • 스토리지 버킷 구성
  • Cloud Storage에서 객체를 읽고 쓰는 Cloud Run 함수 만들기
  • Eventarc 트리거 배포
  • Vision API 통합을 통해 음식 이미지 감지
  • 엔드 투 엔드 솔루션 테스트 및 검증

기본 요건

  • 이 실습에서는 Cloud 콘솔 및 셸 환경에 익숙하다고 가정합니다.
  • 이전 Cloud Storage, Cloud Run 함수 또는 Vision API 경험이 있으면 유용하지만 필수는 아닙니다.

2. 설정 및 요구사항

Cloud 프로젝트 설정

  1. Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • 프로젝트 이름은 이 프로젝트 참가자의 표시 이름입니다. 이는 Google API에서 사용하지 않는 문자열이며 언제든지 업데이트할 수 있습니다.
  • 프로젝트 ID는 모든 Google Cloud 프로젝트에서 고유하며, 변경할 수 없습니다(설정된 후에는 변경할 수 없음). Cloud 콘솔은 고유한 문자열을 자동으로 생성합니다. 일반적으로는 신경 쓰지 않아도 됩니다. 대부분의 Codelab에서는 프로젝트 ID (일반적으로 PROJECT_ID로 식별됨)를 참조해야 합니다. 생성된 ID가 마음에 들지 않으면 다른 임의 ID를 생성할 수 있습니다. 또는 직접 시도해 보고 사용 가능한지 확인할 수도 있습니다. 이 단계 이후에는 변경할 수 없으며 프로젝트 기간 동안 유지됩니다.
  • 참고로 세 번째 값은 일부 API에서 사용하는 프로젝트 번호입니다. 이 세 가지 값에 대한 자세한 내용은 문서를 참고하세요.
  1. 다음으로 Cloud 리소스/API를 사용하려면 Cloud 콘솔에서 결제를 사용 설정해야 합니다. 이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 튜토리얼이 끝난 후에 요금이 청구되지 않도록 리소스를 종료하려면 만든 리소스 또는 프로젝트를 삭제하면 됩니다. Google Cloud 신규 사용자는 300달러(USD) 상당의 무료 체험판 프로그램에 참여할 수 있습니다.

Cloud Shell 활성화

검색창 오른쪽에 있는 아이콘을 클릭하여 Cloud Shell을 활성화합니다.

b02c63d9c7632ef8.png

환경 설정

  1. Cloud Shell 터미널에서 아래 명령어를 실행하여 프로젝트 및 리소스 관련 환경 변수를 만듭니다.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NAME=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
export REGION=us-east1 
export UPLOAD_BUCKET_NAME=menu-item-uploads-$PROJECT_ID
export UPLOAD_BUCKET=gs://menu-item-uploads-$PROJECT_ID
export BUCKET_THUMBNAILS=gs://menu-item-thumbnails-$PROJECT_ID
export MENU_SERVICE_NAME=menu-service
export USER_EMAIL=$(gcloud config list account --format "value(core.account)")
  1. 실습에 필요한 API 사용 설정
gcloud services enable \
    vision.googleapis.com \
    cloudfunctions.googleapis.com \
    pubsub.googleapis.com \
    cloudbuild.googleapis.com \
    logging.googleapis.com \
    eventarc.googleapis.com \
    artifactregistry.googleapis.com \
    run.googleapis.com \
    --quiet
  1. 저장소 복제
git clone https://github.com/GoogleCloudPlatform/cymbal-eats.git && cd cymbal-eats/cloud-functions

3. Cloud Storage 버킷 구성

스토리지 버킷 만들기

이미지 처리 파이프라인의 업로드 및 썸네일 Cloud Storage 버킷을 만듭니다.

gsutil mb 명령어와 고유한 이름을 사용하여 버킷 2개를 만듭니다.

  1. 이미지가 먼저 업로드될 버킷 업로드
  2. 생성된 썸네일 이미지를 저장할 썸네일 버킷

새 이미지를 업로드할 버킷을 만듭니다.

gsutil mb -p $PROJECT_ID -l $REGION $UPLOAD_BUCKET

출력 예시:

Creating gs://menu-item-uploads-cymbal-eats-8399-3119/...

생성된 썸네일을 저장할 버킷을 만듭니다.

gsutil mb -p $PROJECT_ID -l $REGION $BUCKET_THUMBNAILS

출력 예시:

Creating gs://menu-item-thumbnails-cymbal-eats-8399-3119/...

버킷 권한 업데이트

사용자에게 읽기 권한을 허용하도록 저장소 버킷 권한을 업데이트합니다.

gsutil iam ch 명령어를 사용하여 버킷의 객체 읽기 및 쓰기 권한을 부여합니다.

gsutil iam ch allUsers:objectViewer $UPLOAD_BUCKET
gsutil iam ch allUsers:objectViewer $BUCKET_THUMBNAILS

출력 예

Updated IAM policy for project [cymbal-eats-8399-3119].
[...]

4. 서비스 계정 구성

Cloud 함수가 썸네일을 처리할 수 있도록 커스텀 서비스 계정을 만듭니다.

export CF_SERVICE_ACCOUNT=thumbnail-service-sa
gcloud iam service-accounts create ${CF_SERVICE_ACCOUNT}

Artifact Registry에서 읽기 작업을 허용하도록 artifactregistry.reader 역할을 부여합니다.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/artifactregistry.reader"

생성된 이미지를 썸네일 버킷에 저장할 수 있도록 storage.objectCreator 역할을 부여합니다.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/storage.objectCreator"

Cloud Run 서비스 호출을 허용하도록 run.invoker 역할을 부여합니다.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/run.invoker"

제공자로부터 이벤트 수신을 허용하도록 eventarc.eventReceiver 역할을 부여합니다.

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member "serviceAccount:${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
  --role "roles/eventarc.eventReceiver"

Cloud Storage 서비스 계정에 pubsub.publisher 역할을 부여합니다. 이렇게 하면 이미지가 버킷에 업로드될 때 서비스 계정에서 이벤트를 게시할 수 있습니다.

GCS_SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER)

gcloud projects add-iam-policy-binding $PROJECT_NUMBER \
    --member "serviceAccount:$GCS_SERVICE_ACCOUNT" \
    --role "roles/pubsub.publisher"

5. 이미지 처리 함수 개요

Cloud Storage에서 이미지를 다운로드하고, 이미지 크기를 조절하고, 이미지를 Cloud Storage에 다시 업로드하는 함수를 만듭니다. 이 함수는 Vision API를 호출하여 이미지에 설명 라벨을 할당합니다. 이 함수는 설명 라벨을 확인합니다. 라벨이 이미지를 '음식'으로 식별하면 메뉴 서비스로 이벤트가 전송되어 메뉴 항목의 이미지와 썸네일이 업데이트됩니다.

4c3c3b758dba6a9f.png

함수 트리거

Cloud Storage 함수는 Cloud Storage의 Pub/Sub 알림을 기반으로 하며 다음과 같은 유사한 이벤트 유형을 지원합니다.

이 실습에서는 Cloud Storage에서 객체가 완료될 때 함수를 배포하고 트리거합니다.

객체 완료

Cloud Storage 객체의 '쓰기'가 성공적으로 완료되면 객체 완료 이벤트가 트리거됩니다. 특히 새 객체를 만들거나 기존 객체를 덮어쓸 때 이 이벤트가 트리거됩니다. 보관처리 및 메타데이터 업데이트 작업은 해당 트리거에 의해 무시됩니다.

6. Cloud Storage 통합

Cloud Storage는 Google Cloud에 객체를 저장하는 서비스입니다. 객체란 모든 형식의 파일로 구성된 변경할 수 없는 데이터 조각입니다. 객체는 버킷이라는 컨테이너에 저장합니다. 모든 버킷은 프로젝트와 연결되며, 프로젝트를 조직 아래에 그룹화할 수 있습니다. 클라이언트 라이브러리API 를 사용하면 Cloud Storage와 통합할 수 있습니다.

이 실습에서는 클라이언트 라이브러리를 사용하여 Cloud Storage에 객체를 읽고 씁니다.

클라이언트 라이브러리 설치

Cloud 클라이언트 라이브러리는 널리 사용되는 여러 프로그래밍 언어로 제공됩니다. 라이브러리를 사용하려면 클라이언트 라이브러리를 설치해야 합니다.

클라이언트 라이브러리 사용

구현 세부정보는 대체로 프로그래밍 언어에 따라 다릅니다. 애플리케이션에서 클라이언트 라이브러리를 사용하려면 먼저 Cloud Storage 종속 항목을 가져와야 합니다. 예를 들어 Node.js 프로젝트에서는 가져오기가 package.json 파일에 추가됩니다. 아래 스니펫은 이 실습의 package.json 파일 알림을 보여줍니다.

package.json

{
    "name": "thumbnail-service",
    "version": "0.1.0",
    "dependencies": {
      "@google-cloud/functions-framework": "^3.0.0",
      "@google-cloud/storage": "^5.18.2",
      "@google-cloud/vision": "^2.4.2",
        ...
    }
  }

CloudEvent 콜백 등록

새 이미지가 버킷에 업로드될 때 Cloud Storage에서 트리거할 CloudEvent 콜백을 Functions 프레임워크에 등록합니다.

index.js

functions.cloudEvent('process-thumbnails', async (cloudEvent) => {
    console.log(`Event ID: ${cloudEvent.id}`);
    console.log(`Event Type: ${cloudEvent.type}`);
    ...

스토리지 참조 객체 만들기

클라이언트 라이브러리를 가져온 후에는 애플리케이션이 상호작용할 새 스토리지 클라이언트와 버킷을 만들어야 합니다.

index.js

const storage = new Storage();
const bucket = storage.bucket(file.bucket);
const thumbBucket = storage.bucket(process.env.BUCKET_THUMBNAILS);

Cloud Storage 객체 다운로드

index.js

await bucket.file(file.name).download({
            destination: originalFile
        });

Cloud Storage에 객체 업로드

단일 요청, 재개 가능 또는 XML API 멀티파트 업로드의 세 가지 방법으로 Cloud Storage에 업로드 요청을 보낼 수 있습니다. 대용량 업로드 또는 스트리밍 업로드의 경우 재개 가능한 업로드를 사용하세요. XML API를 사용하면 파일이 여러 부분으로 업로드되고 단일 객체로 조합됩니다. 작은 객체의 경우 단일 요청 업로드를 사용하세요.

아래 코드는 단일 요청 업로드를 사용하여 Cloud Storage에 이미지를 업로드합니다.

index.js

const thumbnailImage = await thumbBucket.upload(thumbFile);

7. Vision API 통합

개발자는 Cloud Vision을 사용하여 이미지 라벨링, 얼굴 및 랜드마크 감지, 광학 문자 인식 (OCR), 선정적인 콘텐츠 태그 지정과 같은 시각적 인식 기능을 애플리케이션에 손쉽게 통합할 수 있습니다.

클라이언트 라이브러리 설치

Cloud 클라이언트 라이브러리는 널리 사용되는 여러 프로그래밍 언어로 제공됩니다. 라이브러리를 사용하려면 클라이언트 라이브러리를 설치해야 합니다.

Image Annotator 클라이언트 만들기

공식 클라이언트 SDK를 사용하여 Google API에 액세스하려면 API를 SDK에 설명하는 API의 검색 문서를 기반으로 서비스 객체를 만듭니다. 사용자 인증 정보를 사용하여 Vision API의 검색 서비스에서 가져와야 합니다.

index.js

const client = new vision.ImageAnnotatorClient();

Vision API 요청 빌드

Vision API는 이미지 파일의 콘텐츠를 요청 본문에 base64로 인코딩된 문자열로 전송하여 이미지 파일에서 기능 감지를 수행할 수 있습니다.

이미지 리소스를 사용하여 요청을 빌드하여 이미지에 주석을 추가합니다. 이 API에 대한 요청은 요청 목록이 있는 객체의 형태입니다. 이 목록의 각 항목은 두 가지 정보를 포함합니다.

  • base64로 인코딩된 이미지 데이터
  • 해당 이미지에서 주석을 달고 싶은 특징 목록

index.js

        const client = new vision.ImageAnnotatorClient();
        const visionRequest = {
            image: { source: { imageUri: `gs://${file.bucket}/${file.name}` } },
            features: [
                { type: 'LABEL_DETECTION' },
            ]
        };
        const visionPromise = client.annotateImage(visionRequest);

8. Cloud Run Functions 배포

이 이미지 크기 조절 서비스는 더 큰 Cymbal Eats 시스템의 일부입니다. 이 섹션에서는 이미지 처리 기능과 관련된 구성요소만 배포합니다. 전체 설치에는 이미지를 업로드하는 UI와 결과 메타데이터를 저장하는 다운스트림 요청이 통합되어 있습니다. 이러한 기능은 이 실습의 일부로 설치되지 않습니다.

함수 배포 중에 다음 구성요소가 생성됩니다.

  • Cloud Run Functions
  • Eventarc 트리거
  • Pub/Sub 주제 및 구독

Cloud Shell 터미널에서 아래 명령어를 실행하여 menu-item-uploads-$PROJECT_ID에 트리거 버킷이 있는 Cloud Run 함수를 배포합니다.

Cloud Run 함수를 Cloud Run에 직접 배포하려면 먼저 함수를 배포한 다음 함수의 트리거를 만듭니다.

Cloud Run 함수를 배포합니다.

gcloud beta run deploy process-thumbnails \
      --source=thumbnail \
      --function process-thumbnails \
      --region $REGION \
      --base-image google-22-full/nodejs20 \
      --no-allow-unauthenticated \
      --project=$PROJECT_ID \
--service-account="${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com" \
--set-env-vars=BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS,MENU_SERVICE_URL=$MENU_SERVICE_URL \
  --max-instances=1 \
  --quiet

출력 예시:

Done.                                                                                                                                                                                    
Service [process-thumbnails] revision [process-thumbnails-00001-abc] has been deployed and is serving 100 percent of traffic.
Service URL: https://process-thumbnails-000000000.us-east1.run.app

트리거를 만듭니다.

gcloud eventarc triggers create process-thumbnails-trigger \
     --location=$REGION \
     --destination-run-service=process-thumbnails \
    --destination-run-region=$REGION \
     --event-filters="type=google.cloud.storage.object.v1.finalized" \
     --event-filters="bucket=$UPLOAD_BUCKET_NAME" \
     --service-account="${CF_SERVICE_ACCOUNT}@${PROJECT_ID}.iam.gserviceaccount.com"

출력 예시:

Creating trigger [process-thumbnails-trigger] in project [qwiklabs-gcp-02-53f8532696e1], location [us-east1]...done.                                                                     
WARNING: It may take up to 2 minutes for the new trigger to become active.

권한 문제로 인해 트리거 배포에 실패한 경우 이전 단계의 IAM 변경사항이 적용될 때까지 기다립니다. 일반적으로 1~2분 정도 소요되며, 그런 다음 배포를 다시 시도합니다.

오류 출력 예:

...If you recently started to use Eventarc, it may take a few minutes before all necessary permissions are propagated to the Service Agent...
[...] 

Cloud 콘솔에서 함수용으로 생성된 Cloud Run 서비스를 검토합니다.

546c5c951cf0f2f.png

Cloud 콘솔에서 함수에 대해 생성된 Eventarc 트리거를 검토합니다.

dec11309016b09ac.png

Cloud 콘솔에서 Eventarc 트리거용으로 생성된 Pub/Sub 주제구독을 검토합니다.

affe089c39ae1465.png

a4c41ede2af300db.png

9. 엔드 투 엔드 솔루션 테스트 및 검증

Cloud Storage에 새 사진을 업로드하고 이미지가 분석되는 동안 파이프라인의 진행 상황을 모니터링합니다. Cloud Functions 로그를 모니터링하여 엔드 투 엔드 솔루션을 테스트합니다.

이미지 업로드

ab7b43f876f9c3a9.jpeg

  1. 이미지를 로컬 머신에 저장합니다.
  2. 파일 이름을 1.jpg로 바꿉니다.
  3. Cloud Storage 콘솔을 엽니다.
  4. menu-item-uploads-... 버킷을 클릭합니다.
  5. 파일 업로드를 클릭합니다.
  6. 스토리지 버킷에 1.jpg를 업로드합니다.
  7. Cloud 콘솔에서 Cloud Run으로 이동합니다.
  8. process-thumbails를 클릭합니다.
  9. 로그 탭을 클릭합니다.

fca8e4bafbdf135d.png

  1. menu-item-thumbnails-$PROJECT_ID Cloud Storage 버킷으로 이동합니다.
  2. 썸네일 버킷에 썸네일 이미지가 생성되었는지 확인

1b6dee72a1fde681.png

식품 이외의 이미지 업로드

함수가 제대로 작동하는지 확인하기 위해 '식품'으로 분류될 수 있는 객체가 포함되지 않은 이미지를 업로드합니다.

c76dd525765f66a6.jpeg

  1. 이미지를 로컬 머신에 저장합니다.
  2. 파일 이름을 2.jpg로 바꿉니다.
  3. Cloud Storage 콘솔을 엽니다.
  4. menu-item-uploads-... 버킷을 클릭합니다.
  5. 파일 업로드를 클릭합니다.
  6. 2.jpg를 스토리지 버킷에 업로드합니다.
  7. Cloud 콘솔에서 Cloud Run으로 이동합니다.
  8. process-thumbails를 클릭합니다.
  9. 로그 탭을 클릭합니다.

18b1e30ee78d3955.png

10. 축하합니다.

축하합니다. 실습을 완료했습니다.

다음 단계:

다른 Cymbal Eats Codelab을 살펴보세요.

삭제

이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.

프로젝트 삭제

비용이 청구되지 않도록 하는 가장 쉬운 방법은 튜토리얼에서 만든 프로젝트를 삭제하는 것입니다.