יכולת הרחבה של מישור הנתונים באמצעות EnvoyFilter

אתם יכולים להשתמש ב-EnvoyFilter API כדי להרחיב את היכולות של מישור הנתונים ב-Cloud Service Mesh, שלא ניתן להשיג בדרך אחרת באמצעות ממשקי API אחרים של Istio. באמצעות EnvoyFilter API, אתם יכולים להתאים אישית את ההגדרה של Envoy שנוצרת ממדיניות אחרת שחלה על עומסי העבודה, למשל להוסיף מסננים לשרשרת המסננים של HTTP.

שיקולים חשובים

  • שימו לב שמשטח ה-API קשור לפרטי הטמעה פנימיים, ולכן צריך לנקוט משנה זהירות כשמשתמשים בתכונה הזו, כי הגדרות שגויות עלולות לערער את היציבות של הרשת. מומלץ להשתמש ב-EnvoyFilter API רק אם ממשקי API אחרים של Istio לא מתאימים לצרכים שלכם.
  • ממשק EnvoyFilter API נתמך עם הגבלות ספציפיות על השדות וההרחבות שאפשר להשתמש בהם למטרות אמינות ותמיכה. רשימה מלאה של התכונות הנתמכות ב-EnvoyFilter API זמינה במאמר תכונות נתמכות באמצעות ממשקי Istio API (מישור בקרה מנוהל).
  • היקף התמיכה ש-Google מציעה מוגבל להפצת ההגדרה שסופקה על ידי המשתמש לעומסי העבודה עם Envoy sidecars, ולא כולל את התקינות של ההגדרה שצוינה באמצעות ממשקי API לכל תוסף.

שדות API נתמכים

ממשק EnvoyFilter API נתמך בהטמעה של מישור הבקרה TRAFFIC_DIRECTOR רק עם תמיכה מוגבלת באופן הבא:

  • targetRefs: לא נתמך
  • configPatches[].applyTo : נתמך רק HTTP_FILTER
  • configPatches[].patch.operation: רק INSERT_FIRST ו-INSERT_BEFORE נתמכים כשמשתמשים בהם עם מסנן המסלולים.
  • configPatches[].patch.value.type_url: אפשר לעיין בתוספים נתמכים
  • configPatches[].patch.filterClass: לא נתמך
  • configPatches[].match.proxy: לא נתמך
  • configPatches[].match.routeConfiguration: לא נתמך
  • configPatches[].match.cluster: לא נתמך
  • השדות הבאים נתמכים רק בפעולה INSERT_BEFORE:
    • configPatches[].match.listener: רק filter נתמך.
    • configPatches[].match.listener.filter.name: רק envoy.filters.network.http_connection_manager נתמך.
    • configPatches[].match.listener.filter.subFilter.name: רק envoy.filters.http.router נתמך.

תוספים נתמכים

בהמשך מופיעה רשימה של התוספים הנתמכים, לצד השדות הנתמכים שלהם ב-API בערוצי הפצה שונים. הגדרת ה-API והסמנטיקה שלו מפורטות במסמכי התיעוד הרשמיים של Envoy.

type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit

שדה חדשנות Regular יציב
stat_prefix
status
token_bucket
filter_enabled
filter_enforced
response_headers_to_add
request_headers_to_add_when_not_enforced
local_rate_limit_per_downstream_connection
enable_x_ratelimit_headers

type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb

שדה חדשנות Regular יציב
(אין שדות)

type.googleapis.com/envoy.extensions.filters.http.compressor.v3.Compressor

שדה חדשנות Regular יציב
compressor_library
choose_first
response_direction_config.common_config.min_content_length
response_direction_config.common_config.content_type
response_direction_config.common_config.enabled
response_direction_config.disable_on_etag_header
response_direction_config.remove_accept_encoding_header
response_direction_config.uncompressible_response_codes
request_direction_config.common_config.min_content_length
request_direction_config.common_config.content_type
request_direction_config.common_config.enabled

מידע על עדכון ההגדרה של EnvoyFilter compressor כדי לקבל תמיכה מלאה זמין במאמר Modernize EnvoyFilter compressor configurations.

type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua

שדה חדשנות Regular יציב
stat_prefix
default_source_code.inline_string

‫† שיקולים חשובים והגבלות לגבי סקריפטים של Lua מוטבעים:

  • כדי לשמור על אבטחה ויציבות, מותר להשתמש רק בחלק מתכונות Lua וב-wrappers של Envoy Lua. שימוש בתכונות שלא נתמכות או חריגה מהמגבלות שמפורטות במסמכים יגרמו לדחייה של EnvoyFilter.
  • תסריטי Lua מורכבים עלולים להשפיע על הביצועים. חשוב לבדוק היטב את השימוש במשאבים של הסקריפטים.

