יצירת שירות של Cloud Run באמצעות צדדית

1. סקירה כללית

מבוא

ב-Codelab הזה תלמדו איך לפרוס שירות Cloud Run שמשתמש בקונטיינרים מרובים. יוצרים אפליקצייתNode.js שתשמש כמאגר תעבורת הנתונים הנכנסת (ingress) ב-Cloud Run ואפליקצייתNode.js נוספת שתשמש כרכב צד.

סקירה טכנית

כשמשתמשים במספר קונטיינרים במכונה של Cloud Run, קונטיינר אחד משמש כקונטיינר הראשי לתעבורת נתונים נכנסת (ingress) באינטרנט. המאגר היחיד או יותר נקרא 'כלי עזר'.

יש שתי דרכים שבהן מספר קונטיינרים יכולים לתקשר זה עם זה:

  1. הקונטיינרים חולקים את ממשק הרשת של מארח מקומי, כך שכל הקונטיינרים יכולים להאזין ליציאה, למשל. localhost:port.
  2. אפשר גם להשתמש בנפחי אחסון בזיכרון ולהתקין אותם בקונטיינרים כדי לשתף קבצים.

תרחישים לדוגמה

מכיוון שכל הקונטיינרים במכונה של Cloud Run חולקים את ממשק הרשת של מארח מקומי, אתם יכולים להשתמש במגש צד לפני הקונטיינר הראשי כדי לשלוח בקשות לשרת proxy. שרתי proxy כאלה יכולים לספק שכבת הפשטה נוספת כדי לאפשר זרימה יעילה יותר של תעבורת נתונים לאפליקציה בין הלקוח לשרתים, על ידי יירוט בקשות והעברתן לנקודת הקצה המתאימה. לדוגמה, אפשר להשתמש בתמונת ה-Nginx הרשמית מ-DockerHub (כפי שמוצג כאן).

מכיוון שכמה קונטיינרים יכולים לתקשר על ידי שיתוף קבצים באמצעות נפחי אחסון משותפים, אתם מוסיפים לשירות אפליקציות שונות. לדוגמה, אתם יכולים לגרום לשירות Cloud Run להשתמש בסוכנים מותאמים אישית כמו OpenTelemetry כדי לייצא יומנים, מדדים ומעקב (דוגמה של OpenTelemetry). דוגמה נוספת היא להשתמש בתקשורת צידית למסד נתונים של Cloud Spanner PostgreSQL (דוגמה של Cloud Spanner Postgress).

דוגמאות ב-Codelab הזה

ב-Codelab הזה, בשלב הראשון פורסים שירות של Cloud Run שבו קונטיינר תעבורת הנתונים הנכנסת (ingress) שלו מתקשר עם רכב צידי דרך יציאת Localhost. לאחר מכן צריך לעדכן את מאגר תעבורת הנתונים הנכנסת (ingress) ואת התיבה הצדדית (Sidecar) כדי לשתף קובץ באמצעות טעינת עוצמת קול.

מה תלמדו

  • איך ליצור מאגר תגים שכולל מכונית צדדית
  • איך קונטיינר של תעבורת נתונים נכנסת (ingress) יכול לתקשר עם רכב משני באמצעות Localhost
  • איך קונטיינר של תעבורת נתונים נכנסת (ingress) ומודעה חלופית יכולים לשתף קובץ באמצעות נפח אחסון טעון

2. הגדרה ודרישות

דרישות מוקדמות

הפעלת Cloud Shell

  1. במסוף Cloud, לוחצים על Activate Cloud Shell d1264ca30785e435.png.

cb81e7c8e34bc8d.png

אם זו הפעם הראשונה שאתם מפעילים את Cloud Shell, יוצג לכם מסך ביניים שמתוארת בו. אם הוצג לכם מסך ביניים, לוחצים על המשך.

d95252b003979716.png

ההקצאה וההתחברות ל-Cloud Shell נמשכת כמה דקות.

7833d5e1c5d18f54.png

