הגדרת Cloud Endpoints gRPC ל-Cloud Run עם ESPv2

בדף הזה מוסבר איך להגדיר Cloud Endpoints ל-Cloud Run עם קצה עורפי של gRPC. ‫Endpoints משתמש ב-Extensible Service Proxy V2 ‏ (ESPv2) כשער API. כדי לספק ניהול API ל-Cloud Run, פורסים את קונטיינר ESPv2 שנוצר מראש ב-Cloud Run. לאחר מכן, כדי ש-ESPv2 יוכל להפעיל את השירותים, משתמשים ב-Cloud Run IAM כדי לאבטח אותם.

במסגרת ההגדרה הזו, ESPv2 מיירט את כל הבקשות לשירותים שלכם ומבצע את כל הבדיקות הנדרשות (כמו אימות) לפני הפעלת השירות. כשהשירות מגיב, ESPv2 אוסף ומדווח על טלמטריה, כמו שמוצג באיור שלמטה. אפשר לראות את המדדים של השירות בדף Endpoints > Services במסוף Google Cloud .

ארכיטקטורה של נקודות קצה

סקירה כללית של Cloud Endpoints זמינה במאמרים מידע על Endpoints וארכיטקטורת Endpoints.

מעבר ל-ESPv2

בגרסאות קודמות של Cloud Endpoints לא הייתה תמיכה ב-gRPC ב-Cloud Run עם ESP. כדי להשתמש בתכונה הזו, צריך לעבור ל-Extensible Service Proxy V2.

רשימת משימות

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

  1. יוצרים Google Cloud פרויקט, ואם לא פרסתם את Cloud Run משלכם, פורסים שירות gRPC לדוגמה של קצה עורפי. לפני שמתחילים
  2. משריינים שם מארח ב-Cloud Run לשירות ESPv2. ראו שמירת שם מארח ב-Cloud Run.
  3. יוצרים מסמך הגדרה של gRPC API שמתאר את ה-API, ומגדירים את המסלולים ל-Cloud Run. איך מגדירים נקודות קצה
  4. פורסים את מסמך ההגדרות של gRPC API כדי ליצור שירות מנוהל. איך פורסים את ההגדרה של נקודות הקצה
  5. יצירת קובץ אימג' חדש של ESPv2 Docker עם הגדרות השירות של Endpoints. אפשר לעיין במאמר בנושא יצירת תמונה חדשה של ESPv2.
  6. פורסים את קונטיינר ESPv2 ב-Cloud Run. לאחר מכן, מעניקים ל-ESPv2 הרשאה לניהול זהויות והרשאות גישה (IAM) להפעלת השירות. מידע נוסף זמין במאמר בנושא פריסת מאגר ESPv2.
  7. מפעילים שירות. שליחת בקשה ל-API
  8. מעקב אחר הפעילות בשירותים שלכם. מידע נוסף זמין במאמר בנושא מעקב אחר פעילות של API.
  9. כדי להימנע מחיובים בחשבון Google Cloud , מידע נוסף זמין במאמר בנושא הסרת המשאבים.

עלויות

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

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

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

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

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

כדי להגדיר:

  1. במסוף Google Cloud , נכנסים לדף Manage resources ויוצרים פרויקט.

    כניסה לדף Manage resources

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

    איך מפעילים את החיוב

  3. חשוב לרשום את מזהה הפרויקט כי תצטרכו אותו בהמשך. בהמשך הדף הזה, מזהה הפרויקט הזה יופיע בתור ESPv2_PROJECT_ID.

  4. חשוב לשמור את מספר הפרויקט כי תצטרכו אותו בהמשך. בהמשך הדף הזה, מספר הפרויקט הזה יופיע כ-ESPv2_PROJECT_NUMBER.

  5. מורידים ומתקינים את Google Cloud CLI.

    הורדת ה-CLI של gcloud

  6. כדי להתקין את gRPC ואת כלי gRPC, פועלים לפי השלבים שמפורטים ב מדריך למתחילים של gRPC Python.

  7. פורסים את קצה העורפי לדוגמה python-grpc-bookstore-server, שירות gRPC Cloud Run, לשימוש במדריך הזה. שירות ה-gRPC משתמש בקובץ האימג' של הקונטיינר הבא:

    gcr.io/endpointsv2/python-grpc-bookstore-server:2

    פועלים לפי השלבים במאמר מדריך למתחילים: פריסת קונטיינר לדוגמה שנבנה מראש כדי לפרוס את השירות. חשוב להקפיד להחליף את קובץ האימג' בקונטיינר שצוין במדריך להתחלה מהירה ב-gcr.io/endpointsv2/python-grpc-bookstore-server:2

    הערה לגבי האזור ומזהה הפרויקט שבהם השירות שלכם נפרס. בהמשך הדף הזה, מזהה הפרויקט הזה יופיע בתור BACKEND_PROJECT_ID. השם של שירות Cloud Run שנפרס נקרא BACKEND_SERVICE_NAME. שם המארח של Cloud Run נקרא BACKEND_HOST_NAME.

