1. מבוא
סקירה כללית
פונקציות של Cloud Run הן פתרון מחשוב קל למפתחים, שמאפשר ליצור פונקציות עצמאיות למטרה יחידה שאפשר להפעיל באמצעות HTTPS או להגיב ל-CloudEvents בלי לנהל שרת או סביבת זמן ריצה. בפוסט בבלוג שלנו תוכלו לקרוא מידע נוסף על הפונקציות של Cloud Run.
יש שתי גישות עיקריות לניהול הקריאות לפונקציות של Cloud Run: אבטחת הגישה על סמך זהות ואבטחת הגישה באמצעות אמצעי בקרת גישה מבוססי-רשת. ב-codelab הזה נסביר על הגישה הראשונה ונלמד 3 תרחישים לאבטחת הגישה על סמך זהות כדי להפעיל פונקציה:
- איך משתמשים באסימון הזהות של gcloud כדי להפעיל פונקציה למטרות פיתוח ובדיקה מקומיים
- התחזות לחשבון שירות במהלך פיתוח ובדיקה מקומיים, לצורך שימוש באותם פרטי כניסה כמו בסביבת הייצור
- שימוש בספריות הלקוח של Google לטיפול באימות לממשקי Google Cloud API, למשל כששירות צריך להפעיל פונקציה
מה תלמדו
- איך מגדירים אימות בפונקציה של Cloud Run ומוודאים שהאימות הוגדר כראוי
- איך מפעילים פונקציה מאומתת מסביבת פיתוח מקומית על ידי מתן האסימון של הזהות ב-gcloud
- איך יוצרים חשבון שירות ונותנים לו את התפקיד המתאים להפעלת פונקציה
- איך מתחזים לשירות מסביבת פיתוח מקומית שיש לה את התפקידים המתאימים להפעלת פונקציה
2. הגדרה ודרישות
דרישות מוקדמות
- אתם מחוברים למסוף Cloud
- פרסתם בעבר פונקציית HTTP שהופעלה על ידי Cloud Run. דוגמה במדריך למתחילים
- (אופציונלי) בתרחיש השלישי, ב-codelab הזה נעשה שימוש ב-Node.js וב-npm כדוגמה, אבל אפשר להשתמש בכל סביבת זמן ריצה שנתמכת על ידי ספריות הלקוח של Google Auth.
הפעלת Cloud Shell
- במסוף Cloud, לוחצים על Activate Cloud Shell
.
אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג מסך ביניים עם תיאור של השירות. אם יוצג מסך ביניים, לוחצים על Continue (המשך).
תהליך ההקצאה וההתחברות ל-Cloud Shell אמור להימשך רק כמה רגעים.
במכונה הווירטואלית הזו נמצאים כל כלי הפיתוח הדרושים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, משפרת מאוד את הביצועים והאימות של הרשת. אפשר לבצע את רוב העבודה ב-codelab הזה, אם לא את כולה, באמצעות דפדפן.
אחרי שתתחברו ל-Cloud Shell, אמורה להופיע הודעה על כך שהאימות בוצע והפרויקט מוגדר לפי מזהה הפרויקט שלכם.
- מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהאימות בוצע:
gcloud auth list
פלט הפקודה
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
- מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהפקודה gcloud מכירה את הפרויקט:
gcloud config list project
פלט הפקודה
[core] project = <PROJECT_ID>
אם לא, אפשר להגדיר אותו באמצעות הפקודה הבאה:
gcloud config set project <PROJECT_ID>
פלט הפקודה
Updated property [core/project].
3. יצירת פונקציה מאומתת ב-Cloud Run ובדיקה שלה
דרישה לאימות פירושה שלעיקרון שמפעיל את הפונקציה צריך להיות התפקיד Cloud Run Invoker. אחרת, הפונקציה תחזיר את השגיאה 403 Forbidden. בקודלאב הזה תלמדו איך להקצות לחשבון משתמש את התפקידים המתאימים של Invoker.
הגדרת משתני סביבה מקומיים לפקודות gcloud פשוטות יותר
קודם כול, ניצור כמה משתני סביבה כדי לשפר את הקריאוּת של פקודות gcloud
שבהן נעשה שימוש ב-codelab הזה.
REGION=us-central1 PROJECT_ID=$(gcloud config get-value project)
יצירת קוד המקור של הפונקציה
למרות שבקודלאב הזה נעשה שימוש ב-Node.js, אפשר להשתמש בכל סביבת זמן ריצה שנתמכת בספריות הלקוח של Google Auth.
קודם יוצרים ספרייה ומעבירים את נתיב העבודה (cd) לספרייה הזו.
mkdir auth-function-codelab && cd $_
לאחר מכן יוצרים את הקובץ package.json.
touch package.json echo '{ "dependencies": { "@google-cloud/functions-framework": "^3.0.0" } } ' > package.json
בשלב הבא יוצרים את קובץ המקור index.js.
touch index.js echo 'const functions = require("@google-cloud/functions-framework"); functions.http("helloWorld", (req, res) => { res.send(`Hello ${req.query.name || req.body.name || "World"}!`); });' > index.js
יצירת הפונקציה המאומתת
אלה השלבים ליצירת פונקציה מאומתת בסביבת זמן הריצה nodejs20. עם זאת, אפשר להשתמש בכל סביבת זמן ריצה שנתמכת על ידי ספריות הלקוח של Google Auth.
FUNCTION_NAME=authenticated-function-codelab ENTRY_POINT=helloWorld
כדי לפרוס פונקציה של Cloud Run ישירות ב-Cloud Run, מריצים את הפקודה הבאה:
gcloud beta run deploy $FUNCTION_NAME \ --source . \ --function helloWorld \ --region $REGION \ --no-allow-unauthenticated
ואז תוכלו לשמור את כתובת ה-URL של הפונקציה כמשתנה סביבה כדי להשתמש בה מאוחר יותר.
FUNCTION_URL="$(gcloud run services describe $FUNCTION_NAME --region $REGION --format 'value(status.url)')"
אם אתם מעדיפים לפרוס את Cloud Functions דור שני, תוכלו להשתמש בפקודה הבאה:
gcloud functions deploy nodejs-http-function \ --gen2 \ --runtime=nodejs20 \ --region=$REGION \ --source=. \ --entry-point=helloWorld \ --trigger-http \ --no-allow-unauthenticated
ואז תוכלו לשמור את כתובת ה-URL של הפונקציה כמשתנה סביבה כדי להשתמש בה מאוחר יותר.
FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --gen2 --region us-central1 --format='get(serviceConfig.uri)')"
כדי לוודא שהפונקציה מחייבת אימות על ידי ניסיון להפעיל קריאה אנונימית
כדי לוודא שאתם מקבלים שגיאה צפויה מסוג 403, יש להפעיל את הפונקציה ללא אימות.
מריצים את הפקודה הבאה של curl
משורת הפקודה:
curl -i $FUNCTION_URL
התוצאה שתוצג היא:
<html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>403 Forbidden</title> </head> <body text=#000000 bgcolor=#ffffff> <h1>Error: Forbidden</h1> <h2>Your client does not have permission to get URL <code>/</code> from this server.</h2> <h2></h2> </body></html>
עכשיו אתם מוכנים לעבור על 3 תרחישים שבהם אפשר להפעיל את הפונקציה על ידי מתן אימות.
4. תרחיש 1: שימוש באסימון הזהות של gcloud
בתור מפתחים, חשוב שתהיה לכם דרך לבדוק את הפונקציה שלכם תוך כדי הפיתוח שלה באופן מקומי. בקטע הזה נעשה בדיקה מהירה כדי לוודא שהפונקציה מאומתת כראוי באמצעות הזהות שלכם.
מריצים את הפקודה הבאה כדי לוודא שהאימות בוצע באמצעות gcloud
:
gcloud auth list
אמורה להופיע כוכבית לצד הזהות הפעילה, לדוגמה:
Credentialed Accounts ACTIVE ACCOUNT * <my_account>@<my_domain.com> To set the active account, run: $ gcloud config set account `ACCOUNT`
מידע נוסף על הגדרת gcloud init ועל gcloud auth login זמין במסמכי העזרה.
בשלב הבא, מפעילים את הפונקציה ומעבירים לה את אסימון הזהות.
curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token)"
עכשיו אמורה להופיע התוצאה:
Hello World!
פתרון בעיות
אם מופיעה הודעת השגיאה 403 Forbidden, צריך לוודא שהזהות שלכם כוללת את התפקיד Cloud Run Invoker. אפשר להשתמש במסוף IAM כדי לאמת את התפקידים שהוענקו לחשבון משתמש.
השימוש באסימון הזהות שלכם הוא דרך מהירה לבדוק את הפונקציה במהלך הפיתוח, אבל למבצע הקריאה החוזרת של הפונקציה המאומתת יידרשו התפקידים המתאימים. אחרת, מבצע הקריאה החוזרת יקבל הודעת שגיאה מסוג 403 Forbidden.
כדאי לשמור על העיקרון של הרשאות מינימליות על ידי הגבלת מספר הזהויות וחשבונות השירות שיש להם תפקידים להפעלת הפונקציה. בתרחיש הבא תלמדו איך ליצור חשבון שירות חדש ולהקצות לו את התפקידים המתאימים כדי להפעיל את הפונקציה.
5. תרחיש 2: התחזות לחשבון שירות
בתרחיש הזה, מתחזים (כלומר מקבלים את ההרשאות) לחשבון שירות כדי להפעיל פונקציה במהלך הפיתוח והבדיקה המקומיים. כשמתחזים לחשבון שירות, אפשר לבדוק את הפונקציה עם אותם פרטי כניסה כמו בסביבת הייצור.
כך לא רק תוכלו לאמת את התפקידים, אלא גם לפעול בהתאם לעקרון של הרשאות מינימליות, כי לא תצטרכו להקצות את התפקיד Cloud Functions Invoker לזהויות אחרות רק למטרות בדיקה מקומית.
לצורך סדנת הקוד הזו, ניצור חשבון שירות חדש שיש לו רק תפקידים להפעלת הפונקציה שיצרתם בסדנת הקוד הזו.
יצירת חשבון שירות חדש
קודם כול, יוצרים כמה משתני סביבה נוספים שמייצגים את חשבונות השירות שמשמשים את הפקודות של gcloud.
SERVICE_ACCOUNT_NAME="invoke-functions-codelab" SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com
בשלב הבא יוצרים את חשבון השירות.
gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \ --display-name="Cloud Run function Authentication codelab"
מקצים לחשבון השירות את התפקיד Cloud Run invoker:
gcloud run services add-iam-policy-binding $FUNCTION_NAME \ --region=us-central1 \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role='roles/run.invoker'
קריאה לפונקציה על ידי התחזות לחשבון השירות
לשם כך, מתחזים לחשבון השירות החדש שנוצר על ידי קבלת אסימון המזהה שלו.
הוספת התפקידים הנדרשים להתחזות
כדי להתחזות לחשבון שירות, חשבון המשתמש צריך את התפקיד 'יצירת אסימונים בחשבון שירות' (roles/iam.serviceAccountTokenCreator) כדי ליצור אסימון מזהה לחשבון השירות.
כדי לתת לחשבון המשתמש הפעיל את התפקיד הזה, מריצים את הפקודות הבאות:
ACCOUNT_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)") gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_ADDRESS \ --member user:$ACCOUNT_EMAIL \ --role='roles/iam.serviceAccountTokenCreator'
שימוש באסימון המזהה של חשבון השירות
ממתינים כמה דקות עד שההרשאות יופצו. עכשיו אפשר להפעיל את הפונקציה על ידי העברה של האסימון המזהה של חשבון השירות.
curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token --impersonate-service-account $SERVICE_ACCOUNT_ADDRESS)"
יוצגו לכם הפרטים הבאים:
WARNING: This command is using service account impersonation. All API calls will be executed as [invoke-functions-codelab@<project-id>.iam.gserviceaccount.com]. Hello World!
6. תרחיש 3: שימוש בספריות הלקוח של Google
בקטע האחרון של סדנת הקוד, תפעילו שירות קטן באופן מקומי כדי ליצור אסימון מזהה לחשבון שירות, ולאחר מכן תבצעו קריאה פרוגרמטית לפונקציה באמצעות ספריות הלקוח של Google Auth ו-Application Default Credentials (ADC). מידע נוסף על ספריות הלקוח של Google זמין בקטע 'הסבר על ספריות לקוח' במסמכים.
חשוב במיוחד להשתמש ב-ADC כשרוצים לכתוב ולבדוק את הפונקציה באופן מקומי (למשל, במחשב הנייד, ב-Cloud Shell וכו') תוך אינטראקציה עם משאבים אחרים של Google Cloud (למשל, Cloud Storage, Vision API וכו'). בדוגמה הזו נסביר איך להפעיל פונקציה אחרת שמחייבת אימות. למידע נוסף על ADC ועל פיתוח מקומי, אפשר לעיין בפוסט בבלוג איך מפתחים ומבדקים את Cloud Functions באופן מקומי | הבלוג של Google Cloud.
הפעלת הפקודה gcloud כדי להתחזות לחשבון שירות
השירות ADC מוצא באופן אוטומטי את פרטי הכניסה על סמך הסביבה שבה פועלת האפליקציה, ומשתמש בהם לאימות מול ממשקי ה-API של Google Cloud. הדגל –impersonate-service-account מאפשר להתחזות לחשבון שירות באמצעות הזהות שלו לצורך אימות מול ממשקי Google Cloud APIs.
כדי להתחזות לחשבון שירות, אפשר להריץ את הפקודה הבאה:
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
עכשיו מריצים פקודות של gcloud בתור חשבון השירות הזה, במקום הזהות שלכם.
יצירת שירות והפעלה שלו כדי להפעיל פונקציה מאומתת
לכל סביבת זמן ריצה יש ספריית לקוח משלה של Google Auth שאפשר להתקין. בקודלאב הזה תלמדו איך ליצור אפליקציית Node.js ולהריץ אותה באופן מקומי.
אלה השלבים ל-Node.js:
- יצירת ספרייה חדשה
mkdir local-dev && cd $_
- יצירת אפליקציה חדשה ב-Node.js
npm init -y
- התקנה של ספריית הלקוח של Google Auth
npm install google-auth-library
- יצירת קובץ
index.js
- מאחזרים את כתובת ה-URL של הפונקציה ב-Cloud Run, שתוסיפו לקוד בשלב הבא.
echo $FUNCTION_URL
- מוסיפים את הקוד הבא לקובץ index.js. חשוב לשנות את המשתנה targetAudience לכתובת ה-URL של הפונקציה Cloud Run.
index.js
// Cloud Functions uses your function's url as the `targetAudience` value
const targetAudience = '<YOUR-CLOUD-RUN-FUNCTION-URL>';
// For Cloud Functions, endpoint(`url`) and `targetAudience` should be equal
const url = targetAudience;
const { GoogleAuth } = require('google-auth-library');
const auth = new GoogleAuth();
async function request() {
console.info(`request ${url} with target audience ${targetAudience}`);
// this call retrieves the ID token for the impersonated service account
const client = await auth.getIdTokenClient(targetAudience);
const res = await client.request({ url });
console.info(res.data);
}
request().catch(err => {
console.error(err.message);
process.exitCode = 1;
});
- הפעלת האפליקציה
node index.js
ואמור להופיע הכיתוב 'Hello World!'.
פתרון בעיות
אם מופיעה השגיאה Permission ‘iam.serviceAccounts.getOpenIdToken' denied on resource (or it may not exist), צריך להמתין כמה דקות עד שההרשאה 'יצירת אסימונים בחשבון שירות' תופץ.
אם קיבלתם את הודעת השגיאה 'לא ניתן לאחזר אסימון מזהה בסביבה הזו, צריך להשתמש ב-GCE או להגדיר את משתנה הסביבה GOOGLE_APPLICATION_CREDENTIALS לקובץ JSON של פרטי הכניסה לחשבון שירות', יכול להיות שכחתם להריץ את הפקודה
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
7. מעולה!
כל הכבוד על השלמת ה-Codelab!
מומלץ לעיין במסמכי העזרה בנושא אבטחת פונקציות ב-Cloud Run.
מומלץ גם לקרוא את הפוסט בבלוג על פיתוח מקומי עם פונקציות של Cloud Run כדי ללמוד איך לפתח ולבדוק את הפונקציה של Cloud Run בסביבת הפיתוח המקומית.
מה עסקנו בו
- איך מגדירים אימות בפונקציה של Cloud Run ומוודאים שהאימות הוגדר כראוי
- איך מפעילים פונקציה מאומתת מסביבת פיתוח מקומית על ידי מתן האסימון של הזהות ב-gcloud
- איך יוצרים חשבון שירות ונותנים לו את התפקיד המתאים להפעלת פונקציה
- איך מתחזים לשירות מסביבת פיתוח מקומית שיש לה את התפקידים המתאימים להפעלת פונקציה
8. הסרת המשאבים
כדי להימנע מחיובים לא מכוונים (לדוגמה, הפעלה לא מכוונת של Cloud Function יותר פעמים מההקצאה החודשית שלכם להפעלת פונקציות ב-Cloud Run ברמה החינמית), אתם יכולים למחוק את Cloud Function או למחוק את הפרויקט שיצרתם בשלב 2.
כדי להפסיק את ההתחזות לחשבון השירות, תוכלו להתחבר מחדש באמצעות הזהות שלכם:
gcloud auth application-default login
כדי למחוק את הפונקציה של Cloud Run, עוברים למסוף Cloud של Cloud Run בכתובת https://console.cloud.google.com/functions/. מוודאים שהפרויקט שיצרתם בשלב 2 הוא הפרויקט שנבחר כרגע.
בוחרים את my-authenticated-function שפרסמתם מקודם. לאחר מכן מקישים על מחיקה.
אם בוחרים למחוק את הפרויקט כולו, אפשר לעבור אל https://console.cloud.google.com/cloud-resource-manager, לבחור את הפרויקט שיצרתם בשלב 2 ולבחור באפשרות Delete (מחיקה). אם תמחקו את הפרויקט, יהיה צריך לבצע שינויים בפרויקטים ב-Cloud SDK. כדי להציג את רשימת כל הפרויקטים הזמינים, מריצים את הפקודה gcloud projects list
.