1. מבוא
סקירה כללית
ארגונים רבים משתמשים ברשת של ענן וירטואלי פרטי (VPC) ב-Google Cloud עם אמצעי בקרה היקפיים כדי למנוע זליגת נתונים, וכך לאבטח את תנועה ברשת של השירותים והאפליקציות שלהם. רשת VPC היא גרסה וירטואלית של רשת פיזית שמוטמעת בתוך רשת הייצור של Google. רשת VPC מספקת קישוריות למכונות וירטואליות (VM) ב-Compute Engine, מציעה מאזני עומסים פנימיים של רשת להעברת סיגנל ללא שינוי ומערכות proxy למאזני עומסים פנימיים של אפליקציות, מתחברת לרשתות מקומיות באמצעות מנהרות Cloud VPN וחיבורי VLAN ל-Cloud Interconnect, ומפיצה תנועה ממאזני עומסים חיצוניים של Google Cloud למערכות בק-אנד.
בניגוד למכונות וירטואליות, שירותי Cloud Run לא משויכים לרשת VPC מסוימת כברירת מחדל. ב-Codelab הזה נדגים איך משנים את הגדרות תעבורת הנתונים הנכנסת (ingress) (חיבורים נכנסים) כך שרק תעבורה שמגיעה מ-VPC תוכל לגשת לשירות Cloud Run (למשל, שירות לקצה העורפי). בנוסף, ב-Codelab הזה נסביר איך לגרום לשירות שני (למשל, שירות frontend) לגשת לשירות backend של Cloud Run דרך VPC, וגם להמשיך לקבל גישה לאינטרנט הציבורי.
בדוגמה הזו, שירות הקצה העורפי של Cloud Run מחזיר את המחרוזת hello world. שירות ה-Cloud Run של הקצה הקדמי מספק שדה להזנת קלט בממשק המשתמש לאיסוף כתובת URL. לאחר מכן, שירות הקצה הקדמי מבצע בקשת GET לכתובת ה-URL הזו (למשל, שירות הקצה העורפי), ולכן זו בקשה משירות לשירות (במקום בקשה מדפדפן לשירות). כששירות הקצה הקדמי מצליח להגיע לקצה האחורי, ההודעה hello world מוצגת בדפדפן. לאחר מכן תראו איך אפשר להתקשר אל https://curlmyip.org כדי לאחזר את כתובת ה-IP של שירות הקצה הקדמי.
מה תלמדו
- איך מאפשרים רק תעבורה מרשת VPC לשירות Cloud Run
- איך מגדירים תעבורת נתונים יוצאת (egress) בשירות Cloud Run (למשל, קצה קדמי) כדי לתקשר עם שירות Cloud Run פנימי (למשל, בק-אנד) עם תעבורת נתונים נכנסת (ingress) פנימית בלבד, תוך שמירה על גישה לאינטרנט הציבורי לשירות הקצה הקדמי.
2. הגדרה ודרישות
דרישות מוקדמות
- אתם מחוברים ל-Cloud Console.
- כבר פרסתם פונקציה מדור שני. לדוגמה, אפשר לפעול לפי ההוראות שבמדריך למתחילים של Cloud Functions מדור שני כדי להתחיל.
הפעלת Cloud Shell
- ב-Cloud Console, לוחצים על 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
הגדרה של משתני סביבה
אתם יכולים להגדיר משתני סביבה שישמשו אתכם לאורך כל ה-codelab הזה.
PROJECT_ID=<YOUR_PROJECT_ID> REGION=<YOUR_REGION, e.g. us-central1> FRONTEND=frontend-with-internet BACKEND=backend SUBNET_NAME=default
יצירת שירות הקצה העורפי ב-Cloud Run
קודם יוצרים ספרייה לקוד המקור ועוברים לספרייה הזו.
mkdir -p egress-private-codelab/frontend-w-internet egress-private-codelab/backend && cd egress-private-codelab/backend
לאחר מכן, יוצרים קובץ `package.json`` עם התוכן הבא:
{
"name": "backend-service",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"express": "^4.18.1"
}
}
לאחר מכן, יוצרים קובץ מקור index.js עם התוכן שבהמשך. הקובץ הזה מכיל את נקודת הכניסה לשירות ואת הלוגיקה העיקרית של האפליקציה.
const express = require('express');
const app = express();
app.use(express.urlencoded({ extended: true }));
app.get('/', function (req, res) {
res.send("hello world");
});
const port = parseInt(process.env.PORT) || 8080;
app.listen(port, () => {
console.log(`helloworld: listening on port ${port}`);
});
לבסוף, פורסים את שירות Cloud Run באמצעות הפקודה הבאה.
gcloud run deploy $BACKEND --source . --allow-unauthenticated --region $REGION
יצירת שירות הקצה הקדמי ב-Cloud Run
ניווט לספריית ה-frontend
cd ../frontend-w-internet
לאחר מכן, יוצרים קובץ package.json עם התוכן הבא:
{
"name": "frontend",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "node index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^1.6.6",
"express": "^4.18.2",
"htmx.org": "^1.9.10"
}
}
לאחר מכן, יוצרים קובץ מקור index.js עם התוכן שבהמשך. הקובץ הזה מכיל את נקודת הכניסה לשירות ואת הלוגיקה העיקרית של האפליקציה.
const express = require("express");
const app = express();
const port = 8080;
const path = require('path');
const axios = require('axios');
// serve static content (index.html) using
// built-in middleware function in Express
app.use(express.static('public'));
app.use(express.urlencoded({ extended: true }));
// this endpoint receives a URL in the post body
// and then makes a get request to that URL
// results are sent back to the caller
app.post('/callService', async (req, res) => {
const url = req.body.url;
let message = "";
try {
console.log("url: ", url);
const response = await axios.get(url);
message = response.data;
} catch (error) {
message = error.message;
console.error(error.message);
}
res.send(`
${message}
<p>
</p>
`);
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
יצירת ספרייה ציבורית לקובץ index.html
mkdir public touch public/index.html
מעדכנים את הפרמטר index.html כך שיכלול את הערכים הבאים:
<html>
<script
src="https://unpkg.com/htmx.org@1.9.10"
integrity="sha384-D1Kt99CQMDuVetoL1lrYwg5t+9QdHe7NLX/SoJYkXDFfX37iInKRy5xLSi8nO7UC"
crossorigin="anonymous"
></script>
<body>
<div style="margin-top: 100px; margin-left: 100px">
<h1>I'm the Request Tester service on the Internet</h1>
<form hx-trigger="submit" hx-post="/callService" hx-target="#zen">
<label for="url"> URL:</label>
<input
style="width: 308px"
type="text"
id="url"
name="url"
placeholder="The backend service URL"
required
/>
<button hx-indicator="#loading" type="submit">Submit</button>
<p></p>
<span class="htmx-indicator" id="loading"> Loading... </span>
<div id="zen" style="white-space: pre-wrap"></div>
<p></p>
</form>
</div>
</body>
</html>
לבסוף, פורסים את שירות Cloud Run באמצעות הפקודה הבאה.
gcloud run deploy $FRONTEND --source . --allow-unauthenticated --region $REGION
התקשרות לשירות לקצה העורפי
בקטע הזה תבדקו שפרסתם בהצלחה שני שירותים של Cloud Run.
פותחים את כתובת ה-URL של שירות ה-frontend בדפדפן האינטרנט, לדוגמה https://frontend-your-hash-uc.a.run.app/
בתיבת הטקסט, מזינים את כתובת ה-URL של שירות הבק-אנד. שימו לב שהבקשה הזו מנותבת ממופע הקצה הקדמי של Cloud Run לשירות הקצה העורפי של Cloud Run, ולא מהדפדפן שלכם.
יופיע הכיתוב hello world
4. הגדרת שירות לקצה העורפי רק לתעבורה פנימית
כדי לשלב שירות Cloud Run ברשת הפרטית, מריצים את פקודת gcloud הבאה.
gcloud run services update $BACKEND --ingress internal --region $REGION
אם תנסו להתקשר לשירות העורפי מהשירות החזיתי, תקבלו שגיאת 404. החיבור היוצא (או תעבורת נתונים יוצאת (egress)) של שירות Cloud Run בממשק הקצה הקדמי יוצא קודם לאינטרנט, ולכן Google Cloud לא יודעת מה המקור של הבקשה.
5. הגדרת שירות הקצה הקדמי לגישה ל-VPC
בקטע הזה תגדירו את שירות הקצה הקדמי של Cloud Run כדי שיוכל לתקשר עם שירות הקצה האחורי דרך VPC.
כדי לעשות את זה, צריך להוסיף תעבורת נתונים יוצאת (egress) ישירה מ-VPC לשירות הקצה הקדמי של Cloud Run כדי לוודא שהוא יכול להגיע לכתובות IP פנימיות ברשת ה-VPC. לאחר מכן, תגדירו יציאה כך שרק בקשות לכתובות IP פרטיות ינותבו ל-VPC. ההגדרה הזו תאפשר לחלק הקצה של האתר שלכם להמשיך להגיע לאינטרנט הציבורי. מידע נוסף זמין במאמר בנושא קבלת בקשות משירותים אחרים ב-Cloud Run.
הגדרת תעבורת נתונים יוצאת (egress) ישירה מ-VPC
קודם מריצים את הפקודה הזו כדי להשתמש ביציאה ישירה של VPC בשירות הקצה הקדמי:
gcloud beta run services update $FRONTEND \ --network=$SUBNET_NAME \ --subnet=$SUBNET_NAME \ --vpc-egress=private-ranges-only \ --region=$REGION
עכשיו אפשר לוודא שלשירות הקצה הקדמי יש גישה ל-VPC:
gcloud beta run services describe $FRONTEND \ --region=$REGION
הפלט אמור להיראות כך:
VPC access:
Network: default
Subnet: default
Egress: private-ranges-only
הפעלת גישה פרטית ל-Google
בשלב הבא מפעילים גישה פרטית ל-Google ברשת המשנה על ידי הפעלת הפקודה הבאה:
gcloud compute networks subnets update $SUBNET_NAME \ --region=$REGION \ --enable-private-ip-google-access
כדי לוודא שהופעלה גישה פרטית ל-Google, מריצים את הפקודה הבאה:
gcloud compute networks subnets describe $SUBNET_NAME \ --region=$REGION \ --format="get(privateIpGoogleAccess)"
יצירת תחום DNS ב-Cloud DNS לכתובות URL של run.app
לבסוף, יוצרים תחום DNS של Cloud לכתובות URL של run.app כדי ש-Google Cloud יוכל להתייחס אליהן כאל כתובות IP פנימיות.
בשלב הקודם, כשמגדירים יציאה ישירה מ-VPC לטווחים פרטיים בלבד. המשמעות היא שחיבורים יוצאים משירות ה-frontend שלכם יועברו לרשת ה-VPC רק אם היעד הוא כתובת IP פנימית. עם זאת, שירות לקצה העורפי שלכם משתמש בכתובת URL מסוג run.app שמפנה לכתובת IP ציבורית.
בשלב הזה, יוצרים תחום DNS של Cloud DNS לכתובות ה-URL של run.app כדי לפתור את טווחי כתובות ה-IP של private.googleapis.com, שמזוהים ככתובות IP פנימיות. מעכשיו, כל הבקשות לטווחים האלה ינותבו דרך רשת ה-VPC.
אפשר לעשות את זה באמצעות: https://cloud.google.com/run/docs/securing/private-networking#from-other-services
# do not include the https:// in your DNS Name # for example: backend-<hash>-uc.a.run.app DNS_NAME=<your backend service URL without the https://> gcloud dns --project=$PROJECT_ID managed-zones create codelab-backend-service \ --description="" \ --dns-name="a.run.app." \ --visibility="private" \ --networks=$SUBNET_NAME gcloud dns --project=$PROJECT_ID record-sets create $DNS_NAME. \ --zone="codelab-backend-service" \ --type="A" \ --ttl="60" \ --rrdatas="199.36.153.8,199.36.153.9,199.36.153.10,199.36.153.11"
עכשיו, כשמנסים להגיע לשירות לקצה העורפי של האתר, מוצגת ההודעה hello world.
כשמנסים לגשת לאינטרנט באמצעות https://curlmyip.org/, כתובת ה-IP מוצגת.
6. פתרון בעיות
בהמשך מפורטות כמה הודעות שגיאה אפשריות שיוצגו אם ההגדרות לא הוגדרו בצורה נכונה.
- אם מופיעה השגיאה
getaddrinfo ENOTFOUND backend-your-hash-uc.a.run.app, מוודאים שלא הוספתם את הקידומת https:// לרשומת ה-A של ה-DNS. - אם מופיעה שגיאת 404 כשמנסים לגשת לחלק האחורי של האתר אחרי הגדרת האזור, אפשר לחכות עד שתוקף המטמון ברשומה הגלובלית run.app יפוג (למשל, 6 שעות), או ליצור גרסה חדשה (ובכך לנקות את המטמון) על ידי הפעלת הפקודה הבאה:
gcloud beta run services update $FRONTEND --network=$SUBNET_NAME --subnet=$SUBNET_NAME --vpc-egress=private-ranges-only --region=$REGION
7. מעולה!
כל הכבוד, סיימתם את ה-Codelab!
מומלץ לעיין במסמכי התיעוד בנושא רשת פרטית ב-Cloud Run.
מה נכלל
- איך מאפשרים רק תעבורה מרשת VPC לשירות Cloud Run
- איך מגדירים תעבורת נתונים יוצאת (egress) בשירות Cloud Run (למשל, קצה קדמי) כדי לתקשר עם שירות Cloud Run פנימי (למשל, בק-אנד) עם תעבורת נתונים נכנסת (ingress) פנימית בלבד, תוך שמירה על גישה לאינטרנט הציבורי לשירות הקצה הקדמי.
8. הסרת המשאבים
כדי להימנע מחיובים לא מכוונים (לדוגמה, אם שירות Cloud Run הזה מופעל בטעות יותר פעמים מההקצאה החודשית של הפעלות Cloud Run בחבילה ללא תשלום), אפשר למחוק את שירות Cloud Run או את הפרויקט שיצרתם בשלב 2.
כדי למחוק את שירותי Cloud Run, נכנסים אל Cloud Run Cloud Console בכתובת https://console.cloud.google.com/functions/ ומוחקים את השירותים $FRONTEND ו-$BACKEND שיצרתם ב-codelab הזה.
אם אתם רוצים למחוק את הפרויקט כולו, אתם יכולים להיכנס לכתובת https://console.cloud.google.com/cloud-resource-manager, לבחור את הפרויקט שיצרתם בשלב 2 וללחוץ על 'מחיקה'. אם תמחקו את הפרויקט, תצטרכו לשנות את הפרויקטים ב-Cloud SDK. כדי לראות את רשימת כל הפרויקטים הזמינים, מריצים את הפקודה gcloud projects list.