במאמר הזה מוסבר איך לחשוף לאינטרנט אפליקציה שפועלת באשכול Google Kubernetes Engine (GKE) באמצעות שירות LoadBalancer חיצוני עם פרוטוקול מעורב לתנועת TCP ו-UDP.
למידע נוסף על מאזני עומסי רשת חיצוניים להעברת סיגנל ללא שינוי, אפשר לעיין במאמר מאזן עומסי רשת חיצוני להעברת סיגנל ללא שינוי שמבוסס על שירות לקצה העורפי.
סקירה כללית
אפשר לחשוף אפליקציות שמשתמשות בפרוטוקולי TCP ו-UDP באמצעות שני שירותי LoadBalancer נפרדים של GKE עם כתובת IP משותפת שמתואמת באופן ידני. עם זאת, הגישה הזו לא יעילה כי היא מחייבת ניהול של כמה שירותים עבור אפליקציה אחת, ועלולה להוביל לבעיות כמו שגיאות בהגדרות או חריגה ממכסת כתובות ה-IP.
שירותי LoadBalancer עם פרוטוקולים מעורבים מאפשרים להשתמש בשירות יחיד כדי לנהל תנועה גם ב-TCP וגם ב-UDP. שימוש בשירות יחיד מפשט את ההגדרה, כי הוא מאפשר להשתמש בכתובת IPv4 יחידה ובקבוצה מאוחדת של כללי העברה לשני הפרוטוקולים. התכונה הזו נתמכת במאזן עומסי רשת חיצוני להעברת סיגנל ללא שינוי.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את הפעולות הבאות:
- מפעילים את ממשק ה-API של Google Kubernetes Engine. הפעלת Google Kubernetes Engine API
- אם רוצים להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז להפעיל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
- מוודאים שיש לכם אשכול קיים של Autopilot או Standard. כדי ליצור אשכול חדש, אפשר לעיין במאמר בנושא יצירת אשכול Autopilot.
דרישות
כדי ליצור שירות LoadBalancer חיצוני שמשתמש בפרוטוקולים מעורבים, האשכול צריך לעמוד בדרישות הבאות:
- איזון עומסים של פרוטוקולים מעורבים זמין בגרסה 1.34.1-gke.2190000 ומעלה.
- צריך להפעיל את התוסף
HttpLoadBalancingבאשכול. - כדי להטמיע את מאזן העומסים בשירותים חדשים מסוג LoadBalancer חיצוני, צריך להגדיר את השדה
spec.loadBalancerClassלערךnetworking.gke.io/l4-regional-externalבמניפסט של השירות. בשירותים קיימים, ההערהcloud.google.com/l4-rbs: "enabled"כבר מופיעה במניפסט, ואפשר להשאיר אותה כמו שהיא.
מגבלות
- מאזני עומסים עם פרוטוקולים מעורבים תומכים רק בכתובות IPv4.
אי אפשר להשתמש בפרוטוקולים מעורבים במניפסט של שירות עם הפונקציות הבאות לניקוי:
gke.networking.io/l4-ilb-v1gke.networking.io/l4-netlb-v1
אם בקובץ המניפסט יש את ה-finalizers האלה, צריך למחוק את ה-Service וליצור אותו מחדש בהתאם לדרישות הקודמות.
תמחור
Google Cloud תחויבו על כל כלל העברה, על כל כתובת IP חיצונית ועל הנתונים שנשלחים. בטבלה הבאה מפורט מספר כללי ההעברה וכתובות ה-IP החיצוניות שמשמשים להגדרות שצוינו. מידע נוסף מופיע במאמר בנושא תמחור של רשתות VPC.
| סוג | שכבת התעבורה | שכבת האינטרנט | מספר כללי ההעברה | מספר כתובות ה-IP החיצוניות |
|---|---|---|---|---|
| חיצוני | יחיד (TCP או UDP) | IPv4 | 1 | 1 |
| IPv6 | 1 | 1 | ||
| IPv4 ו-IPv6(DualStack) | 2 | 2 | ||
| מעורב (גם TCP וגם UDP) | IPv4 | 2 | 1 |
פריסת עומס עבודה
בקטע הזה מוסבר איך פורסים עומס עבודה לדוגמה שמקשיב ליציאות TCP ו-UDP. שימו לב: הגדרת הפריסה זהה בין אם משתמשים בשירות LoadBalancer עם פרוטוקול מעורב או בשני שירותי LoadBalancer נפרדים עם פרוטוקול יחיד.
המאניפסט הבא הוא של אפליקציה לדוגמה שמקשיבה ביציאה 8080 לתנועת TCP ו-UDP. שומרים את קובץ המניפסט הבא בשם
mixed-app-deployment.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: mixed-app-deployment spec: replicas: 3 selector: matchLabels: app: mixed-app template: metadata: labels: app: mixed-app spec: containers: - image: gcr.io/kubernetes-e2e-test-images/agnhost:2.6 name: agnhost args: ["serve-hostname", "--port=8080", "--tcp=true", "--udp=true", "--http=false"] ports: - name: tcp8080 protocol: TCP containerPort: 8080 - name: udp8080 protocol: UDP containerPort: 8080מחילים את המניפסט על האשכול:
kubectl apply -f mixed-app-deployment.yaml
יצירת מאזן עומסים עם פרוטוקולים מעורבים
יוצרים שירות מסוג LoadBalancer שחושף את הפריסה לתנועת TCP ו-UDP.
שומרים את קובץ המניפסט הבא בשם
mixed-protocol-lb.yaml:apiVersion: v1 kind: Service metadata: name: mixed-protocol-lb spec: loadBalancerClass: "networking.gke.io/l4-regional-external" type: LoadBalancer selector: app: mixed-app ports: - name: tcp-port protocol: TCP port: 8080 - name: udp-port protocol: UDP port: 8080לשירות שצוין למעלה יש שתי יציאות, אחת ל-TCP ואחת ל-UDP, שתיהן ביציאה 8080.
מחילים את המניפסט על האשכול:
kubectl apply --server-side -f mixed-protocol-lb.yaml
אימות מאזן העומסים של פרוטוקולים מעורבים
אחרי שיוצרים את השירות, מוודאים ש-GKE יצר את מאזן העומסים בהצלחה.
בדיקת השירות:
kubectl describe service mixed-protocol-lbבפלט מוצגת כתובת ה-IP החיצונית של מאזן העומסים וכללי ההעברה של TCP ו-UDP. בודקים את הפרטים הבאים בפלט:
- השדה
status.loadBalancer.ingress.ipמאוכלס. - מוודאים שההערות הבאות לגבי מאזן העומסים החיצוני קיימות:
service.kubernetes.io/tcp-forwarding-ruleservice.kubernetes.io/udp-forwarding-rule
- בקטע
Eventsלא מופיעות הודעות שגיאה.
- השדה
עדכון מאזן העומסים של פרוטוקולים מעורבים
אפשר לעדכן את היציאות במאזן עומסים עם פרוטוקולים מעורבים על ידי עריכה של מניפסט השירות. כדי לערוך את השירות, מריצים את הפקודה הבאה:
kubectl edit service SERVICE_NAME
מחליפים את SERVICE_NAME בשם השירות.
עדכון היציאות
כדי לעדכן את היציאות במאזן עומסים עם פרוטוקולים מעורבים, צריך לשנות את הקטע ports במניפסט השירות. אתם יכולים להוסיף, להסיר או לשנות יציאות.
בדוגמה הבאה מוסיפים יציאת UDP לסטרימינג ויציאת TCP למטא-נתונים של שרת המשחק:
apiVersion: v1
kind: Service
metadata:
name: mixed-protocol-lb
spec:
loadBalancerClass: "networking.gke.io/l4-regional-external"
type: LoadBalancer
selector:
app: mixed-app
ports:
- name: tcp-port
protocol: TCP
port: 8080
- name: streaming
protocol: UDP
port: 10100
- name: gameserver-metadata
protocol: TCP
port: 10400
- name: https
protocol: TCP
port: 443
עדכון מאזן עומסים עם פרוטוקול יחיד לפרוטוקול מעורב
כדי לשנות מאזן עומסים עם פרוטוקול יחיד למאזן עומסים עם פרוטוקול מעורב, צריך לערוך את השירות כך שיכלול יציאות גם לפרוטוקול TCP וגם לפרוטוקול UDP.
בדוגמה הבאה מוסיפים יציאת UDP ל-DNS למאזן עומסים קיים מסוג TCP בלבד:
apiVersion: v1
kind: Service
metadata:
name: already-existing-single-protocol-lb
spec:
loadBalancerClass: "networking.gke.io/l4-regional-external"
type: LoadBalancer
selector:
app: mixed-app
ports:
- name: http
protocol: TCP
port: 80
- name: https
protocol: TCP
port: 443
- name: dns
protocol: UDP
port: 53
עדכון מאזן עומסים עם פרוטוקולים מעורבים לפרוטוקול יחיד
כדי לשנות מאזן עומסים עם פרוטוקולים מעורבים למאזן עומסים עם פרוטוקול יחיד, צריך להסיר את כל היציאות של אחד הפרוטוקולים.
בדוגמה הבאה מסירים את יציאת ה-UDP של DNS, וכך מאזן העומסים הופך ל-TCP בלבד:
apiVersion: v1
kind: Service
metadata:
name: already-existing-mixed-protocol-lb
spec:
loadBalancerClass: "networking.gke.io/l4-regional-external"
type: LoadBalancer
selector:
app: mixed-app
ports:
- name: http
protocol: TCP
port: 80
- name: https
protocol: TCP
port: 443
מחיקת מאזן העומסים של פרוטוקולים מעורבים
כדי למחוק את שירות איזון העומסים החיצוני mixed-protocol-lb, מריצים את הפקודה הבאה:
kubectl delete service mixed-protocol-lb
GKE מסיר אוטומטית את כל משאבי איזון העומסים שנוצרו בשביל השירות.
פתרון בעיות
בקטע הזה מוסבר איך לפתור בעיות נפוצות בשירותי LoadBalancer עם פרוטוקולים מעורבים.
בדיקה של אירועי שגיאה
השלב הראשון בפתרון בעיות הוא לבדוק את האירועים שמשויכים לשירות.
פרטי השירות:
kubectl describe service mixed-protocol-lbבודקים אם יש הודעות שגיאה בקטע
Eventsבסוף הפלט.
שגיאה: אין תמיכה בפרוטוקול מעורב עבור LoadBalancer
אם יצרתם את השירות באמצעות ההערה cloud.google.com/l4-rbs: "enabled", יכול להיות שתראו אירוע אזהרה מבקר השירות המקורי אחרי שתיצרו את מאזן העומסים עם הפרוטוקולים המעורבים: mixed-protocol is not
supported for LoadBalancer.
אפשר להתעלם מההודעה הזו כי הבקר החדש, שתומך בפרוטוקולים מעורבים, מקצה את איזון העומסים בצורה נכונה.
הגדרת היציאה חסרה אחרי עדכון
התסמין:
כשמעדכנים שירות שמשתמש באותה יציאה גם ל-TCP וגם ל-UDP (לדוגמה, יציאה 8080), אחת מהגדרות היציאה חסרה בשירות המעודכן.
הסיבה:
זו בעיה מוכרת ב-Kubernetes. כשמעדכנים שירות עם כמה פרוטוקולים באותה יציאה, יכול להיות שחישוב הטלאי בצד הלקוח ימזג את רשימת היציאות בצורה שגויה, וכתוצאה מכך אחת מהגדרות היציאה תוסר.
הבעיה הזו משפיעה על לקוחות שמשתמשים בתיקון בצד הלקוח, כמו kubectl apply ולקוח Go עם תיקוני מיזוג.
פתרון:
הפתרון הבעיה הזו תלוי בלקוח.
ב-kubectl: משתמשים בדגל
--server-sideעםkubectl apply:kubectl apply --server-side -f YOUR_SERVICE_MANIFEST.yamlמחליפים את
YOUR_SERVICE_MANIFESTבשם של מניפסט השירות.ב-go-client: אל תשתמשו בתיקוני מיזוג. במקום זאת, אפשר להשתמש בקריאה לעדכון כדי להחליף את השירות. לשם כך נדרשת בקשת HTTP
PUTעם כל המפרט של אובייקט השירות.