מעבר ל-Extensible Service Proxy V2

Extensible Service Proxy V2‏ (ESPv2) הוא פרוקסי מבוסס Envoy שמאפשר ל-Cloud Endpoints לספק תכונות של ניהול API. ‫ESPv2 מחליף את Extensible Service Proxy (ESP) שמבוסס על NGINX.

במאמר הזה מוסבר איך להעביר פריסה קיימת של Endpoints API מ-ESP ל-ESPv2.

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

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

תרחישי שימוש שלא נתמכים ב-ESPv2

  • הסביבה הגמישה של App Engine לא נתמכת

    בסביבה הגמישה של App Engine יש תמיכה מובנית ב-Endpoints, שמופעלת על ידי הגדרת endpoints_api_service בקובץ app.yaml של האפליקציה. ההטמעה המובנית הזו של Endpoints תומכת רק ב-ESP, ואי אפשר להעביר אותה ל-ESPv2.

    אם רוצים להשתמש ב-ESPv2 עם הסביבה הגמישה של App Engine, צריך להשבית את endpoints_api_service ב-app.yaml. אפשר לפרוס את ESPv2 כשירות נפרד של Cloud Run שמשמש לניהול האפליקציה בסביבה גמישה של App Engine. הפריסה פועלת באותו אופן שבו ESPv2 משמש לתמיכה בסביבה הרגילה של App Engine.

  • אין תמיכה בהגדרה מותאמת אישית של NGINX

    ‫ESPv2 הוא proxy מבוסס Envoy. היא לא יכולה לתמוך בהגדרת שרת proxy של NGINX בהתאמה אישית. אם בהגדרות של ספק ה-ESP נעשה שימוש בדגלים -n או --nginx_config, יכול להיות שההטמעה שלכם מסתמכת על הגדרות NGINX בהתאמה אישית שלא ניתן להעביר בקלות ל-ESPv2.

שינויי תוכנה שעלולים לגרום לכשלים

  • הפורמט של נתוני הכותרת X-Endpoint-API-UserInfo השתנה. אם האפליקציה שלכם משתמשת בכותרת הזו, צריך לשנות אותה כך שתשתמש בפורמט החדש. פרטים נוספים זמינים במאמר בנושא טיפול ב-JWT בשירות לקצה העורפי.
  • אם נדרש מפתח API בשביל בקשה, ESP שולח את הכותרת X-Endpoint-API-Project-ID עם מזהה פרויקט הצרכן לאפליקציית ה-Backend. ‫ESPv2 משתמש בשתי כותרות שונות,X-Endpoint-API-Consumer-Type ו-X-Endpoint-API-Consumer-Number, כדי לשלוח את הפרטים הנדרשים. פרטים נוספים על הערכים Consumer-Type ו-Consumer-Number שנשלחים עם הכותרות האלה מופיעים במאמרי העזרה בנושא Service Infrastructure.

  • הפורמט של תוכן תגובת שגיאת HTTP השתנה. כש-ESPv2 דוחה בקשת HTTP, הוא יוצר תוכן של תגובת שגיאה בפורמט חדש. אם בהטמעה שלכם נעשה שימוש בקוד לקוח לעיבוד גוף התגובה של שגיאת ה-HTTP בפורמט JSON, צריך לעדכן את קוד הלקוח. פרטים נוספים מופיעים במאמר בנושא תוכן תגובת JSON לשגיאת HTTP.

  • יש דגלים חדשים להפעלה, וחלק מהדגלים של ESP הוצאו משימוש או הוחלפו ב-ESPv2. שינויים בדגלי הפעלה בין ESP ל-ESPv2

העברת ממשקי ה-API של Endpoints לשימוש ב-ESPv2

שלבי ההעברה שנדרשים לשימוש ב-ESPv2 בפלטפורמות ללא שרת (Cloud Run, פונקציות Cloud Run,‏ App Engine) שונים מהשלבים שנדרשים לפלטפורמות ללא שרת (Google Kubernetes Engine,‏ Compute Engine ו-Kubernetes).

בהמשך מפורטים שלבי ההעברה שנדרשים לכל סוג פלטפורמה:

פלטפורמות ללא שרת: GKE, ‏ Compute Engine, ‏ Kubernetes