תכונות Lua שלא נתמכות:
התכונות הבאות של Lua ועטיפות Lua שסופקו על ידי Envoy לא נתמכות:

  • Envoy Wrappers:
    • httpCall
    • filterContext
  • Lua Standard Library:
    • חבילה בסיסית: collectgarbage, dofile, getmetatable, loadfile, rawset, setfenv, setmetatable
    • מודולים: module
    • חבילת מערכת הפעלה: execute, remove, rename, setlocale
    • ספריות קלט/פלט וניפוי באגים: io, debug
  • LuaJIT Extensions: ffi, jit

מגבלות על גודל הסקריפט ומספר הסקריפטים:

  • גודל סקריפט בודד: הגודל של סקריפט Lua מוטבע שמופיע ב-default_source_code.inline_string לא יכול להיות גדול מ-50KB.
  • הגודל הכולל של הסקריפט: הגודל הכולל של כל סקריפטים של Lua בכל משאבי EnvoyFilter באותו אשכול לא יכול לחרוג מ-100KB.
  • מספר תיקוני האבטחה: המספר הכולל של Lua EnvoyFilter configPatches בכל משאבי EnvoyFilter באשכול יחיד מוגבל ל-10.

דוגמאות לשימוש

במדריך הזה תלמדו איך להשתמש בהגבלת קצב מקומית מובנית של Envoy כדי להגביל באופן דינמי את התנועה לשירות באמצעות EnvoyFilter API.

עלויות

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

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

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

  • מוודאים שהחיוב מופעל בפרויקט.
  • הקצאת Cloud Service Mesh באשכול GKE.
  • משכפלים את המאגר:

      git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
      cd anthos-service-mesh-samples
    

פריסת שער כניסה

  1. מגדירים את ההקשר הנוכחי של kubectl לאשכול:

    gcloud container clusters get-credentials CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    
  2. יוצרים מרחב שמות לשער הכניסה:

    kubectl create namespace asm-ingress
    
  3. מפעילים את מרחב השמות להחדרה. השלבים תלויים בהטמעה של מישור הבקרה.

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

    kubectl label namespace asm-ingress \
        istio.io/rev- istio-injection=enabled --overwrite
    
  4. פורסים את שער לדוגמה במאגר anthos-service-mesh-samples:

    kubectl apply -n asm-ingress \
        -f docs/shared/asm-ingress-gateway
    

    הפלט אמור להיראות כך:

    serviceaccount/asm-ingressgateway configured
    service/asm-ingressgateway configured
    deployment.apps/asm-ingressgateway configured
    gateway.networking.istio.io/asm-ingressgateway configured
    

פריסה של אפליקציית Online Boutique לדוגמה

  1. אם לא עשיתם זאת, מגדירים את ההקשר הנוכחי של kubectl לאשכול:

    gcloud container clusters get-credentials CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION 
    
  2. יוצרים את מרחב השמות של האפליקציה לדוגמה:

    kubectl create namespace onlineboutique
    
  3. כדי להוסיף אוטומטית שרתי proxy של Envoy, צריך להוסיף תווית למרחב השמות onlineboutique:

    kubectl label namespace onlineboutique \
       istio.io/rev- istio-injection=enabled --overwrite
    
  4. פורסים את האפליקציה לדוגמה, את VirtualService לקצה הקדמי ואת חשבונות השירות לעומסי העבודה. במדריך הזה תפרסו את Online Boutique, אפליקציית הדגמה של מיקרו-שירות.

    kubectl apply \
      -n onlineboutique \
      -f docs/shared/online-boutique/virtual-service.yaml
    
    kubectl apply \
      -n onlineboutique \
      -f docs/shared/online-boutique/service-accounts
    

