개요
Google Cloud의 서버리스 컴퓨팅을 사용하면 완전 관리형 서버리스 플랫폼에서 확장성이 우수한 애플리케이션을 개발하고 배포할 수 있습니다. 트래픽에 따라 서비스가 자동으로 확장 및 축소됩니다.
서비스 통합을 사용하면 비동기식으로 느슨하게 결합된 방식으로 서비스를 쉽게 통합하여 빠르게 혁신할 수 있습니다. Eventarc를 사용하면 인프라 관리가 필요 없는 이벤트 기반 아키텍처를 빌드할 수 있습니다. Workflows를 사용하면 서비스 및 API를 조정하여 안정적인 애플리케이션을 쉽게 빌드할 수 있습니다. Cloud Scheduler는 워크로드 일정을 예약하기 위한 완전 관리형 크론 작업 서비스입니다. Cloud Tasks는 분산형 태스크 큐를 생성하기 위한 완전 관리형 서비스입니다. Eventarc, Workflows, Cloud Scheduler, Cloud Tasks는 모니터링 가능성, 안정성, 보안을 유지하면서 서비스를 통합하는 데 도움이 됩니다.
이 실습에서는 Workflows를 사용하여 썸네일을 만들고 수신 이미지에서 메타데이터를 추출하는 프로세스를 관리하는 워크플로를 만듭니다. Eventarc는 이미지가 Cloud Storage 버킷에 업로드되면 이를 감지하고 워크플로 실행을 시작합니다.
워크플로는 Cloud Vision API를 호출하고 업로드된 사진을 분석합니다. Cloud Vision은 이미지가 안전한지 판단하고, 이미지에서 텍스트를 감지하며, 이미지 콘텐츠에 라벨을 제공합니다. 비전 데이터는 Cloud Run Functions에서 생성된 커스텀 함수를 사용하여 추출됩니다. 추출된 데이터는 Google Cloud의 완전 관리형 서버리스 문서 데이터베이스인 Firestore에 저장됩니다. 또한 워크플로는 Cloud Tasks를 사용하여 썸네일을 만드는 태스크를 큐에 추가합니다.
Cloud Build는 컨테이너화된 서비스를 실행하기 위한 서버리스 플랫폼인 Cloud Run에 배포되는 세 가지 서비스를 빌드하는 데 사용됩니다. 이러한 서비스 중 하나는 워크플로에서 생성된 태스크에 대한 응답으로 썸네일을 만듭니다.
두 번째 서비스는 가장 최근 이미지의 사진 콜라주를 만듭니다. 콜라주 서비스는 Cloud Scheduler에서 생성된 일정에 따라 실행됩니다.
세 번째 서비스는 이미지가 Cloud Storage 버킷에서 삭제될 때 Eventarc에 의해 트리거됩니다. 이 서비스는 삭제된 이미지의 메타데이터와 썸네일 이미지를 삭제합니다.

학습할 내용
이 실습에서는 다음 작업을 수행하는 방법을 학습합니다.
- Eventarc를 사용하여 서비스와 워크플로를 비동기식으로 트리거합니다.
- Workflows를 사용하여 서비스와 API를 조정합니다.
- Cloud Tasks를 사용하여 분산된 태스크 큐를 관리합니다.
- Cloud Scheduler를 사용하여 일정에 따라 서비스를 실행합니다.
설정 및 요건
각 실습에서는 정해진 기간 동안 새 Google Cloud 프로젝트와 리소스 집합이 무료로 제공됩니다.
-
실습 시작 버튼을 클릭합니다. 실습 비용을 결제해야 하는 경우 결제 수단을 선택할 수 있는 팝업이 열립니다.
왼쪽에는 다음과 같은 항목이 포함된 실습 세부정보 패널이 있습니다.
-
Google Cloud 콘솔 열기 버튼
- 남은 시간
- 이 실습에 사용해야 하는 임시 사용자 인증 정보
- 필요한 경우 실습 진행을 위한 기타 정보
-
Google Cloud 콘솔 열기를 클릭합니다(Chrome 브라우저를 실행 중인 경우 마우스 오른쪽 버튼으로 클릭하고 시크릿 창에서 링크 열기를 선택합니다).
실습에서 리소스가 가동되면 다른 탭이 열리고 로그인 페이지가 표시됩니다.
팁: 두 개의 탭을 각각 별도의 창으로 나란히 정렬하세요.
참고: 계정 선택 대화상자가 표시되면 다른 계정 사용을 클릭합니다.
-
필요한 경우 아래의 사용자 이름을 복사하여 로그인 대화상자에 붙여넣습니다.
{{{user_0.username | "Username"}}}
실습 세부정보 패널에서도 사용자 이름을 확인할 수 있습니다.
-
다음을 클릭합니다.
-
아래의 비밀번호를 복사하여 시작하기 대화상자에 붙여넣습니다.
{{{user_0.password | "Password"}}}
실습 세부정보 패널에서도 비밀번호를 확인할 수 있습니다.
-
다음을 클릭합니다.
중요: 실습에서 제공하는 사용자 인증 정보를 사용해야 합니다. Google Cloud 계정 사용자 인증 정보를 사용하지 마세요.
참고: 이 실습에 자신의 Google Cloud 계정을 사용하면 추가 요금이 발생할 수 있습니다.
-
이후에 표시되는 페이지를 클릭하여 넘깁니다.
- 이용약관에 동의합니다.
- 임시 계정이므로 복구 옵션이나 2단계 인증을 추가하지 않습니다.
- 무료 체험판을 신청하지 않습니다.
잠시 후 Google Cloud 콘솔이 이 탭에서 열립니다.
참고: Google Cloud 제품 및 서비스 목록이 있는 메뉴를 보려면 왼쪽 상단의 탐색 메뉴를 클릭하거나 검색창에 제품 또는 서비스 이름을 입력합니다.
Google Cloud Shell 활성화하기
Google Cloud Shell은 다양한 개발 도구가 탑재된 가상 머신으로, 5GB의 영구 홈 디렉터리를 제공하며 Google Cloud에서 실행됩니다.
Google Cloud Shell을 사용하면 명령줄을 통해 Google Cloud 리소스에 액세스할 수 있습니다.
-
Cloud 콘솔의 오른쪽 상단 툴바에서 'Cloud Shell 열기' 버튼을 클릭합니다.