‫ESPv2 הוא תחליף ל-ESP שניתן להטמעה בקלות. ברוב ההגדרות, צריך רק לעדכן את תג תמונת ה-Docker.

עם זאת, יכול להיות שתצטרכו לשנות את דגלי ההפעלה אם הגדרתם את ה-ESP עם:

  • יותר מיציאה אחת באמצעות הדגלים --http_port, http2_port ו/או --ssl_port.
  • SSL,‏ DNS,‏ Client IP או דגל אחר שמשתמשים בו לעיתים רחוקות.

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

‫GKE ו-Kubernetes

כדי להעביר הגדרות של Endpoints ל-GKE ול-Kubernetes, צריך לשנות את תג התמונה של ESP מ-:1 ל-:2 בקובץ הפריסה yaml. לדוגמה:

- name: esp
  image: gcr.io/endpoints-release/endpoints-runtime:2
  args: [
    "--http_port=8081",
    "--backend=127.0.0.1:8080",
    "--service=SERVICE_NAME",
    "--rollout_strategy=managed",
  ]

Compute Engine

‫ESP ו-ESPv2 נפרסים לקונטיינר Docker באמצעות הפקודה docker run. כדי להעביר את Endpoints for Compute Engine ל-ESPv2, מעדכנים את תג תמונת ה-Docker מהערך :1 לערך :2 בפקודה. לדוגמה:

sudo docker run \
    --detach \
    DOCKER_ARGUMENTS \
    gcr.io/endpoints-release/endpoints-runtime:2 \
    --service=SERVICE_NAME \
    --rollout_strategy=managed \
    --backend=YOUR_API_CONTAINER_NAME:8080

פלטפורמות ללא שרת (Cloud Run, ‏ Cloud Functions, ‏ App Engine)

בפלטפורמות בלי שרת (serverless), ESPv2 נפרס כשירות Cloud Run כדי לנהל את האפליקציה שפועלת ב-Cloud Run, ב-פונקציה של Cloud Functions או ב-App Engine. כדי להעביר את Endpoints ל-ESPv2, צריך ליצור את הגדרת שירות Endpoints הקיימת בקובץ אימג' חדש של ESPv2 Docker, ואז לפרוס את קובץ האימג' בשירות ESPv2 Cloud Run.

שלבי הפריסה של ESP ו-ESPv2 זהים, למעט הפרטים הבאים:

  • כשפורסים את ESPv2 ב-Cloud Run, צריך לשנות את תג התמונה מ-:1 ל-:2 ב-ESPv2. לדוגמה:

    gcloud run deploy CLOUD_RUN_SERVICE_NAME \
    --image="gcr.io/endpoints-release/endpoints-runtime-serverless:2" \
    --allow-unauthenticated \
    --platform managed \
    --project=ESP_PROJECT_ID  
  • gcloud_build_image הסקריפט מורד ממיקום אחר. היא משתמשת ב-gcr.io/endpoints-release/endpoints-runtime-serverless:2 כתמונת הבסיס.

  • משתמשים במשתנה סביבה כדי לציין את דגלי ההפעלה. שם המשתנה של ESP הוא ESP_ARGS. השם של ESPv2 הוא ESPv2_ARGS. מידע נוסף על הגדרת ESPv2_ARGS ועל דגלי ההפעלה הזמינים מופיע במאמר אפשרויות ההפעלה של Extensible Service Proxy V2.

שינויים בדגלי ההפעלה בין ESP ל-ESPv2

בדומה ל-Extensible Service Proxy, אפשר לציין פלאגי תצורה כשפורסים שירותי ESPv2. במסגרת המעבר מ-ESP מבוסס NGINX ל-ESPv2 מבוסס Envoy, חלק מהדגלים הוצאו משימוש או הוחלפו, וחלק מהדגלים חדשים נוספו. בקטע הזה יש שלוש טבלאות שמתארות את השינויים:

  • בטבלה 1 מפורטים סימונים חדשים שמחליפים סימונים שיצאו משימוש.
  • טבלה 2 מתארת דגלים חדשים.
  • בטבלה 3 מתוארים סימונים שהוצאו משימוש.

החלפת סימונים