במכונה הווירטואלית הזו נמצאים כל כלי הפיתוח הדרושים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר משמעותית את ביצועי הרשת והאימות. אם לא את כולן, ניתן לבצע חלק גדול מהעבודה ב-Codelab הזה באמצעות דפדפן.

אחרי ההתחברות ל-Cloud Shell, אתם אמורים לראות שהפרויקט מאומת ושהפרויקט מוגדר לפי מזהה הפרויקט שלכם.

  1. מריצים את הפקודה הבאה ב-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`
  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהפקודה ב-gcloud יודעת על הפרויקט שלכם:
gcloud config list project

פלט הפקודה

[core]
project = <PROJECT_ID>

אם היא לא נמצאת שם, תוכלו להגדיר אותה באמצעות הפקודה הבאה:

gcloud config set project <PROJECT_ID>

פלט הפקודה

Updated property [core/project].

3. יצירת האפליקציה של תעבורת נתונים נכנסת (ingress)

הגדרת משתני סביבה

ב-Codelab הזה תיצרו כמה משתני סביבה כדי לשפר את הקריאות של פקודות gcloud שנמצאות בשימוש ב-Codelab הזה.

REGION=<YOUR-REGION>
PROJECT_ID=<YOUR-PROJECT-ID>

SERVICE_NAME=sidecar-codelab
REPO_NAME=sidecar-codelab

יוצרים מאגר של ArtifactRegistry לשמירת קובצי אימג' של קונטיינרים

אפשר ליצור מאגר ב-Artifact Registry כדי לאחסן את קובצי האימג' של הקונטיינרים בשביל ה-Codelab הזה.

gcloud artifacts repositories create $REPO_NAME --repository-format=docker \
--location=$REGION --description="sidecar codelab"

לאחר מכן, יוצרים קובץ package.json עם התוכן הבא:

{
  "name": "sidecar-codelab",
  "version": "1.0.0",
  "private": true,
  "description": "demonstrates how to use sidecars in cloud run",
  "main": "index.js",
  "author": "Google LLC",
  "license": "Apache-2.0",
  "scripts": {
    "start": "node ingress.js"
  },
  "dependencies": {
    "axios": "^1.6.2",
    "express": "^4.18.2"
  }
}

עכשיו יוצרים קובץ בשם ingress.js עם התוכן הבא:

const express = require('express');
const app = express();
const axios = require("axios");

app.get('/', async (req, res) => {

    let response = await axios.get("http://localhost:5000");

    res.send("The sidecar says: " + response.data);
});

const port = parseInt(process.env.PORT) || 8080;
app.listen(port, () => {
    console.log(`Ingress container listening on port ${port}`);
});

יצירת קובץ docker לקונטיינר של תעבורת נתונים נכנסת (ingress)

FROM node:20.10.0-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --production

# Copy local code to the container image.
COPY . .

# Run the web service on container startup.
ENV PORT=8080
CMD [ "npm", "start" ]

ויוצרים קובץ ``.dockerignore` לקונטיינר של תעבורת הנתונים הנכנסת (ingress).

# Exclude locally installed dependencies
node_modules/

# Exclude "build-time" ignore files.
.dockerignore
.gcloudignore

# Exclude git history and configuration.
.gitignore

עכשיו אפשר ליצור את קובץ האימג' של תעבורת הנתונים הנכנסת (ingress) באמצעות הפקודה הבאה:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest

4. יצירת אפליקציית הצד השלישי

בקטע הזה יוצרים אפליקציה אחת (Node.js) נוספת שתשמש כצידית בשירות Cloud Run.

עוברים אל ספריית קובצי העזר.

cd ../sidecar

יוצרים קובץ package.json עם התוכן הבא:

{
  "name": "sidecar-codelab",
  "version": "1.0.0",
  "private": true,
  "description": "demonstrates how to use sidecars in cloud run",
  "main": "index.js",
  "author": "Google LLC",
  "license": "Apache-2.0",
  "scripts": {
    "start": "node sidecar.js"
  },
  "dependencies": {
    "axios": "^1.6.2",
    "express": "^4.18.2"
  }
}