שמירת שם מארח ב-Cloud Run

כדי להגדיר את מסמך ה-OpenAPI או את הגדרת שירות ה-gRPC, צריך לשריין שם מארח של Cloud Run לשירות ESPv2. כדי לשריין שם מארח, פורסים קונטיינר לדוגמה ב-Cloud Run ומשתמשים בחלק מכתובת ה-URL שנוצרה כשם המארח. בהמשך, תפרסו את קונטיינר ESPv2 באותו שירות לדוגמה של Cloud Run.

  1. מוודאים של-CLI של gcloud יש הרשאה לגשת לנתונים ולשירותים שלכם.
    1. מתחברים לחשבון.
      gcloud auth login
    2. בכרטיסייה החדשה בדפדפן שנפתחת, בוחרים חשבון שיש לו תפקיד עורך או בעלים בפרויקט Google Cloud שיצרתם כדי לפרוס את ESPv2 ב-Cloud Run.
  2. מגדירים את האזור.
    gcloud config set run/region us-central1
  3. פורסים את התמונה לדוגמה gcr.io/cloudrun/hello ב-Cloud Run. מחליפים את ESPv2_CLOUD_RUN_SERVICE_NAME בשם שרוצים לתת לשירות.
    gcloud run deploy ESPv2_CLOUD_RUN_SERVICE_NAME \
        --image="gcr.io/cloudrun/hello" \
        --allow-unauthenticated \
        --platform managed \
        --project=ESPv2_PROJECT_ID
    

    אם הפקודה מסתיימת בלי שגיאות, היא מחזירה הודעה שדומה לזו:

    Service [ESPv2_CLOUD_RUN_SERVICE_NAME] revision [ESPv2_CLOUD_RUN_SERVICE_NAME-REVISION_NUM] has been deployed and is serving traffic at ESPv2_CLOUD_RUN_SERVICE_URL

    לדוגמה, אם מגדירים את ESPv2_CLOUD_RUN_SERVICE_NAME ל-gateway:

    Service [gateway] revision [gateway-00001] has been deployed and is serving traffic at https://gateway-12345-uc.a.run.app

    בדוגמה הזו:

    • ESPv2_CLOUD_RUN_SERVICE_URL היא כתובת ה-URL של השירות https://gateway-12345-uc.a.run.app
    • ESPv2_CLOUD_RUN_HOSTNAME הוא שם המארח gateway-12345-uc.a.run.app.
  4. תציין את ESPv2_CLOUD_RUN_SERVICE_NAME ואת ESPv2_CLOUD_RUN_HOSTNAME. בהמשך פורסים את ESPv2 בשירות ESPv2_CLOUD_RUN_SERVICE_NAME Cloud Run. מציינים את ESPv2_CLOUD_RUN_HOSTNAME בשדה host במסמך OpenAPI.

הגדרת נקודות קצה