דיווחים חדשים הסימונים הוחלפו תיאור
--listener_port --http_port, --http2_port, --ssl_port יציאת מאזין אחת של Envoy תומכת ב-http, ‏ http2 ו-ssl ב-ESPv2. אין צורך לציין יציאות נפרדות.
--ssl_server_cert_path --ssl_port כשמשתמשים ב---ssl_server_cert_path, ‏ ESPv2 משתמש באישורים מקובצי server.key ו-server.crt. ב-ESPv2 אפשר לציין נתיבים של אישורי שרת שאינם /etc/nginx/ssl. הדגל הזה מחליף את --ssl_port ב-ESP, שמשתמש באישורים מנתיבי הקבצים /etc/nginx/ssl/nginx.key ו-/etc/nginx/ssl/nginx.crt.
--ssl_backend_client_cert_path --tls_mutual_auth,‏ --enable_grpc_backend_ssl,‏ --grpc_backend_ssl_private_key_file,‏ --grpc_backend_ssl_cert_chain_file כשמשתמשים ב---ssl_backend_client_cert_path, ‏ ESPv2 משתמש באישורים מקובצי client.key ו-client.crt. ב-ESPv2, אפשר לציין נתיבים של אישורי לקוח שאינם /etc/nginx/ssl. הדגל הזה מחליף את --tls_mutual_auth ב-ESP, שמשתמש באישורים מנתיבי הקבצים /etc/nginx/ssl/backend.key ו-/etc/nginx/ssl/backend.crt.
--ssl_backend_client_root_certs_file --grpc_backend_ssl_root_certs_file עם ESPv2, ‏ --ssl_backend_client_root_certs_file פועל בכל השרתים העורפיים. הדגל הזה מחליף את הדגל --grpc_backend_ssl_root_certs_file ב-ESP, שפועל רק עם עורפי gRPC.
--ssl_minimum_protocol,--ssl_maximum_protocol --ssl_protocols כשמשתמשים ב---ssl_protocols ב-ESP, צריך לפרט את כל פרוטוקולי ה-SSL הרצויים. ב-ESPv2, אפשר לציין פרוטוקול מינימלי ומקסימלי.
--envoy_use_remote_address,--envoy_xff_num_trusted_hops --xff_trusted_proxy_list,--client_ip_header,--client_ip_position כדי להגדיר חילוץ של כתובת ה-IP של הלקוח, צריך להשתמש ב-Envoy ב-use_remote_address וב-xff_num_trusted_hops.
--dns_resolver_addresses --dns הדגל של ההחלפה מתנהג באופן דומה, אבל ערך ברירת המחדל שלו שונה. ‫ESP משתמש ב-8.8.8.8 כמפענח DNS. ‫ESPv2 משתמש במפענח DNS שהוגדר ב-/etc/resolv.conf.
--service_account_key --non_gcp, --service_account_key ב-ESP, הדגל --service_account_key מאפשר באופן מרומז פריסה בפלטפורמות אחרות מלבד GCP. הוא מונע מ-ESP להתקשר אל Instance Metadata Server. ב-ESPv2, ההתנהגות המרומזת הזו מפוצלת לדגל אחר. יכול להיות שתצטרכו להוסיף את --non_gcp כשמבצעים העברה, אחרת ESPv2 לא יופעל בפלטפורמות שאינן GCP.

דגלים חדשים

דיווחים חדשים תיאור
--http_request_timeout_s מגדיר את הזמן הקצוב לתפוגה של כל השיחות המרוחקות מסוג http/https, למעט שיחות backend ושיחות של Google Service Control API, בשניות.
--service_control_check_timeout_ms ההגדרה הזו קובעת את הזמן הקצוב לתפוגה (timeout) של שיחות Google Service Control Check, באלפיות השנייה.
--service_control_report_timeout_ms הגדרה של הזמן הקצוב לתפוגה של קריאות ל-Google Service Control Report.
--service_control_quota_timeout_ms ההגדרה הזו קובעת את הזמן הקצוב לתפוגה של קריאות ל-Google Service Control API Quota.
--service_control_check_retries מציינת את מספר הניסיונות החוזרים לקריאות של Google Service Control API.
--service_control_report_retries מציין את מספר הניסיונות החוזרים לביצוע קריאות ל-Google Service Control Report.
--service_control_quota_retries מציין את מספר הניסיון החוזר לקריאות של Google Service Control Quota.
--backend_dns_lookup_family הגדרה ספציפית ל-Envoy שמשמשת להגדרת משפחת החיפוש של DNS לכל השרתים העורפיים.
--disable_tracing דגל כללי שמשמש להשבתה של כל העקבות.
--tracing_project_id המאפיין הזה משמש להגדרת המזהה של הפרויקט שבבעלותו נתוני המעקב.
--tracing_incoming_context משמש לציון ההקשר של העקבות הנכנסות.
--tracing_outgoing_context משמשת לציון ההקשר של העקבות היוצאות.