-
계속을 클릭합니다.
환경을 프로비저닝하고 연결하는 데 몇 분 정도 소요됩니다. 연결되면 사용자가 미리 인증되어 프로젝트가 PROJECT_ID로 설정됩니다. 예:

gcloud는 Google Cloud의 명령줄 도구입니다. Cloud Shell에 사전 설치되어 있으며 명령줄 자동 완성을 지원합니다.
- 다음 명령어를 사용하여 사용 중인 계정 이름을 나열할 수 있습니다.
gcloud auth list
출력:
Credentialed accounts:
- @.com (active)
출력 예시:
Credentialed accounts:
- google1623327_student@qwiklabs.net
- 다음 명령어를 사용하여 프로젝트 ID를 나열할 수 있습니다.
gcloud config list project
출력:
[core]
project =
출력 예시:
[core]
project = qwiklabs-gcp-44776a13dea667a6
참고:
gcloud 전체 문서는 gcloud CLI 개요 가이드를 참조하세요.
작업 1. API 사용 설정 및 Cloud Storage 버킷 만들기
이 태스크에서는 필요한 API를 사용 설정합니다. 또한 Cloud Storage에 두 개의 버킷을 만듭니다. 하나는 이미지를 업로드하기 위한 버킷이고, 다른 하나는 애플리케이션에서 생성된 이미지를 저장하기 위한 버킷입니다.
API 사용 설정하기
-
필요한 API를 사용 설정하기 위해 다음 명령어를 실행합니다.
gcloud services enable \
workflows.googleapis.com \
workflowexecutions.googleapis.com \
eventarc.googleapis.com \
tasks.googleapis.com \
cloudscheduler.googleapis.com \
storage.googleapis.com \
vision.googleapis.com \
run.googleapis.com \
cloudfunctions.googleapis.com \
firestore.googleapis.com \
appengine.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com
이 애플리케이션은 여러 Google Cloud 서비스를 사용하므로 이러한 서비스의 API를 각각 사용 설정해야 합니다.
사용 설정 중인 API:
Cloud Storage 버킷 만들기
-
Cloud Shell에서 이미지를 업로드할 Cloud Storage 버킷을 만듭니다.
export UPLOAD_BUCKET=uploaded-images-${GOOGLE_CLOUD_PROJECT}
gcloud storage buckets create \
--location={{{project_0.default_region|set at lab start}}} gs://${UPLOAD_BUCKET}
gcloud storage buckets update \
gs://${UPLOAD_BUCKET} --uniform-bucket-level-access
gcloud storage buckets add-iam-policy-binding \
gs://${UPLOAD_BUCKET} \
--member=allUsers --role=roles/storage.objectViewer
이 명령어는 균일한 액세스 권한을 가진 공개 리전 버킷을 만듭니다. 이미지가 버킷에 복사될 때마다 워크플로가 시작되어 사진을 분석하고 메타데이터와 썸네일 이미지를 저장합니다.
-
이미지 애플리케이션에서 생성된 이미지용 Cloud Storage 버킷을 하나 더 만듭니다.
export GENERATED_BUCKET=generated-images-${GOOGLE_CLOUD_PROJECT}
gcloud storage buckets create \
--location={{{project_0.default_region|set at lab start}}} gs://${GENERATED_BUCKET}
gcloud storage buckets update \
gs://${GENERATED_BUCKET} --uniform-bucket-level-access
gcloud storage buckets add-iam-policy-binding \
gs://${GENERATED_BUCKET} \
--member=allUsers --role=roles/storage.objectViewer
-
Google Cloud 콘솔의 탐색 메뉴(
)에서 Cloud Storage > 버킷으로 이동합니다.
생성한 두 개의 버킷이 표시됩니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
Cloud Storage 버킷 만들기
작업 2. Firestore 데이터베이스 만들기
이 태스크에서는 이미지 메타데이터를 저장할 Firestore 데이터베이스를 만듭니다.
데이터베이스 만들기
-
Firestore 데이터베이스를 만들려면 Cloud Shell에서 다음 명령어를 실행합니다.
export FIRESTORE_LOCATION={{{project_0.default_region|set at lab start}}}
gcloud firestore databases create \
--location=${FIRESTORE_LOCATION} \
--type=firestore-native
images라는 이름의 Firestore 컬렉션이 이미지 메타데이터를 저장하는 데 사용됩니다. 콜라주 서비스는 데이터베이스를 검색하여 썸네일이 있는 최신 이미지를 찾아 콜라주를 만듭니다.
데이터베이스를 만든 후에는 이 검색을 지원하기 위한 색인을 만들어야 합니다.
Firestore 복합 색인 만들기
Firestore 복합 색인은 단일 쿼리에서 여러 필드를 참조해야 할 때 사용됩니다.
-
복합 색인을 만들려면 다음 명령어를 실행합니다.
gcloud firestore indexes composite create \
--collection-group=images \
--field-config field-path=thumbnail,order=descending \
--field-config field-path=created,order=descending \
--async
이 색인을 통해 콜라주 서비스는 썸네일이 있는 최신 이미지를 찾을 수 있습니다.
--async 파라미터는 작업이 완료될 때까지 기다리지 않겠다는 의미입니다.
-
Google Cloud 콘솔 제목 표시줄의 검색 필드에 Firestore를 입력하고 검색을 클릭한 다음 Firestore를 클릭합니다.
-
데이터베이스 ID(default)를 클릭하고 왼쪽 창에서 색인을 클릭합니다.
images 컬렉션에 대한 색인이 생성되고 있음을 확인할 수 있습니다.
참고: 검색 색인을 만드는 데 몇 분 정도 걸릴 수 있습니다. 색인 생성이 완료되기 전에 실습을 계속 진행할 수 있습니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
Firestore 데이터베이스 및 복합 색인 만들기
작업 3. 썸네일 태스크 큐 만들기
이 태스크에서는 create-thumbnail 서비스에서 썸네일 생성을 요청하는 데 사용할 Cloud Tasks 큐를 만듭니다.
-
태스크 큐를 만들려면 Cloud Shell에서 다음 명령어를 입력합니다.
export QUEUE_REGION={{{project_0.default_region|set at lab start}}}
gcloud tasks queues create thumbnail-task-queue \
--location=${QUEUE_REGION}
-
Google Cloud 콘솔 제목 표시줄의 검색 필드에 Cloud Tasks를 입력하고 검색을 클릭한 다음 Cloud Tasks를 클릭합니다.
thumbnail-task-queue라는 이름의 큐가 생성되었습니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
Cloud Tasks 큐 만들기
작업 4. Cloud Run 서비스 배포하기
이 태스크에서는 이미지 애플리케이션에서 사용할 Cloud Run 서비스를 빌드하고 배포합니다.
소스 코드 저장소 클론하기
-
Cloud Shell에서 Git 저장소를 클론합니다.
git clone --depth=1 https://github.com/GoogleCloudPlatform/training-data-analyst
-
이 실습의 루트 디렉터리로 연결되는 소프트 링크 바로가기를 생성합니다.
ln -s ~/training-data-analyst/courses/orchestration-and-choreography/lab1 ~/code
Artifact Registry에서 저장소 만들기
Artifact Registry는 차세대 Container Registry입니다. Artifact Registry 저장소 내부에 빌드 아티팩트를 저장할 수 있습니다.
-
Docker 이미지용 Artifact Registry 저장소를 만들려면 Cloud Shell에서 다음 명령어를 실행합니다.
export REPO_NAME=image-app-repo
export REPO_REGION={{{project_0.default_region|set at lab start}}}
gcloud artifacts repositories create ${REPO_NAME} \
--location=${REPO_REGION} --repository-format=docker
create-thumbnail 서비스 빌드 및 배포하기
썸네일 서비스는 업로드된 이미지의 썸네일을 생성하여 generated-images 버킷에 저장합니다.
-
Cloud Shell에서 편집기 열기를 클릭합니다.
-
Cloud Shell 편집기에서 ~/code/cloud-run/create-thumbnail로 이동하여 create-thumbnail 서비스의 파일을 검사합니다.
디렉터리에는 다음 세 개의 파일이 포함되어 있습니다.
-
package.json에는 Node.js 애플리케이션 빌드와 관련된 메타데이터가 포함되어 있습니다. 애플리케이션을 시작하는 명령어(node index.js)를 정의하고 코드에서 사용하는 패키지 버전을 지정합니다.
-
Dockerfile은 시작 이미지(node:16-slim)를 지정하고 서비스를 호스팅할 컨테이너 이미지를 빌드하기 위해 실행되는 명령어 목록을 포함합니다. 설치에는 업로드된 이미지에서 썸네일 이미지를 만드는 데 사용되는 Imagemagick 설치가 포함됩니다.
-
index.js에는 서비스 코드가 포함되어 있습니다.
-
터미널 열기를 클릭합니다.
-
Cloud Build를 사용하여 create-thumbnail 서비스 Docker 이미지를 빌드하려면 Cloud Shell에서 다음 명령어를 실행합니다.
export REPO_NAME=image-app-repo
export REPO_REGION={{{project_0.default_region|set at lab start}}}
export THUMBNAIL_SERVICE_NAME=create-thumbnail
cd ~/code/cloud-run/create-thumbnail
gcloud builds submit \
. \
--tag ${REPO_REGION}-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/${REPO_NAME}/${THUMBNAIL_SERVICE_NAME}
서비스는 Artifact Registry 저장소에 빌드되고 저장됩니다.
-
Cloud Run을 사용하여 서비스를 배포하려면 Cloud Shell에서 다음 명령어를 실행합니다.
export REPO_NAME=image-app-repo
export REPO_REGION={{{project_0.default_region|set at lab start}}}
export THUMBNAIL_SERVICE_REGION={{{project_0.default_region|set at lab start}}}
export THUMBNAIL_SERVICE_NAME=create-thumbnail
export GENERATED_IMAGES_BUCKET=generated-images-${GOOGLE_CLOUD_PROJECT}
cd ~/code/cloud-run/create-thumbnail
gcloud config set run/region ${THUMBNAIL_SERVICE_REGION}
gcloud config set run/platform managed
gcloud run deploy ${THUMBNAIL_SERVICE_NAME} \
--image ${REPO_REGION}-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/${REPO_NAME}/${THUMBNAIL_SERVICE_NAME} \
--no-allow-unauthenticated \
--memory=1Gi \
--max-instances=1 \
--update-env-vars GENERATED_IMAGES_BUCKET=${GENERATED_IMAGES_BUCKET}
generated-images 버킷 이름은 환경 변수를 사용하여 애플리케이션에 전달됩니다.
콜라주 서비스 빌드 및 배포하기
콜라주 서비스는 가장 최근에 업로드된 이미지를 결합하여 콜라주를 만들고 생성된 이미지 버킷에 콜라주를 저장합니다.
-
Cloud Shell에서 편집기 열기를 클릭합니다.
-
Cloud Shell 편집기에서 ~/code/cloud-run/create-collage로 이동하여 create-collage 서비스의 파일을 검사합니다.
이 디렉터리에는 package.json, index.js, Dockerfile이라는 세 가지 파일이 포함되어 있습니다.
-
터미널 열기를 클릭합니다.
-
create-collage 서비스 Docker 이미지를 빌드하고 배포하려면 Cloud Shell에서 다음 명령어를 실행합니다.
export REPO_NAME=image-app-repo
export REPO_REGION={{{project_0.default_region|set at lab start}}}
export COLLAGE_SERVICE_REGION={{{project_0.default_region|set at lab start}}}
export COLLAGE_SERVICE_NAME=create-collage
export GENERATED_IMAGES_BUCKET=generated-images-${GOOGLE_CLOUD_PROJECT}
cd ~/code/cloud-run/create-collage
gcloud builds submit \
. \
--tag ${REPO_REGION}-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/${REPO_NAME}/${COLLAGE_SERVICE_NAME}
gcloud config set run/region ${COLLAGE_SERVICE_REGION}
gcloud config set run/platform managed
gcloud run deploy ${COLLAGE_SERVICE_NAME} \
--image ${REPO_REGION}-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/${REPO_NAME}/${COLLAGE_SERVICE_NAME} \
--no-allow-unauthenticated \
--memory=1Gi \
--max-instances=1 \
--update-env-vars GENERATED_IMAGES_BUCKET=${GENERATED_IMAGES_BUCKET}
이미지 삭제 서비스 빌드 및 배포하기
이미지 삭제 서비스는 생성된 이미지 버킷에서 썸네일 이미지를 삭제하고 데이터베이스에서 이미지 메타데이터를 삭제합니다.
-
Cloud Shell에서 편집기 열기를 클릭합니다.
-
Cloud Shell 편집기에서 ~/code/cloud-run/delete-image로 이동하여 delete-image 서비스의 파일을 검사합니다.
이 디렉터리에는 package.json과 index.js라는 두 개의 파일만 포함되어 있습니다. Dockerfile이 없습니다.
이 실습에서는 컨테이너를 수동으로 빌드하고 게시하는 대신 Google Cloud Buildpacks를 사용하여 컨테이너를 자동으로 빌드합니다.
또한 서비스는 요청을 CloudEvent로 파싱합니다. Eventarc는 표준 CloudEvent 형식을 사용하여 이벤트를 전송합니다.
-
터미널 열기를 클릭합니다.
-
Google Cloud Buildpack을 사용하여 delete-image 서비스를 빌드하고 Cloud Run에 배포하려면 Cloud Shell에서 다음 명령어를 실행합니다.
export DELETE_SERVICE_REGION={{{project_0.default_region|set at lab start}}}
export DELETE_SERVICE_NAME=delete-image
export GENERATED_IMAGES_BUCKET=generated-images-${GOOGLE_CLOUD_PROJECT}
cd ~/code/cloud-run/delete-image
npm install
gcloud config set run/region ${DELETE_SERVICE_REGION}
gcloud config set run/platform managed
gcloud run deploy ${DELETE_SERVICE_NAME} \
--source . \
--no-allow-unauthenticated \
--max-instances=1 \
--update-env-vars GENERATED_IMAGES_BUCKET=${GENERATED_IMAGES_BUCKET}
gcloud run deploy는 Google Cloud Buildpacks로 만든 이미지에 대해 Artifact Registry Docker 저장소를 만들어야 한다고 경고합니다.
-
계속 진행할지 묻는 메시지가 표시되면 Y를 입력합니다.
아티팩트 저장소 및 Cloud Run 서비스 검사하기
-
Google Cloud 콘솔 제목 표시줄의 검색 필드에 Artifact Registry를 입력하고 검색을 클릭한 다음 Artifact Registry를 클릭합니다.
생성한 저장소(image-app-repo)와 Google Cloud Buildpacks에서 생성한 저장소(cloud-run-source-deploy)가 Artifact Registry에 있습니다.
-
image-app-repo를 클릭합니다.
image-app-repo에는 create-collage 및 create-thumbnail 서비스용으로 방금 빌드한 Docker 이미지가 저장되어 있습니다.
-
Artifact Registry > 저장소로 돌아가서 cloud-run-source-deploy를 클릭합니다.
저장소에는 Google Cloud Buildpacks에서 자동으로 생성한 delete-image Docker 이미지가 포함되어 있습니다.
-
Google Cloud 콘솔의 탐색 메뉴(
)에서 Cloud Run > 서비스로 이동합니다.
세 가지 서비스가 모두 배포되었습니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
저장소를 만들고 Cloud Run 서비스 배포
작업 5. Cloud Vision 응답을 파싱하는 함수 만들기
이 작업에서는 Cloud Vision API에서 반환된 이미지 데이터를 파싱하기 위한 Cloud Run 함수를 만듭니다.
-
Cloud Shell에서 편집기 열기를 클릭합니다.
-
Cloud Editor에서 ~/code/cloud-functions/extract-image-metadata로 이동하여 extract-image-metadata 함수의 파일을 검사합니다.
Node.js 서비스에는 index.js 및 package.json 파일이 포함되어 있습니다. Cloud Run Functions는 Buildpacks를 자동으로 사용하여 컨테이너를 생성하므로 Dockerfile이 필요하지 않습니다.
-
터미널 열기를 클릭합니다.
-
함수를 배포하려면 Cloud Shell에서 다음 명령어를 실행합니다.
export EXTRACT_FUNCTION_REGION={{{project_0.default_region|set at lab start}}}
export EXTRACT_FUNCTION_NAME=extract-image-metadata
cd ~/code/cloud-functions/${EXTRACT_FUNCTION_NAME}
gcloud config set functions/region ${EXTRACT_FUNCTION_REGION}
gcloud functions deploy ${EXTRACT_FUNCTION_NAME} \
--gen2 \
--source . \
--runtime=nodejs20 \
--entry-point=extract_image_metadata \
--trigger-http \
--no-allow-unauthenticated
참고: 배포 시 저장소 메타데이터를 가져올 수 없다는 메시지가 표시되면 함수 배포가 작동할 때까지 몇 번 더 시도해 보세요.
-
Google Cloud 콘솔 제목 표시줄의 검색 필드에 Cloud Run Functions를 입력하고 검색을 클릭한 다음 Cloud Run Functions를 클릭합니다.
extract-image-metadata 함수가 배포되었습니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
Cloud Vision 응답을 파싱하는 함수 만들기
작업 6. 워크플로 만들기
이 태스크에서는 서비스와 API 호출을 조정하는 워크플로를 만듭니다.
-
Cloud Shell에서 편집기 열기를 클릭합니다.
-
Cloud Shell 편집기에서 ~/code/workflows로 이동하여 image-add-workflow.yaml YAML 파일을 검사합니다.
워크플로는 워크플로가 시작될 때 수행할 일련의 단계를 지정합니다. 로깅하지 않는 단계는 다음과 같습니다.
-
init는 워크플로에서 사용될 변수를 할당합니다. bucket과 filename은 워크플로가 호출될 때 Eventarc에서 전달된 값으로 채워집니다. projectId는 워크플로에 대해 자동으로 채워지는 환경 변수에서 프로젝트 ID 값을 가져옵니다.
-
imageAnalysisCall은 Cloud Vision API를 호출하여 업로드된 이미지를 분석합니다.
-
extractImageMetadata는 Cloud Run 함수를 호출하여 Cloud Vision API 호출 응답에서 중요한 정보를 추출합니다.
- Cloud Vision API가 이미지가 안전하지 않다고 판단하면 checkSafety가 워크플로를 종료합니다.
-
storeMetadata는 Firestore API를 호출하여 이미지 메타데이터를 저장합니다.
-
getThumbnailService는 Cloud Run 커넥터를 호출하여 create-thumbnail Cloud Run 서비스의 URL을 찾습니다.
-
queueThumbnail은 Cloud Tasks 커넥터를 사용하여 썸네일 서비스를 비동기적으로 호출하는 태스크를 만듭니다.
-
completed는 워크플로를 종료하고 워크플로 실행의 식별자를 반환합니다.
-
터미널 열기를 클릭합니다.
-
워크플로 ID의 서비스 계정을 만들고 몇 가지 기본 권한을 추가하려면 다음 명령어를 실행합니다.
export WORKFLOWS_SA=workflows-sa
gcloud iam service-accounts create ${WORKFLOWS_SA}
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:${WORKFLOWS_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/datastore.user"
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:${WORKFLOWS_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/cloudtasks.enqueuer"
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:${WORKFLOWS_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/logging.logWriter"
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:${WORKFLOWS_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
이러한 역할은 다음 기능을 허용합니다.
-
roles/datastore.user를 사용하면 워크플로가 Firestore에 문서를 작성할 수 있습니다.
-
roles/cloudtasks.enqueuer를 사용하면 워크플로가 Cloud Task를 만들 수 있습니다.
-
roles/logging.logWriter를 사용하면 워크플로가 Cloud Logging에 변수를 기록할 수 있습니다.
-
roles/iam.serviceAccountUser를 사용하면 서비스 계정이 다른 서비스 계정을 가장할 수 있으므로 Cloud Tasks가 워크플로 서비스 계정 ID를 사용하여 요청을 보낼 수 있습니다.
-
함수와 Cloud Run 서비스를 호출할 권한을 추가하려면 다음 명령어를 실행합니다.
export WORKFLOWS_SA=workflows-sa
export THUMBNAIL_SERVICE_NAME=create-thumbnail
export THUMBNAIL_SERVICE_REGION={{{project_0.default_region|set at lab start}}}
export EXTRACT_FUNCTION_NAME=extract-image-metadata
gcloud functions add-iam-policy-binding ${EXTRACT_FUNCTION_NAME} \
--member="serviceAccount:${WORKFLOWS_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/cloudfunctions.invoker"
gcloud run services add-iam-policy-binding ${THUMBNAIL_SERVICE_NAME} \
--region=${THUMBNAIL_SERVICE_REGION} \
--member="serviceAccount:${WORKFLOWS_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/run.viewer"
gcloud run services add-iam-policy-binding ${THUMBNAIL_SERVICE_NAME} \
--region=${THUMBNAIL_SERVICE_REGION} \
--member="serviceAccount:${WORKFLOWS_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/run.invoker"
'Would you like to run this command and additionally grant permission to invoke function [extract-image-metadata] (Y/n)?'(이 명령어를 실행하고 [extract-image-metadata] 함수를 호출할 수 있는 권한을 추가로 부여하시겠습니까? (Y/n))라는 메시지가 표시되면 Y를 입력합니다.
이러한 추가 역할은 다음 기능을 허용합니다.
-
roles/cloudfunctions.invoker를 사용하면 워크플로가 Cloud Vision 응답에서 메타데이터를 추출하는 함수를 호출할 수 있습니다.
-
roles/run.viewer를 사용하면 워크플로가 썸네일 서비스 세부정보를 쿼리할 수 있습니다.
-
roles/run.invoker를 사용하면 워크플로 서비스 계정이 썸네일 서비스를 호출할 수 있습니다. 서비스 계정은 Cloud Tasks에서 서비스를 호출할 때 사용됩니다.
-
워크플로를 배포하려면 다음 명령어를 실행합니다.
export WORKFLOW_NAME=image-add-workflow
export WORKFLOW_REGION={{{project_0.default_region|set at lab start}}}
export WORKFLOWS_SA=workflows-sa
cd ~/code/workflows
gcloud workflows deploy ${WORKFLOW_NAME} \
--source=${WORKFLOW_NAME}.yaml \
--location=${WORKFLOW_REGION} \
--service-account="${WORKFLOWS_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com"
참고: Workflows 서비스 에이전트가 존재하지 않는다는 오류와 함께 명령어가 실패하는 경우 워크플로를 다시 배포합니다.
-
Google Cloud 콘솔 제목 표시줄의 검색 필드에 Workflows를 입력하고 검색을 클릭한 다음 Workflows를 클릭합니다.
-
워크플로 옆에 있는 고정 아이콘을 클릭합니다.
-
image-add-workflow를 클릭한 다음 소스 탭을 클릭합니다.
왼쪽 창에는 워크플로의 코드가 표시되고 오른쪽 창에는 워크플로 단계의 사이트 이용 경로 시각화가 표시됩니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
워크플로 만들기
작업 7. 워크플로를 시작하는 Eventarc 트리거 만들기
이 작업에서는 파일이 uploaded-images 버킷에 추가될 때 워크플로를 실행하는 Eventarc 트리거를 만듭니다.
-
Cloud Shell에서 다음 명령어를 실행하여 워크플로 트리거의 서비스 계정을 만들고 필요한 권한을 부여합니다.
export WORKFLOW_TRIGGER_SA=workflow-trigger-sa
gcloud iam service-accounts create ${WORKFLOW_TRIGGER_SA}
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:${WORKFLOW_TRIGGER_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/workflows.invoker"
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member "serviceAccount:${WORKFLOW_TRIGGER_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/eventarc.eventReceiver"
이러한 명령어는 workflow-trigger-sa라는 서비스 계정을 만들고 이벤트를 수신하고 워크플로를 호출하는 역할을 추가합니다.
-
Cloud Storage 서비스 계정에 이벤트를 만들 수 있는 권한을 부여하려면 다음 명령어를 실행합니다.
export CLOUD_STORAGE_SA="$(gcloud storage service-agent)"
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member="serviceAccount:${CLOUD_STORAGE_SA}" \
--role="roles/pubsub.publisher"
이러한 명령어는 Cloud Storage 서비스 계정을 검색하고 Pub/Sub 이벤트를 게시할 수 있는 권한을 추가합니다.
-
트리거를 만들려면 다음 명령어를 실행합니다.
export WORKFLOW_TRIGGER_REGION={{{project_0.default_region|set at lab start}}}
export WORKFLOW_NAME=image-add-workflow
export WORKFLOW_REGION={{{project_0.default_region|set at lab start}}}
export UPLOAD_BUCKET=uploaded-images-${GOOGLE_CLOUD_PROJECT}
export WORKFLOW_TRIGGER_SA=workflow-trigger-sa
gcloud eventarc triggers create image-add-trigger \
--location=${WORKFLOW_TRIGGER_REGION} \
--destination-workflow=${WORKFLOW_NAME} \
--destination-workflow-location=${WORKFLOW_REGION} \
--event-filters="type=google.cloud.storage.object.v1.finalized" \
--event-filters="bucket=${UPLOAD_BUCKET}" \
--service-account="${WORKFLOW_TRIGGER_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com"
이 트리거는 파일이 uploaded-images 버킷에 기록될 때마다 워크플로를 호출합니다.
참고: 트리거를 만들 때 권한 전파 오류가 발생하면 아직 Eventarc에 권한이 전파되지 않았을 수 있습니다. 트리거 생성을 한두 번 다시 시도하면 작동할 것입니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
워크플로를 시작하기 위한 Eventarc 트리거 만들기
작업 8. 이미지 추가 워크플로 테스트하기
이 작업에서는 이미지가 uploaded-images 버킷에 추가될 때 발생하는 단계를 테스트합니다.
-
uploaded-images 버킷에 이미지를 업로드하려면 다음 명령어를 실행합니다.
export UPLOAD_BUCKET=uploaded-images-${GOOGLE_CLOUD_PROJECT}
export IMAGE_NAME=neon.jpg
gcloud storage cp ~/code/images/${IMAGE_NAME} gs://${UPLOAD_BUCKET}
업로드가 완료되면 Eventarc가 업로드를 감지하고 워크플로를 시작합니다.
-
Google Cloud 콘솔의 탐색 메뉴(
)에서 Workflows > Workflows로 이동합니다.
-
image-add-workflow를 클릭한 다음 실행 탭을 클릭합니다.
곧 워크플로 실행이 표시됩니다.
참고: 실행이 시작되는 데 1~2분 정도 걸릴 수 있습니다.
-
실행 ID를 클릭하여 실행 세부정보 페이지를 엽니다.
이 페이지에는 워크플로 실행의 세부정보가 표시됩니다.
입력 창에는 Eventarc 트리거가 보낸 Cloud Storage 이벤트의 콘텐츠가 표시됩니다.
출력 창에는 워크플로가 끝날 때 반환된 값이 표시됩니다.
로그 창에는 워크플로에서 생성된 로그 항목이 표시됩니다.
-
Google Cloud 콘솔 제목 표시줄의 검색 필드에 Cloud Run Functions를 입력하고 검색을 클릭한 다음 Cloud Run Functions를 클릭합니다.
-
extract-image-metadata를 클릭합니다.
이 대시보드에는 Cloud Vision 응답에서 정보를 추출하는 데 사용된 함수에 대한 세부정보가 표시됩니다.
-
로그 탭을 클릭합니다.
함수 실행에서 로깅된 데이터가 여기에 있습니다. 이미지의 라벨과 텍스트가 기록되었습니다.
-
Google Cloud 콘솔 제목 표시줄의 검색 필드에 Firestore를 입력하고 검색을 클릭한 다음 Firestore를 클릭합니다.
-
(default)를 클릭합니다.
이미지 컬렉션에는 워크플로에서 작성한 neon.jpg라는 문서가 표시되어야 합니다. 이미지에 연결된 라벨과 이미지 내에서 발견된 텍스트가 표시됩니다.
-
Google Cloud 콘솔의 탐색 메뉴(
)에서 Cloud Run > 서비스로 이동한 다음 create-thumbnail을 클릭합니다.
이 대시보드에는 create-thumbnail 서비스에 대한 정보가 표시됩니다.
-
로그 탭을 클릭합니다.
서비스 실행에서 로깅된 데이터가 여기에 있습니다.
-
Cloud Shell에서 다음 명령어를 실행합니다.
export UPLOAD_BUCKET=uploaded-images-${GOOGLE_CLOUD_PROJECT}
export GENERATED_BUCKET=generated-images-${GOOGLE_CLOUD_PROJECT}
export IMAGE_NAME=neon.jpg
echo "uploaded image: https://storage.googleapis.com/${UPLOAD_BUCKET}/${IMAGE_NAME}"
echo "generated image: https://storage.googleapis.com/${GENERATED_BUCKET}/${IMAGE_NAME}"
echo "Listing of generated-images bucket:"
gcloud storage ls gs://${GENERATED_BUCKET}
generated-images 버킷에는 create-thumbnail 서비스에서 생성한 썸네일이 있어야 합니다. Cloud Shell 내에서 링크를 클릭하여 새 탭을 열고 업로드 및 생성된 이미지를 확인할 수 있습니다.
참고: 생성된 이미지가 버킷과 목록에 표시되기까지 약간의 시간이 걸릴 수 있습니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
이미지 추가 워크플로 테스트
작업 9. 콜라주를 만드는 예약된 작업 추가
이 태스크에서는 Cloud Scheduler 작업을 만들어 가장 최근에 업로드된 사진으로 콜라주를 주기적으로 만듭니다.
이미지 업로드
-
uploaded-images 버킷에 이미지를 더 업로드하려면 다음 명령어를 실행합니다.
export UPLOAD_BUCKET=uploaded-images-${GOOGLE_CLOUD_PROJECT}
gcloud storage cp ~/code/images/alley.jpg \
gs://${UPLOAD_BUCKET}
gcloud storage cp ~/code/images/desktop.jpg \
gs://${UPLOAD_BUCKET}
gcloud storage cp ~/code/images/rainbow.jpg \
gs://${UPLOAD_BUCKET}
gcloud storage cp ~/code/images/vegas.jpg \
gs://${UPLOAD_BUCKET}
워크플로는 각 이미지에 대해 실행되며 각 이미지에 대한 썸네일이 생성됩니다.
-
create-collage 서비스를 호출하기 위한 서비스 계정을 만들려면 다음 명령어를 실행합니다.
export COLLAGE_SCHED_SA=collage-schedule-sa
export COLLAGE_SERVICE=create-collage
export COLLAGE_SERVICE_REGION={{{project_0.default_region|set at lab start}}}
gcloud iam service-accounts create ${COLLAGE_SCHED_SA}
gcloud run services add-iam-policy-binding ${COLLAGE_SERVICE} \
--region=${COLLAGE_SERVICE_REGION} \
--member="serviceAccount:${COLLAGE_SCHED_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/run.invoker"
-
Cloud Shell에서 다음 명령어를 실행하여 create-collage 서비스의 서비스 URL을 가져옵니다.
export SERVICE_REGION={{{project_0.default_region|set at lab start}}}
export SERVICE_NAME=create-collage
gcloud run services describe ${SERVICE_NAME} \
--platform managed \
--region ${SERVICE_REGION} \
--format 'value(status.url)'
URL을 클립보드에 복사합니다. 예약된 작업을 만들 때 이 URL이 필요합니다.
-
Google Cloud 콘솔 제목 표시줄의 검색 필드에 Cloud Scheduler를 입력하고 검색을 클릭한 다음 Cloud Scheduler를 클릭합니다.
-
+작업 만들기를 클릭합니다.
-
다음 일정 설정을 지정합니다.
| 속성 |
값 |
| 이름 |
collage-schedule |
| 리전 |
선택
|
| 빈도 |
* * * * * |
| 시간대 |
UTC를 검색한 다음 협정 세계시(UTC)를 선택합니다. |
빈도는 unix-cron 형식으로 일정을 지정합니다. * * * * *는 작업이 1분마다 한 번씩 실행됨을 지정합니다.
테스트를 쉽게 하기 위해 1분마다 한 번씩 실행되도록 빈도를 선택합니다.
-
계속을 클릭한 다음 대상 유형으로 HTTP를 선택합니다.
-
다음 실행 설정을 지정합니다.
| 속성 |
값 |
| URL |
create-collage 서비스 URL을 붙여넣습니다. |
| HTTP 메서드 |
POST 선택 |
| 인증 헤더 |
OIDC 토큰 추가를 선택합니다. |
| 서비스 계정 |
collage-schedule-sa를 선택합니다. |
| 대상 |
create-collage 서비스 URL을 붙여넣습니다. |
-
계속을 클릭한 다음 만들기를 클릭합니다.
collage-schedule 작업이 Cloud Scheduler 작업 페이지에 표시됩니다.
작업은 1분 이내에 실행됩니다.
-
collage-schedule 작업에 성공을 알리는 체크표시가 나타날 때까지 새로고침을 클릭합니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
콜라주를 만드는 예약된 작업 추가
-
Cloud Shell에서 다음 명령어를 실행합니다.
export GENERATED_BUCKET=generated-images-${GOOGLE_CLOUD_PROJECT}
export IMAGE_NAME=collage.png
echo "generated collage: https://storage.googleapis.com/${GENERATED_BUCKET}/${IMAGE_NAME}"
echo "Listing of generated-images bucket:"
gcloud storage ls gs://${GENERATED_BUCKET}
이제 generated-images 버킷에 collage.png 파일이 포함되어야 합니다. Cloud Shell 내에서 '생성된 콜라주' 링크를 클릭하여 새 탭을 열고 콜라주를 확인할 수 있습니다.
Cloud Storage에 복사된 파일은 파일 업로드 프로세스가 완료된 직후에 사용할 수 있으므로 예약된 작업이 완료된 직후에 링크가 작동해야 합니다. 버킷 콘텐츠를 나열할 때 파일이 잠시 후 표시되지 않을 수 있습니다.
작업 10. 이미지 파일 및 메타데이터를 삭제하는 서비스 트리거하기
이 태스크에서는 uploaded-images 버킷에서 이미지가 삭제되면 연결된 썸네일 이미지를 삭제하고 Firestore 문서를 삭제하는 Eventarc 트리거를 만듭니다.
서비스 계정 만들기 및 역할 관리하기
-
Cloud Shell에서 다음 명령어를 실행하여 delete-image 트리거의 서비스 계정을 만들고 필요한 권한을 부여합니다.
export DELETE_TRIGGER_SA=delete-image-trigger-sa
export DELETE_SERVICE_REGION={{{project_0.default_region|set at lab start}}}
export DELETE_SERVICE=delete-image
gcloud iam service-accounts create ${DELETE_TRIGGER_SA}
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member "serviceAccount:${DELETE_TRIGGER_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/eventarc.eventReceiver"
gcloud run services add-iam-policy-binding ${DELETE_SERVICE} \
--region=${DELETE_SERVICE_REGION} \
--member="serviceAccount:${DELETE_TRIGGER_SA}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" \
--role="roles/run.invoker"
이러한 명령어는 delete-image-trigger-sa라는 서비스 계정을 만들고 이벤트를 수신하고 delete-image 서비스를 호출할 수 있는 권한을 추가합니다.
-
Google Cloud 콘솔의 탐색 메뉴(
)에서 Cloud Run으로 이동한 다음 delete-image를 클릭합니다.
-
서비스 세부정보 페이지에서 트리거 탭을 클릭합니다.
-
+ 트리거 추가를 클릭하고 Cloud Storage 트리거를 선택합니다.
-
다음 트리거 설정을 지정합니다.
| 속성 |
값 |
| 트리거 이름 |
image-delete-trigger |
| 이벤트 유형 |
google.cloud.storage.object.v1.deleted를 선택합니다. |
| 버킷 |
둘러보기를 클릭한 다음 uploaded-images 버킷을 선택하고 선택을 클릭합니다. |
| 서비스 계정 |
delete-image-trigger-sa 서비스 계정을 선택합니다. |
| 서비스 URL 경로 |
/ |
-
Pub/Sub에 역할을 부여해야 한다는 메시지가 표시되면 부여를 클릭합니다.
-
트리거 저장을 클릭합니다.
이 트리거는 uploaded-images 버킷에서 파일이 삭제될 때마다 delete-image 서비스를 호출합니다.
참고: 리전이 트리거 리소스에 대한 제약 조건을 위반한다는 오류 메시지가 표시되면 잘못된 Cloud Storage 버킷을 선택했을 가능성이 있습니다. 생성 프로세스를 다시 시도하고 uploaded-images 버킷을 선택했는지 확인합니다.
내 진행 상황 확인하기를 클릭하여 목표를 확인합니다.
이미지 파일 및 메타데이터를 삭제하는 서비스 트리거
이미지 삭제 테스트하기
-
Cloud Storage 버킷의 이미지와 Firestore에 있는 해당 문서를 나열하려면 다음 명령어를 실행합니다.
export UPLOAD_BUCKET=uploaded-images-${GOOGLE_CLOUD_PROJECT}
export GENERATED_BUCKET=generated-images-${GOOGLE_CLOUD_PROJECT}
export IMAGE_NAME=vegas.jpg
echo "Listing of image in uploaded-images bucket:"
gcloud storage ls gs://${UPLOAD_BUCKET}/${IMAGE_NAME}
echo "Listing of image in generated-images bucket:"
gcloud storage ls gs://${GENERATED_BUCKET}/${IMAGE_NAME}
echo "Image document in Firestore:"
curl -q -s -H "Authorization: Bearer $(gcloud auth print-access-token)" \
-X GET "https://firestore.googleapis.com/v1/projects/${GOOGLE_CLOUD_PROJECT}/databases/(default)/documents/images/${IMAGE_NAME}"
이러한 명령어는 단일 이미지에 대한 Cloud Storage 및 Firestore 세부정보를 표시합니다. 다음으로 해당 이미지를 삭제합니다.
-
uploaded-images 버킷에서 이미지를 삭제하려면 다음 명령어를 실행합니다.
export UPLOAD_BUCKET=uploaded-images-${GOOGLE_CLOUD_PROJECT}
export IMAGE_NAME=vegas.jpg
gcloud storage rm gs://${UPLOAD_BUCKET}/${IMAGE_NAME}
Eventarc는 삭제된 파일을 감지하고 image-delete 서비스를 호출하여 썸네일과 Firestore 문서를 삭제합니다.
-
썸네일과 Firestore 문서가 삭제되었는지 확인하려면 앞서 실행한 것과 동일한 명령어를 실행합니다.
export UPLOAD_BUCKET=uploaded-images-${GOOGLE_CLOUD_PROJECT}
export GENERATED_BUCKET=generated-images-${GOOGLE_CLOUD_PROJECT}
export IMAGE_NAME=vegas.jpg
echo "Listing of image in uploaded-images bucket:"
gcloud storage ls gs://${UPLOAD_BUCKET}/${IMAGE_NAME}
echo "Listing of image in generated-images bucket:"
gcloud storage ls gs://${GENERATED_BUCKET}/${IMAGE_NAME}
echo "Image document in Firestore:"
curl -q -s -H "Authorization: Bearer $(gcloud auth print-access-token)" -X GET "https://firestore.googleapis.com/v1/projects/${GOOGLE_CLOUD_PROJECT}/databases/(default)/documents/images/${IMAGE_NAME}"
항목이 삭제되었습니다.
-
Google Cloud 콘솔의 탐색 메뉴(
)에서 Cloud Run > 서비스로 이동한 다음 delete-image를 클릭합니다.
-
로그를 클릭합니다.
delete-image 서비스의 로그를 보면 generated-images 버킷에서 썸네일이 삭제되었고 Firestore 문서가 데이터베이스에서 삭제되었음을 알 수 있습니다.
수고하셨습니다
Eventarc를 사용하여 서비스와 워크플로를 성공적으로 트리거했습니다. Workflows를 사용하여 서비스와 API를 조정했습니다. Cloud Tasks를 사용하여 분산형 태스크 큐를 만들고 사용했습니다. 마지막으로 Cloud Scheduler를 사용하여 서비스를 실행하는 작업을 만들었습니다.
다음 단계/더 학습하기
실습 종료하기
실습을 완료하면 실습 종료를 클릭합니다. Google Cloud Skills Boost에서 사용된 리소스를 자동으로 삭제하고 계정을 지웁니다.
실습 경험을 평가할 수 있습니다. 해당하는 별표 수를 선택하고 의견을 입력한 후 제출을 클릭합니다.
별점의 의미는 다음과 같습니다.
- 별표 1개 = 매우 불만족
- 별표 2개 = 불만족
- 별표 3개 = 중간
- 별표 4개 = 만족
- 별표 5개 = 매우 만족
의견을 제공하고 싶지 않다면 대화상자를 닫으면 됩니다.
의견이나 제안 또는 수정할 사항이 있다면 지원 탭을 사용하세요.
Copyright 2024 Google LLC All rights reserved. Google 및 Google 로고는 Google LLC의 상표입니다. 기타 모든 회사명 및 제품명은 해당 업체의 상표일 수 있습니다.