הדוגמה bookstore-grpc כוללת את הקבצים שצריך להעתיק באופן מקומי ולהגדיר.

  1. יוצרים קובץ תיאור protobuf עצמאי מקובץ השירות .proto:
    1. שומרים עותק של bookstore.proto ממאגר הדוגמאות בספריית העבודה הנוכחית. הקובץ הזה מגדיר את ה-API של שירות חנות הספרים.
    2. יוצרים את הספרייה הבאה בספריית העבודה: mkdir generated_pb2
    3. יוצרים את קובץ התיאור, api_descriptor.pb, באמצעות קומפיילר מאגרי אחסון לפרוטוקולים protoc. מריצים את הפקודה הבאה בספרייה שבה שמרתם את bookstore.proto:
      python3 -m grpc_tools.protoc \
          --include_imports \
          --include_source_info \
          --proto_path=. \
          --descriptor_set_out=api_descriptor.pb \
          --python_out=generated_pb2 \
          --grpc_python_out=generated_pb2 \
          bookstore.proto

      בפקודה הקודמת, --proto_path מוגדר כספריית העבודה הנוכחית. בסביבת ה-build של gRPC, אם אתם משתמשים בספרייה אחרת לקובצי הקלט של .proto, צריך לשנות את --proto_path כדי שהקומפיילר יחפש בספרייה שבה שמרתם את bookstore.proto.

  2. יוצרים קובץ טקסט בשם api_config.yaml בספריית העבודה הנוכחית (אותה ספרייה שמכילה את bookstore.proto). כדי שיהיה נוח, בדף הזה מתייחסים למסמך ההגדרה של gRPC API לפי שם הקובץ הזה, אבל אפשר לתת לו שם אחר אם רוצים. מוסיפים את התוכן הבא לקובץ:
    # The configuration schema is defined by the service.proto file.
    # https://github.com/googleapis/googleapis/blob/master/google/api/service.proto
    
    type: google.api.Service
    config_version: 3
    name: CLOUD_RUN_HOSTNAME
    title: Cloud Endpoints + Cloud Run gRPC
    apis:
      - name: endpoints.examples.bookstore.Bookstore
    usage:
      rules:
      # ListShelves methods can be called without an API Key.
      - selector: endpoints.examples.bookstore.Bookstore.ListShelves
        allow_unregistered_calls: true
    backend:
      rules:
        - selector: "*"
          address: grpcs://BACKEND_HOST_NAME
    
    הזחה חשובה בפורמט yaml. לדוגמה, השדה name חייב להיות באותה רמה כמו type.
  3. בשדה name, מציינים את CLOUD_RUN_HOSTNAME, את החלק של שם המארח בכתובת ה-URL שהוזמנה למעלה בקטע הזמנת שם מארח ב-Cloud Run. אל תכללו את מזהה הפרוטוקול, כמו https:// או grpcs://.

  4. בשדה address בקטע backend.rules, מחליפים את BACKEND_HOST_NAME בשירות gRPC Bookstore Cloud Run שנוצר בפועל בקטע לפני שמתחילים.

  5. שימו לב לערך של מאפיין title בקובץ api_config.yaml:

    title: Cloud Endpoints + Cloud Run gRPC

    הערך של המאפיין title הופך לשם של שירות Endpoints אחרי שפורסים את ההגדרה.

  6. שומרים את מסמך ההגדרה של gRPC API.

מידע נוסף מופיע במאמר הגדרת נקודות קצה.

הגדרת הדרישות למפתחות API

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

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

כדי לבדוק את האכיפה של מפתח API באמצעות מפתח API שמשויך לפרויקט Google Cloud שלכם, פועלים לפי השלבים הבאים:

  1. מפעילים תמיכה במפתחות API בשירות. מזינים את הפקודה הבאה, כאשר:
    • CLOUD_RUN_HOSTNAME הוא רכיב שם המארח של כתובת האתר שמוגדרת לשירות ESPv2 ב-Cloud Run. הוא משמש בשדה host של מסמך OpenAPI כדי לציין את המיקום שבו מתארח ה-API.
    gcloud services enable CLOUD_RUN_HOSTNAME
  2. פותחים את קובץ ההגדרות של שירות gRPC בפרויקט.
  3. מוסיפים קטע usage לקובץ.
  4. כדי להשבית את הדרישה למפתח API לכל השיטות, מוסיפים כלל allow_unregistered_calls עם בורר wildcard ‏ ("*") בקטע usage.
    usage:
      rules:
      # Allow all methods to be called without an API key.
      - selector: "*"
        allow_unregistered_calls: true
  5. כדי להשבית את הדרישה למפתח API עבור method ספציפי, מגדירים את selector לשם המלא של ה-method במקום לתו כל כללי.
    usage:
      rules:
      # Allow the ListShelves method to be called without an API key.
      - selector: "endpoints.examples.bookstore.Bookstore.ListShelves"
        allow_unregistered_calls: true
  6. אחרי שמשנים את קובץ הגדרות השירות, פורסים את ההגדרה המעודכנת בשירות Endpoints.