דגלים שיצאו משימוש

סימונים שיצאו משימוש תיאור
--enable_websocket פרוטוקול WebSocket מופעל ב-Envoy כברירת מחדל.
--experimental_proxy_backend_host_header לא נתמך.
--allow_invalid_headers לא נתמך. זוהי הגדרת NGINX: ignore_invalid_headers. אם בקשת HTTP מכילה שמות כותרות לא תקינים, היא תידחה על ידי ESPv2. שמות כותרות תקינים מורכבים מאותיות באנגלית, ספרות, מקפים ואולי גם קווים תחתונים. ב-ESPv2, הדגל --underscores_in_headers קובע אם מותר להשתמש בקו תחתון בכותרות.
--client_max_body_size הגדרת NGINX לא נתמכת.
--client_body_buffer_size הגדרת NGINX לא נתמכת.
--large_client_header_buffers הגדרת NGINX לא נתמכת.
--keepalive_timeout הגדרת NGINX לא נתמכת.
--client_body_timeout הגדרת NGINX לא נתמכת.
--rewrite לא נתמך.
--experimental_enable_multiple_api_configs לא נתמך.
--enable_backend_routing אין צורך. ניתוב בשרת העורפי מופעל באופן אוטומטי בפלטפורמות ללא שרת.
--rollout_fetch_throttle_window_in_s אין צורך.
--nginx_config לא נתמך.

פרטים נוספים על דגלי ההפעלה של ESPv2 זמינים במאמר אפשרויות ההפעלה של Extensible Service Proxy V2. דוגמאות כלליות נוספות וטקסט עזרה לגבי דגלים זמינים במאגר GitHub.

מיקומי ברירת מחדל של אסימוני JWT

כברירת מחדל, ה-JWT מועבר בכותרת Authorization (עם הקידומת Bearer ), בכותרת X-Goog-Iap-Jwt-Assertion או בפרמטר השאילתה access_token. יש תמיכה במיקומים האלה גם ב-ESP וגם ב-ESPv2. אפשר גם להעביר JWT בכותרת Authorization (ללא קידומת) כשמשתמשים ב-ESP. עם זאת, המיקום הזה לא נתמך ב-ESPv2.

אם אתם רוצים להמשיך להעביר אסימוני JWT באמצעות הכותרת Authorization (ללא קידומת) אחרי המעבר ל-ESPv2, אתם יכולים:

x-google-jwt-locations:
- header: "Authorization"
jwt_locations:
- header: Authorization

טיפול ב-JWT בשירות הקצה העורפי

כשמשתמשים באסימוני JWT כדי לבצע אימות, ‏ ESPv2 ו-ESP שולחים את תוצאת האימות בכותרת X-Endpoint-API-UserInfo אל ה-API של ה-Backend. מומלץ להשתמש בכותרת הזו במקום בכותרת המקורית Authorization, כי יכול להיות שהכותרת המקורית Authorization תשתנה בפלטפורמות ללא שרתים.

הכותרת X-Endpoint-API-UserInfo מכילה אובייקט JSON בקידוד Base64Url. עם זאת, הפורמט שלו השתנה מ-ESP ל-ESPv2.

ב-ESPv2, הכותרת X-Endpoint-API-UserInfo מכילה את מטען הייעודי (payload) של JWT המקורי, ללא שינוי.

ב-ESP, הכותרת X-Endpoint-API-UserInfo מכילה את מטען הייעודי (payload) של ה-JWT וכמה שדות ספציפיים שנוספו על ידי ESP. ‫ESP מוסיף את השדות id, issuer, email ו-audiences לאובייקט ה-JSON. בנוסף, הוא מוסיף את השדה claims כדי לכלול את מטען ה-JWT המקורי.

