1. סקירה כללית
בשיעור ה-Codelab הזה, תיצרו שירות חדש ב-Cloud Run, שנקרא 'איסוף של תמונות', שיופעל על ידי Eventarc, שירות חדש לקבלת אירועים ב-Cloud Run. כשמוחקים תמונה ממאגר התמונות, השירות מקבל אירוע מ-Eventarc. לאחר מכן, התמונה נמחקת ממאגר התמונות הממוזערות ומוסרת גם מאוסף התמונות של Firestore.

מה תלמדו
- Cloud Run
- Cloud Storage
- Cloud Firestore
- Eventarc
2. הגדרה ודרישות
הגדרת סביבה בקצב אישי
- נכנסים ל-מסוף Google Cloud ויוצרים פרויקט חדש או משתמשים בפרויקט קיים. אם עדיין אין לכם חשבון Gmail או Google Workspace, אתם צריכים ליצור חשבון.



- שם הפרויקט הוא השם המוצג למשתתפים בפרויקט. זו מחרוזת של תווים שלא נמצאת בשימוש ב-Google APIs, ואפשר לעדכן אותה בכל שלב.
- מזהה הפרויקט חייב להיות ייחודי לכל הפרויקטים ב-Google Cloud, והוא קבוע (אי אפשר לשנות אותו אחרי שהוא מוגדר). מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית. בדרך כלל לא צריך לדעת מה היא. ברוב סדנאות ה-Codelab, תצטרכו להפנות למזהה הפרויקט (ובדרך כלל הוא מזוהה כ-
PROJECT_ID), אז אם אתם לא אוהבים אותו, תוכלו ליצור מזהה אקראי אחר, או לנסות ליצור מזהה משלכם ולראות אם הוא זמין. אחרי שהפרויקט נוצר, הוא 'קפוא'. - יש ערך שלישי, מספר פרויקט, שמשמש חלק מממשקי ה-API. מידע נוסף על שלושת הערכים האלה מופיע במאמרי העזרה.
- בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API. העלות של התרגול הזה לא אמורה להיות גבוהה, ואולי לא תהיה עלות בכלל. כדי לכבות את המשאבים ולא לחייב אתכם מעבר למה שמוסבר במדריך הזה, צריך לפעול לפי ההוראות לניקוי שמופיעות בסוף ה-Codelab. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.
מפעילים את Cloud Shell
אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-Codelab הזה נשתמש ב-Google Cloud Shell, סביבת שורת פקודה שפועלת בענן.
ב-GCP Console, לוחצים על סמל Cloud Shell בסרגל הכלים שבפינה הימנית העליונה:

הקצאת המשאבים והחיבור לסביבה יימשכו רק כמה רגעים. בסיום התהליך, אמור להופיע משהו כזה:

המכונה הווירטואלית הזו כוללת את כל הכלים שדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את הביצועים והאימות ברשת. אפשר לבצע את כל העבודה ב-Lab הזה רק באמצעות דפדפן.
3. מבוא ל-Eventarc
Eventarc מאפשר לחבר בקלות שירותי Cloud Run לאירועים ממגוון מקורות. הוא מטפל בהטמעה, בשליחה, באבטחה, בהרשאה ובטיפול בשגיאות של אירועים.