שליחת קריאה ל-API באמצעות מפתח API

האופן שבו קוראים ל-API משתנה בהתאם לסוג הלקוח: gRPC או HTTP.

לקוחות gRPC

אם מתודה דורשת מפתח API, לקוחות gRPC צריכים לקבוע ערך (pass) את ערך המפתח כx-api-key מטא-נתונים עם הפעלת method.

Python

def run(
    host, port, api_key, auth_token, timeout, use_tls, servername_override, ca_path

Java

private static final class Interceptor implements ClientInterceptor {
  private final String apiKey;
  private final String authToken;

  private static Logger LOGGER = Logger.getLogger("InfoLogging");

  private static Metadata.Key<String> API_KEY_HEADER =
      Metadata.Key.of("x-api-key", Metadata.ASCII_STRING_MARSHALLER);
  private static Metadata.Key<String> AUTHORIZATION_HEADER =
      Metadata.Key.of("authorization", Metadata.ASCII_STRING_MARSHALLER);

  public Interceptor(String apiKey, String authToken) {
    this.apiKey = apiKey;
    this.authToken = authToken;
  }

  @Override
  public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
      MethodDescriptor<ReqT,RespT> method, CallOptions callOptions, Channel next) {
    LOGGER.info("Intercepted " + method.getFullMethodName());
    ClientCall<ReqT, RespT> call = next.newCall(method, callOptions);

    call = new ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT>(call) {
      @Override
      public void start(Listener<RespT> responseListener, Metadata headers) {
        if (apiKey != null && !apiKey.isEmpty()) {
          LOGGER.info("Attaching API Key: " + apiKey);
          headers.put(API_KEY_HEADER, apiKey);
        }
        if (authToken != null && !authToken.isEmpty()) {
          System.out.println("Attaching auth token");
          headers.put(AUTHORIZATION_HEADER, "Bearer " + authToken);
        }
        super.start(responseListener, headers);
      }
    };
    return call;
  }
}

המשך

func main() {
	flag.Parse()

	// Set up a connection to the server.
	conn, err := grpc.Dial(*addr, grpc.WithInsecure())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	c := pb.NewGreeterClient(conn)

	if *keyfile != "" {
		log.Printf("Authenticating using Google service account key in %s", *keyfile)
		keyBytes, err := ioutil.ReadFile(*keyfile)
		if err != nil {
			log.Fatalf("Unable to read service account key file %s: %v", *keyfile, err)
		}

		tokenSource, err := google.JWTAccessTokenSourceFromJSON(keyBytes, *audience)
		if err != nil {
			log.Fatalf("Error building JWT access token source: %v", err)
		}
		jwt, err := tokenSource.Token()
		if err != nil {
			log.Fatalf("Unable to generate JWT token: %v", err)
		}
		*token = jwt.AccessToken
		// NOTE: the generated JWT token has a 1h TTL.
		// Make sure to refresh the token before it expires by calling TokenSource.Token() for each outgoing requests.
		// Calls to this particular implementation of TokenSource.Token() are cheap.
	}

	ctx := context.Background()
	if *key != "" {
		log.Printf("Using API key: %s", *key)
		ctx = metadata.AppendToOutgoingContext(ctx, "x-api-key", *key)
	}
	if *token != "" {
		log.Printf("Using authentication token: %s", *token)
		ctx = metadata.AppendToOutgoingContext(ctx, "Authorization", fmt.Sprintf("Bearer %s", *token))
	}

	// Contact the server and print out its response.
	name := defaultName
	if len(flag.Args()) > 0 {
		name = flag.Arg(0)
	}
	r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
	if err != nil {
		log.Fatalf("could not greet: %v", err)
	}
	log.Printf("Greeting: %s", r.Message)
}

Node.js

