בדף הזה מוסבר איך Google Kubernetes Engine (GKE) משתמש בתוספי שירות כדי להוסיף לוגיקה מותאמת אישית ל-Cloud Load Balancing.
הדף הזה מיועד לאדמינים של זהויות וחשבונות ב-GKE ולמפתחים שצריכים להגדיר לוגיקה מותאמת אישית לניהול תנועה באמצעות תוספי שירות.
לפני שקוראים את הדף הזה, חשוב לוודא שמכירים את הנושאים הבאים:
- מושגים בסיסיים של רשתות GKE
- GKE Gateway API
- GKE Gateway Controllers
- GKE GatewayClasses
- סקירה כללית על Service Extensions
סקירה כללית
ב-GKE משתמשים בתוספים לשירותים כדי להוסיף לוגיקה בהתאמה אישית ל-Cloud Load Balancing. אתם יכולים להשתמש בתוספי שירות למשימות כמו פיצול תנועה מתקדם, אימות בהתאמה אישית או רישום בקשות ביומן.
בקר GKE Gateway תומך בתוספי השירות הבאים:
- GCPRoutingExtension: התוסף הזה מוסיף לוגיקה מותאמת אישית ל-Cloud Load Balancing כדי לשלוט בניתוב התנועה.
- GCPTrafficExtension: התוסף הזה מוסיף לוגיקה מותאמת אישית ל-Cloud Load Balancing כדי לשנות את התעבורה. הלוגיקה הזו חלה על התנועה אחרי בחירת השירות. מאזן העומסים יכול להוסיף או לשנות את הכותרות ואת המטענים הייעודיים (payloads) של בקשות ותגובות HTTP. GCPTrafficExtension לא משפיע על בחירת שירותים או על מדיניות אבטחת שירותים.
- GCPEdgeExtension: התוסף הזה מאפשר לכם להשפיע על בחירת שירות הקצה העורפי ועל מפתחות המטמון של Cloud CDN על ידי שינוי כותרות הבקשות. הוא נתמך באופן בלעדי במאזני עומסים גלובליים חיצוניים מנוהלים.
- GCPAuthzExtension: התוסף הזה מאפשר להעביר החלטות בנושא הרשאות למנוע הרשאות בהתאמה אישית או של צד שלישי (כמו חומת אש ליישומי אינטרנט (WAF) חיצונית) או לשרת proxy לאימות זהויות (IAP). התוסף הזה משמש עם משאב GCPAuthzPolicy, שאוכף את בקרת הגישה לתנועה שנכנסת לשער וקובע מתי צריך להתרחש ה-callout לתוסף.
תוסף מצורף לשער. ב-Gateway של אשכול יחיד, התוסף מפנה למשאב Service, למשאב GCPWasmPlugin או למשאב GoogleAPIServiceName. בשער מרובה-אשכולות, ההרחבה מפנה למשאב ServiceImport או למשאב GoogleAPIServiceName.
הפניה למשאב Service או למשאב ServiceImport: במודל הזה, אתם פורסים את הלוגיקה המותאמת אישית כאפליקציית קצה עורפי נפרדת, שמוצגת כשירות Kubernetes. מאזן העומסים מבצע קריאה לשירות הזה כדי לעבד את התנועה. הגישה הזו היא רב-תכליתית ומאפשרת לכם להטמיע לוגיקה מותאמת אישית של ניתוב או לבצע מניפולציה של תעבורה, כמו שינוי של כותרת או בדיקה של מטען ייעודי.
הפניה למשאב GCPWasmPlugin: לתרחישי שימוש שדורשים ביצועים גבוהים, אפשר להחדיר לוגיקה מותאמת אישית שנכתבה על ידי המשתמש ישירות לנתיב הנתונים של מאזן העומסיםCloud de Confiance by S3NS באמצעות מודול WebAssembly (Wasm). מגדירים משאב GCPWasmPlugin שמפנה לתמונה של מודול ה-Wasm ב-Artifact Registry. השיטה הזו משמשת רק עם משאבי GCPTrafficExtension ו-GCPEdgeExtension ועם מאזן עומסים גלובלי חיצוני של אפליקציות (ALB)
הפניה לשירות Google API: אפשר גם להפנות ישירות לשירות Google API באמצעות השדה
googleAPIServiceNameב-GCPTrafficExtension או ב-GCPAuthzExtension.
בתרשים הבא, המשאב GCPRoutingExtension מצורף ל-Gateway ומפנה לכמה שירותים. התוסף שולט בהפניית התעבורה לשירותים.
בתרשים הבא, המשאב GCPTrafficExtension מצורף ל-Gateway ומתייחס לשירות, ל-GoogleAPIServiceName או ל-GCPWasmPlugin. התוסף משנה את הכותרות ואת המטען הייעודי (payload) של הבקשות והתגובות.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:
- מפעילים את ממשק ה-API של Google Kubernetes Engine. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
מפעילים את Compute Engine API, את Network Services API ואת Model Armor API, אם צריך.
עוברים אל הפעלת גישה לממשקי API ופועלים לפי ההוראות.
מידע מפורט על התמחור של Cloud de Confianceתוספי שירות זמין במאמר בנושא תמחור.
בודקים את התפקידים וההרשאות הנדרשים במאמר בקרת גישה לתוספי שירות.
מומלץ לעיין במכסות ובמגבלות שמופיעות במאמר מכסות של הרחבות שירות.
אם אתם מתכוונים להשתמש בהתאמות של Common Expression Language (CEL), כדאי לעיין במאפיינים ובאופרטורים הנתמכים בחומר העזר בנושא שפת ההתאמה של CEL.
מומלץ לעיין בהגבלות על תוספים לשירותים.
דרישות של בקר GKE Gateway
- האשכול צריך להשתמש ב-GKE מגרסה 1.33 ואילך.
- כדי להשתמש ב-GCPWasmPlugin, האשכול צריך להיות בגרסה 1.33.3 של GKE ומעלה.
- כדי להשתמש במשאב ServiceImport, באשכול צריכה להיות גרסה 1.34.3 ומעלה של GKE.
- צריך להגדיר משאב Gateway ל-Gateway פנימי מרובה אשכולות. המשאב יכול להיות מאזן עומסים גלובלי חיצוני של אפליקציות (ALB), מאזן עומסים פנימי של אפליקציות (ALB) בין אזורים, מאזן עומסים חיצוני אזורי של אפליקציות (ALB) או שער אזורי של מאזן עומסים פנימי של אפליקציות (ALB).
- צריך להפעיל את Gateway API באשכול.
- צריך להגדיר משאב Gateway. המשאב הזה יכול להיות מאזן עומסים גלובלי חיצוני של אפליקציות (ALB), מאזן עומסים חיצוני אזורי של אפליקציות (ALB) או שער מאזן עומסים פנימי אזורי של אפליקציות (ALB). אם משתמשים במשאב GCPWasmPlugin, צריך לפרוס רק שער של מאזן עומסים של אפליקציות (ALB) חיצוני גלובלי.
- צריך להיות לכם משאב HTTPRoute מוגדר.
הגבלות ומגבלות
בטבלה הבאה מפורטות המגבלות שקשורות להגדרה של Gateway Service Extensions ב-GKE:
| קטגוריה | הגבלות ומגבלות |
|---|---|
| מאזן עומסים |
יש תמיכה ב-GCPRoutingExtension במאזני העומסים הבאים:
gke-l7-global-external-managed Gateway).
|
| שרשרת תוספים ומפרט |
|
| פסק זמן |
|
| MatchCondition |
|
| כותרת |
|
| מטא-נתונים |
|
| אירוע |
|
| RequestBodySendMode |
|
| ResponseBodySendMode |
|
| הפניות למשאבים |
|
| GCPWasmPlugin |
|
| GCPAuthzPolicy ו-GCPAuthzExtension |
|
googleAPIServiceName |
|
backendRef |
כשמפנים ל-Service שמשתמש ב-backendRef בתוסף, צריך לעמוד בתנאים הבאים:
|
observabilityMode |
אפשר להגדיר את השדה observabilityMode ב-Extension עם המגבלות הבאות:
|
הפניה לשירות
ב-Service Extensions, אפשר להפנות לשירות שמארח את הלוגיקה המותאמת אישית שרוצים שמאזן העומסים יבצע. כברירת מחדל, לשערי תשלום אין תוספי שירות.
כדי להגדיר את GKE Service Extensions:
פריסת שירות לקריאה חוזרת (callout) לקצה העורפי: יוצרים שירות Kubernetes שמייצג את השירות לקצה העורפי להרצת לוגיקה בהתאמה אישית. מאזן העומסים מפעיל את השירות הזה.
הגדרת תוספים לשירותים: משתמשים בתוסף המתאים בהתאם לסוג מאזן העומסים.
GCPRoutingExtension לשערים אזוריים: משתמשים בתוסף הזה למאזן עומסים חיצוני אזורי של אפליקציות (ALB) ולמאזן עומסים פנימי אזורי של אפליקציות (ALB) כדי להטמיע לוגיקת ניתוב בהתאמה אישית בתוך האזור.
GCPTrafficExtension למאזני עומסים גלובליים חיצוניים, אזוריים חיצוניים ופנימיים: משתמשים בתוסף הזה למאזן עומסים גלובלי חיצוני של אפליקציות (ALB), למאזן עומסים חיצוני אזורי של אפליקציות (ALB) ולמאזן עומסים פנימי אזורי של אפליקציות (ALB) כדי לבצע שינויים בתנועה, כמו שינוי כותרות או בדיקת מטען ייעודי (payload), בסוגים שונים של מאזני עומסים.
פריסת שירות לקצה העורפי של קריאות ל-API
שירות קריאה חיצונית מטמיע לוגיקה מותאמת אישית לתוספי שירות של שער ב-GKE. השער מפעיל את אפליקציות הבק-אנד האלה, על סמך ההגדרות של GCPTrafficExtension או GCPRoutingExtension, כדי לשנות או לנתב את התנועה.
אתם פורסים שירות callout כדי להוסיף לוגיקה בהתאמה אישית ל-Gateway. השירות הנפרד הזה מטפל בעיבוד מותאם אישית, כמו שינוי כותרות, המרות של נתוני payload או ניתוב תנועה.
כדי לפרוס שירות שיכול לשמש כהפניה ל-Gateway, מבצעים את השלבים הבאים:
(אופציונלי) יצירת סוד ל-TLS: הפקודה הזו יוצרת סוד Kubernetes מסוג TLS שמכיל את אישור ה-TLS והמפתח הפרטי שלכם.
כדי ליצור את סוד ה-TLS לשירות ה-callout, מחליפים את הערכים הבאים:
-
SECRET_NAME: שם הסוד של שירות ה-callout path-to-cert: הנתיבים לקובץ האישור-
path-to-key: הנתיבים לקובץ המפתח
-
כדי לוודא שהסוד נוסף, מריצים את הפקודה הבאה:
kubectl get secrets SECRET_NAMEמחליפים את
SECRET_NAMEבשם הסוד של שירות ההתקשרות.הפלט אמור להיראות כך:
NAME TYPE DATA AGE SECRET_NAME kubernetes.io/tls 2 12sהגדרת משאבי פריסה ושירות.
צריך להגדיר את הפרטים הבאים:
- פריסה: כדי לנהל את קבוצות ה-Pod של האפליקציה שמכילות את הלוגיקה בהתאמה אישית של Service Extensions.
- Service: כדי לחשוף את ה-pods של האפליקציה שמנוהלים על ידי ה-Deployment כשירות רשת.
יוצרים קובץ מניפסט לדוגמה
extension-service-app.yamlעם הגדרות של Deployment ו-Service:apiVersion: apps/v1 kind: Deployment metadata: name: extension-service-app spec: selector: matchLabels: app: store replicas: 1 template: metadata: labels: app: store spec: containers: - name: serviceextensions image: us-docker.pkg.dev/service-extensions-samples/callouts/python-example-basic:public-image-e42d951 ports: - containerPort: 8080 - containerPort: 443 volumeMounts: - name: certs mountPath: "/etc/certs/" readOnly: true env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: TLS_SERVER_CERT_PATH value: "/etc/certs/path-to-cert" - name: TLS_SERVER_PRIVKEY value: "/etc/certs/path-to-key" resources: requests: cpu: 10m volumes: - name: certs secret: secretName: SECRET_NAME optional: false --- apiVersion: v1 kind: Service metadata: name: extension-service spec: ports: - port: 443 targetPort: 443 appProtocol: HTTP2 selector: app: storeמחליפים את מה שכתוב בשדות הבאים:
-
POD_NAME: שם ה-Pod. -
SECRET_NAME: השם הסודי של שירות ההתקשרות. -
TLS_SERVER_CERT_PATH: הנתיב לאישור השרת TLS בתוך ה-Pod. -
TLS_SERVER_PRIVKEY: הנתיב למפתח הפרטי של שרת TLS בתוך ה-Pod.
-
החלת מניפסט
extension-service-app.yaml:kubectl apply -f extension-service-app.yaml
אימות ההגדרות:
מוודאים שהאפליקציה נפרסה:
kubectl get pod --selector app=storeאחרי שהאפליקציה מתחילה לפעול, הפלט אמור להיראות כך:
NAME READY STATUS RESTARTS AGE extension-service-app-85f466bc9b-b5mf4 1/1 Running 0 7sמוודאים שהשירות נפרס:
kubectl get service extension-serviceהפלט אמור להיראות כך, עם שירות לכל פריסת חנות:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE extension-service ClusterIP 34.118.225.9 <none> 443/TCP 2m40s
הגדרת Service Extensions
אתם יכולים להגדיר GCPRoutingExtension או GCPTrafficExtension כדי להתאים אישית את זרימת התנועה.
הגדרת GCPRoutingExtension לשערים אזוריים
אפשר לנתב מחדש את התנועה באמצעות GCPRoutingExtension. כדי להגדיר GCPRoutingExtension, צריך לעדכן את HTTPRoute כדי לציין את הבקשות עבור המארח service-extensions.com.
מעדכנים את HTTPRoute. משנים את ה-HTTPRoute כך שיכלול שמות מארחים או נתיבים שיפעילו את תוסף הניתוב.
שומרים את קובץ המניפסט הבא לדוגמה כקובץ
store-route.yaml:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store spec: parentRefs: - kind: Gateway name:GATEWAY_NAME hostnames: - "store.example.com" - "service-extensions.example.com" rules: - backendRefs: - name: store-v1 port: 8080 - matches: - headers: - name: env value: canary backendRefs: - name: store-v2 port: 8080 - matches: - path: value: /de backendRefs: - name: store-german port: 8080מחליפים את
GATEWAY_NAMEבשם השער.מחילים את המניפסט
store-route.yaml:kubectl apply -f store-route.yaml
מגדירים את GCPRoutingExtension.
שומרים את ההגדרה של GCPRoutingExtension בקובץ ה-
gcp-routing-extension.yamlלדוגמה:kind: GCPRoutingExtension apiVersion: networking.gke.io/v1 metadata: name: my-gateway-extension namespace: default spec: targetRefs: - group: "gateway.networking.k8s.io" kind: Gateway name: GATEWAY_NAME extensionChains: - name: chain1 matchCondition: celExpressions: - celMatcher: request.path.contains("serviceextensions") extensions: - name: ext1 authority: "myext.com" timeout: 1s backendRef: group: "" kind: Service name: extension-service port: 443מחליפים את
GATEWAY_NAMEבשם השער.מחילים את המניפסט לדוגמה על האשכול:
kubectl apply -f gcp-routing-extension.yaml
מאמתים את ההגדרה של GCPRoutingExtension ואת הקישור שלה ל-Gateway.
בדיקת הפריסה של GCPRoutingExtension:
kubectl describe gcproutingextension my-gateway-extensionהפלט אמור להיראות כך:
Name: my-gateway-extension Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: GCPRoutingExtension Metadata: Creation Timestamp: 2025-03-02T17:12:30Z Generation: 1 Resource Version: 31283253 UID: ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0 Spec: Extension Chains: Extensions: Authority: myext.com Backend Ref: Group: Kind: Service Name: extension-service Port: 443 Name: ext1 Timeout: 1s Match Condition: Cel Expressions: Cel Matcher: request.path.contains("serviceextensions") Name: chain1 Target Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: GATEWAY_NAME Events: <none>הפלט מציג את הפרטים של GCPRoutingExtension, שנקרא
my-gateway-extension, בתוך מרחב השמות שמוגדר כברירת מחדל. בפלט מוצג השדהSpec, שמכיל את ההגדרה של אופן הפעולה של התוסף.מאמתים את הקישור של שער הגישה:
מוודאים שה-GCPRoutingExtension מקושר לשער. יכול להיות שהפעולה תימשך כמה דקות:
kubectl describe gateway GATEWAY_NAMEמחליפים את
GATEWAY_NAMEבשם השער.הפלט אמור להיראות כך:
Name: GATEWAY_NAME Namespace: default Labels: none Annotations: networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr networking.gke.io/backend-services: /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re... networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1 networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73 networking.gke.io/health-checks: /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio... networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z networking.gke.io/lb-route-extensions: /projects/1234567890/locations/us-central1/lbRouteExtensions/test-hgbk-default-internal-http-lwh0op4qorb0 networking.gke.io/lb-traffic-extensions: networking.gke.io/ssl-certificates: networking.gke.io/target-http-proxies: /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj networking.gke.io/target-https-proxies: networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj API Version: gateway.networking.k8s.io/v1 Kind: Gateway Metadata: Creation Timestamp: 2025-03-02T16:37:50Z Finalizers: gateway.finalizer.networking.gke.io Generation: 1 Resource Version: 31284863 UID: fd512611-bad2-438e-abfd-5619474fbf31 ...בפלט מוצגות ההערות שבהן GKE משתמש כדי לאחסן את הקישורים בין השער לבין משאבי ה-Cloud de Confiance הבסיסיים. ההערה
networking.gke.io/lb-route-extensionsמאשרת את הקישור של השער ל-GCPRoutingExtension.בודקים את סטטוס התוסף כדי לוודא שהסטטוס של GCPRoutingExtension הוא
Programmedוהסיבה היאProgrammingSucceeded. הפעלת הפקודה הזו עשויה להימשך כמה דקות.kubectl describe gcproutingextension my-gateway-extensionהפלט אמור להיראות כך:
Name: my-gateway-extension Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: GCPRoutingExtension Metadata: Creation Timestamp: 2025-03-02T17:12:30Z Generation: 1 Resource Version: 31284378 UID: ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0 Spec: Extension Chains: Extensions: Authority: myext.com Backend Ref: Group: Kind: Service Name: extension-service Port: 443 Name: ext1 Timeout: 1s Match Condition: Cel Expressions: Cel Matcher: request.path.contains("serviceextensions") Name: chain1 Target Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: GATEWAY_NAME Status: Ancestors: Ancestor Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: GATEWAY_NAME Namespace: default Conditions: Last Transition Time: 2025-03-02T17:14:15Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-03-02T17:14:15Z Message: Reason: ProgrammingSucceeded Status: True Type: Programmed Controller Name: networking.gke.io/gateway Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 2m31s sc-gateway-controller default/my-gateway-extension Normal SYNC 51s (x2 over 98s) sc-gateway-controller Attachment of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: GATEWAY_NAME, SectionName: nil, Port: nil} was a success Normal SYNC 23s sc-gateway-controller Reconciliation of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: GATEWAY_NAME, SectionName: nil, Port: nil} was a successבשדה
Status.Conditionsמוצג תנאיProgrammedעםStatus: Trueו-Reason: ProgrammingSucceeded. המידע הזה מאשר שההרחבה הוחלה בהצלחה.
שולחים תנועה לאפליקציה.
אחרי ששער, מסלול ואפליקציה נפרסים באשכול, אפשר להעביר תנועה לאפליקציה.
כדי לגשת לאפליקציה, צריך למצוא את כתובת ה-IP של השער.
בטרמינל, משתמשים בפקודה הבאה:
kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"מחליפים את
GATEWAY_NAMEבשם השער.הפקודה הזו מחזירה את כתובת ה-IP של השער. בפקודות הבאות, מחליפים את
GATEWAY_IP_ADDRESSבכתובת ה-IP מהפלט.כדי לבדוק את עדכון הנתיב, עוברים לגרסה
serviceextensionsשל שירות החנות בכתובתstore.example.com/serviceextensions:curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vהפלט אמור להיראות כך:
{ "cluster_name": "gke1", "host_header": "service-extensions.com", "metadata": "store-v1", "pod_name": "store-v1-5d9554f847-cvxpd", "pod_name_emoji": "💇🏼♀️", "project_id": "gateway-demo", "timestamp": "2025-03-15T12:00:00", "zone": "us-central1-c" }
הגדרת ה-GCPTrafficExtension
אתם יכולים להשתמש ב-GCPTrafficExtension כדי להשתמש ביכולות מתקדמות של ניהול תנועה בסביבת Cloud de Confiance . אפשר להגדיר את התוסף הזה במאזני עומסים גלובליים חיצוניים של אפליקציות (ALB), במאזני עומסים אזוריים חיצוניים של אפליקציות (ALB) ובמאזני עומסים אזוריים פנימיים של אפליקציות (ALB). אתם יכולים להשתמש ב-GCPTrafficExtension כדי להטמיע לוגיקה מותאמת אישית של בקשות ותשובות HTTP, ניתוב מתוחכם, טרנספורמציות ומדיניות אבטחה.
מעדכנים את HTTPRoute. משנים את ה-HTTPRoute כך שיכלול שמות מארחים או נתיבים שיפעילו את תוסף התנועה.
שומרים את קובץ המניפסט הבא לדוגמה כקובץ
store-route.yaml:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store spec: parentRefs: - kind: Gateway name: GATEWAY_NAME hostnames: - "store.example.com" - "service-extensions.example.com" rules: - backendRefs: - name: store-v1 port: 8080 - matches: - headers: - name: env value: canary backendRefs: - name: store-v2 port: 8080 - matches: - path: value: /de backendRefs: - name: store-german port: 8080מחליפים את
GATEWAY_NAMEבשם השער, לדוגמהinternal-http,external-httpאוglobal-external-http.מחילים את המניפסט
store-route.yamlעל האשכול:kubectl apply -f store-route.yaml
מגדירים את GCPTrafficExtension.
שומרים את ההגדרה של GCPTrafficExtension בקובץ
gcp-traffic-extension.yamlלדוגמה:kind: GCPTrafficExtension apiVersion: networking.gke.io/v1 metadata: name: my-traffic-extension namespace: default spec: targetRefs: - group: "gateway.networking.k8s.io" kind: Gateway name: GATEWAY_NAME extensionChains: - name: chain1 matchCondition: celExpressions: - celMatcher: request.path.contains("serviceextensions") extensions: - name: ext1 authority: "myext.com" timeout: 1s backendRef: group: "" kind: Service name: extension-service port: 443 supportedEvents: - RequestHeaders - RequestBody - ResponseHeaders - ResponseBodyמחליפים את
GATEWAY_NAMEבשם השער, כמוinternal-http,external-httpאוglobal-external-http.מחילים את קובץ המניפסט לדוגמה על האשכול:
kubectl apply -f gcp-traffic-extension.yaml
מאמתים את ההגדרות של GCPTrafficExtension ואת הקישור שלו לשער.
בודקים את הפריסה של GCPTrafficExtension:
kubectl describe gcptrafficextension my-traffic-extensionהפלט אמור להיראות כך:
Name: my-traffic-extension Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: GCPTrafficExtension Metadata: Creation Timestamp: 2025-03-02T17:12:30Z Generation: 1 Resource Version: 31283253 UID: ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0 Spec: Extension Chains: Extensions: Authority: myext.com Backend Ref: Group: Kind: Service Name: extension-service Port: 443 Name: ext1 Timeout: 1s Match Condition: Cel Expressions: Cel Matcher: request.path.contains("serviceextensions") Name: chain1 Target Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: GATEWAY_NAME Events: <none>בפלט מוצגים הפרטים של GCPTrafficExtension בשם
my-traffic-extensionבמרחב השמות שמוגדר כברירת מחדל. הוא מציג את השדהSpec, שמכיל את ההגדרה של אופן הפעולה של התוסף.מאמתים את הקישור של שער הגישה:
מוודאים ש-GCPTrafficExtension קשור ל-Gateway. הפקודה הזו עשויה להימשך כמה דקות:
kubectl describe gateway GATEWAY_NAMEהפלט אמור להיראות כך:
Name: GATEWAY_NAME Namespace: default Labels: <none> Annotations: networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr networking.gke.io/backend-services: /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re... networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1 networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73 networking.gke.io/health-checks: /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio... networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z networking.gke.io/lb-traffic-extensions: /projects/1234567890/locations/us-central1/lbTrafficExtensions/test-hgbk-default-internal-http-lwh0op4qorb0 networking.gke.io/ssl-certificates: networking.gke.io/target-http-proxies: /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj networking.gke.io/target-https-proxies: networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj API Version: gateway.networking.k8s.io/v1 Kind: Gateway Metadata: Creation Timestamp: 2025-03-02T16:37:50Z Finalizers: gateway.finalizer.networking.gke.io Generation: 1 Resource Version: 31284863 UID: fd512611-bad2-438e-abfd-5619474fbf31 ...בפלט מוצגות ההערות, שמשמשות את GKE לאחסון הקישורים בין ה-Gateway לבין Cloud de Confiance המשאבים הבסיסיים. ההערה
networking.gke.io/lb-traffic-extensionsמאשרת את הקישור.בודקים את סטטוס התוסף:
כדי לבדוק את סטטוס התוסף של GCPTrafficExtension, מריצים את הפקודה הבאה:
kubectl describe gcptrafficextension my-traffic-extensionמוודאים שהסטטוס של GCPTrafficExtension הוא
Programmedעם הסיבהProgrammingSucceeded. יכול להיות שיחלפו כמה דקות עד שהפקודה תסתיים.הפלט של המשאב GCPTrafficExtension אמור להיראות כך:
Name: my-traffic-extension Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: GCPTrafficExtension Metadata: Creation Timestamp: 2025-03-02T17:12:30Z Generation: 1 Resource Version: 31284378 UID: ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0 Spec: Extension Chains: Extensions: Authority: myext.com Backend Ref: Group: Kind: Service Name: extension-service Port: 443 Name: ext1 Timeout: 1s Match Condition: Cel Expressions: Cel Matcher: request.path.contains("serviceextensions") Name: chain1 Target Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: GATEWAY_NAME Status: Ancestors: Ancestor Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: GATEWAY_NAME Namespace: default Conditions: Last Transition Time: 2025-03-02T17:14:15Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-03-02T17:14:15Z Message: Reason: ProgrammingSucceeded Status: True Type: Programmed Controller Name: networking.gke.io/gateway Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 2m31s sc-gateway-controller default/my-traffic-extension Normal SYNC 51s (x2 over 98s) sc-gateway-controller Attachment of GCPTrafficExtension "default/my-gateway-extension" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: GATEWAY_NAME, SectionName: nil, Port: nil} was a success Normal SYNC 23s sc-gateway-controller Reconciliation of GCPTrafficExtension "default/my-traffic-extension" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: GATEWAY_NAME, SectionName: nil, Port: nil} was a successבשדה
Status.Conditionsמוצג תנאיProgrammedעםStatus: Trueו-Reason: ProgrammingSucceeded. המידע הזה מאשר שההארכה הוחלה בהצלחה.
שליחת תנועה לאפליקציה.
אחרי ששער, מסלול ואפליקציה נפרסים באשכול, אפשר להעביר תנועה לאפליקציה.
כדי לגשת לאפליקציה, צריך למצוא את כתובת ה-IP של השער.
בטרמינל, משתמשים בפקודה הבאה:
kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"מחליפים את
GATEWAY_NAMEבשם השער.הפקודה הזו מחזירה את כתובת ה-IP של השער. בפקודות הבאות, מחליפים את
GATEWAY_IP_ADDRESSבכתובת ה-IP מהפלט.כדי לבדוק את עדכון הנתיב, עוברים לגרסה
serviceextensionsשל שירות החנות בכתובתstore.example.com/serviceextensions:curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vהפלט אמור להיראות כך:
{ * Request completely sent off < HTTP/1.1 200 OK < server: Werkzeug/2.3.7 Python/3.11.3 < date: Sun, 02 Mar 2025 16:58:10 GMT < content-type: application/json < access-control-allow-origin: * < hello: service-extensions < via: 1.1 google < transfer-encoding: chunked }
הגדרת המשאב GCPAuthzExtension
אתם יכולים להשתמש ב-GCPAuthzExtension עם GCPAuthzPolicy כדי לאכוף החלטות הרשאה מורכבות על ידי העברתן לשירות חיצוני או ל-Identity-Aware Proxy (IAP).
מגדירים את GCPAuthzExtension:
אפשר להגדיר את GCPAuthzExtension כך שיפנה לשירות תוספים בהתאמה אישית או ל-IAP כשירות קריאה חוזרת.
אפשרות 1: הפניה לשירות תוסף בהתאמה אישית
- שומרים את ההגדרה של GCPAuthzExtension בקובץ הדוגמה
gcp-authz-extension.yaml:
apiVersion: networking.gke.io/v1 kind: GCPAuthzExtension metadata: name: my-authz-ext namespace: default spec: backendRef: kind: Service name: "${authz-service}" forwardHeaders: - Authorization failOpen: false timeout: "0.1s" wireFormat: EXT_PROC_GRPCבדוגמה הקודמת,
"${authz-service}"הוא שירות הרחבה שצריך להיות באותו מרחב שמות כמו GCPAuthzPolicy.- החלת המניפסט:
kubectl apply -f gcp-authz-extension.yaml- שומרים את ההגדרה של GCPAuthzExtension בקובץ הדוגמה
אפשרות 2: הפניה אל IAP כשירות מותאם אישית לתיאור קצר
אפשר גם להגדיר את IAP כשירות מותאם אישית להצגת מידע על שיחות, על ידי ציון
iap.googleapis.comבשדהgoogleAPIServiceName:- שומרים את ההגדרה של GCPAuthzExtension בקובץ הדוגמה
authz-extension-iap.yaml:
apiVersion: networking.gke.io/v1 kind: GCPAuthzExtension metadata: name: my-authz-ext-iap namespace: default spec: googleAPIServiceName: iap.googleapis.com timeout: 50ms failOpen: false- החלת המניפסט:
kubectl apply -f authz-extension-iap.yaml- שומרים את ההגדרה של GCPAuthzExtension בקובץ הדוגמה
הגדרת ה-GCPAuthzPolicy:
מדיניות ה-GCPAuthzPolicy מכוונת לשער ומציינת את הפעולה שיש לבצע בתעבורה תואמת:
הגדרת
CUSTOMמדיניות הרשאות:הפעולה
CUSTOMמעבירה את ההחלטה על ההרשאה לתוסף שיצרתם בשלב הקודם.שומרים את קובץ המניפסט הבא ב-
gcp-authz-policy.yaml:apiVersion: networking.gke.io/v1 kind: GCPAuthzPolicy metadata: name: my-gateway-authz namespace: default spec: enforcementLevel: L7 targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: "GATEWAY_NAME" rules: - from: sources: - principals: - principal_selector: CLIENT_CERT_URI_SANS principal: exact: "spiffee://cluster.local/ns1/pod1" - to: operations: - paths: - exact: "/api/secure-endpoint" action: CUSTOM customProvider: authzExtension: extensionRefs: - group: networking.gke.io kind: GCPAuthzExtension name: my-authz-extמחליפים את
GATEWAY_NAMEבשם השער.מחילים את המניפסט:
kubectl apply -f gcp-authz-policy.yaml
הפניה למשאב GCPWasmPlugin
אתם יכולים להוסיף לוגיקה בהתאמה אישית ישירות לנתיב הנתונים של מאזן העומסים, באמצעות GCPWasmPlugin עם GCPTrafficExtension או GCPEdgeExtension. השיטה הזו מאפשרת לפרוס יכולות מותאמות אישית לניהול תנועה, שמאוגדות כמודול Wasm.
כדי להגדיר תוספי שירות של GKE, מבצעים את השלבים הבאים:
פריסת GCPWasmPlugin: יוצרים ופורסים GCPWasmPlugin CustomResourceDefinition (CRD) שמכיל את הקוד המותאם אישית של מודול Wasm. אפשר להשתמש ב-GCPWasmPlugin עם GCPTrafficExtension או GCPEdgeExtension עבור
gke-l7-global-external-managedGatewayClass.הגדרת תוספי שירות: מגדירים אחד מהתוספים הבאים באמצעות GCPWasmPlugin:
פריסת GCPWasmPlugin
התוסף GCPWasmPlugin מאפשר להוסיף לוגיקה מותאמת אישית שנכתבה על ידי המשתמש ישירות לנתיב הנתונים של מאזן העומסים ב- Cloud de Confiance . המשאב GCPWasmPlugin מצביע על תמונת מודול ה-Wasm ב-Artifact Registry, שמופעלת על ידי מאזן העומסים.
לפני שממשיכים לשלבים הבאים, צריך לוודא שהעליתם את מודול ה-Wasm למאגר של Artifact Registry. מידע נוסף זמין במאמר הכנת קוד הפלאגין.
כדי לפרוס משאב GCPWasmPlugin, מבצעים את השלבים הבאים:
שומרים את קובץ המניפסט הבא בשם
wasm-plugin.yaml:kind: GCPWasmPlugin apiVersion: networking.gke.io/v1 metadata: name: gcp-wasm-plugin spec: versions: - name: wasm-plugin-version description: "Test wasm plugin version" image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main" weight: 1000000 logConfig: enabled: true # Configures the sampling rate of activity logs. # The value of the field must be in range [0, 1e6]. sampleRate: 1000000 # Specifies the lowest level of logs that are exported to Cloud Logging. minLogLevel: INFOשימו לב לנקודות הבאות:
-
spec.versions.name: שם הגרסה צריך להיות ייחודי במשאב GCPWasmPlugin. אפשר לציין עד 10 גרסאות, ורק לגרסה אחת צריך להיות משקל שונה מאפס. -
spec.versions.image: מפנה לתמונה שמכילה את קוד הפלאגין שמאוחסן ב-Artifact Registry. -
spec.versions.weight: מציין את המשקל של גרסת הפלאגין. המשקל חייב להיות מספר בין 0 ל-1,000,000, כולל. -
spec.logConfig: מציין אם להפעיל את Cloud Logging בפלאגין הזה. אם לא מציינים ערך, Cloud Logging מושבת כברירת מחדל. spec.logConfig.sampleRate: מגדיר את תדירות הדגימה של יומני הפעילות. השיעור חייב להיות מספר בין 0 ל-1,000,000, כולל. אם לא מציינים ערך כשמפעילים את Cloud Logging, ערך ברירת המחדל הוא1,000,000(100% מהבקשות נרשמות ביומן).-
spec.logConfig.minLogLevel: מציין את הרמה הנמוכה ביותר של יומנים שמיוצאים ל-Cloud Logging. אם הערך לא צוין כש-Cloud Logging מופעל, השדה מוגדר כברירת מחדל ל-INFO.
-
החלת מניפסט
wasm-plugin.yaml:kubectl apply -f wasm-plugin.yamlמוודאים שהפלאגין נפרס:
kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-pluginהפלט אמור להיראות כך:
Name: gcp-wasm-plugin Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: GCPWasmPlugin Metadata: Creation Timestamp: 2025-08-08T19:54:18Z Generation: 1 Resource Version: 44578 UID: 549a12c7-91d1-43ad-a406-d6157a799b79 Spec: Log Config: Enabled: true Min Log Level: INFO Sample Rate: 1000000 Versions: Description: Test wasm plugin version Image: us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main Name: wasm-plugin-version Weight: 1000000 Events: <none>
הגדרת GCPTrafficExtension
כדי להוסיף לוגיקה מותאמת אישית למאזן עומסים של אפליקציות (ALB) חיצוני גלובלי, אתם יכולים להגדיר GCPTrafficExtension לשימוש ב-GCPWasmPlugin. אתם יכולים להשתמש ב-GCPTrafficExtension כדי להשתמש ביכולות מתקדמות של ניהול תנועה בסביבת Cloud de Confiance שלכם. אפשר להגדיר את התוסף הזה במאזני עומסים גלובליים חיצוניים של אפליקציות (ALB).
כדי להגדיר GCPTrafficExtension לשימוש ב-GCPWasmPlugin, מבצעים את השלבים הבאים:
מגדירים את GCPTrafficExtension.
שומרים את ההגדרות של GCPTrafficExtension בתור
gcp-traffic-extension-with-plugin.yaml:kind: GCPTrafficExtension apiVersion: networking.gke.io/v1 metadata: name: gcp-traffic-extension-with-plugin namespace: default spec: targetRefs: - group: "gateway.networking.k8s.io" kind: Gateway name: GATEWAY_NAME extensionChains: - name: chain1 matchCondition: celExpressions: - celMatcher: request.path.contains("serviceextensions") extensions: - name: ext1 supportedEvents: - RequestHeaders - ResponseHeaders backendRef: group: "networking.gke.io" kind: GCPWasmPlugin name: gcp-wasm-pluginמחליפים את
GATEWAY_NAMEבשם השער, למשלglobal-external-http.מחילים את קובץ המניפסט לדוגמה על האשכול:
kubectl apply -f gcp-traffic-extension-with-plugin.yaml
מאמתים את ההגדרות של GCPTrafficExtension ואת הקישור שלו לשער.
בודקים את הפריסה של GCPTrafficExtension:
kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-pluginהפלט אמור להיראות כך:
Name: gcp-traffic-extension-with-plugin Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: GCPTrafficExtension Metadata: Creation Timestamp: 2025-03-02T17:12:30Z Generation: 1 Resource Version: 31283253 UID: ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0 Spec: Extension Chains: Extensions: Backend Ref: Group: networking.gke.io Kind: GCPWasmPlugin Name: gcp-wasm-plugin Name: ext1 Supported Events: RequestHeaders ResponseHeaders Match Condition: Cel Expressions: Cel Matcher: request.path.contains("serviceextensions") Name: chain1 Target Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: GATEWAY_NAME Events: <none>מחליפים את
GATEWAY_NAMEבשם השער.בפלט מוצגים הפרטים של GCPTrafficExtension בשם
gcp-traffic-extension-with-pluginבמרחב השמות שמוגדר כברירת מחדל. הוא מציג את השדהSpec, שמכיל את ההגדרה של אופן הפעולה של התוסף.מאמתים את הקישור של שער הגישה:
מוודאים ש-GCPTrafficExtension קשור ל-Gateway. השלמת הפקודה הזו עשויה להימשך כמה דקות:
kubectl describe gateway GATEWAY_NAMEמחליפים את
GATEWAY_NAMEבשם השער.הפלט אמור להיראות כך:
Name: GATEWAY_NAME Namespace: default Labels: <none> Annotations: networking.gke.io/addresses: /projects/922988411345/global/addresses/test-k18j-default-external-http-2jfqxrkgd0fm networking.gke.io/backend-services: /projects/922988411345/global/backendServices/test-k18j-default-gw-serve404-80-8zjp3d8cqfsu, /projects/922988411345/global/backendServices... networking.gke.io/certmap: store-example-com-map networking.gke.io/firewalls: /projects/922988411345/global/firewalls/test-k18j-l7-default-global networking.gke.io/forwarding-rules: /projects/922988411345/global/forwardingRules/test-k18j-default-external-http-wt1tl0cwi6zr networking.gke.io/health-checks: /projects/922988411345/global/healthChecks/test-k18j-default-gw-serve404-80-8zjp3d8cqfsu, /projects/922988411345/global/healthChecks/test-... networking.gke.io/last-reconcile-time: 2025-08-08T20:27:35Z networking.gke.io/lb-route-extensions: networking.gke.io/lb-traffic-extensions: projects/922988411345/locations/global/lbTrafficExtensions/test-k18j-default-external-http-0tdum40yts35 networking.gke.io/ssl-certificates: networking.gke.io/target-http-proxies: networking.gke.io/target-https-proxies: /projects/922988411345/global/targetHttpsProxies/test-k18j-default-external-http-jy9mc97xb5yh networking.gke.io/url-maps: /projects/922988411345/global/urlMaps/test-k18j-default-external-http-jy9mc97xb5yh networking.gke.io/wasm-plugin-versions: projects/922988411345/locations/global/wasmPlugins/test-k18j-default-gcp-wasm-plugin-itle20jj9nyk/versions/test-k18j-wasm-plugin-version-i... networking.gke.io/wasm-plugins: projects/922988411345/locations/global/wasmPlugins/test-k18j-default-gcp-wasm-plugin-itle20jj9nyk API Version: gateway.networking.k8s.io/v1 Kind: Gateway Metadata: Creation Timestamp: 2025-03-02T16:37:50Z Finalizers: gateway.finalizer.networking.gke.io Generation: 1 Resource Version: 31284863 UID: fd512611-bad2-438e-abfd-5619474fbf31 Spec: Gateway Class Name: gke-l7-global-external-managed Listeners: Allowed Routes: Namespaces: From: Same Name: https Port: 443 Protocol: HTTPS ...הפלט מציג את ההערות, ש-GKE משתמש בהן כדי לאחסן את הקישורים בין שער הרשת לבין המשאבים הבסיסיים Cloud de Confiance. ההערות
networking.gke.io/lb-traffic-extensions,networking.gke.io/wasm-plugin-versionsו-networking.gke.io/wasm-pluginsמאשרות את הקישור.בודקים את הסטטוס של התוסף:
מוודאים שהסטטוס של GCPTrafficExtension הוא
Programmedוהסיבה היאProgrammingSucceeded. יכול להיות שיעברו כמה דקות עד שהפקודה תסתיים.kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-pluginהפלט אמור להיראות כך:
Name: gcp-traffic-extension-with-plugin Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: GCPTrafficExtension Metadata: Creation Timestamp: 2025-08-08T20:08:09Z Generation: 1 Resource Version: 56528 UID: 1389f790-9663-45ca-ac4e-a2c082f43359 Spec: Extension Chains: Extensions: Backend Ref: Group: networking.gke.io Kind: GCPWasmPlugin Name: gcp-wasm-plugin Name: ext1 Supported Events: RequestHeaders ResponseHeaders Match Condition: Cel Expressions: Cel Matcher: request.path.contains("serviceextensions") Name: chain1 Target Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Status: Ancestors: Ancestor Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Namespace: default Conditions: Last Transition Time: 2025-08-08T20:16:13Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-08-08T20:16:13Z Message: Observed Generation: 1 Reason: ResolvedRefs Status: True Type: ResolvedRefs Last Transition Time: 2025-08-08T20:16:13Z Message: Observed Generation: 1 Reason: ProgrammingSucceeded Status: True Type: Programmed Controller Name: networking.gke.io/gateway Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 19m sc-gateway-controller default/gcp-traffic-extension-with-plugin Normal SYNC 3m25s (x4 over 11m) sc-gateway-controller Attachment of GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} was a success Normal SYNC 3m25s (x4 over 11m) sc-gateway-controller All the object references were able to be resolved for GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" bound to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} Normal SYNC 3m25s (x4 over 11m) sc-gateway-controller Programming of GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} was a successבודקים את סטטוס הפלאגין.
מוודאים שהסטטוס של המשאב GCPWasmPlugin הוא
Programmedעם הסיבהProgrammingSucceeded. יכול להיות שיעברו כמה דקות עד שהפקודה תסתיים.kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-pluginהפלט אמור להיראות כך:
Name: gcp-wasm-plugin Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: GCPWasmPlugin Metadata: Creation Timestamp: 2025-08-08T19:54:18Z Generation: 1 Resource Version: 44578 UID: 549a12c7-91d1-43ad-a406-d6157a799b79 Spec: Log Config: Enabled: true Min Log Level: INFO Sample Rate: 1000000 Versions: Description: Test wasm plugin version Image: us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main Name: wasm-plugin-version Weight: 1000000 Status: Ancestors: Ancestor Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Namespace: default Conditions: Last Transition Time: 2025-08-08T19:59:06Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-08-08T19:59:06Z Message: Observed Generation: 1 Reason: ResolvedRefs Status: True Type: ResolvedRefs Last Transition Time: 2025-08-08T19:59:06Z Message: Observed Generation: 1 Reason: ProgrammingSucceeded Status: True Type: Programmed Controller Name: networking.gke.io/gateway Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 31m sc-gateway-controller default/gcp-wasm-plugin Normal SYNC 2m1s (x7 over 26m) sc-gateway-controller Attachment of WasmPlugin "default/gcp-wasm-plugin" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} was a success Normal SYNC 2m1s (x7 over 26m) sc-gateway-controller All the object references were able to be resolved for WasmPlugin "default/gcp-wasm-plugin" bound to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} Normal SYNC 2m1s (x7 over 26m) sc-gateway-controller Programming of WasmPlugin "default/gcp-wasm-plugin" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} was a success
שליחת תנועה לאפליקציה.
אחרי ששער, מסלול ואפליקציה נפרסים באשכול, אפשר להעביר תנועה לאפליקציה.
כדי לגשת לאפליקציה, צריך למצוא את כתובת ה-IP של השער.
בטרמינל, משתמשים בפקודה הבאה:
kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"מחליפים את
GATEWAY_NAMEבשם השער.הפקודה הזו מחזירה את כתובת ה-IP של השער. בפקודות הבאות, מחליפים את
GATEWAY_IP_ADDRESSבכתובת ה-IP מהפלט.כדי לבדוק את עדכון הנתיב, עוברים לגרסה
serviceextensionsשל שירות החנות בכתובתstore.example.com/serviceextensions:curl https://store.example.com/serviceextensions --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -vהפלט שמתקבל הוא
Hello World.
הגדרת GCPEdgeExtension באמצעות GCPWasmPlugin
כדי להוסיף לוגיקה מותאמת אישית למאזן עומסים גלובלי-חיצוני של אפליקציות (ALB) באמצעות מודול WebAssembly (Wasm), צריך להגדיר GCPEdgeExtension שמפנה אל GCPWasmPlugin.
שומרים את המניפסט הבא של GCPEdgeExtension בתור
gcp-edge-extension-with-plugin.yaml:kind: GCPEdgeExtension apiVersion: networking.gke.io/v1 metadata: name: gcp-edge-extension-with-plugin namespace: default spec: targetRefs: - group: "gateway.networking.k8s.io" kind: Gateway name: GATEWAY_NAME extensionChains: - name: chain1 matchCondition: celExpressions: - celMatcher: request.path.startsWith("/serviceextensions") extensions: - name: ext1 supportedEvents: - RequestHeaders backendRef: group: "networking.gke.io" kind: GCPWasmPlugin name: gcp-wasm-pluginמחליפים את
GATEWAY_NAMEבשם השער.מחילים את המניפסט על האשכול:
kubectl apply -f gcp-edge-extension-with-plugin.yamlמאמתים את ההגדרות של GCPEdgeExtension ואת הקישור שלו לשער:
בודקים את הסטטוס של התוסף:
כדי לבדוק את סטטוס התוסף של GCPEdgeExtension, מריצים את הפקודה הבאה:
kubectl describe gcpedgeextensions.networking.gke.io gcp-edge-extension-with-pluginמוודאים שהסטטוס של GCPEdgeExtension הוא
Programmedוהסיבה היאProgrammingSucceeded. יכול להיות שהפקודה הזו תימשך כמה דקות.מאמתים את הקישור של שער הגישה:
מריצים את הפקודה הבאה:
kubectl describe gateway GATEWAY_NAMEמחליפים את
GATEWAY_NAMEבשם השער.מוודאים ש-GCPEdgeExtension קשור ל-Gateway. השלמת הפקודה עשויה להימשך כמה דקות. הפלט כולל את ההערה
networking.gke.io/lb-edge-extensions, שמאשרת את הקישור בין שער ה-Gateway לבין תוסף ה-Edge.
שליחת תנועה לתוסף
אחרי שפורסים את Gateway ואת GCPEdgeExtension, בודקים את לוגיקת הניתוב על ידי שליחת תנועה לאפליקציה.
כדי לגשת לאפליקציה, צריך לקבל את כתובת ה-IP של השער:
kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"הפלט הוא כתובת ה-IP של השער. בפקודות הבאות, מחליפים את
GATEWAY_IP_ADDRESSבכתובת ה-IP מהפלט.שליחת בקשה לכתובת ה-URL הבסיסית:
curl http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vהשער מנתב את הבקשה לשירות שמוגדר כברירת מחדל, כמו
store-v1.שולחים בקשה לנתיב שצוין ב-celMatcher, למשל
/serviceextensions:curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vהתוסף מפעיל את פלאגין ה-Wasm, שמנתב את הבקשה לשירות המשני, כמו
store-v2.
ניהול המשאב GCPWasmPlugin
אתם יכולים לעדכן את ה-CRD של GCPWasmPlugin ולעקוב אחרי הפלאגין.
עדכון של GCPWasmPlugin
כדי לעדכן משאב GCPWasmPlugin, פועלים לפי השלבים הבאים:
מבצעים את השינוי במניפסט של GCPWasmPlugin ופועלים לפי השלבים שמפורטים במאמר פריסת GCPWasmPlugin.
לדוגמה, כדי שיהיו שתי גרסאות של הפלאגין, כשגרסה אחת מכניסה תעבורת נתונים לשימוש בסביבת הייצור והשנייה לא, מעדכנים את הקובץ
wasm-plugin.yamlכך:kind: GCPWasmPlugin apiVersion: networking.gke.io/v1 metadata: name: gcp-wasm-plugin spec: versions: - name: wasm-plugin-version-v1 description: "Serving Wasm Plugin version" image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main" weight: 1000000 - name: wasm-plugin-version-v2 description: "Non serving Wasm Plugin version" image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main" weight: 0 logConfig: enabled: true sampleRate: 1000000 minLogLevel: INFOבדוגמה הזו, התנאים הבאים חלים:
- ל-
wasm-plugin-version-v1ישweightשל1000000, כלומר הוא מציג מודעות לכל התנועה. - הערך של
wasm-plugin-version-v2הואweight, כלומר הוא לא מציג תנועה.0
- ל-
כדי לוודא שהשער עודכן, מריצים את הפקודה הבאה. הפקודה הזו עשויה להימשך כמה דקות:
kubectl describe gateway GATEWAY_NAMEמחליפים את
GATEWAY_NAMEבשם השער.
מעקב אחרי GCPWasmPlugin
במאמר מעקב מנקודת מבט של תוספים מוסבר איך לראות את המדדים של GCPWasmPlugin במסוף Cloud de Confiance .
כשמגיעים לשלב במדריך שבו צריך לבחור ערך מהרשימה Plugin version filter (מסנן גרסאות של פלאגינים), מחפשים את הפורמט prefix−WASM_PLUGIN_VERSION_NAME_FROM_FILE−suffix, כאשר WASM_PLUGIN_VERSION_NAME_FROM_FILE הוא שם הגרסה הספציפי שהגדרתם בקובץ התצורה של GCPWasmPlugin.
פתרון בעיות שקשורות לתוספי תנועה בשערי כניסה
בקטע הזה אנחנו מציעים טיפים לפתרון בעיות בהגדרת תוספים להפניית תנועה ב-Gateways.
השער לא נמצא
השגיאה הבאה מציינת שמשאב השער שצוין בשדה targetRefs של המשאב GCPTrafficExtension, GCPRoutingExtension או GCPEdgeExtension לא קיים:
error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.gatewayRef: gateway "my-gateway" not found in namespace "default"
כדי לפתור את הבעיה, צריך לוודא שהמשאב Gateway שצוין בשדה targetRefs של המשאב GCPTrafficExtension או GCPRoutingExtension קיים במרחב השמות שצוין.
לא נמצא שירות או יציאת שירות
השגיאה הבאה מציינת שהשירות או יציאת השירות שצוינו בשדה backendRef של המשאב GCPTrafficExtension או GCPRoutingExtension לא קיימים:
error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: service "callout-service" not found in namespace "default"
כדי לפתור את הבעיה, צריך לוודא שהשירות ויציאת השירות שצוינו בשדה backendRef של משאב GCPTrafficExtension או GCPRoutingExtension קיימים במרחב השמות שצוין.
אין נקודות קצה (endpoint) ברשת ב-NEG
השגיאה הבאה מציינת שאין נקודות קצה ברשת ב-NEG שמשויכות לשירות שצוין בשדה backendRef של המשאב GCPTrafficExtension או GCPRoutingExtension:
error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: no network endpoints found for service "callout-service"
כדי לפתור את הבעיה, צריך לוודא שלשירות שצוין בשדה backendRef של משאב GCPTrafficExtension או GCPRoutingExtension יש נקודות קצה ברשת.
אין תשובה או שיש תשובה עם שגיאה כששולחים את הבקשה
אם לא קיבלתם תשובה או שקיבלתם תשובה עם שגיאה כששלחתם בקשה, יכול להיות ששירות ה-callout לא פועל בצורה תקינה.
כדי לפתור את הבעיה, צריך לבדוק את היומנים של שירות ההתקשרות כדי לראות אם יש שגיאות.
קוד שגיאה 404 במטען הייעודי (payload) בפורמט JSON
השגיאה הבאה מציינת שלא נמצא שירות של callout או שהוא לא מגיב לבקשה:
{
"error": {
"code": 404,
"message": "Requested entity was not found.",
"status": "NOT_FOUND"
}
}
כדי לפתור את הבעיה, צריך לוודא שהשירות של ה-callout פועל, שהוא מאזין ביציאה הנכונה ושהשירות מוגדר בצורה נכונה במשאב GCPTrafficExtension או GCPRoutingExtension.
קוד שגיאה 500 במטען הייעודי (payload) בפורמט JSON
השגיאה הבאה מציינת שיש שגיאת שרת פנימית בשירות ה-callout:
{
"error": {
"code": 500,
"message": "Internal server error.",
"status": "INTERNAL"
}
}
כדי לפתור את הבעיה, צריך לבדוק את היומנים של שירות ההתקשרות כדי לזהות את הסיבה לשגיאת השרת הפנימית.
GCPWasmPlugin לא קיים
השגיאה הבאה מציינת שהמשאב GCPWasmPlugin לא קיים בפרויקט שלכם עבור GCPTrafficExtension או GCPEdgeExtension:
Status:
Ancestors:
Ancestor Ref:
Group: gateway.networking.k8s.io
Kind: Gateway
Name: external-http
Namespace: default
Conditions:
Last Transition Time: 2025-03-06T16:27:57Z
Message:
Reason: Accepted
Status: True
Type: Accepted
Last Transition Time: 2025-03-06T16:27:57Z
Message: error cause: invalid-wasm-plugin: GCPWasmPlugin default/my-wasm-plugin in GCPTrafficExtension default/my-gateway-plugin-extension does not exist
Reason: GCPWasmPluginNotFound
Status: False
Type: ResolvedRefs
Controller Name: networking.gke.io/gateway
כדי לפתור את הבעיה, צריך ליצור GCPWasmPlugin תואם בפרויקט Cloud de Confiance או להפנות תוסף אל GCPWasmPlugin קיים.
המאמרים הבאים
- מידע על GKE Inference Gateway
- איך מפעילים מודל שפה גדול (LLM) באמצעות GKE Inference Gateway
- איך צופים במדדי יכולת התצפית