עכשיו יוצרים קובץ בשם sidecar.js עם התוכן הבא:

const express = require('express');
const app = express();

app.get('/', async (req, res) => {
    res.send("Hello ingress container! I'm the sidecar.");
});

const port = parseInt(process.env.PORT || 5000);
app.listen(port, () => {
    console.log(`Sidecar container listening on port ${port}`);
});

יצירת קובץ Docker לקונטיינר צד במכונית

FROM node:20.10.0-slim
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --production

# Copy local code to the container image.
COPY . .

# Run the web service on container startup.
ENV PORT=5000
CMD [ "npm", "start" ]

ויוצרים קובץ ``.dockerignore` למאגר ה-Sidecar.

# Exclude locally installed dependencies
node_modules/

# Exclude "build-time" ignore files.
.dockerignore
.gcloudignore

# Exclude git history and configuration.
.gitignore

עכשיו אפשר ליצור את קובץ האימג' של תעבורת הנתונים הנכנסת (ingress) באמצעות הפקודה הבאה:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest

פריסת השירות Cloud Run

פריסת השירות Cloud Run באמצעות קובץ yaml.

עוברים לספריית ההורה.

cd ..

יוצרים קובץ בשם sidecar-codelab.yaml עם התוכן הבא:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  annotations:
  name: sidecar-codelab
  labels:
    cloud.googleapis.com/location: "<YOUR_REGION>"
spec:
  template:
    spec:
      containers:
        - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/ingress:latest"
          ports:
            - containerPort: 8080
        - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/sidecar:latest"
          env:
            - name: PORT
              value: "5000"

לאחר מכן פרסו את השירות באמצעות הפקודה הבאה. צריך להשתמש בגרסת הבטא של gcloud כי טעינת עוצמת הקול זמינה בגרסת טרום-השקה ציבורית.

gcloud beta run services replace sidecar-codelab.yaml

לאחר הפריסה, שומרים את כתובת ה-URL של השירות במשתנה סביבה.

SERVICE_URL=$(gcloud run services describe $SERVICE_NAME --platform managed --region $REGION --format 'value(status.url)') 

5. קריאה לשירות Cloud Run

עכשיו אפשר להתקשר לשירות באמצעות אסימון הזהות.

curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}

התוצאות אמורות להיות דומות לפלט לדוגמה הבא:

The sidecar says: Hello ingress container! I'm the sidecar.

6. שיתוף קובץ באמצעות טעינת נפח

בקטע הזה מעדכנים את הקונטיינרים כדי לשתף קובץ באמצעות טעינת נפח. בדוגמה הזו, מאגר התגים של תעבורת הנתונים הנכנסת (ingress) ייכתב לקובץ בנפח אחסון משותף. החלונית הצדדית תקרא את הקובץ ותחזיר את התוכן שלו חזרה למאגר של תעבורת הנתונים הנכנסת (ingress).

קודם כול מעדכנים את הקוד של קונטיינר של תעבורת נתונים נכנסת (ingress). עוברים לספריית תעבורת הנתונים הנכנסת (ingress).

cd ../ingress

ואז מחליפים את התוכן של הקובץ ingress.js בערך הבא:

const express = require('express');
const app = express();
const fs = require('fs');
const axios = require("axios");

const filename = "test.txt"

let path = "/my-volume-mount";
app.use(path, express.static(path));

try {
    fs.writeFileSync(`${path}/${filename}`, "The ingress container created this file.");
} catch (err) {
    console.error(err);
}

app.get('/', async (req, res) => {

    let response = await axios.get("http://localhost:5000");

    res.send("The sidecar says: " + response.data);
});

const port = parseInt(process.env.PORT) || 8080;
app.listen(port, () => {
    console.log(`Ingress container listening on port ${port}`);
});

ולפתח את קובץ האימג' החדש לקונטיינר של תעבורת הנתונים הנכנסת (ingress) על ידי הרצת הפקודה הבאה:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/ingress:latest

עכשיו עוברים לספריית הצד של הרכב:

cd ../sidecar

ולעדכן את sidecar.js בתוכן הבא:

const express = require('express');
const app = express();
const fs = require('fs');

const filename = "test.txt"

let path = "/my-volume-mount";
app.use(path, express.static(path));

async function readFile() {
    try {
        return await fs.readFileSync(`${path}/${filename}`, { encoding: 'utf8' });
    } catch (err) {
        console.log(err);
    }
}

app.get('/', async (req, res) => {
    let contents = await readFile();
    res.send(contents);
});

const port = parseInt(process.env.PORT || 5000);
app.listen(port, () => {
    console.log(`Sidecar container listening on port ${port}`);
});

כדי ליצור את קובץ האימג' החדש למאגר ה-צדדי במכונית, מריצים את הפקודה הבאה:

gcloud builds submit --tag $REGION-docker.pkg.dev/$PROJECT_ID/$REPO_NAME/sidecar:latest

כדי לשתף עוצמת קול, צריך לעדכן את sidecar-codelab.yaml בפרטים הבאים:

apiVersion: serving.knative.dev/v1
kind: Service
metadata:
  annotations:
  name: sidecar-codelab
  labels:
    cloud.googleapis.com/location: "<YOUR_REGION>"
spec:
  template:
    spec:
      containers:
        - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/ingress:latest"
          ports:
            - containerPort: 8080
          volumeMounts:
            - mountPath: /my-volume-mount
              name: in-memory-1
        - image: "<YOUR_REGION>-docker.pkg.dev/<YOUR_PROJECT_ID>/sidecar-codelab/sidecar:latest"
          env:
            - name: PORT
              value: "5000"
          volumeMounts:
            - mountPath: /my-volume-mount
              name: in-memory-1
      volumes:
        - emptyDir:
            medium: Memory
          name: in-memory-1

פורסים את קובץ sidecar-codelab.yaml המעודכן

gcloud beta run services replace sidecar-codelab.yaml

עכשיו אפשר להתקשר לשירות באמצעות אסימון הזהות.

curl -X GET -H "Authorization: Bearer $(gcloud auth print-identity-token)" ${SERVICE_URL}

התוצאות אמורות להיות דומות לפלט לדוגמה הבא:

The sidecar says: the ingress container created this file.

7. מעולה!

מזל טוב, השלמת את Codelab!

מומלץ לעיין במסמכים של Cloud Run, ובאופן ספציפי: פריסה של קונטיינרים מרובים ושימוש בטעינות נפח אחסון בזיכרון.

אילו נושאים דיברנו?

  • איך ליצור מאגר תגים שכולל מכונית צדדית
  • איך קונטיינר של תעבורת נתונים נכנסת (ingress) יכול לתקשר עם רכב משני באמצעות Localhost
  • איך קונטיינר של תעבורת נתונים נכנסת (ingress) ומכונית חלופית יכולים לחלוק נפח אחסון טעון

8. הסרת המשאבים

כדי להימנע מחיובים לא מכוונים (לדוגמה, אם הפונקציה של Cloud Functions הופעלה בטעות יותר פעמים מההקצאה החודשית של ההפעלה ב-Cloud Run בתוכנית ללא תשלום), אפשר למחוק את שירות Cloud Run או למחוק את הפרויקט שיצרתם בשלב 2.

כדי למחוק את הפונקציה של Cloud Functions, נכנסים אל מסוף הפונקציה של Cloud Functions בכתובת https://console.cloud.google.com/run/ ומוחקים את השירות sidecar-codelab (או את $SERVICE_NAME אם השתמשתם בשם אחר).

אם בוחרים למחוק את הפרויקט כולו, נכנסים לכתובת https://console.cloud.google.com/cloud-resource-manager, בוחרים את הפרויקט שיצרתם בשלב 2 ובוחרים באפשרות 'מחיקה'. אם תמחקו את הפרויקט, יהיה צריך לבצע שינויים בפרויקטים ב-Cloud SDK. כדי להציג את הרשימה של כל הפרויקטים הזמינים, אפשר להריץ את הפקודה gcloud projects list.