const makeGrpcRequest = (JWT_AUTH_TOKEN, API_KEY, HOST, GREETEE) => {
  // Uncomment these lines to set their values
  // const JWT_AUTH_TOKEN = 'YOUR_JWT_AUTH_TOKEN';
  // const API_KEY = 'YOUR_API_KEY';
  // const HOST = 'localhost:50051'; // The IP address of your endpoints host
  // const GREETEE = 'world';

  // Import required libraries
  const grpc = require('@grpc/grpc-js');
  const protoLoader = require('@grpc/proto-loader');
  const path = require('path');

  // Load protobuf spec for an example API
  const PROTO_PATH = path.join(__dirname, '/protos/helloworld.proto');

  const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
    keepCase: true,
    longs: String,
    enums: String,
    defaults: true,
    oneofs: true,
  });

  const protoObj = grpc.loadPackageDefinition(packageDefinition).helloworld;

  // Create a client for the protobuf spec
  const client = new protoObj.Greeter(HOST, grpc.credentials.createInsecure());

  // Build gRPC request
  const metadata = new grpc.Metadata();
  if (API_KEY) {
    metadata.add('x-api-key', API_KEY);
  } else if (JWT_AUTH_TOKEN) {
    metadata.add('authorization', `Bearer ${JWT_AUTH_TOKEN}`);
  }

  // Execute gRPC request
  client.sayHello({name: GREETEE}, metadata, (err, response) => {
    if (err) {
      console.error(err);
    }

    if (response) {
      console.log(response.message);
    }
  });
};

לקוחות HTTP

אם אתם משתמשים בתכונה Cloud Endpoints for gRPC' HTTP transcoding, לקוחות HTTP יכולים לשלוח את המפתח כפרמטר של שאילתה באותו אופן שבו הם עושים זאת עבור שירותי OpenAPI.

פריסת ההגדרה של נקודות הקצה

כדי לפרוס את ההגדרה של Endpoints, משתמשים בפקודה gcloud endpoints services deploy. הפקודה הזו משתמשת בService Management כדי ליצור שירות מנוהל.

  1. חשוב לוודא שאתם נמצאים בספרייה שבה נמצאים הקבצים api_descriptor.pb ו-api_config.yaml.
  2. מוודאים שפרויקט ברירת המחדל שבו כלי שורת הפקודה gcloud משתמש כרגע הוא הפרויקט Google Cloud שבו רוצים לפרוס את ההגדרה של Endpoints. כדי לוודא שהשירות לא נוצר בפרויקט הלא נכון, מאמתים את מזהה הפרויקט שמוחזר מהפקודה הבאה:
    gcloud config list project
    

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

    gcloud config set project YOUR_PROJECT_ID
    
  3. פורסים את הקובץ proto descriptor ואת קובץ ההגדרות באמצעות Google Cloud CLI:
    gcloud endpoints services deploy api_descriptor.pb api_config.yaml
    

    במהלך היצירה וההגדרה של השירות, Service Management מציג מידע במסוף. בסיום הפריסה, תוצג הודעה שדומה לזו:

    Service Configuration [CONFIG_ID] uploaded for service [bookstore.endpoints.example-project.cloud.goog]

    CONFIG_ID הוא המזהה הייחודי של הגדרת שירות Endpoints שנוצר על ידי הפריסה. לדוגמה:

    Service Configuration [2017-02-13r0] uploaded for service [bookstore.endpoints.example-project.cloud.goog]
    

    בדוגמה הקודמת, 2017-02-13r0 הוא מזהה הגדרות השירות ו-bookstore.endpoints.example-project.cloud.goog הוא שם השירות. מזהה הגדרות השירות מורכב מחותמת זמן ואחריה מספר הגרסה. אם תפרסו את ההגדרה של Endpoints שוב באותו יום, מספר הגרסה יוגדל במזהה הגדרת השירות.

בדיקת השירותים הנדרשים

לפחות, צריך להפעיל את שירותי Google הבאים כדי להשתמש ב-Endpoints וב-ESP:
שם כותרת
servicemanagement.googleapis.com Service Management API
servicecontrol.googleapis.com Service Control API

ברוב המקרים, הפקודה gcloud endpoints services deploy מפעילה את השירותים הנדרשים האלה. עם זאת, הפקודה gcloud מסתיימת בהצלחה אבל לא מפעילה את השירותים הנדרשים בנסיבות הבאות:

  • אם השתמשתם באפליקציה של צד שלישי כמו Terraform ולא כללתם את השירותים האלה.

  • הפריסה של הגדרת ה-Endpoints בוצעה בפרויקטGoogle Cloud קיים שבו השירותים האלה הושבתו באופן מפורש.

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

