1. מבוא
סקירה כללית
פונקציות של Cloud Run הן פתרון מחשוב קל למפתחים, שמאפשר ליצור פונקציות עצמאיות למטרה יחידה שאפשר להפעיל באמצעות HTTPS או להגיב ל-CloudEvents בלי לנהל שרת או סביבת זמן ריצה. בפוסט בבלוג שלנו תוכלו לקרוא מידע נוסף על הפונקציות של Cloud Run.
יש שתי גישות עיקריות לניהול הקריאות לפונקציות של Cloud Run: אבטחת הגישה על סמך זהות ואבטחת הגישה באמצעות אמצעי בקרת גישה מבוססי-רשת. ב-codelab הזה נסביר על הגישה הראשונה ונלמד 3 תרחישים לאבטחת הגישה על סמך זהות כדי להפעיל פונקציה:
- שימוש באסימון הזהות של gcloud כדי להפעיל פונקציה לצורכי פיתוח ובדיקה מקומיים
- התחזות לחשבון שירות במהלך פיתוח ובדיקה מקומיים, לצורך שימוש באותם פרטי כניסה כמו בסביבת הייצור
- שימוש בספריות הלקוח של Google לטיפול באימות מול Google Cloud APIs, למשל כששירות צריך להפעיל פונקציה
מה תלמדו
- איך מגדירים אימות בפונקציה של Cloud Run ומוודאים שהאימות הוגדר כראוי
- איך מפעילים פונקציה מאומתת מסביבת פיתוח מקומית על ידי מתן האסימון של הזהות ב-gcloud
- איך יוצרים חשבון שירות ונותנים לו את התפקיד המתאים להפעלת פונקציה
- איך מתחזים לשירות מסביבת פיתוח מקומית שיש לה את התפקידים המתאימים להפעלת פונקציה
2. הגדרה ודרישות
דרישות מוקדמות
- אתם מחוברים למסוף Cloud
- פרסתם בעבר פונקציית Cloud Run שמופעל על ידי טריגר HTTP. לדוגמה למדריך למתחילים
- (אופציונלי) בתרחיש השלישי, ב-codelab הזה נעשה שימוש ב-Node.js וב-npm כדוגמה, אבל אפשר להשתמש בכל סביבת זמן ריצה שנתמכת על ידי ספריות הלקוח של Google Auth.
הפעלת Cloud Shell
- במסוף Cloud, לוחצים על Activate Cloud Shell
.
אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג לכם מסך ביניים שמתאר מהו. אם יוצג לכם מסך ביניים, תוכלו ללחוץ על המשך.
תהליך ההקצאה וההתחברות ל-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. ה-Codelab הזה יסביר איך להקצות את התפקידים המתאימים ב-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 ועל התחברות auth של gcloud.
בשלב הבא, מפעילים את הפונקציה ומעבירים לה את אסימון הזהות.
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 שאפשר להתקין. ה-Codelab הזה ידריך אותך איך ליצור ולהפעיל אפליקציית 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
.