1. מבוא
סקירה כללית
כדי לאבטח את תעבורת הנתונים ברשת עבור השירותים והאפליקציות שלהם, ארגונים רבים משתמשים ברשת ענן וירטואלי פרטי (VCP) ב-Google Cloud עם אמצעי בקרה היקפיים שמונעים זליגת נתונים. רשת VPC היא גרסה וירטואלית של רשת פיזית שמוטמעת בתוך רשת הייצור של Google. רשת VPC מספקת קישוריות למכונות הווירטואליות (VM) של Compute Engine, מציעה מאזני עומסים פנימיים של רשתות חיצוניות ומערכות לשרת proxy עבור מאזני עומסים פנימיים באפליקציות, מתחברת לרשתות מקומיות באמצעות מנהרות Cloud VPN וקבצים מצורפים ל-VLAN בשביל Cloud Interconnect, ומפיצה תעבורת נתונים מאזני עומסים חיצוניים של Google Cloud לקצה העורפי.
בניגוד למכונות וירטואליות, שירותי Cloud Run לא משויכים לרשת VPC מסוימת כברירת מחדל. ה-Codelab הזה מדגים איך לשנות הגדרות של תעבורת נתונים נכנסת (ingress) (חיבורים נכנסים), כך שרק תנועה שמגיעה מ-VPC יכולה לגשת לשירות Cloud Run (למשל לשירות לקצה העורפי). בנוסף, בשיעור הזה תלמדו איך לתת לשירות שני (למשל שירות קצה קדמי) לגשת לשירות Cloud Run לקצה העורפי דרך VPC, וגם להמשיך לקבל גישה ציבורית לאינטרנט.
בדוגמה הזו, שירות Cloud Run הקצה העורפי מחזיר את World hello. שירות Cloud Run בקצה הקדמי מספק בממשק המשתמש שדה להזנת קלט, לאיסוף כתובת URL. לאחר מכן שירות הקצה הקדמי שולח בקשת GET לכתובת ה-URL הזו (למשל, השירות לקצה העורפי), ולכן הוא הופך לבקשת שירות לשירות (ולא מאתר לבקשת שירות). כששירות הקצה הקדמי יכול להגיע לקצה העורפי, הודעת שלום העולם מוצגת בדפדפן. לאחר מכן נסביר איך אפשר לבצע שיחה אל https://curlmyip.org כדי לאחזר את כתובת ה-IP של שירות הקצה הקדמי.
מה תלמדו
- איך לאפשר תעבורת נתונים רק מ-VPC לשירות Cloud Run
- איך להגדיר תעבורת נתונים יוצאת (egress) בשירות Cloud Run (למשל קצה קדמי) כדי לתקשר עם שירות Cloud Run לתעבורת נתונים נכנסת (ingress) פנימית בלבד (למשל, קצה עורפי), תוך שמירה על גישה ציבורית לאינטרנט לשירות הקצה הקדמי.
2. הגדרה ודרישות
דרישות מוקדמות
- אתם מחוברים למסוף Cloud.
- פרסתם בעבר פונקציה של דור שני. לדוגמה, תוכלו להיעזר במדריך לפריסת מדריך למתחילים של Cloud Functions דור שני.
הפעלת 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
הגדרה של משתני סביבה
אתם יכולים להגדיר משתני סביבה שישמשו ב-Codelab הזה.
PROJECT_ID=<YOUR_PROJECT_ID> REGION=<YOUR_REGION, e.g. us-central1> FRONTEND=frontend-with-internet BACKEND=backend SUBNET_NAME=default
יצירת שירות Cloud Run לקצה העורפי
קודם כול, יוצרים ספרייה עבור קוד המקור וה-cd בספרייה הזו.
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 בקצה הקדמי
מעבר לספריית הקצה הקדמי
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 של השירות בקצה הקדמי בדפדפן, למשל. https://frontend-your-hash-uc.a.run.app/
בתיבת הטקסט, מזינים את כתובת ה-URL של השירות לקצה העורפי. שימו לב שהבקשה הזו מנותבת ממכונה הקצה הקדמי של Cloud Run לשירות Cloud Run לקצה העורפי, ולא מהדפדפן שלכם.
יופיע הכיתוב 'שלום עולם'
4. הגדרת השירות לקצה העורפי לתעבורת נתונים נכנסת (ingress) פנימית בלבד
תוכלו להריץ את הפקודה הבאה ב-gcloud כדי לשלב שירות Cloud Run ברשת הפרטית שלכם.
gcloud run services update $BACKEND --ingress internal --region $REGION
אם תנסו להתקשר לשירות לקצה העורפי מהשירות בקצה הקדמי, תקבלו שגיאה 404. החיבור היוצא (או תעבורת הנתונים היוצאת) (egress) של השירות החזיתי יוצא קודם לאינטרנט, ולכן ל-Google Cloud אין מידע על מקור הבקשה.
5. הגדרת שירות Frontend לגישה ל-VPC
בחלק הזה תגדירו את שירות Cloud Run בקצה הקדמי כדי שיתקשר עם השירות לקצה העורפי דרך VPC.
לשם כך, תצטרכו להוסיף תעבורת נתונים יוצאת (egress) ישירה של VPC לשירות Cloud Run בקצה הקדמי כדי לוודא שהיא יכולה להגיע לכתובות IP פנימיות ברשת ה-VPC. לאחר מכן צריך להגדיר תעבורת נתונים יוצאת (egress), כך שרק בקשות לכתובות IP פרטיות ינותבו ל-VPC. התצורה הזו תאפשר לממשק הקצה עדיין לגשת לאינטרנט הציבורי. תוכלו לקרוא מידע נוסף במסמכים על קבלת בקשות משירותי Cloud Run אחרים.
הגדרת תעבורת נתונים יוצאת (egress) ישירה של VPC
ראשית, מריצים את הפקודה הבאה כדי להשתמש בתעבורת נתונים יוצאת (egress) ישירה של 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)"
יצירת תחום של Cloud DNS לכתובות URL של run.app
לסיום, יוצרים תחום (zone) של Cloud DNS לכתובות URL של run.app, כדי ש-Google Cloud יוכל להתייחס אליהן בתור כתובות IP פנימיות.
בשלב הקודם הגדרת גם תעבורת נתונים יוצאת (egress) ישירה של VPC ל-טווחים פרטיים בלבד. כלומר, חיבורים יוצאים משירות הקצה הקדמי יעברו לרשת ה-VPC רק אם היעד הוא כתובת IP פנימית. עם זאת, השירות לקצה העורפי משתמש בכתובת URL של run.app שמפנה לכתובת IP ציבורית.
בשלב הזה תיצרו תחום של Cloud DNS לכתובות ה-URL של run.app, שיוצגו לטווחי כתובות ה-IP מסוג private.googleapis.com, שמזוהים ככתובות IP פנימיות. מעכשיו, כל בקשה לטווחים האלה ינותבו דרך רשת ה-VPC.
תוכלו לעשות זאת כך: https://cloud.google.com/run/docs/securs/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:// . לרשומת DNS A - אם מתקבלת שגיאת 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
.