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

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

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

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

שדות API נתמכים

‫API של EnvoyFilter נתמך בהטמעה של מישור הבקרה של 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 כך שיהיה נתמך באופן מלא, קראו את המאמר מודרניזציה של הגדרות הדוחס EnvoyFilter.

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

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

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

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

תכונות Lua שלא נתמכות:
התכונות הבאות של Lua ו-Envoy-provided Lua wrappers לא נתמכות:

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

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

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

הערכת תיקון הגדרות ועיבוד חלקי

כשמגדירים משאב EnvoyFilter עם כמה תיקונים מסוג configPatches, ‏Cloud Service Mesh מעריך כל תיקון בנפרד.

  • הגדרות תקינות חלקית: אם המשאב EnvoyFilter מכיל גם תיקונים תקינים וגם תיקונים עם שגיאות או שדות שלא נתמכים, המשאב הכולל מתקבל. ‫Cloud Service Mesh מתעלם מהתיקונים הלא חוקיים או הלא נתמכים ומעבד רק את התיקונים החוקיים. במקרה כזה, במשאב יופיע תנאי סטטוס Warning, שבו מפורטים השדות הלא נתמכים שגרמו להשמטת חלק מהתיקונים.
  • הגדרות לא תקינות לחלוטין: אם אף אחד מהערכים של configPatches ב-EnvoyFilter לא תקין, המשאב כולו נדחה ומוצגת שגיאה.

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

במדריך הזה תלמדו איך להשתמש בהגבלת קצב של יצירת בקשות המובנית של 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. פורסים את שער ה-API לדוגמה במאגר 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. מוסיפים תווית למרחב השמות onlineboutique כדי להוסיף באופן אוטומטי שרתי proxy של Envoy:

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

    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
    

    כל ה-pods של האפליקציה אמורים לפעול, עם 2/2 בעמודה READY. זה מצביע על כך שהוזרק בהצלחה קובץ עזר חיצוני של 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 
    

פתרון בעיות

פתרון בעיות שקשורות ליכולת ההרחבה של מישור הנתונים