# ESPv1 X-Endpoint-API-UserInfo header value
{
  "id": "extracted from 'sub' field",
  "issuer": "extracted from 'iss' field",
  "email": "extracted from 'email' field",
  # The following "audiences" is extracted from 'aud' field.
  # The 'aud' field may have multiple audiences delimited by coma. e.g. "aud: aud1,aud2".
  # but the following "audiences" is always a JSON array.
  "audiences": ["aud1", "aud2"],
  "claims": {
     Original JWT payload
   }
}

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

# This is an example of the original JWT payload:
{
  &quotiss&quot: &quothttps://accounts.google.com&quot,
  &quotemail&quot: &quotabcdefg123456@gmail.com&quot,
  &quotsub&quot: &quot1234567890123456789&quot,
  &quotaud&quot: &quotxyz1.example.com,xyz2.example.com&quot,
  &quotfoo&quot: &quotfoo.foo.foo.foo&quot,
  &quotbar&quot: &quotbar.bar.bar.bar&quot,
  &quotazp&quot: &quot98765432109876543210&quot,
  &quotexp&quot: &quot1642809446&quot,
  &quotiat&quot: &quot1642805846&quot
}

# This is an example of the `X-Endpoint-API-UserInfo` header from ESPv2
# extracted from above JWT payload.
{
  &quotiss&quot: &quothttps://accounts.google.com&quot,
  &quotemail&quot: &quotabcdefg123456@gmail.com&quot,
  &quotsub&quot: &quot1234567890123456789&quot,
  &quotaud&quot: &quotxyz1.example.com,xyz2.example.com&quot,
  &quotfoo&quot: &quotfoo.foo.foo.foo&quot,
  &quotbar&quot: &quotbar.bar.bar.bar&quot,
  &quotazp&quot: &quot98765432109876543210&quot,
  &quotexp&quot: &quot1642809446&quot,
  &quotiat&quot: &quot1642805846&quot
}

# This is an example of the `X-Endpoint-API-UserInfo` header from ESP
# extracted from above JWT payload.
{
  &quotid&quot:&quot1234567890123456789&quot,
  &quotissuer&quot: &quothttps://accounts.google.com&quot,
  &quotemail&quot: &quotabcdefg123456@gmail.com&quot,
  &quotaudiences&quot: [
    &quotxyz1.example.com&quot
    &quotxyz2.example.com&quot
  ],
  &quotclaims&quot: {
    &quotiss&quot: &quothttps://accounts.google.com&quot,
    &quotemail&quot: &quotabcdefg123456@gmail.com&quot,
    &quotsub&quot: &quot1234567890123456789&quot,
    &quotaud&quot: &quotxyz1.example.com,xyz2.example.com&quot,
    &quotfoo&quot: &quotfoo.foo.foo.foo&quot,
    &quotbar&quot: &quotbar.bar.bar.bar&quot,
    &quotazp&quot: &quot98765432109876543210&quot,
    &quotexp&quot: &quot1642809446&quot,
    &quotiat&quot: &quot1642805846&quot
  }
}

במאמרים שימוש בשיטה מותאמת אישית לאימות משתמשים ואימות בין שירותים יש מידע נוסף על שימוש ב-JWT לצורך אימות.

פורמט גוף תגובת JSON של שגיאה

אם בקשת HTTP נדחית על ידי ESP או ESPv2, גוף התגובה מכיל קוד סטטוס והודעת שגיאה בפורמט JSON. הפורמט של גוף התגובה השתנה ב-ESPv2, כמו שמוצג בדוגמאות הבאות:

התוכן של תגובת השגיאה מ-ESP

{
 "code": 5,
 "message": "Method does not exist.",
 "details": [
  {
   "@type": "type.googleapis.com/google.rpc.DebugInfo",
   "stackEntries": [],
   "detail": "service_control"
  }
 ]
}

התוכן של תגובת השגיאה מ-ESPv2

{
 "code": 400,
 "message": "Method does not exist.",
}

יש שני הבדלים עיקריים:

  • ב-ESPv2, השדה code מכיל קוד סטטוס של HTTP, ולא קוד מצב RPC שמופיע ב-ESP.
  • גוף תגובת השגיאה ב-ESPv2 לא מכיל את השדה details.

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

מידע על: