פריסת משאבי Kubernetes Gateway כדי לנהל את האופן שבו תעבורה חיצונית מגיעה לאפליקציות באשכול יחיד של Google Kubernetes Engine (GKE). הגדרת GKE Gateway מספקת שליטה גמישה ועוצמתית בתעבורת נתונים נכנסת (ingress), ומשפרת את יכולת ההתאמה ואת המהימנות של האפליקציות. לדוגמה, GKE Gateway מציע יכולות אופטימיזציה של ניתוב והתאמה אוטומטית לעומס. היכולות האלה חיוניות למילוי בקשה באופן מיידי עם זמן אחזור נמוך, וכך הן עוזרות לספק חוויית משתמש רספונסיבית ולשלוט בעלויות.
כדי לפרוס שערים בכמה אשכולות או ב-Fleet, אפשר לעיין במאמר בנושא פריסת שערים מרובי אשכולות. למידע על הגדרות ספציפיות של Gateway, כמו ניתוב בין מרחבי שמות ופיצול תנועת HTTP, אפשר לעיין במדריכים למשתמש של Gateway API.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:
- מפעילים את ממשק Google Kubernetes Engine API. הפעלת Google Kubernetes Engine API
- אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
- מוודאים שיש לכם אשכול קיים במצב Autopilot או במצב Standard. כדי ליצור אשכול חדש, אפשר לעיין במאמר בנושא יצירת אשכול Autopilot.
דרישות של GKE Gateway Controller
- Gateway API נתמך רק באשכולות VPC-native.
- אם אתם משתמשים ב-GatewayClasses אזוריים או חוצי-אזורים, אתם צריכים להפעיל רשת משנה ל-proxy בלבד.
- צריך להפעיל את התוסף
HttpLoadBalancingבאשכול. - אם אתם משתמשים ב-Istio, אתם צריכים לשדרג את Istio לאחת מהגרסאות הבאות:
- גרסה 1.15.2 ואילך
- 1.14.5 ואילך
- 1.13.9 ואילך.
- אם משתמשים ב-VPC משותף, צריך להקצות את התפקיד
Compute Network Userלחשבון השירות של GKE בפרויקט המארח של פרויקט השירות.
הגבלות ומגבלות
כשמשתמשים ב-GKE Gateway, חשוב להבין את המגבלות וההגבלות הבאות:
מחלקות GKE Gateway תומכות ביכולות שונות בהתאם למאזן העומסים שבו הן משתמשות. מידע נוסף על התכונות השונות שנתמכות בכל GatewayClass זמין במאמר יכולות של GatewayClass.
שיטה מומלצת: כדי לקבל ביצועים אופטימליים, מומלץ להגביל את מספר השערים ל-100 לכל היותר. חריגה מהמגבלה הזו עלולה להשפיע על הביצועים או לגרום להגדלת זמן האחזור.
אי אפשר להשתמש ב-FrontendConfig או ב-BackendConfig כדי להגדיר שער. חובה להשתמש במדיניות.
התנהגות של GKE Gateway שונה מזו של Ingress, כי Gateway לא מסיק פרמטרים של בדיקת תקינות. אם השירות לא מחזיר 200 לבקשות אל
GET /, או אם יש לכם בדיקות מוכנות אחרות של פודים שהותאמו, אתם צריכים להגדיר HealthCheckPolicy לשירות.אי אפשר לציין מספר יציאה ישירות בשם המארח (לדוגמה, web.example.com:80) לניתוב תנועה.
אפשר לראות את משאבי איזון העומסים ש-GKE יוצר עבור Gateways במסוף Google Cloud , אבל המשאבים האלה לא מפנים אל ה-Gateway או אל אשכול GKE שאליהם הם מצורפים.
אי אפשר ליצור באופן אוטומטי אישור SSL בניהול Google באמצעות Gateways, אבל אפשר ליצור אישור SSL בניהול Google באופן ידני ולהפנות אליו. מידע נוסף זמין במאמר בנושא אבטחת שער.
HTTPRoute הוא סוג ה-Route היחיד שנתמך. אין תמיכה ב-TCPRoutes, ב-UDPRoutes וב-TLSRoutes. רשימת השדות שנתמכים בבקר GKE Gateway מופיעה במאמר בנושא יכולות של GatewayClass.
האפשרות להשתמש בכותרות מותאמות אישית של בקשות ותגובות עם הפניות אוטומטיות של שער או נתיב, ושינוי כתובות URL עם שער, זמינה רק ב-GKE מגרסה 1.27 ואילך.
ה-GatewayClass
gke-l7-gxlbלא נתמך בכותרות מותאמות אישית של בקשות ותגובות עם הפניות אוטומטיות של שערים ונתיבים, ועם שכתוב של כתובות URL עם שערים.כשמגדירים כותרות מותאמות אישית של בקשות ותגובות ב-HTTPRoute, אין תמיכה בGoogle Cloud משתנים הבאים:
-
origin_request_header(מדיניות CORS לא נתמכת ב-GKE Gateway)
-
אין תמיכה בכותרות מותאמות אישית של TLS הדדי (mTLS עם GKE Gateway לא נתמך)
Google Cloud המגבלות של מאזן עומסים קלאסי של אפליקציות (ALB) חלות על GKE Gateway. בנוסף, אי אפשר להגדיר כותרת תגובה של מארח בהתאמה אישית בשירות הקצה העורפי.
הפניות אוטומטיות של נתיבים ושינוי כתובות URL הן פעולות שאי אפשר לבצע בו-זמנית, ולכן אי אפשר להשתמש בשני המסננים האלה באותם כללים.
הפניית תעבורת נתונים ליציאה אחרת לא נתמכת ב-Cloud Load Balancing. רשימת השדות שנתמכים על ידי בקר GKE Gateway מופיעה במאמר בנושא יכולות של GatewayClass.
GKE Gateway לא תומך בתווים כלליים לחיפוש, בביטויים רגולריים ובכתובות URL דינמיות.
אם מציינים שער עם סיווג של שער חיצוני אזורי, הבקר מקצה כתובת IP פנימית במקום כתובת חיצונית. כדי ללמוד איך להשתמש בכתובת עם שם במאזן עומסים אזורי חיצוני של אפליקציות (ALB), אפשר לעיין במאמר בנושא פריסת שער חיצוני אזורי.
שער הרשת משתמש בקבוצות עצמאיות של נקודות קצה ברשת כדי להקצות קבוצות של נקודות קצה ברשת. כדי לוודא שבקר Gateway מבצע התאמה נכונה של ההגדרות של איזון העומסים, אסור לשנות את ההערה
cloud.google.com/negשל שירות שמשויך ל-Gateway.GKE Gateway לא תומך בהפניה לשירות שמופנה גם על ידי GKE Ingress.
כשמגדירים
Gatewayלהקצאת כתובת IP, אי אפשר לשנות אתGateway.spec.gatewayClass. כדי לוודא שבקר Gateway מבצע התאמה נכונה של איזון העומסים, צריך למחוק את Gateway הקיים ולפרוס מחדש את המניפסט עם הערך המעודכן שלgatewayClass.ההערה
networking.gke.io/app-protocolsלא אפשרית. כדי להשיג את אותה התוצאה, צריך להשתמש במקום זאת בשדהappProtocol.אם אתם משתמשים ב-GKE Gateway עם
external-dnsומצב התקינות של ה-Gateway הוא unhealthy, כברירת מחדל, כל רשומות ה-DNS שמשויכות ל-Gateway נמחקות מאזורי ה-DNS שלכם.שיטה מומלצת: כשמריצים את הפקודה
external-dns, מגדירים את הדגלpolicy=upsert-only. ההגדרה הזו עוזרת למנוע מחיקה של רשומות DNS קיימות.אם יציאה מוסרת מ-
Serviceש-GKE Gateway מפנה אליו דרך מסלול, צריך לעדכן גם את הערת ה-NEG העצמאי בשירות כדי להסיר את היציאה הזו. אם לא תעשו זאת, בקר ה-NEG יפסיק בסופו של דבר לסנכרן את נקודות הקצה של ה-Pod בשירות הזה. פרטים נוספים זמינים במאמר NEG Controller מפסיק לנהל נקודות קצה כשמסירים יציאה משירות.פריסות שמשתמשות בשערים מרובי אשכולות (MCG) שמשתמשים באשכולות אזוריים חשופות לשיבושים בשירות במהלך שדרוגים של אשכולות. הבעיה הזו מתרחשת כי מנגנון גילוי מדור קודם של קבוצת נקודות קצה ברשת (NEG) עשוי לדווח באופן שגוי על אפס שרתים עורפיים כשמישור הבקרה של האשכול האזורי לא זמין באופן זמני. אנחנו עובדים על פתרון לטווח ארוך. כדי להימנע מנקודת כשל יחידה, מומלץ להשתמש באשכולות GKE אזוריים עם MCG.
הפעלת Gateway API באשכול
כדי להשתמש במשאבי Gateway ב-GKE, צריך להפעיל את Gateway API באשכול.
לפני שמעדכנים אשכול GKE קיים כדי להפעיל את Gateway API, צריך לוודא שמתקיימות הדרישות המינימליות לפני שממשיכים בעדכון.
כדי להפעיל את Gateway API באשכול GKE קיים (במצב Autopilot או Standard), משתמשים בפקודה הבאה. יכול להיות שיחלפו עד 45 דקות עד שהאשכול יתאים את עצמו ויתקין את ה-CRD.
gcloud container clusters update CLUSTER_NAME \
--location=CLUSTER_LOCATION\
--gateway-api=standard
מחליפים את מה שכתוב בשדות הבאים:
CLUSTER_NAME: השם של האשכול הקיים.
CLUSTER_LOCATION: האזור או התחום של Compute Engine שבו נמצא האשכול.
הדגל --gateway-api=standard מורה ל-GKE להתקין את ה-CRD של ערוץ התקנים של Gateway API עם האשכול.
אימות האשכול
אחרי שיוצרים או משדרגים את האשכול, הבקר של GKE Gateway מתקין באופן אוטומטי GatewayClasses. יכול להיות שיחלפו כמה דקות עד שהבקר יזהה את ה-CRD ויתקין את GatewayClasses.
מוודאים ש-Gateway API מופעל במישור הבקרה של GKE:
gcloud container clusters describe CLUSTER_NAME \ --location=CLUSTER_LOCATION \ --format jsonהפלט אמור להיראות כך: אם הפלט הזה ריק, מריצים מחדש את הפקודה לעדכון האשכול.
"networkConfig": { ... "gatewayApiConfig": { "channel": "CHANNEL_STANDARD" }, ... },מוודאים שרכיבי GatewayClasses מותקנים באשכול:
kubectl get gatewayclassהפלט אמור להיראות כך:
NAME CONTROLLER ACCEPTED AGE gke-l7-global-external-managed networking.gke.io/gateway True 16h gke-l7-regional-external-managed networking.gke.io/gateway True 16h gke-l7-gxlb networking.gke.io/gateway True 16h gke-l7-rilb networking.gke.io/gateway True 16h
כדי להבין את היכולות של כל GatewayClass, אפשר לעיין במאמר יכולות GatewayClass.
רק GatewayClasses של אשכול יחיד מותקנים באופן אוטומטי. כדי להתקין ולהשתמש ב-GatewayClasses מרובי אשכולות לאיזון עומסים פנימי וחיצוני מרובה אשכולות, אפשר לעיין במאמר בנושא הפעלת שערים מרובי אשכולות.
פריסת שער פנימי
שער פנימי חושף אפליקציות שאפשר להגיע אליהן רק מתוך ה-VPC או רשתות שמחוברות ל-VPC.
פריסת שער פנימי אזורי
בדוגמה הבאה מוצג איך פורסים שער פנימי אזורי שמאפשר תקשורת יעילה ומאובטחת בין שירותים באזור גיאוגרפי ספציפי.
הגדרת רשת משנה לשרת proxy בלבד
לפני שיוצרים שער שמשתמש במאזן עומסים של אפליקציות (ALB) פנימי, צריך להגדיר רשת משנה של פרוקסי בלבד. לכל אזור של VPC שבו אתם משתמשים במאזני עומסים פנימיים של אפליקציות (ALB) צריך להיות תת-רשת של שרת proxy בלבד. רשת המשנה הזו מספקת כתובות IP פנימיות לשרתי ה-proxy של מאזן העומסים.
יוצרים תת-רשת לשרתי proxy בלבד:
gcloud compute networks subnets create SUBNET_NAME \ --purpose=REGIONAL_MANAGED_PROXY \ --role=ACTIVE \ --region=COMPUTE_REGION \ --network=VPC_NETWORK_NAME \ --range=CIDR_RANGEמחליפים את מה שכתוב בשדות הבאים:
-
SUBNET_NAME: השם של תת-הרשת של ה-proxy בלבד. -
COMPUTE_REGION: האזור של תת-הרשת של ה-proxy בלבד. -
VPC_NETWORK_NAME: השם של רשת ה-VPC שבה יוצרים את רשת המשנה הזו מסוג proxy בלבד. חשוב לוודא שזו אותה רשת VPC שבה נמצא אשכול GKE ושבה פורס השער. ההגדרה הזו חשובה כדי לאפשר תקשורת חלקה בין מאזן העומסים לבין שירותי הקצה העורפי. -
CIDR_RANGE: טווח כתובות ה-IP הראשי של רשת המשנה. צריך להשתמש במסכה של רשת משנה באורך של/26לכל היותר, כדי שיהיו לפחות 64 כתובות IP זמינות לשרתי proxy באזור. מסכה של רשת משנה המומלצת היא/23.
-
מאמתים את רשת המשנה של ה-proxy בלבד:
gcloud compute networks subnets describe SUBNET_NAME \ --region=COMPUTE_REGIONהפלט אמור להיראות כך:
... gatewayAddress: 10.1.1.1 ipCidrRange: 10.1.1.0/24 kind: compute#subnetwork name: proxy-subnet network: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/networks/default privateIpGoogleAccess: false privateIpv6GoogleAccess: DISABLE_GOOGLE_ACCESS purpose: REGIONAL_MANAGED_PROXY region: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION role: ACTIVE selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION/subnetworks/proxy-subnet state: READY
יצירת שער
משאב Gateway מייצג מישור נתונים שמנתב תעבורה ב-Kubernetes. שער יכול לייצג סוגים שונים של איזון עומסים וניתוב, בהתאם ל-GatewayClass שממנו הוא נגזר. מידע נוסף על משאב Gateway מופיע בתיאור משאב Gateway או במפרט ה-API.
במקרה הזה, האדמין של אשכול GKE רוצה ליצור שער שאפשר להשתמש בו בצוותים שונים כדי לחשוף את האפליקציות שלהם באופן פנימי. האדמין פורס את שער הכניסה, וצוותי האפליקציות פורסים את המסלולים שלהם באופן עצמאי ומצרפים אותם לשער הכניסה הזה.
שומרים את מניפסט השער הבא בקובץ בשם
gateway.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: internal-http spec: # Specify an existing GatewayClass. gatewayClassName: gke-l7-rilb listeners: # Listen for HTTP traffic on port 80. - name: http protocol: HTTP port: 80המניפסט הזה כולל את השדות הבאים:
-
gatewayClassName: gke-l7-rilb: מציין את GatewayClass שממנו נגזר שער הגישה הזה. gke-l7-rilbתואם למאזן עומסים פנימי של אפליקציות (ALB). -
port: 80: מציין שהשער חושף רק את יציאה 80 להאזנה לתנועת HTTP.
השער הזה מוגדר לטיפול בתנועת HTTP רק ביציאה 80. הוא לא תומך ב-HTTPS (יציאה 443) כברירת מחדל, ואם מנסים להתחבר דרך HTTPS, יכול להיות שהבקשה תיכשל.
-
פורסים את שער הכניסה באשכול:
kubectl apply -f gateway.yamlמוודאים שהשער נפרס בצורה נכונה. יכול להיות שיעברו כמה דקות עד שכל המשאבים יופעלו.
kubectl describe gateways.gateway.networking.k8s.io internal-httpהפלט אמור להיראות כך:
Name: internal-http Namespace: default Spec: Gateway Class Name: gke-l7-rilb Listeners: Allowed Routes: Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 192.168.1.14 Conditions: Last Transition Time: 2025-03-19T19:53:46Z Message: The OSS Gateway API has deprecated this condition, do not depend on it. Observed Generation: 1 Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2025-03-19T19:53:46Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-03-19T19:53:46Z Message: Observed Generation: 1 Reason: Programmed Status: True # Indicates that the Gateway is ready. Type: Programmed Last Transition Time: 2025-03-19T19:53:46Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reserved it for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Last Transition Time: 2025-03-19T19:53:46Z Message: Observed Generation: 1 Reason: Healthy Status: True Type: networking.gke.io/GatewayHealthy Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 92s networking.gke.io/gateway test/internal-http Normal UPDATE 45s (x3 over 91s) networking.gke.io/gateway test/internal-http Normal SYNC 45s networking.gke.io/gateway SYNC on test/internal-http was a successבפלט הזה, הסטטוס של
Trueעבור התנאיProgrammedמציין שהשער מוכן.בשלב הזה, יש שער שנפרס באשכול שלכם, שסופק לו מאזן עומסים וכתובת IP. לשער אין נתיבים, ולכן הוא לא יודע איך לשלוח תנועה לשרתי קצה. בלי מסלולים, כל התנועה מועברת לחלק האחורי שמוגדר כברירת מחדל, שמחזיר HTTP 404. בשלב הבא פורסים אפליקציה ומסלולים, שמציינים ל-Gateway איך להגיע לשרתי הקצה של האפליקציה.
פריסת אפליקציות ההדגמה
צוותי אפליקציות יכולים לפרוס את האפליקציות והנתיבים שלהם בנפרד מהפריסה של שערים. במקרים מסוימים, צוות האפליקציה עשוי לרצות להיות הבעלים של השער ולפרוס אותו בעצמו כמשאב שמוקדש לאפליקציות שלו. בקטע Route binding מוסבר על מודלים שונים של בעלות על שערים ועל מסלולים. בדוגמה הזו, צוות החנות פורס את האפליקציה שלו ואת ה-HTTPRoute הנלווה כדי לחשוף את האפליקציה שלו דרך שער internal-http שנוצר בקטע הקודם.
למשאב HTTPRoute יש הרבה שדות שניתנים להגדרה להתאמת תנועה. הסבר על השדות של HTTPRoute מופיע במפרט ה-API.
פורסים את אפליקציית החנות (פריסות store-v1, store-v2 ו-store-german) באשכול:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yamlכך נוצרות שלוש פריסות ושלושה שירותים בשמות store-v1, store-v2 ו-store-german.
מוודאים שהפריסה של האפליקציה בוצעה בהצלחה:
kubectl get podהפלט אמור להיראות כך אחרי שהאפליקציה פועלת:
NAME READY STATUS RESTARTS AGE store-german-66dcb75977-5gr2n 1/1 Running 0 38s store-v1-65b47557df-jkjbm 1/1 Running 0 14m store-v2-6856f59f7f-sq889 1/1 Running 0 14mבודקים שהשירותים נפרסו:
kubectl get serviceהפלט מציג שירות לכל פריסת חנות:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE store-german ClusterIP 10.48.3.183 <none> 8080/TCP 4s store-v1 ClusterIP 10.48.2.224 <none> 8080/TCP 5s store-v2 ClusterIP 10.48.4.48 <none> 8080/TCP 5s
פריסת ה-HTTPRoute
משאבי ניתוב מגדירים כללים ספציפיים לפרוטוקול למיפוי תנועה מ-Gateway לקצה העורפי של Kubernetes. רכיב HTTPRoute מבצע התאמה וסינון של תנועת HTTP ו-HTTPS, והוא נתמך על ידי כל רכיבי gke-l7GatewayClass.
בקטע הזה פורסים HTTPRoute, שמגדיר את ה-Gateway עם כללי הניתוב שנדרשים כדי להגיע לאפליקציית החנות.
שומרים את מניפסט ה-HTTPRoute הבא בקובץ בשם
store-route.yaml:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store spec: # Attach the HTTPRoute to a Gateway. parentRefs: - kind: Gateway name: internal-http # Route requests that have `store.example.com` in the Host header. hostnames: - "store.example.com" rules: # Send requests with the `env: canary` header to the `store-v2` Service. - matches: - headers: - name: env value: canary backendRefs: - name: store-v2 port: 8080 # Send requests with `/de` in the path to the `store-german` Service. - matches: - path: value: /de backendRefs: - name: store-german port: 8080 # Send unmatched requests to the store-v1 Service. - backendRefs: - name: store-v1 port: 8080פורסים את ה-HTTProute באשכול:
kubectl apply -f store-route.yaml
storeHTTPRoute קשור ל-internal-httpGateway באמצעות המאפייןparentRefs. כללי הניתוב האלה מוגדרים במאזן העומסים הבסיסי, כמו בתרשים הזה:כללי הניתוב האלה מעבדים תנועת HTTP באופן הבא:
- תנועת הגולשים אל
store.example.com/deמועברת לשירותstore-german. - תנועה אל
store.example.comעם כותרת ה-HTTP"env: canary"עוברת אל השירותstore-v2. - שאר התנועה אל
store.example.comמופנית אל השירותstore-v1.
- תנועת הגולשים אל
מוודאים שרכיב ה-HTTPRoute נפרס:
kubectl describe httproute storeהפלט אמור להיראות כך:
Name: store Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1 Kind: HTTPRoute # Multiple lines are omitted here. Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: /de Status: Parents: Conditions: Last Transition Time: 2022-11-01T04:18:52Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2022-11-01T04:18:52Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 24m sc-gateway-controller default/store Normal SYNC 16m (x4 over 23m) sc-gateway-controller Bind of HTTPRoute "default/store" to ParentRef {Group: gateway.networking.k8s.io", # Multiple lines are omitted here.מוודאים ש-HTTPRoute קשור ל-Gateway:
kubectl describe gatewayהפלט אמור להיראות כך:
Name: internal-http Namespace: default Labels: <none> <...> Status: Addresses: Type: IPAddress Value: 10.128.15.203 Conditions: Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute <...>
שליחת תנועה לאפליקציה
עכשיו, אחרי ששער, מסלול ואפליקציה נפרסו באשכול, אפשר להעביר תנועה לאפליקציה. השער מוגדר להעברת תנועת HTTP רק ביציאה 80. בקשות שמבוצעות באמצעות HTTPS עלולות להיכשל אלא אם TLS הוגדר בנפרד.
מאחזרים את כתובת ה-IP מהשער כדי שתוכלו לשלוח תנועה לאפליקציה:
kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}"הפלט הוא כתובת IP.
שליחת תעבורה לכתובת ה-IP הזו מהמעטפת במכונה וירטואלית (VM) עם קישוריות לאשכול. אפשר ליצור מכונה וירטואלית (VM) למטרה הזו. הפעולה הזו נדרשת כי לשער יש כתובת IP פנימית, ואפשר לגשת אליו רק מתוך רשת ה-VPC. מכיוון ש-
internal-httpהוא מאזן עומסים אזורי, מעטפת הלקוח צריכה להיות באותו אזור כמו אשכול GKE.שליחת בקשה אל store.example.com:
curl http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vמחליפים את
GATEWAY_IP_ADDRESSבכתובת ה-IP מהשלב הקודם.הפלט מאפליקציית ההדגמה מציג מידע על המיקום שבו האפליקציה פועלת:
{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v1-84b47c7f58-pmgmk", "pod_name_emoji": "💇🏼♀️", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:31:17", "zone": "ZONE_NAME" }כדי לבדוק את ההתאמה לנתיב, עוברים לגרסה הגרמנית של שירות החנות בכתובת
store.example.com/de:curl http://store.example.com/de --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vהפלט מאשר שהבקשה נשלחה על ידי
store-germanPod:{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "Gutentag!", "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal", "pod_name": "store-german-5cb6474c55-lq5pl", "pod_name_emoji": "🧞♀", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:35:37", "zone": "ZONE_NAME" }לבסוף, משתמשים בכותרת
env: canaryHTTP כדי לשלוח תנועה לגרסת הקנרי של שירות החנות:curl -H "env: canary" http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -vהפלט מאשר שהבקשה נשלחה על ידי
store-v2Pod:{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v2", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v2-5788476cbd-s9thb", "pod_name_emoji": "🦰", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:38:26", "zone": "ZONE_NAME" }
פריסת שער חיצוני
שער חיצוני חושף אפליקציות שאפשר להגיע אליהן מהאינטרנט או מרשתות מחוץ לרשת ה-VPC. הפריסה דומה לפריסת שער פנימי, אבל צריך לאבטח את האפליקציות כי השער נגיש לאינטרנט הציבורי.
יש שתי אפשרויות ליצירת שער חיצוני: שער חיצוני גלובלי או שער חיצוני אזורי.
- שער חיצוני אזורי: השער הזה משתמש בכתובת IP אזורית כחלק הקדמי של השער. ההתנהגות של השער הזה תלויה במסלול שירות הרשת שתבחרו:
- אם בוחרים במסלול הרגיל של שירותי הרשת (ברירת המחדל), כתובת ה-IP האזורית מפורסמת רק באזור Google Cloud Compute המקומי שבו נפרס שער חיצוני אזורי. לקוחות ששולחים תעבורת נתונים לכתובת ה-IP הזו מנותבים על ידי ספק האינטרנט המקומי שלהם דרך האינטרנט הציבורי, לפני שהם מגיעים לאזור של Google שבו כתובת ה-IP מפורסמת.
- אם בוחרים במסלול הפרימיום של שירות הרשת, כתובת ה-IP האזורית מפורסמת בכל הרשת הגלובלית של Google. כלומר, תעבורת הנתונים של הלקוח נכנסת לרשת הגלובלית האיכותית של Google בשדרה המרכזית בנקודת קישור בין רשתות שכנות (peering) בקצה של Google, הכי קרוב שאפשר ללקוח, גם אם היעד הוא כתובת IP אזורית. המיקום הזה מפחית באופן משמעותי את זמן האחזור ומשפר את הביצועים, כי הוא מצמצם את המרחק שהתנועה עוברת באינטרנט הציבורי.
- שער חיצוני גלובלי: השער הזה משתמש בכתובת IP גלובלית (או בכתובת IP מסוג Anycast) כחלק הקדמי של השער. כתובת ה-IP הזו מפורסמת בכל האזורים של Google Cloud Compute. לקוחות ששולחים תעבורת נתונים לכתובת ה-IP מסוג Anycast הזו מנותבים למיקום הקרוב ביותר של Google שבו כתובת ה-IP מפורסמת. שער חיצוני גלובלי זמין רק במסלול הפרימיום של שירות הרשת.
פריסת שער חיצוני אזורי
בדוגמה הבאה מוצג אופן החשיפה של אפליקציית חנות עם כמה אישורים שמצורפים לשער החיצוני האזורי באמצעות אישורים בניהול עצמי ו-HTTPRoute.
יצירת תת-רשת של שרת proxy לשער אזורי
לפני שיוצרים שער שמשתמש במאזן עומסים חיצוני אזורי של אפליקציות (ALB), צריך להגדיר רשת משנה לשרת proxy בלבד. לכל אזור של VPC שבו משתמשים במאזן עומסים חיצוני אזורי של אפליקציות (ALB) צריך להיות external_managed_proxy רשת משנה. רשת המשנה הזו מספקת כתובות IP פנימיות לשרתי ה-proxy של מאזן העומסים.
יצירת אישור לאבטחת תנועת הלקוחות
אתם יכולים להשתמש באישור שהונפק ואומת על ידי רשות האישורים (CA) שלכם או ליצור אישור עם חתימה עצמית. מידע נוסף על יצירת אישור זמין במאמר בנושא אחסון אישור ב-Kubernetes Secret.
כדי לאבטח את התעבורה בין הלקוחות לבין שער אזורי, אפשר להשתמש בשיטות הבאות:
- אישורים שמנוהלים על ידי Google או שמנוהלים באופן עצמאי ב-Certificate Manager
- אישורי SSL אזוריים בניהול עצמי
- סודות של Kubernetes
CertificateMap או אישורי SSL בניהול Google לא נתמכים עם שערים אזוריים.
מידע נוסף זמין במאמר בנושא אישורים ומאזני עומסים. Google Cloud
יצירת שער HTTP(S) חיצוני אזורי
יוצרים כתובת IP סטטית אזורית למאזן העומסים החיצוני.
gcloud compute addresses create IP_ADDRESS_NAME \ --region=COMPUTE_REGION \ --network-tier=STANDARDמחליפים את מה שכתוב בשדות הבאים:
-
IP_ADDRESS_NAME: השם של כתובת ה-IP הסטטית החדשה. -
COMPUTE_REGION: האזור ב-Compute Engine שבו האשכול פועל.
-
כדי ליצור שער אזורי חיצוני של מאזן עומסים של אפליקציות באמצעות אישור בניהול עצמי, פועלים לפי השלבים הבאים ושומרים את המניפסט כ-
regional-gateway.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-regional-http spec: # Name of an existing GatewayClass. gatewayClassName: gke-l7-regional-external-managed # Listen for HTTPS traffic on port 443 listeners: - name: https protocol: HTTPS port: 443 tls: # Terminate the TLS session with the client at the Gateway. mode: Terminate # Certificates for the Gateway to use to create a new TLS session. certificateRefs: - name: store-example-com # The name of the static IP address of the external load balancer. # You can also use the `IPAddress` type to specify the actual IP address. addresses: - type: NamedAddress value: IP_ADDRESS_NAMEהחלת המניפסט
regional-gateway:kubectl apply -f regional-gateway.yamlבודקים את ההגדרות.
kubectl get gatewayהפלט אמור להיראות כך:
NAME CLASS ADDRESS READY AGE external-http gke-l7-regional-external-managed 35.118.32.224 True 49sכדי לקבל פרטים נוספים, משתמשים בפקודה describe:
kubectl describe gatewayהפלט אמור להיראות כך:
Name: external-regional-http Namespace: default Labels: <none> ... Spec: Gateway Class Name: gke-l7-regional-external-managed Listeners: Allowed Routes: Namespaces: From: Same Name: https Port: 443 Protocol: HTTPS Tls: Certificate Refs: Group: Kind: Secret Name: store-example-com Mode: Terminate ...
פריסת אפליקציות ההדגמה
צוותי אפליקציות יכולים לפרוס את האפליקציות והנתיבים שלהם בנפרד מהפריסה של שערים. במקרים מסוימים, צוות הפיתוח של האפליקציה עשוי לרצות להיות הבעלים של שער הנתונים ולפרוס אותו בעצמו כמשאב שמוקדש לאפליקציות שלו. מידע נוסף על מודלים שונים של בעלות על שערים ומסלולים זמין במאמר בנושא שיוך מסלולים. בדוגמה הזו, צוות החנות פורס את האפליקציה שלו ואת ה-HTTPRoute הנלווה כדי לחשוף את האפליקציה שלו דרך שער external-http שנוצר בקטע הקודם.
מידע נוסף על שדות HTTPRoute זמין במפרט ה-API.
פורסים את האפליקציה לדוגמה באשכול:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yamlאפליקציית הדוגמה הזו יוצרת שלוש פריסות ושלושה שירותים בשמות
store-v1,store-v2ו-store-german.מוודאים שהפריסה של האפליקציה בוצעה בהצלחה:
kubectl get podהפלט אמור להיראות כך:
NAME READY STATUS RESTARTS AGE store-german-66dcb75977-5gr2n 1/1 Running 0 38s store-v1-65b47557df-jkjbm 1/1 Running 0 14m store-v2-6856f59f7f-sq889 1/1 Running 0 14mמוודאים שהשירותים נפרסו בהצלחה:
kubectl get serviceהפלט אמור להיראות כך:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE store-german ClusterIP 10.48.3.183 <none> 8080/TCP 4s store-v1 ClusterIP 10.48.2.224 <none> 8080/TCP 5s store-v2 ClusterIP 10.48.4.48 <none> 8080/TCP 5s
יצירת HTTPRoute
משאבי ניתוב מגדירים כללים ספציפיים לפרוטוקול למיפוי תנועה מ-Gateway לקצה העורפי של Kubernetes. המשאב HTTPRoute מבצע התאמה וסינון של תנועת HTTP ו-HTTPS, והוא נתמך על ידי כל המחלקות gke-l7-* GatewayClasses.
בקטע הזה, פורסים HTTPRoute, שמגדיר את ה-Gateway עם כללי הניתוב שנדרשים כדי להגיע לאפליקציית הדוגמה.
שומרים את המניפסט הבא בקובץ בשם
store-route-external.yaml:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store-external spec: parentRefs: # Bind the route to the 'external-http' Gateway. - kind: Gateway name: external-http hostnames: - "store.example.com" rules: # Default rule for store.example.com that sends traffic to the store-v1 service. - backendRefs: - name: store-v1 port: 8080 # Match requests with the "env: canary" header and send them to the store-v2 service. - matches: - headers: - name: env value: canary backendRefs: - name: store-v2 port: 8080 # Match requests with the path "/de" and sends them to the store-german service. - matches: - path: value: /de backendRefs: - name: store-german port: 8080במניפסט הזה מתואר HTTPRoute שמפנה אל
external-httpGateway.מחילים את המניפסט על האשכול:
kubectl apply -f store-route-external.yaml
storeHTTPRoute קשור ל-external-httpGateway באמצעות המאפייןparentRefs. התרשים הבא מציג את כללי הניתוב שהוגדרו במאזן העומסים הבסיסי:כללי הניתוב מעבדים את תנועת ה-HTTP באופן הבא:
- תנועה אל מסלולים של
store.example.com/deאל שירותstore-german. - תנועה אל
store.example.comעם כותרת ה-HTTP"env: canary"מנותבת אל שירותstore-v2. - התנועה שנותרה אל
store.example.comמנותבת אל שירותstore-v1.
- תנועה אל מסלולים של
מוודאים שרכיב ה-HTTPRoute נפרס:
kubectl describe httproute store-externalהפלט אמור להיראות כך:
Name: store-external Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1 Kind: HTTPRoute # Multiple lines are omitted here. Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: /de Status: Parents: # This section shows the status of this route in relation to each Gateway attached. Conditions: Last Transition Time: 2022-11-01T05:42:31Z Message: Reason: Accepted Status: True # Means that the Gateway has validated and accepted this route's configuration. Type: Accepted Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 2m48s sc-gateway-controller default/store-external Normal SYNC 61s (x3 over 2m27s) sc-gateway-controller Bind of HTTPRoute "default/store-external" to ParentRef Group: "gateway.networking.k8s.io", ...מוודאים ש-HTTPRoute קשור ל-Gateway:
kubectl describe gateway external-httpהפלט אמור להיראות כך:
Name: external-http Namespace: default Labels: <none> # Multiple lines are omitted here. Status: Addresses: Type: IPAddress Value: 34.149.207.45 Conditions: Last Transition Time: 2022-11-01T05:37:21Z Message: Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: Ready Status: True Type: Ready Name: https Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute # Multiple lines are omitted here.
שליחת תנועה לאפליקציה
עכשיו, אחרי ששער, מסלול ואפליקציה נפרסו באשכול, אפשר להעביר תנועה לאפליקציה.
מקבלים את כתובת ה-IP של השער:
kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"הפלט הוא כתובת IP.
יוצרים מכונה וירטואלית:
gcloud cloud-shell sshשליחת תנועה לכתובת ה-IP של השער מהמכונה הווירטואלית. צריך להגדיר את כותרת המארח באופן ידני כי אתם לא הבעלים של שם המארח
example.com.curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -vמחליפים את
GATEWAY_IP_ADDRESSבכתובת ה-IP של השער מהשלב הקודם.cacert.pem: קובץ האישור שיצרתם. צריך לשמור את הקובץ הזה במחשב שבו משתמשים כדי להתחבר לשער.
בפלט מוצג מידע מאפליקציית ההדגמה על המיקום שבו האפליקציה פועלת:
{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v1-84b47c7f58-pmgmk", "pod_name_emoji": "💇🏼♀️", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:31:17", "zone": "us-central1-a" }כדי לבדוק את ההתאמה לנתיב, עוברים לגרסה הגרמנית של שירות
storeבכתובתstore.example.com/de:curl https://store.example.com/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -vהפלט מאשר שהבקשה נשלחה על ידי
store-germanPod:{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "Gutentag!", "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal", "pod_name": "store-german-5cb6474c55-lq5pl", "pod_name_emoji": "🧞♀", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:35:37", "zone": "us-central1-a" }שליחת תנועה לגרסת הקנרי של שירות
storeבאמצעות כותרת ה-HTTPenv: canary:curl -H "env: canary" https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -vהפלט מאשר שהבקשה נשלחה על ידי
store-v2Pod:{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v2", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v2-5788476cbd-s9thb", "pod_name_emoji": "👩🏿", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:38:26", "zone": "us-central1-a" }
פריסת שער חיצוני גלובלי
בדוגמה הבאה מוצג איך חושפים אפליקציה בחנות עם כמה אישורים שמצורפים לשער החיצוני הגלובלי ומקובצים במפת אישורים באמצעות Certificate Manager ו-HTTPRoute.
יצירת מיפוי אישורים
Google ממליצה להשתמש בCertificate Manager כדי לנהל אישורים כשצריך 15 אישורים או יותר לכל שער, או כשצריך להשתמש באישור כללי.
אפשר גם לאבטח את שער הכניסה החיצוני באמצעות סודות של Kubernetes או אישורי SSL בניהול Google. מידע נוסף זמין במאמר בנושא אבטחת שערים.
בקטע הזה מוסבר איך ליצור אישורים באמצעות Certificate Manager כדי לאבטח את האפליקציות שפועלות באשכול.
מפעילים את Certificate Manager API:
gcloud services enable certificatemanager.googleapis.comיוצרים מפת אישורים:
gcloud beta certificate-manager maps create store-example-com-mapטוענים את האישור והמפתחות שמנוהלים על ידי Google לתוך אישור:
gcloud beta certificate-manager certificates create store-example-com-cert \ --certificate-file="CERTIFICATE_FILE" \ --private-key-file="PRIVATE_KEY_FILE"מחליפים את מה שכתוב בשדות הבאים:
-
CERTIFICATE_FILE: השם של קובץ האישור. הקובץ חייב לכלול את הסיומת.pem. לדוגמה:cert.pem. PRIVATE_KEY_FILE: השם של קובץ המפתח הפרטי.
מידע נוסף זמין במאמר יצירת מפתח פרטי ותעודה.
-
יוצרים
CertificateMapEntryשמשייך את האישור למיפוי האישורים:gcloud beta certificate-manager maps entries create store-example-com-map-entry \ --map=store-example-com-map \ --hostname=store.example.com \ --certificates=store-example-com-cert
כדי ללמוד איך לאבטח שער באמצעות מקורות אחרים לאישורים, כמו סודות של Kubernetes או אישורי SSL, אפשר לעיין במאמר בנושא אבטחת שער.
יצירת שער
משאב Gateway מייצג מישור נתונים שמנתב תעבורה ב-Kubernetes. שער יכול לייצג סוגים שונים של איזון עומסים וניתוב, בהתאם ל-GatewayClass שבו הוא משתמש.
מידע נוסף על משאב Gateway מופיע בתיאור משאב Gateway או במפרט ה-API.
בקטע הזה יוצרים שער. צוותי אפליקציות יכולים להשתמש ב-Gateway כדי לחשוף את האפליקציות שלהם לאינטרנט על ידי פריסת מסלולים באופן עצמאי וצירוף שלהם ל-Gateway בצורה מאובטחת.
שומרים את המניפסט הבא בקובץ בשם
gateway.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-http annotations: networking.gke.io/certmap: store-example-com-map spec: # This GatewayClass uses a global external Application Load Balancer. gatewayClassName: gke-l7-global-external-managed listeners: - name: https protocol: HTTPS port: 443קובץ המניפסט הזה מתאר שער עם השדות הבאים:
-
gatewayClassName: gke-l7-global-external-managed: מציין את GatewayClass לשער הזה. השער הזה משתמש במאזן עומסים גלובלי חיצוני של אפליקציות (ALB). -
protocol: HTTPSו-port: 443: מציינים ששער הגישה חושף את יציאה 443 לתנועת HTTPS. השדות האלה מאפשרים TLS. -
networking.gke.io/certmap: store-example-com-map: מציין את השם של מיפוי האישורים ב-Certificate Manager.
אין קטע TLS כי TLS מוגדר באמצעות Certificate Manager באמצעות ההערה
networking.gke.io/certmap.-
מחילים את המניפסט על האשכול:
kubectl apply -f gateway.yamlיכול להיות שיחלפו כמה דקות עד ש-GKE יפרוס את המשאבים.
כדי לוודא שהשער נפרס בהצלחה:
kubectl describe gatewayהפלט אמור להיראות כך:
Name: external-http Namespace: default Labels: <none> ... Spec: Gateway Class Name: gke-l7-global-external-managed Listeners: Allowed Routes: Namespaces: From: Same Name: https Port: 443 Protocol: HTTPS Tls: Certificate Refs: Group: Kind: Secret Name: store-example-com Mode: Terminate ...הפלט הזה מראה שלשער שהופעל באשכול יש מאזן עומסים וכתובת IP ציבורית. לשער אין נתיבים, ולכן הוא לא יכול לשלוח תעבורה לשרתי קצה. בלי נתיבים, כל התנועה מועברת לחלק האחורי שמוגדר כברירת מחדל, שמחזיר תגובת HTTP 404. בקטע הבא, פורסים נתיבים שמנחים את שער הכניסה לשלוח תנועה לשרתי קצה.
פריסת אפליקציית ההדגמה
אתם יכולים לפרוס את האפליקציות והמסלולים שלכם בנפרד מהפריסה של שערים.
מידע נוסף על פריסת אפליקציות ההדגמה זמין במאמר פריסת אפליקציות ההדגמה.
יצירת HTTPRoute
כדי להתאים ולסנן תנועה מסוג HTTP ו-HTTPS, צריך ליצור HTTPRoute.
שליחת תנועה לאפליקציה
אחרי שפורסים את האפליקציה ויוצרים HTTPRoutes, אפשר להעביר תנועה לאפליקציה.
מידע נוסף על שליחת תעבורה לאפליקציה זמין במאמר שליחת תעבורה לאפליקציה.
שימוש בשערי גישה משותפים
Gateway API משתמש במשאבים נפרדים, משאבי Gateways ו-Route, כדי לפרוס מאזני עומסים וכללי ניתוב. ההגדרה הזו שונה מ-Ingress, שבה הכול משולב במשאב אחד. ה-Gateway מאפשר לפצל את האחריות בין המשאבים, כך שמאזן העומסים וכללי הניתוב שלו יכולים להיפרס בנפרד, ומשתמשים או צוותים שונים יכולים לפרוס אותם. כך שערים יכולים להפוך לשערים משותפים שמצורפים למסלולים שונים רבים, שאפשר להיות הבעלים שלהם ולנהל אותם על ידי צוותים עצמאיים, גם במרחבי שמות שונים.
פריסת מסלולים מול שער משותף
הדוגמה הזו מבוססת על internal-http השער שנפרס בפריסת שער פנימי.
בדוגמה הזו, צוות האתר פורס את האפליקציה, את השירותים ואת HTTPRoute כדי להתאים את התנועה מהשער לשירותים האלה.
מפעילים את האפליקציה לדוגמה:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/site.yamlשומרים את המניפסט הבא בקובץ בשם
site-route-internal.yaml:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: site-internal spec: # Attach the HTTPRoute to the `internal-http` Gateway. parentRefs: - kind: Gateway name: internal-http # Route requests that have `site.example.com` in the Host header. hostnames: - "site.example.com" # Send all requests to the `site-v1` Service. rules: - backendRefs: - name: site-v1 port: 8080במניפסט הזה מתואר HTTPRoute שתואם לכל התנועה של
site.example.comומנתב אותה לשירותsite-v1.מחילים את המניפסט על האשכול:
kubectl apply -f site-route-internal.yamlמוודאים ש-HTTPRoute מצורף ל-Gateway:
kubectl describe httproute.gateway.networking.k8s.io site-internalהפלט אמור להיראות כך:
Status: Parents: Conditions: Last Transition Time: 2023-01-09T15:05:43Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-01-09T15:05:43Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http ...אם התנאי
Acceptedשל שער הכניסה הואTrue, ה-HTTPRoute נקשר בהצלחה לשער הכניסה. מידע נוסף על השדה 'סטטוס' זמין במאמר בנושא סטטוס המסלול.מוודאים שהתנועה אל שער הכניסה מנותבת בצורה נכונה:
curl -H "host: site.example.com" GATEWAY_IP_ADDRESS curl -H "host: store.example.com" GATEWAY_IP_ADDRESSמחליפים את
GATEWAY_IP_ADDRESSבכתובת ה-IP של השער הפנימי.חובה להשתמש במכונה וירטואלית (VM) באותו ענן וירטואלי פרטי (VPC) כמו שער.
הפלט אמור להיראות כך:
{ "cluster_name": "CLUSTER_NAME", "host_header": "site.example.com", "metadata": "site-v1", "pod_name": "site-v1-5d64fc4d7d-fz6f6", "pod_name_emoji": "👩🏼🍳", "project_id": "PROJECT_ID", "timestamp": "2022-11-02T19:07:01", "zone": "ZONE_NAME" } ... { "cluster_name": "CLUSTER_NAME", "host_header": "store.example.com", "metadata": "store-v1", "pod_name": "store-v1-6d8d58d78-vz8pn", "pod_name_emoji": "🧝🏻♂️", "project_id": "PROJECT_ID", "timestamp": "2022-11-02T19:07:01", "zone": "ZONE_NAME" }הפלט הזה מציין שבקשות עם כותרת המארח
site.example.comמגיעות לשירותsite-v1, ובקשות עם כותרת המארחstore.example.comמגיעות לשירותstore-v1.
הגדרת מסלול רשת
כדי לציין את מסלול הרשת של כתובת מאזין של מאזן עומסים חיצוני אזורי של אפליקציות, משתמשים בשדה type במערך addresses[] בהגדרת שער. אם לא מציינים מסלול רשת, כברירת מחדל מוגדרת כתובת IP ארעית במסלול הרגיל לשער.
משתמשים בערכים הבאים בשדה type:
-
networking.gke.io/premium-ephemeral-ipv4-address: מקצה כתובת IP ברמת פרימיום. -
networking.gke.io/standard-ephemeral-ipv4-address: מקצה כתובת IP ברמה Standard.
כדי להקצות כתובות IP משני מסלולי הרשת, מציינים את שני הסוגים בשדה addresses.
בדוגמה הבאה אפשר לראות איך מקצים כתובת IP במסלול פרימיום לשער. Google Cloud כדי להקצות כתובת IP במסלול הרגיל, משתמשים ב-networking.gke.io/standard-ephemeral-ipv4-address.
שומרים את קובץ המניפסט לדוגמה הבא בשם
external-regional-http.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-regional-http spec: # Name of an existing GatewayClass. gatewayClassName: gke-l7-regional-external-managed # Listen for HTTPS traffic on port 443. listeners: - name: https protocol: HTTPS port: 443 tls: # Terminate the TLS session with the client at the Gateway. mode: Terminate # Certificates for the Gateway to use to create a new TLS session. certificateRefs: - name: store-example-com addresses: # Request a Premium Tier ephemeral IPv4 address for the Gateway. - type: networking.gke.io/premium-ephemeral-ipv4-addressמחילים את קובץ המניפסט לדוגמה:
kubectl apply -f external-regional-http.yaml
הגדרת קצה עורפי שמוגדר כברירת מחדל בשער
כל ה-GatewayClasses מחזירים HTTP 404 לתנועה שלא תואמת.gke-l7-* אפשר להגדיר את קצה העורף (backend) שמוגדר כברירת מחדל באמצעות מסלול ברירת מחדל מפורש ששולח תנועה שלא תואמת לשום מסלול לשירות שסופק על ידי המשתמש.
הגדרנו את השערים כך שיטפלו בקודי שגיאה כמו 404 (לא נמצא) ו-500 (שגיאה בחיבור לשרת), גם ללא הגדרות ספציפיות של קצה העורפי. ההתנהגות שמוגדרת כברירת מחדל עשויה להשתנות בין הטמעות שונות של Gateway. כדי לשלוט טוב יותר בטיפול בשגיאות, כדאי להגדיר קצה עורפי בהתאמה אישית.
ה-HTTPRoute הבא הוא דוגמה לאופן שבו אפשר להתאים אישית את ה-backend שמוגדר כברירת מחדל. אם מחילים HTTPRoute שדומה לזה שבהמשך, הוא מקבל עדיפות על פני קצה העורפי (backend) שמוגדר כברירת מחדל באופן מרומז:
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: custom-default-backend
spec:
parentRefs:
- kind: Gateway
name: my-internal-gateway
# Omit the `hostnames` field to route all unmatched traffic from the
# attached Gateway.
rules:
- backendRefs:
- name: my-custom-default-backend-service
port: 8080
ה-HTTPRoute הזה תואם לכל התנועה משער מסוים. אפשר להגדיר רק כלל אחד כזה לכל שער, אחרת הכללים יתנגשו וסדר העדיפות יחול.
אפשר להשתמש בשרת קצה עורפי שמוגדר כברירת מחדל כדי למנוע יצירה של נתיב ברירת מחדל Backend שמנתב את כל התנועה של שער. ל-HTTPRoute מפורש תמיד יש עדיפות על פני HTTPRoute חדש עם כללי ניתוב סותרים.
הגדרת כתובת IP סטטית לשער
לכל שער יש כתובת IP שמשמשת אותו להאזנה לתנועה. אם לא מציינים כתובת IP בשער, בקר השער מספק כתובת IP באופן אוטומטי. אפשר גם ליצור כתובת IP סטטית, כך שכתובת ה-IP תתקיים ללא תלות במחזור החיים של שער.
אחרי פריסת שער, כתובת ה-IP שלו מוצגת בשדה הסטטוס:
kind: Gateway
...
status:
addresses:
- value: 10.15.32.3
בהתאם ל-GatewayClass, כתובת ה-IP מוקצית מתת-הרשתות הבאות:
| GatewayClasses | מאגר כתובות IP שמוגדר כברירת מחדל |
|---|---|
|
|
כתובות IP פרטיות אזוריות מטווח כתובות ה-IPv4/IPv6 של הצומת הראשי |
|
|
כתובות IP ציבוריות אזוריות מטווחים אזוריים של כתובות IPv4/IPv6 חיצוניות של Google |
|
|
כתובות IP ציבוריות גלובליות מטווחים גלובליים של IPv4/IPv6 חיצוניים של Google |
בשדה addresses.NamedAddress אפשר לציין כתובת IP בנפרד מהשער. אפשר ליצור משאב של כתובת IP סטטית לפני פריסת השער, והמשאב מפנה אל NamedAddress. אפשר לעשות שימוש חוזר בכתובת ה-IP הסטטית גם אם שער ברירת המחדל נמחק.
שימוש בכתובת IP עם שם
אפשר להגדיר כתובת IPv4 או IPv6 על ידי ציון NamedAddress. צריך להקצות כתובת IP סטטית לפני שיוצרים שער.
יוצרים משאב של כתובת IP סטטית:
gcloud compute addresses create IP_ADDRESS_NAME \ --purpose=SHARED_LOADBALANCER_VIP \ --region=COMPUTE_REGION \ --subnet=SUBNET \ --project=PROJECT_IDמחליפים את מה שכתוב בשדות הבאים:
-
IP_ADDRESS_NAME: השם של כתובת ה-IP הסטטית החדשה -
COMPUTE_REGION: עבור שערים אזוריים, האזור ב-Compute Engine שבו האשכול פועל. לא צריך להשתמש בדגל הזה בשערים גלובליים חיצוניים. -
SUBNET: רשת המשנה של כתובת ה-IP. לא צריך להשתמש בדגל הזה בשערים גלובליים חיצוניים. -
PROJECT_ID: הפרויקט שבו פועל אשכול GKE.
-
שומרים את המניפסט הבא בקובץ בשם
named-ip-gateway.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: internal-http spec: gatewayClassName: gke-l7-rilb listeners: - name: http protocol: HTTP port: 80 addresses: - type: NamedAddress value: IP_ADDRESS_NAMEהמניפסט הזה מתאר שער שמפנה לכתובת ה-IP שצוינה בשם.
מחילים את המניפסט על האשכול:
kubectl apply -f named-ip-gateway.yamlמאמתים את כתובת ה-IP של השער:
kubectl describe gateway internal-httpהפלט אמור להיראות כך:
Name: internal-http Namespace: default Labels: <none> ... Spec: Addresses: Type: NamedAddress Value: IP_ADDRESS_NAME Gateway Class Name: gke-l7-rilb Listeners: Allowed Routes: Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 10.15.32.103
הגדרת הפניות אוטומטיות מ-HTTP ל-HTTPS
ב-Cloud Load Balancing יש פונקציונליות של הפניה אוטומטית מ-HTTP ל-HTTPS. מאזן עומסים חיצוני של אפליקציות מפנה בקשות HTTP לא מוצפנות למאזן עומסים של HTTPS שמשתמש באותה כתובת IP. כשיוצרים שער עם הפניות אוטומטיות מ-HTTP ל-HTTPS, שני מאזני העומסים האלה נוצרים אוטומטית. בקשות לכתובת ה-IP החיצונית של השער ביציאה 80 מופנות אוטומטית לאותה כתובת IP חיצונית ביציאה 443.
כברירת מחדל, הפניות מ-HTTP ל-HTTPS לא מוגדרות בשער.
כדי להפנות תנועת HTTP באופן אוטומטי אל HTTPS, צריך להגדיר Gateway שיטפל בתנועת HTTP ובתנועת HTTPS. אם משביתים את HTTP או את HTTPS, השער לא מפנה תנועה באופן אוטומטי.
בדוגמה הבאה מוצג איך אפשר להשתמש בהפניה אוטומטית מ-HTTP ל-HTTPS כדי לוודא שהתנועה מהלקוחות לאפליקציות האינטרנט תמיד מופנית לדף מאובטח.
אין תמיכה בהפניות אוטומטיות מ-HTTP ל-HTTPS ב-GatewayClasses gke-l7-gxlb ו-gke-l7-gxlb-mc. מידע נוסף על התכונות השונות שנתמכות בכל GatewayClass זמין במאמר יכולות של GatewayClass.
שימו לב: הקטע hostnames ב-HTTPRoute הוא אופציונלי. אפשר ליצור הפניה כללית לכל שמות המארחים ביציאת HTTP ספציפית על ידי השמטת הקטע hostnames. בנוסף, אפשר להשתמש בהפניה אוטומטית עם תו כללי, לדוגמה:
...
hostnames:
- "*.example.com" # Matches all subdomains of example.com
...
הפניית תנועת HTTP ממרחב שמות של תשתית
במקרים מסוימים, אין הבחנה ברורה בין צוות האדמינים של התשתית או הפלטפורמה לבין צוותי האפליקציות, ולכן יכול להיות קשה למנוע שימוש לרעה בשער.
בדוגמה הבאה מוצגת הגבלה נוספת של השימוש במאזין HTTP כדי למנוע שימוש לא מכוון בפרוטוקול לא מאובטח מצד צוותי האפליקציה. בדוגמה הזו מוגדר שער שיאפשר ל-HTTPRoute להשתמש במאזין HTTP רק אם המסלול נמצא במרחב שמות עם התווית otherInfra: httpToHttps. עם זאת,
השער מאפשר ל-HTTPRoutes בכל מרחב שמות להשתמש במאזין HTTPS. אפשר להגביל את מרחב השמות http-redirect באמצעות Kubernetes RBAC, כדי שצוותי פיתוח אפליקציות לא יוכלו ליצור בטעות HTTPRoute במרחב השמות הזה.
יוצרים את מרחב השמות של שער. שומרים את קובץ המניפסט בשם
gateway-namespace.yaml:apiVersion: v1 kind: Namespace metadata: name: gateway-infraהחלת המניפסט:
kubectl apply -f gateway-namespace.yamlיוצרים את מרחב השמות של שער ושומרים את המניפסט כ-
redirect-namespace.yaml:apiVersion: v1 kind: Namespace metadata: name: http-redirect labels: otherInfra: httpToHttpsמרחב השמות
http-redirectכולל את התוויתotherInfra: httpToHttps.החלת המניפסט:
kubectl apply -f redirect-namespace.yamlכדי להגביל את השימוש במאזין ה-http, יוצרים שער באמצעות המניפסט הבא. שומרים את קובץ המניפסט בשם
external-gateway.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-http namespace: gateway-infra spec: # Name of an existing GatewayClass. gatewayClassName: gke-l7-global-external-managed listeners: - name: http protocol: HTTP port: 80 # Allow only HTTPRoutes from namespaces that have the # `otherInfra: httpToHttps` label to use this listener. allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: Selector selector: matchLabels: otherInfra: httpToHttps - name: https protocol: HTTPS port: 443 # Allow HTTPRoutes from any namespace to use this listener. allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: store-example-comהשדה
namespaceמציין שהשער נוצר במרחב השמותgateway-infra.השדה
namespacesבקטעallowedRoutesמגביל את מאזין ה-HTTP למרחב השמות שתואם לתוויתotherInfra: httpToHttps.
החלת המניפסט:
kubectl apply -f external-gateway.yamlכדי לכפות את ההפניה האוטומטית ל-HTTPS, יוצרים HTTPRoute שמוגדר כברירת מחדל באמצעות המניפסט הבא. שומרים את קובץ המניפסט בשם
http-redirect.yaml:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: redirect # Create the HTTPRoute in the `http-redirect` namespace. namespace: http-redirect spec: # Attach the HTTPRoute to the `http` listener in the `external-http` # Gateway. parentRefs: - namespace: gateway-infra name: external-http sectionName: http rules: # Respond to the request with an HTTPS redirection. - filters: - type: RequestRedirect requestRedirect: scheme: https- השדה
sectionNameמורה ל-Gateway להתאים רק ל-http listener. המסנןRequestRedirectכופה את ההפניה למאזין https.
- השדה
החלת המניפסט:
kubectl apply -f http-redirect.yamlיוצרים שירות לאפליקציה באמצעות המניפסט הבא. שומרים את קובץ המניפסט בשם
service-deployment.yaml:apiVersion: v1 kind: Service metadata: name: store-v1 spec: selector: app: store version: v1 ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: store-v1 spec: replicas: 2 selector: matchLabels: app: store version: v1 template: metadata: labels: app: store version: v1 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080 env: - name: METADATA value: "store-v1"החלת המניפסט:
kubectl apply -f service-deployment.yamlיוצרים HTTPRoute לאפליקציה שמאפשרת רק HTTPS באמצעות המניפסט הבא. שומרים את קובץ המניפסט בשם
http-route.yaml:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store-external labels: gateway: external-http spec: # Attach the HTTPRoute to the HTTPS listener in the `external-http` # Gateway. parentRefs: - name: external-http namespace: gateway-infra sectionName: https # Match requests that have the `store.example.com` Host header. hostnames: - "store.example.com" # Route requests to the `store-v1` Service. rules: - backendRefs: - name: store-v1 port: 8080החלת המניפסט:
kubectl apply -f http-route.yaml
הגדרת הפניות אוטומטיות של נתיבים ושכתוב של כתובות URL
הפניות אוטומטיות של נתיבים כוללות הפניה אוטומטית של בקשה נכנסת מנתיב אחד של כתובת URL לנתיב אחר. הפניות נתיב מאפשרות לשנות את מבנה כתובת ה-URL כשצריך לטפל בכתובות URL לא עדכניות או שהוצאו משימוש.
שינוי כתובות URL עוזר לשנות את כתובת ה-URL הנכנסת לפני העיבוד שלה בשרת. היא מאפשרת לכם לשנות את המבנה או הפורמט של כתובת ה-URL בלי לשנות את התוכן הבסיסי או את מבנה הקובץ. כתיבה מחדש של כתובות URL מועילה ליצירת כתובות URL ידידותיות למשתמש וידידותיות לקידום אתרים, שקל לזכור ולהבין. כברירת מחדל, הפניות אוטומטיות של נתיבים ושכתוב של כתובות URL לא מוגדרים, ולכן צריך להגדיר אותם באופן מפורש באמצעות מסנן ב-HTTPRoute.
GKE Gateway תומך בהפניות אוטומטיות של נתיבים ובשכתוב של כתובות URL. מידע נוסף זמין במאמר הפניות לכתובת אחרת ושכתוב של נתיבי HTTP.
הגדרת הפניות אוטומטיות של נתיבים
אפשר להגדיר הפניות אוטומטיות של נתיבים כך שיחליפו את הנתיב כולו או רק קידומת בכתובת ה-URL.
החלפת הנתיב כולו
כדי להחליף נתיב שלם, מגדירים מסנן ב-HTTPRoute שמחליף כל כתובת URL שמכילה את הקידומת
/any-pathבנתיב כתובת ה-URL בערך המדויק/new-path.יוצרים קובץ מניפסט
HTTPRouteבאופן הבא ונותנים לו את השםstore.yaml:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: store spec: parentRefs: - kind: Gateway name: external-http hostnames: - store.example.com rules: - matches: - path: # Match requests by a prefix, like `/any-path` and `/any-path/home`. type: PathPrefix value: /any-path filters: - type: RequestRedirect requestRedirect: path: # Replace the full path with `/new-path`. For example, both # `/any-path/home` and `/any-path` become `/new-path`. type: ReplaceFullPath replaceFullPath: /new-path statusCode: 302לדוגמה, במניפסט הזה מוגדר כלל ניתוב ל-HTTPRoute באופן הבא: כל ניתוב לכתובת ה-URL
https://store.example.com/any-path/...צריך להיות מופנה למיקום חדש,https://store.example.com/new-path/(strict).החלת המניפסט:
kubectl apply -f store.yaml
כלל הניתוב הזה פועל לפי כלל הפניה קפדני, כלומר הדפדפן לא מנסה לשמור במטמון את ההפניה, אלא מפנה לגרסה העדכנית ביותר.
החלפת קידומת בלבד
כדי להחליף רק קידומת, מגדירים מסנן ב-HTTPRoute שמחליף כל כתובת URL שמכילה את הקידומת
/any-prefixבנתיב כתובת ה-URL בערך המדויק/new-prefix.יוצרים קובץ מניפסט
HTTPRouteבאופן הבא ונותנים לו את השםstore.yaml:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: store spec: parentRefs: - kind: Gateway name: external-http hostnames: - store.example.com rules: - matches: - path: # Match requests by prefix, like `/any-prefix` and # `/any-prefix/home`. type: PathPrefix value: /any-prefix filters: - type: RequestRedirect requestRedirect: path: # Replace the matched prefix with `/new-prefix`. For example, # `/any-prefix` becomes `/new-prefix` and `/any-prefix/home` # becomes `/new-prefix/home`. type: ReplacePrefixMatch replacePrefixMatch: /new-prefix statusCode: 302לדוגמה, במניפסט הזה מוגדר כלל ניתוב ל-HTTPRoute באופן הבא: כל ניתוב לכתובת ה-URL
https://store.example.com/any-path/v1/...צריך להיות מופנה למיקום חדש,https://store.example.com/new-path/v1/...(בלבד).החלת המניפסט:
kubectl apply -f store.yaml
כלל הניתוב הזה פועל לפי כלל ההפניה האוטומטית היחיד, וכך עוזר לוודא שהדפדפן תמיד יפנה אתכם לאותו דף שהתכוונתם להגיע אליו.
הגדרת כתיבה מחדש של כתובות URL
הגדרת כתיבה מחדש של כתובות URL כדי לשנות את האופן שבו כתובת URL מוצגת למשתמשים. אפשר להשתמש בשכתוב כתובות URL כדי להפוך אותן לידידותיות יותר למשתמשים, כדי לשפר את ה-SEO או כדי להפנות משתמשים לדף חדש.
לשכתב את שם המארח כולו
כדי לשכתב את שם המארח כולו:
מגדירים מסנן ב-HTTPRoute שמורה ל-Gateway להחליף את המידע
Hostבכותרת הבקשה מ-www.example.comל-store.example.comלפני העברת הבקשה לשירות לקצה העורפי.יוצרים קובץ מניפסט
HTTPRouteבאופן הבא ונותנים לו את השםwww.yaml:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: www spec: parentRefs: - kind: Gateway name: external-http hostnames: - www.example.com rules: - filters: - type: URLRewrite # Replace the hostname in the URL with `store.example.com`. urlRewrite: hostname: store.example.com backendRefs: - name: store-v1 port: 8080לדוגמה, עם ההגדרה שלמעלה, כל בקשה אל
https://www.example.comמועברת לשירות לקצה העורפי עם הכותרתHost: store.example.com, במקוםHost: www.example.com.החלת המניפסט:
kubectl apply -f www.yaml
שינוי הכתיבה באמצעות משני נתיבים
אפשר לשלב שכתובים עם משני נתיבים כדי לספק שינויים מתקדמים בכתובות URL ובנתיבים לפני העברת הבקשה לשירות לקצה העורפי.
כדי לשכתב באמצעות משני נתיבים:
מגדירים מסנן ב-HTTPRoute שמורה ל-Gateway להחליף את פרטי ה-Host בכותרת הבקשה מ-www.example.com
to store.example.comולהחליף את הערך/storeב-/לפני העברת הבקשה לשירות הקצה העורפי.יוצרים קובץ מניפסט
HTTPRouteבאופן הבא ונותנים לו את השםwww.yaml:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: www spec: parentRefs: - kind: Gateway name: external-http hostnames: - www.example.com rules: - matches: - path: type: PathPrefix value: /store filters: - type: URLRewrite # For URLs that have `/store` in the path, replace the hostname with # store.example.com and replace the `/store` prefix with `/de`. urlRewrite: hostname: store.example.com path: type: ReplacePrefixMatch replacePrefixMatch: /de backendRefs: - name: store-german port: 8080לדוגמה, עם ההגדרה שלמעלה, כל בקשה אל
https://www.example.com/store/...מועברת לשירות לקצה העורפי עםHost: store.example.comבכותרת הבקשה (במקוםHost: www.example.com), ו-/storeנכתב מחדש כ-/de.החלת המניפסט:
kubectl apply -f www.yaml
אימות ההגדרות את ההגדרות
כדי לוודא שהמסנן הוחל אחרי שיצרתם את ה-HTTPRoute עם מסנני שכתוב כתובות URL או הפניות אוטומטיות של נתיבים, צריך לבצע את הפעולות הבאות:
kubectl get httproute www -o yaml
הפלט אמור להיראות כך:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"gateway.networking.k8s.io/v1","kind":"HTTPRoute","metadata":{"annotations":{},"name":"www","namespace":"default"},"spec":{"hostnames":["www.example.com"],"parentRefs":[{"kind":"Gateway","name":"external-http"}],"rules":[{"backendRefs":[{"name":"store-german","port":8080}],"filters":[{"type":"URLRewrite","urlRewrite":{"hostname":"store.example.com","path":{"replacePrefixMatch":"/de","type":"ReplacePrefixMatch"}}}],"matches":[{"path":{"type":"PathPrefix","value":"/store"}}]}]}}
creationTimestamp: "2023-06-22T01:00:42Z"
generation: 3
name: www
namespace: default
resourceVersion: "51268631"
uid: e516493e-806d-44d6-ae0d-1c9ff25682cf
spec:
hostnames:
- www.example.com
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: external-http
rules:
- backendRefs:
- group: ""
kind: Service
name: store-german
port: 8080
weight: 1
filters:
- type: URLRewrite
urlRewrite:
hostname: store.example.com
path:
replacePrefixMatch: /de
type: ReplacePrefixMatch
matches:
- path:
type: PathPrefix
value: /store
status:
parents:
- conditions:
- lastTransitionTime: "2023-06-22T01:11:26Z"
message: ""
observedGeneration: 2
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2023-06-22T01:11:26Z"
message: ""
observedGeneration: 2
reason: ReconciliationSucceeded
status: "True"
type: Reconciled
controllerName: networking.gke.io/gateway
parentRef:
group: gateway.networking.k8s.io
kind: Gateway
name: external-http
כדי לקבל פרטים נוספים, משתמשים בפקודה describe:
kubectl describe httproute
הגדרת כותרות מותאמות אישית של בקשות ותגובות
כותרות מותאמות אישית של בקשות ותגובות מאפשרות לכם לציין כותרות נוספות לבקשות ולתגובות של HTTP(S). בהתאם למידע שזוהה על ידי מאזן העומסים, הכותרות האלה יכולות לכלול את המידע הבא:
- זמן האחזור ללקוח
- המיקום הגיאוגרפי של כתובת ה-IP של הלקוח
- פרמטרים של חיבור TLS
כברירת מחדל, לא מתווספות כותרות מותאמות אישית לבקשה שנשלחת אל שירותי הקצה העורפיים או מתקבלת מהם. צריך להגדיר במפורש כותרות מותאמות אישית באמצעות מסנן ב-HTTPRoute.
כדי להגדיר כותרות בהתאמה אישית, מוסיפים קטע של מסנן לכללים של HTTPRoute באופן הבא:
הגדרת כותרות בקשות בהתאמה אישית
יוצרים מניפסט HTTPRoute עם מסנן RequestHeaderModifier ושומרים אותו בשם
http-route-request.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store
spec:
<...>
rules:
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
<...>
החלת המניפסט:
kubectl apply -f http-route-request.yaml
הגדרת כותרות תגובה מותאמות אישית
יוצרים מניפסט HTTPRoute עם מסנן ResponseHeaderModifier ושומרים אותו בשם
http-route-response.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store
spec:
<...>
rules:
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
<...>
החלת המניפסט:
kubectl apply -f http-route-response.yaml
אפשר להוסיף, להגדיר ולהסיר כותרות כמו שמתואר במאמר בנושא הטמעה של Gateway API. אפשר להגדיר את HTTPRoute עם כותרת בהתאמה אישית באמצעות Google Cloud משתנים נתמכים.
דוגמה 1:
כדי להגדיר HTTPRoute שמוסיף פרטי מיקום של לקוח לבקשת HTTP לפני שליחתה לשירות הקצה העורפי, יוצרים מניפסט HTTPRoute ונותנים לו את השם external-http-request.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store
spec:
parentRefs:
- kind: Gateway
name: external-http
hostnames:
- store.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /fr
filters:
# Add custom headers to requests that have `/fr` in the path.
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Client-Geo-Location
value: "{client_region},{client_city}"
backendRefs:
- name: store-french
port: 8080
לדוגמה, עבור לקוחות שממוקמים בשטרסבורג שבצרפת, שער הכניסה מוסיף כותרת בתור X-Client-Geo-Location:FR,Strasbourg.
דוגמה 2:
כדי להגדיר HTTPRoute שמוסיף כותרת תגובה מותאמת אישית לתמיכה ב-HTTP
Strict Transport Security, יוצרים מניפסט HTTPRoute ונותנים לו את השם
external-http-response.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store
spec:
parentRefs:
- kind: Gateway
name: external-http
hostnames:
- store.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /de
filters:
# Add custom headers to responses to requests that have `/de` in the
# path.
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: Strict-Transport-Security
value: max-age=63072000
backendRefs:
- name: store-german
port: 8080
אימות ההגדרות את ההגדרות
כדי לאמת את ההגדרה אחרי הגדרת כותרות מותאמות אישית של בקשות ותגובות:
kubectl get httprouteהפלט אמור להיראות כך:
NAME HOSTNAMES AGE store ["store.example.com"] 4d23hכדי לקבל פרטים נוספים, משתמשים בפקודה describe:
kubectl describe httprouteהפלט אמור להיראות כך:
Name: store Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1 Kind: HTTPRoute Metadata: Creation Timestamp: 2023-05-27T00:51:01Z Generation: 5 Resource Version: 25418887 UID: 2e07a1b8-420b-41b4-acd1-cecbfcd39f42 Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Filters: Request Header Modifier: Add: Name: X-Client-Geo-Location Value: {client_region},{client_city} Type: RequestHeaderModifier Matches: Path: Type: PathPrefix Value: /de Status: <...>
הגדרת mTLS בקצה הקדמי
כדי להפעיל אימות באמצעות אישורי לקוח, מאזן העומסים של Google Application מספק mTLS בחזית. ב-GKE Gateways, mTLS בחזית מאפשר לכם להגדיר ולאכוף אימות של אישורי לקוח על כל המשאבים הנתמכים, בין אם הם גלובליים או אזוריים.GatewayClass מידע נוסף זמין במאמר הגדרת mTLS בחזית של שער.
הגדרת TLS בקצה העורפי
TLS מאומת ב-Backend הוא תכונת אבטחה שמאפשרת למאזן העומסים של GKE Gateway לאמת את הזהות של ה-Backends שהוא מתחבר אליהם. ב-GKE Gateways, הפונקציונליות הזו מאפשרת להגדיר אימות של אישורי בק-אנד ולהחיל אותו על GatewayClasses נתמכים, כמו מאזני עומסים מנוהלים חיצוניים גלובליים או אזוריים ומאזני עומסים פנימיים אזוריים.
מידע נוסף זמין במאמר בנושא אבטחת שער.
סטטוס המסלול
משאבי HTTPRoute פולטים תנאים ואירועים כדי לעזור למשתמשים להבין אם HTTPRoute נקשר בהצלחה לשער אחד או יותר, או אם הוא נדחה.
תנאים של HTTPRoute
תנאי HTTPRoute מציינים את הסטטוס של המסלול והשערים שהוא מקושר אליהם. מכיוון שנתיב יכול להיות קשור לכמה שערים, זוהי רשימה של שערים והתנאים הנפרדים בין הנתיב לכל שער.
-
Accepted=Trueמציין ש-HTTPRoute נקשר בהצלחה ל-Gateway. -
Accepted=Falseמציין ש-HTTPRoute נדחה מקישור ל-Gateway הזה.
אם אין שערים שמופיעים מתחת לכותרת Gateway bindings, יכול להיות שתוויות ה-HTTPRoute ובוררי התוויות של השער לא תואמים. מצב כזה יכול לקרות אם אף שער לא בוחר את המסלול שלכם.
אירועים של HTTPRoute
אירועי HTTPRoute מספקים פרטים על הסטטוס של HTTPRoute. האירועים מקובצים לפי הסיבות הבאות:
ADDאירועים מופעלים כשמוסיפים משאב.- אירועי
UPDATEמופעלים כשמשאב מתעדכן. - אירועי
SYNCמופעלים על ידי התאמה תקופתית.
מיזוג מסלולים, קדימות ואימות
קדימות של מסלולים
Gateway API מגדיר כללי עדיפות מחמירים לגבי האופן שבו תנועה מותאמת ל-Routes עם כללי ניתוב חופפים. הקדימות בין שני נתיבי HTTP חופפים היא כדלקמן:
- מיזוג של שמות מארחים: ההתאמה הארוכה או הספציפית ביותר של שם המארח.
- מיזוג נתיבים: ההתאמה לנתיב הארוך או הספציפי ביותר.
- מיזוג כותרות: המספר הגדול ביותר של כותרות HTTP שתואמות.
- התנגשות: אם שלוש ההגדרות הקודמות לא קובעות סדר עדיפות, סדר העדיפות נקבע לפי משאב HTTPRoute עם חותמת הזמן הכי ישנה.
מיזוג מסלולים
ב-gke-l7 GatewayClasses, כל ה-HTTPRoutes של Gateway נתון ממוזגים לתוך אותה מפת URL. אופן המיזוג של HTTPRoutes תלוי בסוג החפיפה בין HTTPRoutes. אפשר לפצל את ה-HTTPRoute מהדוגמה הקודמת לשלושה HTTPRoute נפרדים כדי להמחיש את מיזוג המסלולים ואת סדר העדיפויות:
- מיזוג של נתיבים: כל שלושת נתיבי ה-HTTP מחוברים לאותו
internal-httpGateway, ולכן הם ממוזגים יחד. - מיזוג של שמות מארחים: כל שלושת המסלולים תואמים ל-
store.example.com, ולכן כללי שם המארח שלהם ממוזגים. - מיזוג נתיבים: הנתיב store-german-route ספציפי יותר
/de, ולכן הוא לא מתמזג עם נתיבים אחרים. הנתיבים store-v1-route ו-store-v2-route תואמים גם הם לנתיב/*, ולכן הם מתמזגים עם הנתיב. - מיזוג כותרות: ל-store-v2-route יש קבוצה ספציפית יותר של התאמות של כותרות HTTP מאשר ל-store-v1-route, ולכן הן לא ממוזגות יותר.
- התנגשות: מכיוון שאפשר למזג את המסלולים לפי שם המארח, הנתיב והכותרות, אין התנגשויות וכל כללי הניתוב חלים על התנועה.
ה-HTTPRoute היחיד שבו נעשה שימוש בדוגמה הקודמת שווה ערך לשלושת המסלולים הנפרדים האלה:
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: store-v1-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- backendRefs:
- kind: Service
name: store-v1
port: 8080
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: store-v2-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- matches:
- headers:
- type: Exact
name: env
value: canary
backendRefs:
- kind: Service
name: store-v2
port: 8080
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: store-german-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /de
backendRefs:
- kind: Service
name: store-german
port: 8080
Kubernetes Gateways ו-Istio Gateways
שימו לב של-Kubernetes Gateway API ול-Istio API יש משאב בשם Gateway. למרות שהם מבצעים פונקציות דומות, הם לא אותו משאב. אם אתם משתמשים ב-Istio וב-Gateway API באותו אשכול Kubernetes, השמות האלה חופפים כשמשתמשים ב-kubectl בשורת הפקודה.
יכול להיות שהפונקציה kubectl get gateway תחזיר את משאבי Kubernetes Gateway ולא את משאבי Istio Gateway, או להיפך.
$ kubectl api-resources
NAME SHORTNAMES APIGROUP NAMESPACED KIND
gateways gw networking.istio.io/v1beta1 true Gateway
gateways gtw networking.k8s.io/v1beta1 true Gateway
אם אתם משתמשים ב-Istio ומשדרגים ל-GKE 1.20 ואילך, מומלץ להתחיל להשתמש בשם הקצר של משאב Gateway או לציין את קבוצת ה-API. השם הקצר של שער Kubernetes הוא gtw והשם הקצר של שער Istio הוא gw. הפקודות הבאות מחזירות את משאבי Kubernetes Gateway ו-Istio Gateway בהתאמה.
# Kubernetes Gateway
$ kubectl get gtw
NAME CLASS
multi-cluster-gateway gke-l7-global-external-managed-mc
$ kubectl get gateway.networking.x-k8s.io
NAME CLASS
multi-cluster-gateway gke-l7-global-external-managed-mc
# Istio Gateway
$ kubectl get gw
NAME AGE
bookinfo-gateway 64m
$ kubectl get gateway.networking.istio.io
NAME AGE
bookinfo-gateway 64m
פתרון בעיות
חסרה רשת משנה של שרת proxy בלבד באזור
תסמין:
יכול להיות שתיתקלו בבעיה הבאה כשתיצרו שער אזורי (פנימי או חיצוני):
generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/[REGION_NAME]/targetHttpProxies/gkegw-x5vt-default-internal-http-[ID]'. A reserved managed proxy subnetwork with purpose REGIONAL_MANAGED_PROXY is required.
הסיבה:
הודעת השגיאה הזו מציינת שאין רשת משנה של פרוקסי בלבד באזור של השער.
פתרון עקיף:
כדי לפתור את הבעיה, צריך להגדיר רשת משנה (subnet) לשרת proxy בלבד.
כבר קיימת רשת משנה לשרת proxy באזור עם מטרה שגויה
תסמין:
יכולה להתרחש הבעיה הבאה כשיוצרים רשת משנה מסוג proxy בלבד עבור שער אזורי (פנימי או חיצוני):
ERROR: (gcloud.compute.networks.subnets.create) Could not fetch resource:
- The resource 'projects/[PROJECT_NAME]/regions/[REGION_NAME]/subnetworks/[PROXY_ONLY_SUBNET_NAME]' already exists
הסיבה:
הודעת השגיאה הזו מציינת שניסיתם ליצור תת-רשת אזורית מסוג proxy בלבד באזור שכבר יש בו תת-רשת מסוג proxy בלבד.
פתרון עקיף:
כדי לפתור את הבעיה, מבצעים את השלבים הבאים:
בודקים שרשת משנה של פרוקסי בלבד כבר קיימת באזור, ומוודאים שהמטרה שלה נכונה:
מציגים את רשימת רשתות המשנה כדי לראות איזו מהן היא רשת המשנה של שרת proxy בלבד באזור:
gcloud compute networks subnets list --regions=COMPUTE_REGIONמחליפים את
COMPUTE_REGIONבאזור Compute Engine שבו רוצים ליצור את השער האזורי.כדי להבין את המטרה של רשת המשנה שמוגדרת רק לשרת proxy, צריך לתאר אותה באזור:
gcloud compute networks subnets describe PROXY_ONLY_SUBNET \ --region COMPUTE_REGION | grep -E 'name|purpose'מחליפים את
PROXY_ONLY_SUBNETברשת המשנה של ה-proxy בלבד.
GKE Gateway תומך רק ברשתות משנה של
REGIONAL_MANAGED_PROXYproxy-only עבור שערים אזוריים (פנימיים או אזוריים).אם רשת המשנה הקיימת באזור שמוגדרת רק לשימוש בשרת proxy נוצרה עם
INTERNAL_HTTPS_LOAD_BALANCERמטרה, צריך להעביר את המטרה שלה ל-REGIONAL_MANAGED_PROXY.
אין מקור תקין
תסמין:
הבעיה הבאה עלולה להתרחש כשיוצרים שער אבל אין גישה לשירותי הקצה העורפי (קוד תגובה 503):
no healthy upstream
הסיבה:
הודעת השגיאה הזו מציינת שכלי הבדיקה של בדיקת תקינות לא יכול למצוא שירותי קצה עורפיים תקינים. יכול להיות שהשירותים שלכם בבק-אנד תקינים, אבל תצטרכו להתאים אישית את בדיקות התקינות.
פתרון עקיף:
כדי לפתור את הבעיה, צריך להתאים אישית את בדיקת תקינות על סמך הדרישות של האפליקציה (לדוגמה, /health) באמצעות HealthCheckPolicy.
משאבי Gateway יתומים אחרי מחיקת אשכול
תסמין:
כשמנסים ליצור מחדש את שער הכניסה, משאבי איזון העומסים שמנוהלים על ידי GKE עדיין מוצגים במסוף Google Cloud , אבל אי אפשר למחוק אותם באמצעות ממשק המשתמש. מוצגת הודעה שדומה להודעה הבאה:
This load balancing service is read-only. It is managed by GKE and can be modified only by GKE.
הסיבה:
הבעיה הזו מתרחשת כשבקר השער לא מצליח לנקות את המשאבים הבסיסיים המיושנים במהלך מחיקה ויצירה מחדש של אשכול או שער. Google Cloud
פתרון עקיף:
כדי לפתור את הבעיה, מוחקים את משאבי איזון העומסים היתומים באמצעות פקודות Google Cloud CLI באופן הבא:
gcloud compute forwarding-rules delete FORWARDING_RULE_NAME
# For HTTP proxies
gcloud compute target-http-proxies delete PROXY_NAME
# For HTTPS proxies
gcloud compute target-https-proxies delete PROXY_NAME
gcloud compute url-maps delete URL_MAP_NAME
# For global backend services
gcloud compute backend-services delete BACKEND_SERVICE_NAME --global
# For regional backend services
gcloud compute backend-services delete BACKEND_SERVICE_NAME --region=REGION
gcloud compute health-checks delete HEALTH_CHECK_NAME
gcloud compute network-endpoint-groups delete NEG_NAME --zone=ZONE
מחליפים את מה שכתוב בשדות הבאים:
-
FORWARDING_RULE_NAME: השם של כלל ההעברה. -
PROXY_NAME: השם של שרת ה-proxy של היעד. -
URL_MAP_NAME: השם של מפת URL. -
BACKEND_SERVICE_NAME: השם של השירות לקצה העורפי. -
HEALTH_CHECK_NAME: השם של בדיקת תקינות. -
NEG_NAME: השם של קבוצת נקודות הקצה ברשת. -
REGION: האזור של שירות הקצה העורפי האזורי. -
ZONE: האזור של קבוצת נקודות הקצה ברשת.
המאמרים הבאים
- מידע נוסף על בקר שער
- איך מגדירים משאבי Gateway באמצעות מדיניות
- מידע נוסף על תצורות אחרות של שערים זמין בתיעוד של Gateway API.