gcloud services list

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

gcloud services enable servicemanagement.googleapis.com
gcloud services enable servicecontrol.googleapis.com

צריך גם להפעיל את שירות Endpoints:

gcloud services enable ENDPOINTS_SERVICE_NAME

כדי לדעת מהו ENDPOINTS_SERVICE_NAME, אפשר:

  • אחרי פריסת ההגדרה של Endpoints, נכנסים לדף Endpoints במסוף Cloud. רשימת האפשרויות האפשריות של ENDPOINTS_SERVICE_NAME מוצגת בעמודה שם השירות.

  • ב-OpenAPI, ‏ ENDPOINTS_SERVICE_NAME הוא הערך שציינתם בשדה host במפרט OpenAPI. ב-gRPC, ‏ ENDPOINTS_SERVICE_NAME הוא הערך שציינתם בשדה name בהגדרות של נקודות הקצה של gRPC.

מידע נוסף על פקודות gcloud זמין במאמר שירותי gcloud.

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

מידע נוסף זמין במאמר פריסת ההגדרה של Endpoints.

יצירת תמונה חדשה של ESPv2

יוצרים קובץ אימג' חדש של ESPv2 Docker מהגדרות השירות של Endpoints. בהמשך תפרסו את האימג' הזה בשירות Cloud Run השמור.

כדי ליצור את קובץ ההגדרות של השירות בקובץ אימג' חדש של ESPv2 Docker:

  1. מורידים את הסקריפט הזה למחשב המקומי שבו מותקן ה-CLI של gcloud.

  2. מריצים את הסקריפט באמצעות הפקודה הבאה:

    chmod +x gcloud_build_image
    
    ./gcloud_build_image -s ESPv2_CLOUD_RUN_HOSTNAME \
        -c CONFIG_ID -p ESPv2_PROJECT_ID

    בשדה ESPv2_CLOUD_RUN_HOSTNAME, מציינים את שם המארח של כתובת ה-URL שהזמנתם למעלה בקטע הזמנת שם מארח ב-Cloud Run. לא כוללים את מזהה הפרוטוקול, https://.

    לדוגמה:

    chmod +x gcloud_build_image
    
    ./gcloud_build_image -s gateway-12345-uc.a.run.app \
        -c 2019-02-01r0 -p your-project-id
  3. הסקריפט משתמש בפקודה gcloud כדי להוריד את הגדרות השירות, ליצור מהן קובץ אימג' חדש של ESPv2 ולהעלות את קובץ האימג' החדש למאגר הקונטיינרים של הפרויקט. הסקריפט משתמש אוטומטית בגרסה האחרונה של ESPv2, שמסומנת ב-ESPv2_VERSION בשם של תמונת הפלט. התמונה שנוצרה מועלית אל:

    gcr.io/ESPv2_PROJECT_ID/endpoints-runtime-serverless:ESPv2_VERSION-ESPv2_CLOUD_RUN_HOSTNAME-CONFIG_ID

    לדוגמה:

    gcr.io/your-project-id/endpoints-runtime-serverless:2.14.0-gateway-12345-uc.a.run.app-2019-02-01r0"