אתם יכולים לשלוף אירועים ממקורות של Google Cloud ומאפליקציות בהתאמה אישית שמפרסמות ב-Cloud Pub/Sub, ולהעביר אותם ליעדים של Google Cloud Run.
אירועים ממגוון רחב של מקורות ב-Google Cloud מועברים באמצעות יומני הביקורת של Cloud. החביון והזמינות של מסירת אירועים מהמקורות האלה קשורים לאלה של יומני הביקורת של Cloud. בכל פעם שמופעל אירוע ממקור ב-Google Cloud, נוצרת רשומה תואמת ביומן הביקורת של Cloud.
אפליקציות בהתאמה אישית שמפרסמות ב-Cloud Pub/Sub יכולות לפרסם הודעות בנושא ב-Pub/Sub שהן מציינות בכל פורמט.
טריגרים של אירועים הם מנגנון הסינון שמאפשר לציין אילו אירועים יועברו לאיזה יעד.
כל האירועים מועברים בפורמט CloudEvents v1.0 לצורך פעולה הדדית בין שירותים.
4. לפני שמתחילים
הפעלת ממשקי ה-API
תצטרכו את שירות Eventarc כדי להפעיל את שירות Cloud Run. מוודאים שהיא מופעלת:
gcloud services enable eventarc.googleapis.com
הפעולה אמורה להסתיים בהצלחה:
Operation "operations/acf.5c5ef4f6-f734-455d-b2f0-ee70b5a17322" finished successfully.
הגדרת חשבונות שירות
חשבון השירות שמוגדר כברירת מחדל לחישוב ישמש בטריגרים. מקצים את התפקיד eventarc.eventReceiver לחשבון השירות שמוגדר כברירת מחדל ב-Compute:
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
מקצים את התפקיד pubsub.publisher לחשבון השירות של Cloud Storage. ההרשאה הזו נדרשת לטריגר Cloud Storage של Eventarc:
SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER)
gcloud projects add-iam-policy-binding $PROJECT_NUMBER \
--member serviceAccount:$SERVICE_ACCOUNT \
--role roles/pubsub.publisher
אם הפעלתם את חשבון השירות של Pub/Sub ב-8 באפריל 2021 או לפני כן, צריך להקצות לחשבון השירות של 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. שיבוט הקוד
משכפלים את הקוד, אם עדיין לא עשיתם את זה בסדנת הקוד הקודמת:
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 כדי לקרוא את CloudEvents שנשלחים על ידי Eventarc. 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 הוא מסגרת האינטרנט של Node שבה נשתמש, Bluebird היא ספרייה לטיפול בהבטחות של JavaScript, Storage ו-Firestore משמשים לעבודה עם Google Cloud Storage (הקטגוריות של התמונות שלנו) ומאגר הנתונים של Cloud Firestore, בהתאמה. בנוסף, אנחנו דורשים מ-CloudEvent לקרוא את CloudEvent שנשלח על ידי Eventarc StoreObjectData מספריית Google Events כדי לקרוא את גוף האירוע של Cloud Storage ב-CloudEvent.
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);
}
});
למעלה אפשר לראות את המבנה של ה-handler של Node: האפליקציה שלנו מגיבה לבקשות HTTP POST. הפונקציה קוראת את CloudEvent מבקשת ה-HTTP, ואנחנו מבצעים טיפול בשגיאות למקרה שמשהו ישתבש. עכשיו נבדוק מה יש בתוך המבנה הזה.
השלב הבא הוא לאחזר ולנתח את גוף ה-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}'.`);
עכשיו צריך לגרום לסקריפט Node להאזין לבקשות נכנסות. כדאי גם לוודא שמשתני הסביבה הנדרשים מוגדרים:
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 Buildpacks.
מריצים את הפקודה הבאה כדי ליצור את קובץ האימג' של הקונטיינר באמצעות Google Cloud Buildpacks, ואז פורסים את קובץ האימג' של הקונטיינר ב-Cloud Run:
SERVICE_NAME=garbage-collector-service
gcloud run deploy $SERVICE_NAME \
--source . \
--no-allow-unauthenticated \
--update-env-vars BUCKET_THUMBNAILS=$BUCKET_THUMBNAILS
שימו לב לסימון –-source. הדגל הזה מציין ל-Cloud Run להשתמש ב-Google Cloud Buildpacks כדי ליצור את קובץ האימג' של הקונטיינר בלי Dockerfile. הדגל --no-allow-unauthenticated הופך את שירות Cloud Run לשירות פנימי שיופעל רק על ידי חשבונות שירות ספציפיים. בהמשך, תיצרו טריגר עם חשבון השירות שמוגדר כברירת מחדל בשביל שירותי מחשוב, עם התפקיד run.invoker, כדי לבצע קריאה לשירותי Cloud Run פנימיים.
9. יצירת טריגר
ב-Eventarc, טריגר מגדיר איזה שירות צריך לקבל איזה סוג של אירועים. במקרה הזה, רוצים שהשירות יקבל אירועים כשקובץ נמחק ממאגר.
מגדירים את המיקום של הטריגר באותו אזור שבו נמצאת קטגוריית התמונות שהועלו:
gcloud config set eventarc/location eu
יוצרים טריגר AuditLog כדי לסנן אירועים מסוג storage.objects.delete ולשלוח אותם לשירות Cloud Run:
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