1. מבוא
סקירה כללית
פונקציות Cloud Run הן חבילת השירות של Google Cloud מסוג Functions as a Service שמבוססת על Cloud Run ו-Eventarc. היא מספקת לכם שליטה מתקדמת יותר על הביצועים והתאימות לעומס, ועל זמן הריצה והטריגרים של הפונקציות מיותר מ-90 מקורות אירועים.
בקודלאב הזה נסביר איך יוצרים פונקציות של Cloud Run שמגיבות לשיחות HTTP, ומופעלות על ידי הודעות Pub/Sub ויומני ביקורת של Cloud.
ב-codelab הזה נעשה גם שימוש בעדכונים אוטומטיים של קובץ האימג' הבסיסי לפריסות של פונקציות, על ידי ציון קובץ אימג' בסיסי באמצעות הדגל --base-image
. עדכונים אוטומטיים של קובץ האימג' הבסיסי ב-Cloud Run מאפשרים ל-Google להחיל תיקוני אבטחה באופן אוטומטי על רכיבי מערכת ההפעלה ועל רכיבי סביבת זמן הריצה של השפה בקובץ האימג' הבסיסי. אין צורך ליצור מחדש את השירות או לפרוס אותו מחדש כדי לעדכן את קובץ האימג' הבסיסי. מידע נוסף זמין במאמר עדכונים אוטומטיים של קובצי אימג' בסיסיים
אם אתם מעדיפים לא להשתמש בעדכונים אוטומטיים של קובצי אימג' בסיסיים, תוכלו להסיר את הדגל --base-image
מהדוגמאות שמוצגות ב-codelab הזה.
מה תלמדו
- סקירה כללית על פונקציות Cloud Run ועל השימוש בעדכונים אוטומטיים של קובצי אימג' בסיסיים.
- איך כותבים פונקציה שתגיב לבקשות HTTP.
- איך לכתוב פונקציה שמגיבה להודעות Pub/Sub.
- איך כותבים פונקציה שמגיבה לאירועים ב-Cloud Storage.
- איך לפצל את התנועה בין שתי גרסאות.
- איך להימנע מהפעלה במצב התחלתי (cold start) באמצעות מכונות מינימליות.
2. הגדרה ודרישות
יצירת תיקיית Root
יוצרים תיקיית root לכל הדוגמאות.
mkdir crf-codelab cd crf-codelab
הגדרת משתני סביבה
מגדירים משתני סביבה שישמשו לאורך כל הקודלה.
gcloud config set project <YOUR-PROJECT-ID> REGION=<YOUR_REGION> PROJECT_ID=$(gcloud config get-value project)
הפעלת ממשקי API
מפעילים את כל השירותים הנדרשים:
gcloud services enable \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ eventarc.googleapis.com \ run.googleapis.com \ logging.googleapis.com \ pubsub.googleapis.com
3. פונקציית HTTP
בפונקציה הראשונה, נוצר פונקציית Node.js מאומתת שמגיבה לבקשות HTTP. נשתמש גם בזמן קצוב לתפוגה של 10 דקות כדי להמחיש איך אפשר לתת לפונקציה יותר זמן להגיב לבקשות HTTP.
יצירה
יוצרים תיקייה לאפליקציה ומנווטים לתיקייה:
mkdir hello-http cd hello-http
יוצרים קובץ index.js
שמגיב לבקשות HTTP:
const functions = require('@google-cloud/functions-framework'); functions.http('helloWorld', (req, res) => { res.status(200).send('HTTP with Node.js in Cloud Run functions!'); });
יוצרים קובץ package.json
כדי לציין את יחסי התלות:
{ "name": "nodejs-run-functions-codelab", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
פריסה
פורסים את הפונקציה:
gcloud run deploy nodejs-run-function \ --source . \ --function helloWorld \ --base-image nodejs22 \ --region $REGION \ --timeout 600 \ --no-allow-unauthenticated
הפקודה הזו משתמשת ב-buildpacks כדי להמיר את קוד המקור של הפונקציה לקובץ אימג' בקונטיינר שמוכנים לייצור.
שימו לב:
- הדגל
--source
משמש להודעה ל-Cloud Run ליצור את הפונקציה כשירות מבוסס-קונטיינר שאפשר להריץ - הדגל
--function
(חדש) משמש להגדרת נקודת הכניסה של השירות החדש כחתימת הפונקציה שרוצים להפעיל - הדגל
--base-image
(חדש) מציין את סביבת קובץ האימג' הבסיסי של הפונקציה, למשלnodejs22
,python312
,go123
,java21
,dotnet8
,ruby33
אוphp83
. מידע נוסף על קובצי אימג' בסיסיים ועל החבילות הכלולות בכל קובץ אימג' זמין במאמר קובצי אימג' בסיסיים של סביבת זמן ריצה. - (אופציונלי) הדגל
--timeout
מאפשר לפונקציה להגדיר זמן קצוב ארוך יותר לתגובה לבקשות HTTP. בדוגמה הזו, נעשה שימוש ב-600 שניות כדי להדגים זמן תגובה של 10 דקות. - (אופציונלי) את
--no-allow-unauthenticated
כדי למנוע הפעלה ציבורית של הפונקציה
בדיקה
בודקים את הפונקציה באמצעות הפקודות הבאות:
# get the Service URL SERVICE_URL="$(gcloud run services describe nodejs-run-function --region $REGION --format 'value(status.url)')" # invoke the service curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
התשובה אמורה להיות ההודעה HTTP with Node.js in Cloud Run functions!
.
4. פונקציית Pub/Sub
בפונקציה השנייה, נגדיר פונקציית Python שתופעל על ידי הודעת Pub/Sub שפורסמה בנושא ספציפי.
הגדרת אסימוני אימות של Pub/Sub
אם הפעלתם את חשבון השירות של Pub/Sub ב-8 באפריל 2021 או לפני כן, מקצים את התפקיד iam.serviceAccountTokenCreator
לחשבון השירות של Pub/Sub:
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)') gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:service-$PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \ --role roles/iam.serviceAccountTokenCreator
יצירה
יוצרים נושא Pub/Sub לשימוש בדוגמה:
TOPIC=cloud-run-functions-pubsub-topic gcloud pubsub topics create $TOPIC
יוצרים תיקייה לאפליקציה ומנווטים לתיקייה:
mkdir ../hello-pubsub cd ../hello-pubsub
יוצרים קובץ main.py
שמתעד ביומן הודעה שמכילה את מזהה CloudEvent:
import functions_framework @functions_framework.cloud_event def hello_pubsub(cloud_event): print('Pub/Sub with Python in Cloud Run functions! Id: ' + cloud_event['id'])
יוצרים קובץ requirements.txt
עם התוכן הבא כדי לציין את יחסי התלות:
functions-framework==3.*
פריסה
פורסים את הפונקציה:
gcloud run deploy python-pubsub-function \ --source . \ --function hello_pubsub \ --base-image python313 \ --region $REGION \ --no-allow-unauthenticated
אחזור של מספר הפרויקט שישמש לזהות של חשבון השירות.
PROJECT_NUMBER=$(gcloud projects list --filter="project_id:$PROJECT_ID" --format='value(project_number)')
יצירת הטריגר
gcloud eventarc triggers create python-pubsub-function-trigger \ --location=$REGION \ --destination-run-service=python-pubsub-function \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \ --transport-topic=projects/$PROJECT_ID/topics/$TOPIC \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
בדיקה
כדי לבדוק את הפונקציה, שולחים הודעה לנושא:
gcloud pubsub topics publish $TOPIC --message="Hello World"
אירוע CloudEvent שהתקבל אמור להופיע ביומן:
gcloud run services logs read python-pubsub-function --region $REGION --limit=10
5. Cloud Storage Function
בפונקציה הבאה נשתמש ב-Node.js כדי ליצור פונקציה שתגיב לאירועים מקטגוריה של Cloud Storage.
הגדרה
כדי להשתמש בפונקציות של Cloud Storage, מקצים לחשבון השירות של Cloud Storage את תפקיד ה-IAM pubsub.publisher
:
SERVICE_ACCOUNT=$(gsutil kms serviceaccount -p $PROJECT_NUMBER) gcloud projects add-iam-policy-binding $PROJECT_ID \ --member serviceAccount:$SERVICE_ACCOUNT \ --role roles/pubsub.publisher
יצירה
יוצרים תיקייה לאפליקציה ומנווטים לתיקייה:
mkdir ../hello-storage cd ../hello-storage
יוצרים קובץ index.js
שמגיב לאירועים ב-Cloud Storage:
const functions = require('@google-cloud/functions-framework'); functions.cloudEvent('helloStorage', (cloudevent) => { console.log('Cloud Storage event with Node.js in Cloud Run functions!'); console.log(cloudevent); });
יוצרים קובץ package.json
כדי לציין את יחסי התלות:
{ "name": "nodejs-crf-cloud-storage", "version": "0.0.1", "main": "index.js", "dependencies": { "@google-cloud/functions-framework": "^2.0.0" } }
פריסה
קודם כול יוצרים קטגוריה של Cloud Storage (או משתמשים בקטגוריה קיימת שכבר יש לכם):
export BUCKET_NAME="gcf-storage-$PROJECT_ID" export BUCKET="gs://gcf-storage-$PROJECT_ID" gsutil mb -l $REGION $BUCKET
פורסים את הפונקציה:
gcloud run deploy nodejs-crf-cloud-storage \ --source . \ --base-image nodejs22 \ --function helloStorage \ --region $REGION \ --no-allow-unauthenticated
אחרי הפריסה, תוכלו לראות את הפונקציה בקטע Cloud Run במסוף Cloud.
עכשיו יוצרים את הטריגר של Eventarc.
BUCKET_REGION=$REGION gcloud eventarc triggers create nodejs-crf-cloud-storage-trigger \ --location=$BUCKET_REGION \ --destination-run-service=nodejs-crf-cloud-storage \ --destination-run-region=$REGION \ --event-filters="type=google.cloud.storage.object.v1.finalized" \ --event-filters="bucket=$BUCKET_NAME" \ --service-account=$PROJECT_NUMBER-compute@developer.gserviceaccount.com
בדיקה
כדי לבדוק את הפונקציה, מעלים קובץ לקטגוריה:
echo "Hello World" > random.txt gsutil cp random.txt $BUCKET/random.txt
אירוע CloudEvent שהתקבל אמור להופיע ביומן:
gcloud run services logs read nodejs-crf-cloud-storage --region $REGION --limit=10
6. חלוקת תנועה
פונקציות Cloud Run תומכות בכמה גרסאות של הפונקציות, בחלוקת התנועה בין גרסאות שונות ובחזרה לגרסה קודמת של הפונקציה.
בשלב הזה, תפרסו 2 גרסאות של פונקציה ואז תחלקו את התנועה ביניהן ביחס של 50-50.
יצירה
יוצרים תיקייה לאפליקציה ומנווטים לתיקייה:
mkdir ../traffic-splitting cd ../traffic-splitting
יוצרים קובץ main.py
עם פונקציית Python שקוראת משתנה סביבה של צבע ומחזירה Hello World
בצבע הרקע הזה:
import os color = os.environ.get('COLOR') def hello_world(request): return f'<body style="background-color:{color}"><h1>Hello World!</h1></body>'
יוצרים קובץ requirements.txt
עם התוכן הבא כדי לציין את יחסי התלות:
functions-framework==3.*
פריסה
פורסים את הגרסה הראשונה של הפונקציה עם רקע כתום:
COLOR=orange gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
בשלב הזה, אם בודקים את הפונקציה על ידי הצגת הטריגר של ה-HTTP (פלט ה-URI של פקודת הפריסה שלמעלה) בדפדפן, אמור להופיע Hello World
עם רקע כתום:
פורסים את הגרסה השנייה עם רקע צהוב:
COLOR=yellow gcloud run deploy hello-world-colors \ --source . \ --base-image python313 \ --function hello_world \ --region $REGION \ --allow-unauthenticated \ --update-env-vars COLOR=$COLOR
מכיוון שזו הגרסה האחרונה, אם תבדקו את הפונקציה, אמורה להופיע Hello World
עם רקע צהוב:
חלוקת התנועה ביחס של 50-50
כדי לפצל את התנועה בין הגרסאות הכתומה והצהובה, צריך למצוא את מזהי הגרסאות של שירותי Cloud Run. זו הפקודה להצגת מזהי הגרסאות:
gcloud run revisions list --service hello-world-colors \ --region $REGION --format 'value(REVISION)'
הפלט אמור להיראות כך:
hello-world-colors-00001-man hello-world-colors-00002-wok
עכשיו צריך לפצל את התנועה בין שתי הגרסאות הבאות באופן הבא (מעדכנים את X-XXX
בהתאם לשמות הגרסאות):
gcloud run services update-traffic hello-world-colors \ --region $REGION \ --to-revisions hello-world-colors-0000X-XXX=50,hello-world-colors-0000X-XXX=50
בדיקה
כדי לבדוק את הפונקציה, נכנסים לכתובת ה-URL הציבורית שלה. חצי מהזמן אמורה להופיע הגרסה הכתומה, ובחצי השני אמורה להופיע הגרסה הצהובה:
מידע נוסף זמין במאמר החזרות לאחור, השקות הדרגתיות והעברת תנועה.
7. מספר מינימלי של מכונות
בפונקציות של Cloud Run, אפשר לציין מספר מינימלי של מכונות פונקציה שיישמרו במצב 'מוכנות' ויהיה אפשר להשתמש בהן כדי למלא בקשות. האפשרות הזו שימושית להגבלת מספר ההפעלות הראשוניות (cold start).
בשלב הזה, תפרסו פונקציה עם אתחול איטי. תוכלו לראות את הבעיה של ההפעלה במצב התחלתי (cold start). לאחר מכן, תפרסו את הפונקציה עם ערך המכונה המינימלי שמוגדר כ-1 כדי להיפטר מזמן ההפעלה הראשונית.
יצירה
יוצרים תיקייה לאפליקציה ועוברים אליה:
mkdir ../min-instances cd ../min-instances
יוצרים קובץ main.go
. לשירות Go הזה יש פונקציית init
שנכנסת למצב שינה למשך 10 שניות כדי לדמות אתחול ארוך. יש לו גם פונקציה HelloWorld
שמגיבה לשיחות HTTP:
package p import ( "fmt" "net/http" "time" ) func init() { time.Sleep(10 * time.Second) } func HelloWorld(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Slow HTTP Go in Cloud Run functions!") }
פריסה
פורסים את הגרסה הראשונה של הפונקציה עם ערך ברירת המחדל של אפס למכונה המינימלית:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated
בודקים את הפונקציה באמצעות הפקודה הבאה:
# get the Service URL SERVICE_URL="$(gcloud run services describe go-slow-function --region $REGION --format 'value(status.url)')" # invoke the service curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
בשיחה הראשונה תהיה עיכוב של 10 שניות (הפעלה קרה), ולאחר מכן תוצג ההודעה. שיחות חוזרות אמורות להתקבל באופן מיידי.
הגדרת מספר מינימלי של מכונות
כדי להימנע מהפעלה מחדש (cold start) בבקשה הראשונה, צריך לפרוס מחדש את הפונקציה עם הדגל --min-instances
מוגדר ל-1 באופן הבא:
gcloud run deploy go-slow-function \ --source . \ --base-image go123 \ --function HelloWorld \ --region $REGION \ --no-allow-unauthenticated \ --min-instances 1
בדיקה
בודקים שוב את הפונקציה:
curl -H "Authorization: bearer $(gcloud auth print-identity-token)" -X GET $SERVICE_URL
עיכוב של 10 שניות לא אמור להופיע יותר בבקשה הראשונה. הבעיה של הפעלה במצב התחלתי (cold start) בקריאה הראשונה (אחרי זמן רב ללא קריאה) נפתרה, בזכות מכונות מינימום!
מידע נוסף זמין במאמר שימוש במספר מינימלי של מכונות.
8. מעולה!
כל הכבוד על השלמת ה-Codelab!
מה עסקנו בו
- סקירה כללית על פונקציות Cloud Run ועל השימוש בעדכונים אוטומטיים של קובצי אימג' בסיסיים.
- איך כותבים פונקציה שתגיב לבקשות HTTP.
- איך לכתוב פונקציה שמגיבה להודעות Pub/Sub.
- איך כותבים פונקציה שמגיבה לאירועים ב-Cloud Storage.
- איך לפצל את התנועה בין שתי גרסאות.
- איך להימנע מהפעלה במצב התחלתי (cold start) באמצעות מכונות מינימליות.