פריסת הקונטיינר של ESPv2

  1. פורסים את שירות ESPv2 Cloud Run עם קובץ האימג' החדש שיצרתם למעלה. מחליפים את CLOUD_RUN_SERVICE_NAME באותו שם שירות של Cloud Run שבו השתמשתם כששריינתם את שם המארח למעלה בקטע שריון שם מארח ב-Cloud Run:

    gcloud run deploy CLOUD_RUN_SERVICE_NAME \
      --image="gcr.io/ESPv2_PROJECT_ID/endpoints-runtime-serverless:ESPv2_VERSION-CLOUD_RUN_HOSTNAME-CONFIG_ID" \
      --allow-unauthenticated \
      --platform managed \
      --project=ESPv2_PROJECT_ID
  2. אם רוצים להגדיר את Endpoints כך שישתמש באפשרויות נוספות להפעלה של ESPv2, כמו הפעלת CORS, אפשר להעביר את הארגומנטים במשתנה הסביבה ESPv2_ARGS:

    gcloud run deploy CLOUD_RUN_SERVICE_NAME \
      --image="gcr.io/ESPv2_PROJECT_ID/endpoints-runtime-serverless:ESPv2_VERSION-CLOUD_RUN_HOSTNAME-CONFIG_ID" \
      --set-env-vars=ESPv2_ARGS=--cors_preset=basic \
      --allow-unauthenticated \
      --platform managed \
      --project ESPv2_PROJECT_ID

    למידע נוסף ולדוגמאות על הגדרת משתנה הסביבה ESPv2_ARGS, כולל רשימת האפשרויות הזמינות ומידע על ציון כמה אפשרויות, אפשר לעיין במאמר Extensible Service Proxy V2 flags.

  3. נותנים ל-ESPv2 הרשאה להפעיל את שירותי Cloud Run. מריצים את הפקודה הבאה לכל שירות. בפקודה הבאה:
    • מחליפים את BACKEND_SERVICE_NAME בשם של שירות Cloud Run שמופעל. אם אתם משתמשים בשירות שנוצר על ידי פריסת `gcr.io/endpointsv2/python-grpc-bookstore-server:2`, צריך להשתמש ב-python-grpc-bookstore-server כערך הזה.
    • מחליפים את ESPv2_PROJECT_NUMBER במספר הפרויקט שיצרתם עבור ESPv2. אחת הדרכים למצוא את זה היא להיכנס לדף IAM במסוף Google Cloud ולחפש את חשבון השירות שמוגדר כברירת מחדל ל-Compute, שהוא חשבון השירות שמשמש בדגל member.
    gcloud run services add-iam-policy-binding BACKEND_SERVICE_NAME \
      --member "serviceAccount:ESPv2_PROJECT_NUMBER-compute@developer.gserviceaccount.com" \
      --role "roles/run.invoker" \
      --platform managed \
      --project BACKEND_PROJECT_ID

מידע נוסף מופיע במאמר ניהול גישה באמצעות IAM.

שליחת בקשות ל-API

כדי לשלוח בקשות ל-API לדוגמה, אפשר להשתמש בלקוח gRPC לדוגמה שנכתב ב-Python.

  1. משכפלים את מאגר ה-Git שבו מתארח קוד הלקוח של gRPC:

    git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
  2. כדי לשנות את ספריית העבודה:

    cd python-docs-samples/endpoints/bookstore-grpc/
  3. יחסי תלות של התקנות:

    pip3 install virtualenv
    virtualenv env
    source env/bin/activate
    pip3 install -r requirements.txt
  4. שליחת בקשה ל-API לדוגמה:

    python3 bookstore_client.py --host CLOUD_RUN_HOSTNAME --port 443 --use_tls true

    מציינים את שם המארח של שירות ESPv2 Cloud Run ב-CLOUD_RUN_HOSTNAME, בלי מזהה הפרוטוקול. לדוגמה:

    python3 bookstore_client.py --host espv2-grpc-HASH-uc.a.run.app --port 443 --use_tls true
    • מעיינים בתרשימי הפעילות של ה-API בדף Endpoints > Services.

      לדף Endpoints Services

      יכול להיות שיעברו כמה רגעים עד שהבקשה תשתקף בתרשימים.

    • מעיינים ביומני הבקשות של ה-API בדף Logs Explorer.

      כניסה לדף Logs Explorer

אם לא מקבלים תגובה, אפשר להיעזר במאמר בנושא פתרון בעיות שקשורות לתגובות.

הרגע פרסתם ובדקתם API ב-Endpoints!

מעקב אחר פעילות ב-API

  1. אפשר לראות את הגרפים של הפעילות ב-API בדף Endpoints ‏ > Service במסוף Google Cloud .

    הצגת גרפים של פעילות ב-Endpoints

    יכול להיות שיעברו כמה רגעים עד שהבקשה תשתקף בתרשימים.

  2. מעיינים ביומני הבקשות של ה-API בדף Logs Explorer.

    הצגת יומני הבקשות של Endpoints

הסרת המשאבים

כדי לא לצבור חיובים לחשבון Google Cloud על המשאבים שבהם השתמשתם בדף הזה, פועלים לפי השלבים הבאים:

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

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