1. 개요
이 Codelab에서는 Cloud Run에서 이벤트를 수신하는 새로운 서비스인 Eventarc에서 트리거하는 새로운 Cloud Run 서비스인 이미지 가비지 컬렉터를 만듭니다. 사진 버킷에서 사진이 삭제되면 서비스가 Eventarc에서 이벤트를 수신합니다. 그런 다음 썸네일 버킷에서 이미지를 삭제하고 Firestore 사진 컬렉션에서도 삭제합니다.
학습할 내용
- Cloud Run
- Cloud Storage
- Cloud Firestore
- Eventarc
2. 설정 및 요구사항
자습형 환경 설정
- Google Cloud Console에 로그인하여 새 프로젝트를 만들거나 기존 프로젝트를 재사용합니다. 아직 Gmail이나 Google Workspace 계정이 없는 경우 계정을 만들어야 합니다.
- 프로젝트 이름은 이 프로젝트 참가자의 표시 이름입니다. 이는 Google API에서 사용하지 않는 문자열이며 언제든지 업데이트할 수 있습니다.
- 프로젝트 ID는 모든 Google Cloud 프로젝트에서 고유해야 하며, 변경할 수 없습니다(설정된 후에는 변경할 수 없음). Cloud Console은 고유한 문자열을 자동으로 생성합니다. 일반적으로 신경 쓰지 않아도 됩니다. 대부분의 Codelab에서는 프로젝트 ID를 참조해야 하며(일반적으로
PROJECT_ID
로 식별됨), 마음에 들지 않는 경우 임의로 다시 생성하거나 직접 지정해서 사용할 수 있는지 확인하세요. 프로젝트가 생성되면 프로젝트 ID가 '고정'됩니다. - 세 번째 값은 일부 API에서 사용하는 프로젝트 번호입니다. 이 세 가지 값에 대한 자세한 내용은 문서를 참조하세요.
- 다음으로 Cloud 리소스/API를 사용하려면 Cloud Console에서 결제를 사용 설정해야 합니다. 이 Codelab 실행에는 많은 비용이 들지 않습니다. 이 튜토리얼을 마친 후 비용이 결제되지 않도록 리소스를 종료하려면 Codelab의 끝에 있는 '삭제' 안내를 따르세요. Google Cloud 새 사용자에게는 미화 $300 상당의 무료 체험판 프로그램에 참여할 수 있는 자격이 부여됩니다.
Cloud Shell 시작
Google Cloud를 노트북에서 원격으로 실행할 수 있지만, 이 Codelab에서는 Cloud에서 실행되는 명령줄 환경인 Google Cloud Shell을 사용합니다.
GCP 콘솔에서 오른쪽 상단 툴바의 Cloud Shell 아이콘을 클릭합니다.
환경을 프로비저닝하고 연결하는 데 몇 분 정도 소요됩니다. 완료되면 다음과 같이 표시됩니다.
가상 머신에는 필요한 개발 도구가 모두 들어있습니다. 영구적인 5GB 홈 디렉토리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 실습의 모든 작업은 브라우저만으로 수행할 수 있습니다.
3. Eventarc 소개
Eventarc를 사용하면 Cloud Run 서비스를 다양한 소스의 이벤트와 쉽게 연결할 수 있습니다. 이벤트 수집, 전송, 보안, 승인, 오류 처리를 자동으로 처리합니다.
Cloud Pub/Sub에 게시하는 Google Cloud 소스 및 커스텀 애플리케이션에서 이벤트를 가져와 Google Cloud Run 싱크로 전달할 수 있습니다.
다양한 Google Cloud 소스의 이벤트는 Cloud 감사 로그를 통해 전달됩니다. 이러한 소스의 이벤트 전송 지연 시간과 가용성은 Cloud 감사 로그의 지연 시간과 가용성과 관련이 있습니다. Google Cloud 소스에서 이벤트가 발생할 때마다 해당하는 Cloud 감사 로그 항목이 생성됩니다.
Cloud Pub/Sub에 게시하는 커스텀 애플리케이션은 원하는 형식으로 지정한 Pub/Sub 주제에 메시지를 게시할 수 있습니다.
이벤트 트리거는 어떤 이벤트를 어떤 싱크로 전달할지 지정하는 필터링 메커니즘입니다.
모든 이벤트는 서비스 간 상호 운용성을 위해 CloudEvents v1.0 형식으로 전달됩니다.
4. 시작하기 전에
API 사용 설정
Cloud Run 서비스를 트리거하려면 Eventarc 서비스가 필요합니다. 사용 설정되어 있는지 확인합니다.
gcloud services enable eventarc.googleapis.com
작업이 성공적으로 완료됩니다.
Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.
서비스 계정 구성
기본 컴퓨팅 서비스 계정이 트리거에 사용됩니다. 기본 컴퓨팅 서비스 계정에 eventarc.eventReceiver
역할을 부여합니다.
PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format='value(projectNumber)') gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \ --member serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \ --role roles/eventarc.eventReceiver
Cloud Storage 서비스 계정에 pubsub.publisher
역할을 부여합니다. Eventarc Cloud Storage 트리거에 필요합니다.
SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER) gcloud projects add-iam-policy-binding $PROJECT_NUMBER \ --member serviceAccount:$SERVICE_ACCOUNT \ --role roles/pubsub.publisher
2021년 4월 8일 이전에 Pub/Sub 서비스 계정을 사용 설정한 경우 Pub/Sub 서비스 계정에 iam.serviceAccountTokenCreator
역할을 부여합니다.
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \ --role roles/iam.serviceAccountTokenCreator
5. 코드 클론
이전 Codelab에서 아직 클론하지 않았다면 코드를 클론합니다.
git clone https://github.com/GoogleCloudPlatform/serverless-photosharing-workshop
그런 다음 서비스가 포함된 디렉터리로 이동하면 됩니다.
cd serverless-photosharing-workshop/services/garbage-collector/nodejs
서비스의 파일 레이아웃은 다음과 같습니다.
services | ├── garbage-collector | ├── nodejs | ├── index.js ├── package.json
폴더 안에는 3개의 파일이 있습니다.
index.js
에는 Node.js 코드가 포함됩니다.package.json
는 라이브러리 종속 항목을 정의합니다.
6. 코드 살펴보기
종속 항목
package.json
파일은 필요한 라이브러리 종속 항목을 정의합니다.
{
"name": "garbage_collector_service",
"version": "0.0.1",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"cloudevents": "^4.0.1",
"express": "^4.17.1",
"@google/events": "^3.1.0",
"@google-cloud/firestore": "^4.9.9",
"@google-cloud/storage": "^5.8.3"
}
}
Cloud Storage 라이브러리를 사용하여 Cloud Storage 내의 이미지를 삭제합니다. Cloud Firestore에 대한 종속 항목을 선언하여 이전에 저장한 사진 메타데이터도 삭제합니다. 또한 CloudEvents SDK 및 Google 이벤트 라이브러리를 사용하여 Eventarc에서 전송된 CloudEvents를 읽습니다. Express는 JavaScript / Node 웹 프레임워크입니다. Bluebird는 프로미스 처리에 사용됩니다.
index.js
index.js
코드를 자세히 살펴보겠습니다.
const express = require('express');
const {Storage} = require('@google-cloud/storage');
const Firestore = require('@google-cloud/firestore');
const { HTTP } = require("cloudevents");
const {toStorageObjectData} = require('@google/events/cloud/storage/v1/StorageObjectData');
프로그램을 실행하는 데 필요한 다양한 종속 항목이 필요합니다. Express는 사용할 노드 웹 프레임워크이고, Bluebird는 JavaScript 프로미스를 처리하기 위한 라이브러리, Storage 및 Firestore는 각각 Google Cloud Storage (이미지 버킷) 및 Cloud Firestore 데이터 스토어와 함께 작동하는 데 사용됩니다. 또한 CloudEvent가 Google 이벤트 라이브러리에서 Eventarc StoreObjectData가 전송한 CloudEvent를 읽어 CloudEvent의 Cloud Storage 이벤트 본문을 읽어야 합니다.
const app = express();
app.use(express.json());
app.post('/', async (req, res) => {
try {
const cloudEvent = HTTP.toEvent({ headers: req.headers, body: req.body });
console.log(cloudEvent);
/* ... */
} catch (err) {
console.log(`Error: ${err}`);
res.status(500).send(err);
}
});
위에는 Node 핸들러의 구조가 있습니다. 앱이 HTTP POST 요청에 응답합니다. HTTP 요청에서 CloudEvent를 읽고 문제가 발생할 경우 약간의 오류 처리를 수행합니다. 이제 이 구조 안에 무엇이 있는지 살펴보겠습니다.
다음 단계는 CloudEvent 본문을 검색 및 파싱한 후 객체 이름을 가져오는 것입니다.
const storageObjectData = toStorageObjectData(cloudEvent.data);
console.log(storageObjectData);
const objectName = storageObjectData.name;
이미지 이름을 알면 썸네일 버킷에서 삭제할 수 있습니다.
try {
await storage.bucket(bucketThumbnails).file(objectName).delete();
console.log(`Deleted '${objectName}' from bucket '${bucketThumbnails}'.`);
}
catch(err) {
console.log(`Failed to delete '${objectName}' from bucket '${bucketThumbnails}': ${err}.`);
}
마지막 단계로 Firestore 컬렉션에서도 사진 메타데이터를 삭제합니다.
try {
const pictureStore = new Firestore().collection('pictures');
const docRef = pictureStore.doc(objectName);
await docRef.delete();
console.log(`Deleted '${objectName}' from Firestore collection 'pictures'`);
}
catch(err) {
console.log(`Failed to delete '${objectName}' from Firestore: ${err}.`);
}
res.status(200).send(`Processed '${objectName}'.`);
이제 노드 스크립트가 수신 요청을 리슨하도록 해보겠습니다. 또한 필수 환경 변수가 설정되었는지 확인합니다.
app.listen(PORT, () => {
if (!bucketThumbnails) throw new Error("BUCKET_THUMBNAILS not set");
console.log(`Started service on port ${PORT}`);
});
7. 로컬에서 테스트
클라우드에 배포하기 전에 로컬에서 코드를 테스트하여 작동하는지 확인합니다.
garbage-collector/nodejs
폴더 내에 npm 종속 항목을 설치하고 서버를 시작합니다.
export BUCKET_THUMBNAILS=thumbnails-$GOOGLE_CLOUD_PROJECT npm install; npm start
모든 것이 잘 진행되었다면 포트 8080에서 서버를 시작합니다.
Started service on port 8080
종료하려면 CTRL-C
을(를) 사용하세요.
8. 빌드 후 Cloud Run에 배포
Cloud Run에 배포하기 전에 Cloud Run 리전을 지원되는 리전 중 하나로 설정하고 플랫폼을 managed
으로 설정합니다.
REGION=europe-west1 gcloud config set run/region $REGION gcloud config set run/platform managed
다음 명령어로 구성이 설정되었는지 확인할 수 있습니다.
gcloud config list ... [run] platform = managed region = europe-west1
Cloud Build를 사용하여 컨테이너 이미지를 수동으로 빌드하고 게시하는 대신, Cloud Run에 의존하여 Google Cloud 빌드팩을 사용하여 컨테이너 이미지를 빌드할 수도 있습니다.
다음 명령어를 실행하여 Google Cloud Buildpack으로 컨테이너 이미지를 빌드한 후 컨테이너 이미지를 Cloud Run에 배포합니다.
SERVICE_NAME=garbage-collector-service gcloud run deploy $SERVICE_NAME \ --source . \ --no-allow-unauthenticated \ --update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS
–-source
플래그를 확인합니다. 이 플래그는 Google Cloud 빌드팩을 사용하여 Dockerfile.
없이 컨테이너 이미지를 빌드하도록 Cloud Run에 플래그를 지정합니다. --no-allow-unauthenticated
플래그는 Cloud Run 서비스를 특정 서비스 계정에 의해서만 트리거되는 내부 서비스로 만듭니다. 나중에 내부 Cloud Run 서비스를 호출하는 run.invoker
역할이 있는 기본 컴퓨팅 서비스 계정으로 트리거를 만듭니다.
9. 트리거 만들기
Eventarc에서 트리거는 어떤 서비스가 어떤 종류의 이벤트를 가져와야 하는지 정의합니다. 이 경우 버킷에서 파일이 삭제될 때 서비스에서 이벤트를 수신하기를 원합니다.
업로드된 사진 버킷과 동일한 리전에서 트리거의 위치를 설정합니다.
gcloud config set eventarc/location eu
storage.objects.delete
이벤트를 필터링하고 Cloud Run 서비스로 전송하는 AuditLog 트리거를 만듭니다.
BUCKET_IMAGES=uploaded-pictures-$GOOGLE_CLOUD_PROJECT gcloud eventarc triggers create trigger-$SERVICE_NAME \ --destination-run-service=$SERVICE_NAME \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.storage.object.v1.deleted" \ --event-filters="bucket=$BUCKET_IMAGES" \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
다음 명령어를 사용하여 트리거가 생성되었는지 다시 확인할 수 있습니다.
gcloud eventarc triggers list
10. 서비스 테스트
서비스가 작동하는지 테스트하려면 uploaded-pictures
버킷으로 이동하여 사진 중 하나를 삭제합니다. 서비스 로그에서 thumbnails
버킷의 관련 사진이 삭제되고 pictures
Firestore 컬렉션에서 문서도 삭제되었음을 확인할 수 있습니다.
11. 정리(선택 사항)
이 시리즈의 다른 실습을 계속하지 않으려는 경우 리소스를 삭제하여 비용을 절감하고 전반적으로 클라우드를 잘 활용할 수 있습니다. 다음과 같이 리소스를 개별적으로 삭제할 수 있습니다.
서비스 삭제:
gcloud run services delete $SERVICE_NAME -q
Eventarc 트리거를 삭제합니다.
gcloud eventarc triggers delete trigger-$SERVICE_NAME -q
또는 전체 프로젝트를 삭제할 수 있습니다.
gcloud projects delete $GOOGLE_CLOUD_PROJECT
12. 축하합니다.
축하합니다. Cloud Run에서 이벤트를 수신하는 새로운 서비스인 Eventarc에 의해 트리거되는 Cloud Run 서비스, 이미지 가비지 컬렉터를 만들었습니다. 사진 버킷에서 사진이 삭제되면 서비스가 Eventarc에서 이벤트를 수신합니다. 그런 다음 썸네일 버킷에서 이미지를 삭제하고 Firestore 사진 컬렉션에서도 삭제합니다.
학습한 내용
- Cloud Run
- Cloud Storage
- Cloud Firestore
- Eventarc