צפייה בשירותים

  1. צופים בפודים במרחב השמות onlineboutique:

    kubectl get pods -n onlineboutique
    

    הפלט אמור להיראות כך:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-m84m6               2/2     Running   0          2m7s
    cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
    checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
    currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
    emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
    frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
    loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
    paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
    productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
    recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
    redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
    shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
    

    כל הפודים של האפליקציה צריכים לפעול, ובעמודה READY צריך להופיע 2/2. המשמעות היא שפרוקסי קובץ עזר חיצוני Envoy הוזרק לפודים בהצלחה. אם הסמל 2/2 לא מופיע אחרי כמה דקות, אפשר להיעזר במדריך לפתרון בעיות.

  2. מקבלים את כתובת ה-IP החיצונית ומגדירים אותה כמשתנה:

    kubectl get services -n asm-ingress
    export FRONTEND_IP=$(kubectl --namespace asm-ingress \
    get service --output jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}' \
    )
    

    הפלט אמור להיראות כך:

    NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                      AGE
    asm-ingressgateway   LoadBalancer   10.19.247.233   35.239.7.64   80:31380/TCP,443:31390/TCP,31400:31400/TCP   27m
    
    
  3. נכנסים לכתובת EXTERNAL-IP בדפדפן האינטרנט. החנות Online Boutique אמורה להופיע בדפדפן.

    ממשק המשתמש של חנות בוטיק אונליין

החלת הגדרות של הגבלת קצב של יצירת בקשות

בקטע הזה מוחל משאב EnvoyFilter כדי להגביל את כל התנועה לשירות frontend ל-5 בקשות לדקה.

  1. החלת ה-CR על השירות frontend:

    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: frontend-local-ratelimit
      namespace: onlineboutique
    spec:
      workloadSelector:
        labels:
          app: frontend
      configPatches:
        - applyTo: HTTP_FILTER
          match:
            context: SIDECAR_INBOUND
            listener:
              filterChain:
                filter:
                  name: "envoy.filters.network.http_connection_manager"
                  subFilter:
                    name: "envoy.filters.http.router"
          patch:
            operation: INSERT_BEFORE
            value:
              name: envoy.filters.http.local_ratelimit
              typed_config:
                "@type": type.googleapis.com/udpa.type.v1.TypedStruct
                type_url: type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
                value:
                  stat_prefix: http_local_rate_limiter
                  token_bucket:
                    max_tokens: 5
                    tokens_per_fill: 5
                    fill_interval: 60s
                  filter_enabled:
                    runtime_key: local_rate_limit_enabled
                    default_value:
                      numerator: 100
                      denominator: HUNDRED
                  filter_enforced:
                    runtime_key: local_rate_limit_enforced
                    default_value:
                      numerator: 100
                      denominator: HUNDRED
    EOF
    

    הפלט אמור להיראות כך:

    envoyfilter.networking.istio.io/frontend-local-ratelimit created
    
  2. מוודאים שבדוח הסטטוס של ה-CR לא מופיעות שגיאות:

    kubectl get envoyfilter -n onlineboutique frontend-local-ratelimit -o yaml
    

    הפלט אמור להיראות כך:

    ...
    status:
      conditions:
      - lastTransitionTime: "2025-06-30T14:29:25.467017594Z"
        message: This resource has been accepted. This does not mean it has been propagated
          to all proxies yet
        reason: Accepted
        status: "True"
        type: Accepted
    
  3. מסירים את הפריסה loadgenerator כי היא קוראת לשירות מספר פעמים וצורכת טוקנים:

    kubectl delete -n onlineboutique deployment loadgenerator
    

    הפלט אמור להיראות כך:

    deployment.apps/loadgenerator deleted
    
  4. באמצעות curl, בודקים שמותר לשלוח עד 5 בקשות ב-60 שניות. הקוד 429 מציין שהגבלת הקצב נאכפת.

    for i in {1..10}; do curl -s http://${FRONTEND_IP} -o /dev/null -w "%{http_code}\n"; sleep 1; done
    

    הפלט אמור להיראות כך:

    200
    200
    200
    200
    200
    429
    429
    429
    429
    429
    

הסרת המשאבים

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

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

ב-Cloud Shell, מוחקים את הפרויקט:

  gcloud projects delete PROJECT_ID

מחיקת המשאבים

  • אם רוצים לשמור את האשכול ולהסיר את הדוגמה Online Boutique:

    1. מוחקים את מרחבי השמות של האפליקציה:

      kubectl delete namespace onlineboutique
      

      הפלט אמור להיראות כך:

      namespace "onlineboutique" deleted
      
    2. מחיקת מרחב השמות של Ingress Gateway:

      kubectl delete namespace asm-ingress
      

      הפלט אמור להיראות כך:

      namespace "asm-ingress" deleted
      
  • כדי למנוע חיובים נוספים, צריך למחוק את האשכול:

    gcloud container clusters delete CLUSTER_NAME  \
      --project=PROJECT_ID \
      --zone=CLUSTER_LOCATION 
    

פתרון בעיות

מידע נוסף זמין במאמר בנושא פתרון בעיות בהרחבת מישור הנתונים.