מדריך לשימוש ב-Pub/Sub עם Cloud Run

במדריך הזה מוסבר איך לכתוב, לפרוס ולקרוא לשירות Cloud Run ממינוי דחיפה של Pub/Sub.

מטרות

  • כתיבה, פיתוח ופריסה של שירות ב-Cloud Run
  • קוראים לשירות על ידי פרסום הודעה בנושא Pub/Sub.

עלויות

במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

בעזרת מחשבון העלויות אתם יכולים להעריך את העלויות בהתאם לשימוש הצפוי.

משתמשים חדשים של Google Cloud ? יכול להיות שאתם זכאים לתקופת ניסיון בחינם.

לפני שמתחילים

  1. נכנסים לחשבון Google Cloud . אנחנו ממליצים למשתמשים חדשים ב- Google Cloud ליצור חשבון כדי שיוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  5. Verify that billing is enabled for your Google Cloud project.

  6. מפעילים את ממשקי ה-API של Artifact Registry, ‏ Cloud Build, ‏ Pub/Sub ו-Cloud Run, אם הם עדיין לא מופעלים.

    התפקידים שנדרשים כדי להפעיל ממשקי API

    כדי להפעיל ממשקי API, צריך את ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד "בעלים" (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד "אדמין בממשק 'שימוש בשירות'" (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    הפעלת ממשקי ה-API

  7. מתקינים ומפעילים את ה-CLI של gcloud.
  8. מעדכנים את הרכיבים:
    gcloud components update

התפקידים הנדרשים

כדי לקבל את ההרשאות שדרושות להשלמת המדריך, בקשו מהאדמין לתת לכם את התפקידים הבאים ב-IAM ברמת הפרויקט:

להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.

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

הגדרת ברירות המחדל של gcloud

כדי להגדיר את gcloud עם ברירות מחדל לשירות Cloud Run:

  1. מגדירים את פרויקט ברירת המחדל:

    gcloud config set project PROJECT_ID

    מחליפים את PROJECT_ID בשם הפרויקט שיצרתם בשביל המדריך הזה.

  2. מגדירים את gcloud לאזור שבחרתם:

    gcloud config set run/region REGION

    מחליפים את REGION באזור הנתמך של Cloud Run לבחירתכם.

מיקומים של Cloud Run

‫Cloud Run הוא שירות אזורי, כלומר התשתית שמפעילה את שירותי Cloud Run נמצאת באזור ספציפי ומנוהלת על ידי Google, כך שהיא זמינה באופן יתיר בכל האזורים באותו אזור.

הגורמים העיקריים לבחירת האזור שבו יפעלו שירותי Cloud Run הם עמידה בדרישות של זמן אחזור, זמינות או עמידות. בדרך כלל אפשר לבחור את האזור הכי קרוב למשתמשים, אבל כדאי להביא בחשבון את המיקום של המוצרים Google Cloudהאחרים שמשמשים את שירות Cloud Run. שימוש במוצרי Google Cloud ביחד בכמה מיקומים יכול להשפיע על זמן האחזור של השירות וגם על העלות.

אפשר להשתמש ב-Cloud Run באזורים הבאים:

בכפוף לתמחור ברמה 1

בכפוף לתמחור ברמה 2

  • africa-south1 (יוהנסבורג)
  • asia-east2 (הונג קונג)
  • asia-northeast3 (סיאול, דרום קוריאה)
  • asia-southeast1 (סינגפור)
  • asia-southeast2 (ג'קרטה)
  • asia-south2 (דלהי, הודו)
  • australia-southeast1 (סידני)
  • australia-southeast2 (מלבורן)
  • europe-central2 (ורשה, פולין) סמל של עלה רמה נמוכה של CO2
  • europe-west10 (ברלין)
  • ‫europe-west12 (טורינו) סמל של עלה רמה נמוכה של CO2
  • ‫europe-west2 (לונדון, בריטניה) סמל של עלה רמה נמוכה של CO2
  • europe-west3 (פרנקפורט, גרמניה)
  • europe-west6 (ציריך, שווייץ) סמל של עלה רמה נמוכה של CO2
  • me-central1 (דוחא)
  • me-central2 (דמאם)
  • ‫northamerica-northeast1 (מונטריאול) סמל של עלה רמה נמוכה של CO2
  • ‫northamerica-northeast2 (טורונטו) סמל של עלה רמה נמוכה של CO2
  • ‫southamerica-east1 (סאו פאולו, ברזיל) סמל של עלה רמה נמוכה של CO2
  • southamerica-west1 (סנטיאגו, צ'ילה) סמל של עלה רמה נמוכה של CO2
  • us-west2 (לוס אנג'לס)
  • us-west3 (סולט לייק סיטי)
  • us-west4 (לאס וגאס)

אם כבר יצרתם שירות Cloud Run, אתם יכולים לראות את האזור במרכז הבקרה של Cloud Run במסוףGoogle Cloud .

יצירת מאגר רגיל ב-Artifact Registry

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

gcloud artifacts repositories create REPOSITORY \
    --repository-format=docker \
    --location=REGION

מחליפים את:

  • ‫REPOSITORY בשם ייחודי למאגר.
  • REGION באזור שבו רוצים להשתמש למאגר של Artifact Registry. Google Cloud

יוצרים נושא Pub/Sub

שירות הדוגמה מופעל על ידי הודעות שפורסמו בנושא Pub/Sub, לכן צריך ליצור נושא ב-Pub/Sub.

gcloud

כדי ליצור נושא חדש ב-Pub/Sub, משתמשים בפקודה:

gcloud pubsub topics create myRunTopic

אפשר להשתמש ב-myRunTopic או להחליף אותו בשם נושא ייחודי בפרויקט Google Cloud .

Terraform

כדי ללמוד איך להחיל הגדרות ב-Terraform או להסיר אותן, ראו פקודות בסיסיות ב-Terraform.

כדי ליצור נושא Pub/Sub, מוסיפים את הקוד הבא לקובץ main.tf הקיים:

resource "google_pubsub_topic" "default" {
  name = "pubsub_topic"
}

אפשר להשתמש בשם נושא ייחודי בפרויקט בענן.

אחזור של דוגמת הקוד

כדי לאחזר את דוגמת הקוד לשימוש:

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

    Node.js

    git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples.git

    אפשר גם להוריד את הדוגמה כקובץ ZIP ולחלץ אותו.

    Python

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git

    אפשר גם להוריד את הדוגמה כקובץ ZIP ולחלץ אותו.

    המשך

    git clone https://github.com/GoogleCloudPlatform/golang-samples.git

    אפשר גם להוריד את הדוגמה כקובץ ZIP ולחלץ אותו.

    Java

    git clone https://github.com/GoogleCloudPlatform/java-docs-samples.git

    אפשר גם להוריד את הדוגמה כקובץ ZIP ולחלץ אותו.

    C#‎

    git clone https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git

    אפשר גם להוריד את הדוגמה כקובץ ZIP ולחלץ אותו.

  2. עוברים לספרייה שמכילה את הקוד לדוגמה של Cloud Run:

    Node.js

    cd nodejs-docs-samples/run/pubsub/

    Python

    cd python-docs-samples/run/pubsub/

    Go

    cd golang-samples/run/pubsub/

    Java

    cd java-docs-samples/run/pubsub/

    C#‎

    cd dotnet-docs-samples/run/Run.Samples.Pubsub.MinimalApi/

בודקים את הקוד

הקוד של המדריך הזה מורכב מהחלקים הבאים:

  • שרת שמטפל בבקשות נכנסות.

    Node.js

    כדי שיהיה קל לבדוק את שירות Node.js, הגדרת השרת נפרדת מהפעלת השרת.

    שרת האינטרנט של Node.js מוגדר ב-app.js.

    const express = require('express');
    const app = express();
    
    // This middleware is available in Express v4.16.0 onwards
    app.use(express.json());

    שרת האינטרנט מופעל ב-index.js:

    const app = require('./app.js');
    const PORT = parseInt(parseInt(process.env.PORT)) || 8080;
    
    app.listen(PORT, () =>
      console.log(`nodejs-pubsub-tutorial listening on port ${PORT}`)
    );

    Python

    import base64
    
    from flask import Flask, request
    
    
    app = Flask(__name__)
    

    Go

    
    // Sample run-pubsub is a Cloud Run service which handles Pub/Sub messages.
    package main
    
    import (
    	"encoding/json"
    	"io"
    	"log"
    	"net/http"
    	"os"
    )
    
    func main() {
    	http.HandleFunc("/", HelloPubSub)
    	// Determine port for HTTP service.
    	port := os.Getenv("PORT")
    	if port == "" {
    		port = "8080"
    		log.Printf("Defaulting to port %s", port)
    	}
    	// Start HTTP server.
    	log.Printf("Listening on port %s", port)
    	if err := http.ListenAndServe(":"+port, nil); err != nil {
    		log.Fatal(err)
    	}
    }
    

    Java

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class PubSubApplication {
      public static void main(String[] args) {
        SpringApplication.run(PubSubApplication.class, args);
      }
    }

    C#‎

    var builder = WebApplication.CreateBuilder(args);
    var app = builder.Build();
    
    var port = Environment.GetEnvironmentVariable("PORT");
    if (port != null)
    {
        app.Urls.Add($"http://0.0.0.0:{port}");
    }
    

  • רכיב handler שמעבד את ההודעה ב-Pub/Sub ומתעד ברכה ביומן.

    Node.js

    app.post('/', (req, res) => {
      if (!req.body) {
        const msg = 'no Pub/Sub message received';
        console.error(`error: ${msg}`);
        res.status(400).send(`Bad Request: ${msg}`);
        return;
      }
      if (!req.body.message) {
        const msg = 'invalid Pub/Sub message format';
        console.error(`error: ${msg}`);
        res.status(400).send(`Bad Request: ${msg}`);
        return;
      }
    
      const pubSubMessage = req.body.message;
      const name = pubSubMessage.data
        ? Buffer.from(pubSubMessage.data, 'base64').toString().trim()
        : 'World';
    
      console.log(`Hello ${name}!`);
      res.status(204).send();
    });

    Python

    @app.route("/", methods=["POST"])
    def index():
        """Receive and parse Pub/Sub messages."""
        envelope = request.get_json()
        if not envelope:
            msg = "no Pub/Sub message received"
            print(f"error: {msg}")
            return f"Bad Request: {msg}", 400
    
        if not isinstance(envelope, dict) or "message" not in envelope:
            msg = "invalid Pub/Sub message format"
            print(f"error: {msg}")
            return f"Bad Request: {msg}", 400
    
        pubsub_message = envelope["message"]
    
        name = "World"
        if isinstance(pubsub_message, dict) and "data" in pubsub_message:
            name = base64.b64decode(pubsub_message["data"]).decode("utf-8").strip()
    
        print(f"Hello {name}!")
    
        return ("", 204)
    
    

    Go

    
    // WrappedMessage is the payload of a Pub/Sub event.
    //
    // For more information about receiving messages from a Pub/Sub event
    // see: https://cloud.google.com/pubsub/docs/push#receive_push
    type WrappedMessage struct {
    	Message struct {
    		Data []byte `json:"data,omitempty"`
    		ID   string `json:"id"`
    	} `json:"message"`
    	Subscription string `json:"subscription"`
    }
    
    // HelloPubSub receives and processes a Pub/Sub push message.
    func HelloPubSub(w http.ResponseWriter, r *http.Request) {
    	var m WrappedMessage
    	body, err := io.ReadAll(r.Body)
    	defer r.Body.Close()
    	if err != nil {
    		log.Printf("io.ReadAll: %v", err)
    		http.Error(w, "Bad Request", http.StatusBadRequest)
    		return
    	}
    	// byte slice unmarshalling handles base64 decoding.
    	if err := json.Unmarshal(body, &m); err != nil {
    		log.Printf("json.Unmarshal: %v", err)
    		http.Error(w, "Bad Request", http.StatusBadRequest)
    		return
    	}
    
    	name := string(m.Message.Data)
    	if name == "" {
    		name = "World"
    	}
    	log.Printf("Hello %s!", name)
    }
    

    Java

    import com.example.cloudrun.Body;
    import java.util.Base64;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    // PubsubController consumes a Pub/Sub message.
    @RestController
    public class PubSubController {
      @RequestMapping(value = "/", method = RequestMethod.POST)
      public ResponseEntity<String> receiveMessage(@RequestBody Body body) {
        // Get PubSub message from request body.
        Body.Message message = body.getMessage();
        if (message == null) {
          String msg = "Bad Request: invalid Pub/Sub message format";
          System.out.println(msg);
          return new ResponseEntity<>(msg, HttpStatus.BAD_REQUEST);
        }
    
        String data = message.getData();
        String target =
            !StringUtils.isEmpty(data) ? new String(Base64.getDecoder().decode(data)) : "World";
        String msg = "Hello " + target + "!";
    
        System.out.println(msg);
        return new ResponseEntity<>(msg, HttpStatus.OK);
      }
    }

    C#‎

    app.MapPost("/", (Envelope envelope) =>
    {
        if (envelope?.Message?.Data == null)
        {
            app.Logger.LogWarning("Bad Request: Invalid Pub/Sub message format.");
            return Results.BadRequest();
        }
    
        var data = Convert.FromBase64String(envelope.Message.Data);
        var target = System.Text.Encoding.UTF8.GetString(data);
    
        app.Logger.LogInformation($"Hello {target}!");
    
        return Results.NoContent();
    });
    

    צריך לתכנת את השירות כך שיחזיר קוד תגובה מדויק של HTTP. קודי הצלחה, כמו HTTP 200 או 204, מאשרים את העיבוד המלא של הודעת Pub/Sub. קודי שגיאה, כמו HTTP 400 או 500, מציינים שההודעה תישלח שוב, כפי שמתואר במדריך קבלת הודעות באמצעות Push. בניגוד לפונקציות שנוצרו באמצעות Cloud Functions v2 API, אי אפשר להשבית ניסיונות חוזרים בפונקציות שנוצרו באמצעות Cloud Run Admin API. מידע נוסף זמין במאמר הגדרת ניסיונות חוזרים של פונקציות מבוססות-אירועים.

  • ‫Dockerfile שמגדיר את סביבת ההפעלה של השירות. התוכן של Dockerfile משתנה בהתאם לשפה.

    Node.js

    
    # Use the official lightweight Node.js image.
    # https://hub.docker.com/_/node
    FROM node:20-slim
    # Create and change to the app directory.
    WORKDIR /usr/src/app
    
    # Copy application dependency manifests to the container image.
    # A wildcard is used to ensure both package.json AND package-lock.json are copied.
    # Copying this separately prevents re-running npm install on every code change.
    COPY package*.json ./
    
    # Install dependencies.
    # if you need a deterministic and repeatable build create a
    # package-lock.json file and use npm ci:
    # RUN npm ci --omit=dev
    # if you need to include development dependencies during development
    # of your application, use:
    # RUN npm install --dev
    
    RUN npm install --omit=dev
    
    # Copy local code to the container image.
    COPY . .
    
    # Run the web service on container startup.
    CMD [ "npm", "start" ]
    

    Python

    
    # Use the official Python image.
    # https://hub.docker.com/_/python
    FROM python:3.14
    
    # Allow statements and log messages to immediately appear in the Cloud Run logs
    ENV PYTHONUNBUFFERED True
    
    # Copy application dependency manifests to the container image.
    # Copying this separately prevents re-running pip install on every code change.
    COPY requirements.txt ./
    
    # Install production dependencies.
    RUN pip install -r requirements.txt
    
    # Copy local code to the container image.
    ENV APP_HOME /app
    WORKDIR $APP_HOME
    COPY . ./
    
    # Run the web service on container startup.
    # Use gunicorn webserver with one worker process and 8 threads.
    # For environments with multiple CPU cores, increase the number of workers
    # to be equal to the cores available.
    # Timeout is set to 0 to disable the timeouts of the workers to allow Cloud Run to handle instance scaling.
    CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 main:app
    

    Go

    
    # Use the official Go image to create a binary.
    # This is based on Debian and sets the GOPATH to /go.
    # https://hub.docker.com/_/golang
    FROM golang:1.25-bookworm as builder
    
    # Create and change to the app directory.
    WORKDIR /app
    
    # Retrieve application dependencies.
    # This allows the container build to reuse cached dependencies.
    # Expecting to copy go.mod and if present go.sum.
    COPY go.* ./
    RUN go mod download
    
    # Copy local code to the container image.
    COPY . ./
    
    # Build the binary.
    RUN go build -v -o server
    
    # Use the official Debian slim image for a lean production container.
    # https://hub.docker.com/_/debian
    # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
    FROM debian:bookworm-slim
    RUN set -x && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
        ca-certificates && \
        rm -rf /var/lib/apt/lists/*
    
    # Copy the binary to the production image from the builder stage.
    COPY --from=builder /app/server /server
    
    # Run the web service on container startup.
    CMD ["/server"]
    

    Java

    בדוגמה הזו משתמשים ב-Jib כדי ליצור קובצי אימג' של Docker באמצעות כלי Java נפוצים. ‫Jib מבצע אופטימיזציה של גרסאות build של קונטיינרים בלי צורך בקובץ Docker או בהתקנה של Docker. מידע נוסף על יצירת קונטיינרים של Java באמצעות Jib

    <plugin>
      <groupId>com.google.cloud.tools</groupId>
      <artifactId>jib-maven-plugin</artifactId>
      <version>3.4.0</version>
      <configuration>
        <to>
          <image>gcr.io/PROJECT_ID/pubsub</image>
        </to>
      </configuration>
    </plugin>
    

    C#‎

    # Build in SDK base image
    FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
    WORKDIR /app
    
    COPY *.csproj ./
    RUN dotnet restore
    
    COPY . ./
    RUN dotnet publish -r linux-x64 --no-self-contained -p:PublishReadyToRun=true -c Release -o out
    
    # Copy to runtime image
    FROM mcr.microsoft.com/dotnet/aspnet:6.0
    WORKDIR /app
    COPY --from=build-env /app/out .
    
    # Port passed in by Cloud Run via environment variable PORT.  Default 8080.
    ENV PORT=8080
    
    ENTRYPOINT ["dotnet", "Run.Samples.Pubsub.MinimalApi.dll"]

במאמר שילוב עם Pub/Sub מוסבר איך לאמת את המקור של בקשות Pub/Sub.

השקת הקוד

העברת הקוד כוללת שלושה שלבים: יצירת קובץ אימג' של קונטיינר באמצעות Cloud Build, העלאת קובץ האימג' של הקונטיינר ל-Artifact Registry ופריסת קובץ האימג' של הקונטיינר ב-Cloud Run.

כדי להעביר את הקוד:

  1. יוצרים את הקונטיינר ומפרסמים אותו ב-Artifact Registry:

    Node.js

    gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
    מחליפים את:
    • ‫PROJECT_ID במזהה הפרויקט ב- Google Cloud .
    • ‫REPOSITORY בשם המאגר ב-Artifact Registry.
    • REGION באזור שבו רוצים להשתמש למאגר Artifact Registry. Google Cloud

    ‫pubsub הוא שם התמונה.

    אם הפעולה תצליח, תופיע הודעת SUCCESS עם המזהה, זמן היצירה ושם התמונה. התמונה מאוחסנת ב-Artifact Registry ואפשר להשתמש בה שוב אם צריך.

    Python

    gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
    מחליפים את:
    • ‫PROJECT_ID במזהה הפרויקט ב- Google Cloud .
    • ‫REPOSITORY בשם המאגר ב-Artifact Registry.
    • REGION באזור שבו רוצים להשתמש למאגר של Artifact Registry. Google Cloud

    ‫pubsub הוא שם התמונה.

    אם הפעולה תצליח, תופיע הודעת SUCCESS עם המזהה, זמן היצירה ושם התמונה. התמונה מאוחסנת ב-Artifact Registry ואפשר להשתמש בה שוב אם צריך.

    המשך

    gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
    מחליפים את:
    • ‫PROJECT_ID במזהה הפרויקט ב- Google Cloud .
    • ‫REPOSITORY בשם המאגר ב-Artifact Registry.
    • REGION באזור שבו רוצים להשתמש למאגר של Artifact Registry. Google Cloud

    ‫pubsub הוא שם התמונה.

    אם הפעולה תצליח, תופיע הודעת SUCCESS עם המזהה, זמן היצירה ושם התמונה. התמונה מאוחסנת ב-Artifact Registry ואפשר להשתמש בה שוב אם צריך.

    Java

    • משתמשים בכלי העזר של מסמך האימות של ה-CLI של gcloud כדי לאשר ל-Docker להעביר קבצים בדחיפה ל-Artifact Registry.
      gcloud auth configure-docker
    • משתמשים בפלאגין Jib Maven כדי ליצור את הקונטיינר ולהעביר אותו בדחיפה ל-Artifact Registry.
      mvn compile jib:build -D image=REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
      מחליפים את:
      • ‫PROJECT_ID במזהה הפרויקט ב- Google Cloud .
      • ‫REPOSITORY בשם המאגר ב-Artifact Registry.
      • REGION באזור שבו רוצים להשתמש למאגר של Artifact Registry. Google Cloud

      ‫pubsub הוא שם התמונה.

      אם הפעולה תצליח, תופיע ההודעה BUILD SUCCESS. התמונה מאוחסנת ב-Artifact Registry ואפשר להשתמש בה שוב אם צריך.

    C#‎

    gcloud builds submit --tag REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
    מחליפים את:
    • ‫PROJECT_ID במזהה הפרויקט ב- Google Cloud .
    • ‫REPOSITORY בשם המאגר ב-Artifact Registry.
    • REGION באזור שבו רוצים להשתמש למאגר של Artifact Registry. Google Cloud

    ‫pubsub הוא שם התמונה.

    אם הפעולה תצליח, תופיע הודעת SUCCESS עם המזהה, זמן היצירה ושם התמונה. התמונה מאוחסנת ב-Artifact Registry ואפשר להשתמש בה שוב לפי הצורך.

  2. פורסים את האפליקציה:

    שורת הפקודה

    1. מריצים את הפקודה הבאה כדי לפרוס את האפליקציה:

      gcloud run deploy pubsub-tutorial --image REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub  --no-allow-unauthenticated
      מחליפים את:
      • ‫PROJECT_ID במזהה הפרויקט ב- Google Cloud .
      • ‫REPOSITORY בשם המאגר ב-Artifact Registry.
      • REGION באזור שבו רוצים להשתמש למאגר של Artifact Registry. Google Cloud

      ‫pubsub הוא שם קובץ האימג' ו-pubsub-tutorial הוא שם השירות. שימו לב שקובץ האימג' של הקונטיינר נפרס בשירות ובאזור שהגדרתם קודם בקטע הגדרת gcloud.

      הדגל --no-allow-unauthenticated מגביל את הגישה לשירות ללא אימות. אם השירות פרטי, אפשר להסתמך על השילוב האוטומטי של Cloud Run עם Pub/Sub כדי לאמת בקשות. במאמר שילוב עם Pub/Sub מוסבר איך להגדיר את זה. לפרטים נוספים על אימות שמבוסס על ניהול זהויות והרשאות גישה (IAM), קראו את המאמר ניהול הגישה באמצעות IAM.

      מחכים עד שהפריסה תסתיים. זה יכול לקחת כחצי דקה. אם הפעולה מצליחה, כתובת ה-URL של השירות מוצגת בשורת הפקודה. כתובת ה-URL הזו משמשת להגדרת מינוי ל-Pub/Sub.

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

    Terraform

    כדי ליצור שירות Cloud Run, מוסיפים את הקוד הבא לקובץ .tf הקיים.

    resource "google_project_service" "cloudrun_api" {
       service            = "run.googleapis.com"
       disable_on_destroy = false
    }
    
    resource "google_cloud_run_v2_service" "default" {
       name     = "pubsub-tutorial"
       location = "REGION"
    
       template {
          containers {
             image = "IMAGE_URL"
         }
       }
       depends_on = [google_project_service.cloudrun_api]
    }
             
    מחליפים את:
    • IMAGE_URL עם כתובת ה-URL של התמונה: REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/pubsub
    • REGION באזור שבו רוצים להשתמש למאגר של Artifact Registry. Google Cloud

שילוב עם Pub/Sub

כדי לשלב את השירות עם Pub/Sub:

gcloud

  1. יוצרים או בוחרים חשבון שירות שייצג את הזהות של המינוי ל-Pub/Sub.

    gcloud iam service-accounts create cloud-run-pubsub-invoker \
        --display-name "Cloud Run Pub/Sub Invoker"

    אפשר להשתמש ב-cloud-run-pubsub-invoker או להחליף אותו בשם ייחודי בפרויקט ב- Google Cloud .

  2. יוצרים מינוי ל-Pub/Sub באמצעות חשבון השירות:

    1. נותנים לחשבון השירות המפעיל הרשאה להפעיל את שירות pubsub-tutorial:

      gcloud run services add-iam-policy-binding pubsub-tutorial \
      --member=serviceAccount:cloud-run-pubsub-invoker@PROJECT_ID.iam.gserviceaccount.com \
      --role=roles/run.invoker

      יכול להיות שיחלפו כמה דקות עד שהשינויים ב-IAM יתעדכנו. בינתיים, יכול להיות שיופיעו שגיאות HTTP 403 ביומני השירות.

    2. מאפשרים ל-Pub/Sub ליצור אסימוני אימות בפרויקט:

      gcloud projects add-iam-policy-binding PROJECT_ID \
         --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
         --role=roles/iam.serviceAccountTokenCreator

      מחליפים את:

      • ‫PROJECT_ID במזהה הפרויקט ב- Google Cloud .
      • ‫PROJECT_NUMBER במספר הפרויקט ב- Google Cloud .

      מזהה הפרויקט ומספר הפרויקט מופיעים בחלונית Project info במסוףGoogle Cloud של הפרויקט.

    3. יוצרים מינוי ל-Pub/Sub באמצעות חשבון השירות:

      gcloud pubsub subscriptions create myRunSubscription --topic myRunTopic \
      --ack-deadline=600 \
      --push-endpoint=SERVICE-URL/ \
      --push-auth-service-account=cloud-run-pubsub-invoker@PROJECT_ID.iam.gserviceaccount.com

      מחליפים את:

      הדגל --push-auth-service-account מפעיל את פונקציונליות הדחיפה של Pub/Sub לאימות והרשאה.

      הדומיין של שירות Cloud Run רשום באופן אוטומטי לשימוש עם מינויים ל-Pub/Sub.

      רק ב-Cloud Run, יש בדיקת אימות מובנית שהאסימון תקין ובדיקת הרשאה שלחשבון השירות יש הרשאה להפעיל את שירות Cloud Run.

השירות שלכם משולב עכשיו באופן מלא עם Pub/Sub.

Terraform

  1. יוצרים או בוחרים חשבון שירות שייצג את הזהות של המינוי ל-Pub/Sub.

    resource "google_service_account" "sa" {
      account_id   = "cloud-run-pubsub-invoker"
      display_name = "Cloud Run Pub/Sub Invoker"
    }
  2. יוצרים מינוי ל-Pub/Sub באמצעות חשבון השירות:

    1. נותנים לחשבון השירות המפעיל הרשאה להפעיל את שירות pubsub-tutorial:

      resource "google_cloud_run_service_iam_binding" "binding" {
        location = google_cloud_run_v2_service.default.location
        service  = google_cloud_run_v2_service.default.name
        role     = "roles/run.invoker"
        members  = ["serviceAccount:${google_service_account.sa.email}"]
      }
    2. מאפשרים ל-Pub/Sub ליצור אסימוני אימות בפרויקט:

      resource "google_project_service_identity" "pubsub_agent" {
        provider = google-beta
        project  = data.google_project.project.project_id
        service  = "pubsub.googleapis.com"
      }
      
      resource "google_project_iam_binding" "project_token_creator" {
        project = data.google_project.project.project_id
        role    = "roles/iam.serviceAccountTokenCreator"
        members = ["serviceAccount:${google_project_service_identity.pubsub_agent.email}"]
      }
    3. יוצרים מינוי ל-Pub/Sub באמצעות חשבון השירות:

      resource "google_pubsub_subscription" "subscription" {
        name  = "pubsub_subscription"
        topic = google_pubsub_topic.default.name
        push_config {
          push_endpoint = google_cloud_run_v2_service.default.uri
          oidc_token {
            service_account_email = google_service_account.sa.email
          }
          attributes = {
            x-goog-version = "v1"
          }
        }
        depends_on = [google_cloud_run_v2_service.default]
      }

השירות שלכם משולב עכשיו באופן מלא עם Pub/Sub.

רוצה לנסות?

כדי לבדוק את הפתרון מקצה לקצה:

  1. שולחים הודעת Pub/Sub לנושא:

    gcloud pubsub topics publish myRunTopic --message "Runner"

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

  2. עוברים ליומני השירות:

    1. נכנסים למסוףGoogle Cloud .
    2. לוחצים על השירות pubsub-tutorial.
    3. לוחצים על הכרטיסייה יומנים.

      יכול להיות שייקח ליומנים כמה דקות להופיע. אם הם לא מופיעים מיד, כדאי לבדוק שוב אחרי כמה דקות.

  3. מחפשים את ההודעה "Hello Runner!‎".

הסרת המשאבים

כדי לראות תרחיש לדוגמה מעמיק יותר של שימוש ב-Cloud Run עם Pub/Sub, דלגו על הניקוי בינתיים והמשיכו למדריך בנושא עיבוד תמונות באמצעות Cloud Run.

כדי להימנע מחיובים נוספים בחשבון Google Cloud , צריך למחוק את כל המשאבים שפרסתם באמצעות המדריך הזה.

מחיקת הפרויקט

אם יצרתם פרויקט חדש בשביל המדריך הזה, מחקו את הפרויקט. אם השתמשתם בפרויקט קיים ואתם רוצים לשמור אותו בלי השינויים שהוספתם במדריך הזה, מחקו את המשאבים שיצרתם בשביל המדריך.

הדרך הקלה ביותר לבטל את החיוב היא למחוק את הפרויקט שיצרתם בשביל המדריך.

כדי למחוק את הפרויקט:

  1. במסוף Google Cloud , נכנסים לדף Manage resources.

    כניסה לדף Manage resources

  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

מחיקת משאבי המדריך

  1. מוחקים את שירות Cloud Run שפרסתם במדריך הזה. שירותי Cloud Run לא צוברים עלויות עד שהם מקבלים בקשות.

    כדי למחוק את השירות ב-Cloud Run, מריצים את הפקודה הבאה:

    gcloud run services delete SERVICE-NAME

    מחליפים את SERVICE-NAME בשם השירות.

    אפשר גם למחוק שירותי Cloud Run ממסוףGoogle Cloud .

  2. מסירים את הגדרת ברירת המחדל של האזור gcloud שהוספתם במהלך הגדרת המדריך:

     gcloud config unset run/region
    
  3. מסירים את הגדרות הפרויקט:

     gcloud config unset project
    
  4. מוחקים משאבים אחרים של Google Cloud שנוצרו במדריך הזה:

המאמרים הבאים