איזון עומסים מקובץ מאפשר להריץ את מאזני העומסים של אשכול Google Distributed Cloud בצמתים של האשכול עצמו. Keepalived ו-HAProxy משרתים את כתובת ה-IP הווירטואלית (VIP) של מישור הבקרה, ו-MetalLB במצב Layer 2 מספק איזון עומסים במישור הנתונים לשירותים מסוג LoadBalancer.
מאזני העומסים יכולים לפעול בצמתים של מישור הבקרה או במאגר ייעודי של צמתים לאיזון עומסים. אפשר גם להריץ את מאזני העומסים של מישור הבקרה ומישור הנתונים בצמתים נפרדים.
במאמר סקירה כללית של מאזני עומסים תוכלו לקרוא דוגמאות לטופולוגיות נתמכות של איזון עומסים.
דרישות
- כל הצמתים של מאזן העומסים צריכים להיות באותה רשת משנה של שכבה 2.
- כל כתובות ה-VIP חייבות להיות ברשת המשנה של הצמתים של מאזן העומסים, וצריך להיות אפשרי לנתב אותן דרך השער של רשת המשנה.
- שער רשת המשנה של מאזן העומסים צריך להאזין להודעות ARP מיותרות ולהעביר חבילות ARP לצומתי מאזן העומסים.
שדות תצורה
עורכים את הקטע cluster.spec.loadBalancer בקובץ התצורה של האשכול כדי להגדיר איזון עומסים בחבילה. למידע על קובצי תצורה של אשכולות ודוגמאות להגדרות תקינות, עיינו באחד מהדפים הבאים:
loadBalancer.mode
כדי להפעיל איזון עומסים בחבילה, הערך הזה חייב להיות bundled.
loadBalancer.ports.controlPlaneLBPort
הערך הזה מציין את יציאת היעד שמשמשת לתנועה שנשלחת למישור הבקרה של Kubernetes (שרתי ה-API של Kubernetes).
loadBalancer.vips.controlPlaneVIP
הערך הזה מציין את כתובת ה-IP של היעד שבה צריך להשתמש לתנועה שנשלחת למישור הבקרה של Kubernetes (שרתי ה-API של Kubernetes). כתובת ה-IP הזו צריכה להיות באותה רשת משנה של שכבה 2 כמו הצמתים באשכול. אל תציינו את הכתובת הזו בקטע address pools של קובץ התצורה.
loadBalancer.vips.ingressVIP
הערך הזה מציין את כתובת ה-IP שבה ישתמשו השירותים שמאחורי מאזן העומסים לתעבורת נתונים נכנסת (ingress). אי אפשר להשתמש בשדה הזה בקובצי תצורה של אשכולות אדמין. הכתובת הזו צריכה להופיע בקטע מאגרי כתובות בהגדרות.
loadBalancer.addressPools
הקטע הזה בהגדרות מכיל מאגר כתובות אחד או יותר. כל מאגר כתובות מציין רשימה של טווחי כתובות IP. כשיוצרים שירות מסוג LoadBalancer, כתובות ה-IP החיצוניות של השירות נבחרות מהטווחים האלה.
מאגרי הכתובות מצוינים בפורמט הבא:
- name: POOL_NAME
avoidBuggyIPs: BOOLEAN
manualAssign: BOOLEAN
addresses:
- IP_RANGE
- IP_RANGE2
-
name: השם של מאגר הכתובות, pool-name, למטרות הארגון שלכם. אי אפשר לשנות את השדה הזה. -
avoidBuggyIPs: (אופציונלי)trueאוfalse. אםtrue, המאגר משמיט כתובות IP שמסתיימות ב-.0וב-.255. חלק מחומרת הרשת מפילה את התנועה לכתובות המיוחדות האלה. אפשר להשמיט את השדה הזה, ערך ברירת המחדל שלו הואfalse. אפשר לשנות את השדה הזה. -
manualAssign: (אופציונלי)trueאוfalse. אם הערך הואtrue, הכתובות במאגר הזה לא מוקצות באופן אוטומטי לשירותי Kubernetes. אם הערך הואtrue, כתובת IP במאגר הזה משמשת רק כששירות מציין אותה במפורש. אפשר להשמיט את השדה הזה, ערך ברירת המחדל שלו הואfalse. אפשר לשנות את השדה הזה. -
addressesרשימה של טווח אחד או יותר של כתובות IP שלא חופפות. אפשר לציין את ip-range בסימון CIDR (כמו198.51.100.0/24) או בסימון טווח (כמו198.51.100.0-198.51.100.10, בלי רווחים לפני ואחרי המקף). אי אפשר לשנות את השדה הזה.
טווח כתובות ה-IP ברשימה addresses לא יכול לחפוף, והוא חייב להיות באותה רשת משנה כמו הצמתים שמריצים את מאזני העומסים.
loadBalancer.nodePoolSpec
בקטע הזה של ההגדרה מצוינת רשימה של צמתים שבהם יופעלו מאזני העומסים. צומתי מאזן העומסים יכולים להריץ עומסי עבודה רגילים כברירת מחדל, ואין להם טיינט מיוחד. למרות שהצמתים במאגר הצמתים של מאזן העומסים יכולים להריץ עומסי עבודה, הם נפרדים מהצמתים במאגרי הצמתים של ה-workers. אי אפשר לכלול צומת אשכול נתון ביותר ממאגר צמתים אחד. כתובות IP חופפות של צמתים בין מאגרי צמתים חוסמות את היצירה של האשכול ופעולות אחרות באשכול.
כדי למנוע מעומסי עבודה לפעול בצומת במאגר הצמתים של מאזן העומסים, מוסיפים לצומת את ה-taint הבא:
node-role.kubernetes.io/load-balancer:NoSchedule
ב-Google Distributed Cloud, לפודים שנדרשים לאיזון עומסים נוספות סבילות לטיינט הזה.
הדוגמה הבאה מציגה מאגר צמתים לאיזון עומסים עם שני צמתים. לצומת הראשון יש כתובת IP רגילה nodePoolSpec.nodes.address ('1.2.3.4') וכתובת IP של Kubernetes nodePoolSpec.nodes.k8sIP (10.0.0.32). כשמציינים את הכתובת האופציונלית k8sIP לצומת, היא מוקדשת לטיפול בתנועת הנתונים של הצומת, כמו בקשות ותגובות ל-Kubernetes API, ל-kubelet ולעומסי העבודה. במקרה כזה, כתובת ה-IP הרגילה nodePoolSpec.nodes.address משמשת לחיבורי SSH לצומת לפעולות של אשכול הניהול. אם לא מציינים כתובת k8sIP, כתובת ה-IP הרגילה של הצומת מטפלת בכל התנועה של הצומת.
nodePoolSpec:
nodes:
- address: 1.2.3.4
k8sIP: 10.0.0.32
- address: 10.0.0.33
כברירת מחדל, כל הצמתים במאגר הצמתים של מאזן העומסים צריכים להיות באותה רשת משנה של שכבה 2 כמו כתובות ה-VIP של מאזן העומסים שהוגדרו בקטע loadBalancer.addressPools של קובץ התצורה.
עם זאת, אם מציינים כתובת IP של Kubernetes k8sIP לצומת, רק הכתובת הזו צריכה להיות באותה רשת משנה של שכבה 2 כמו כתובות ה-VIP האחרות של מאזן העומסים.
אם לא מגדירים את nodePoolSpec, מאזני העומסים המצורפים פועלים בצומתי מישור הבקרה. מומלץ להריץ מאזני עומסים במאגרי צמתים נפרדים, אם אפשר.
איזון עומסים במישור הבקרה
מאזן העומסים של מישור הבקרה משרת את כתובת ה-IP הווירטואלית (VIP) של מישור הבקרה. ב-Google Distributed Cloud, Keepalived ו-HAProxy פועלים כפודים סטטיים של Kubernetes בצומתי מאזן העומסים כדי להכריז על ה-VIP של מישור הבקרה. Keepalived משתמש ב-Virtual Router Redundancy Protocol (VRRP) בצומתי מאזן העומסים כדי להבטיח זמינות גבוהה.
איזון עומסים במישור הנתונים
מאזן העומסים של מישור הנתונים מיועד לכל שירותי Kubernetes מסוג LoadBalancer.
ב-Google Distributed Cloud נעשה שימוש ב-MetalLB שפועל במצב Layer 2 לאיזון עומסים במישור הנתונים. אפשר להגדיר את איזון העומסים במישור הנתונים רק דרך Google Distributed Cloud, אל תשנו ישירות את ה-ConfigMap של MetalLB. אתם יכולים להשתמש בכל התכונות של MetalLB, כולל שיתוף כתובות IP בין שירותים.
למידע על התכונות, קראו את המאמרים בנושא MetalLB.
MetalLB מריץ פוד של רמקול בכל צומת באמצעות daemonset, ומשתמש ב-memberlist לזמינות גבוהה. לכל שירות Kubernetes יש צומת ייעודי של מאזן עומסים ב-MetalLB, במקום צומת אחד לכל האשכול. כך התנועה מתפזרת בין צומתי מאזן העומסים אם יש כמה שירותים.
מאזני העומסים של מישור הנתונים יכולים לפעול בצמתים של מישור הבקרה או בקבוצת משנה של צמתים עובדים. כשמקבצים את מאזני העומסים של מישור הנתונים בצומתי מישור הבקרה, הניצול של צומתי מישור הבקרה גדל. בנוסף, קיבוץ בצומתי מישור הבקרה מגביר את הסיכון לעומס יתר במישור הבקרה, ומגדיל את פרופיל הסיכון של מידע סודי במישור הבקרה, כמו מפתחות SSH.
הפרדה של מאזן העומסים
בגרסאות שקדמו ל-1.32, כשמגדירים איזון עומסים בשכבה 2 באמצעות MetalLB, מאזני העומסים של מישור הבקרה ומאזני העומסים של מישור הנתונים פועלים באותם צמתים. בהתאם להגדרות האישיות, כל מאזני העומסים פועלים בצמתים של מישור הבקרה או במאגר הצמתים של מאזן העומסים.
בתרשים הבא מוצגת הגדרת ברירת המחדל של מאזן העומסים המצורף, שבה גם מאזן העומסים של מישור הבקרה וגם מאזן העומסים של מישור הנתונים פועלים בצומתי מישור הבקרה, או ששניהם פועלים במאגר הצמתים של מאזן העומסים:
באשכולות בגרסה 1.32, אתם יכולים להגדיר את מאזני העומסים של מישור הבקרה כך שיפעלו בצומתי מישור הבקרה, ואת מאזני העומסים של מישור הנתונים כך שיפעלו במאגר הצמתים של מאזן העומסים. אתם יכולים להגדיר את ההפרדה הזו של מאזני העומסים כשאתם יוצרים אשכול חדש בגרסה 1.32, או לעדכן אשכול בגרסה 1.32 כדי להעביר את מאזני העומסים של מישור הנתונים מהצמתים של מישור הבקרה למאגר הצמתים של מאזני העומסים.
הגדרת האשכול של מאזני עומסים נפרדים צריכה להיראות כמו בדוגמה הבאה:
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
name: hybrid-ha-lb
namespace: cluster-hybrid-ha-lb
spec:
type: hybrid
profile: default
anthosBareMetalVersion: 1.36
gkeConnect:
projectID: project-fleet
controlPlane:
loadBalancer:
mode: bundled
nodePoolSpec:
nodes:
- address: 10.200.0.2
- address: 10.200.0.3
- address: 10.200.0.4
clusterNetwork:
pods:
cidrBlocks:
- 192.168.0.0/16
services:
cidrBlocks:
- 10.96.0.0/20
...
loadBalancer:
mode: bundled
...
nodePoolSpec:
nodes:
- address: 10.200.0.5
- address: 10.200.0.6
- address: 10.200.0.7
clusterOperations:
...
מאזני עומסים נפרדים כשיוצרים אשכול
אם אתם יוצרים אשכול חדש בגרסה 1.32 ואילך, אתם יכולים להגדיר את מאזני העומסים כך שיפעילו את מאזני העומסים של מישור הבקרה בצמתים של מישור הבקרה, ואת מאזני העומסים של מישור הנתונים במאגר הצמתים של מאזן העומסים.
בתרשים הבא מוצגים מאזני העומסים של מישור הבקרה ומישור הנתונים, כשהם מופרדים לצמתים שונים:
כדי להפריד בין מאזני העומסים כשיוצרים אשכול:
בקובץ התצורה של האשכול, מציינים מאגר של צומתי מאזן עומסים עם
loadBalancer.nodePoolSpec, כמו שמתואר בקטעloadBalancer.nodePoolSpecבמסמך הזה.מוסיפים את
controlPlane.loadBalancer.modeלקובץ התצורה של האשכול ומגדירים את הערך שלmodeל-bundled.מסיימים להגדיר את האשכול ומריצים את הפקודה
bmctl create clusterכדי ליצור את האשכול.
העברת מאזני העומסים של מישור הנתונים מחוץ למישור הבקרה
אם יש לכם אשכול קיים בגרסה 1.32 ומעלה, שבו לא מוגדרים controlPlane.loadBalancer.mode וגם לא loadBalancer.nodePoolSpec, גם מאזן העומסים של מישור הבקרה וגם מאזן העומסים של מישור הנתונים פועלים במאגר הצמתים של מישור הבקרה. אתם יכולים לעדכן את האשכול כדי להעביר את מאזן העומסים של מישור הנתונים למאגר של צומתי מאזן עומסים.
בתרשים הבא מוצגים מאזני העומסים של מישור הבקרה ומישור הנתונים, אחרי שמאזן העומסים של מישור הנתונים הועבר מהצמתים של מישור הבקרה:
כדי להעביר את מאזן העומסים של מישור הנתונים למאגר צמתים של מאזן עומסים כשמעדכנים אשכול, צריך לפעול לפי השלבים הבאים:
בקובץ התצורה של האשכול, מציינים מאגר של צומתי מאזן עומסים עם
loadBalancer.nodePoolSpec, כמו שמתואר בקטעloadBalancer.nodePoolSpecבמסמך הזה.מוסיפים את
controlPlane.loadBalancer.modeלקובץ התצורה של האשכול ומגדירים את הערך שלmodeל-bundled.מעדכנים את האשכול באמצעות הפקודה הבאה:
bmctl update cluster -c CLUSTER_NAME --kubeconfig=ADMIN_KUBECONFIGמחליפים את מה שכתוב בשדות הבאים:
CLUSTER_NAME: שם האשכול שמעדכנים.
ADMIN_KUBECONFIG: הנתיב לקובץ kubeconfig של אשכול האדמין.
שמירה על כתובת ה-IP של מקור הלקוח
השירות LoadBalancer שנוצר באמצעות פתרון איזון העומסים המצורף של שכבה 2 משתמש בהגדרה Cluster שמוגדרת כברירת מחדל למדיניות התנועה החיצונית.
ההגדרה הזו, spec.externalTrafficPolicy: Cluster, מנתבת תנועה חיצונית לנקודות קצה ברמת האשכול, אבל היא גם מסתירה את כתובת ה-IP של מקור הלקוח.
ב-Google Distributed Cloud יש שתי שיטות לשמירה על כתובת ה-IP של מקור הלקוח:
מגדירים את מצב ההעברה לאיזון עומסים ל-Direct Server Return (DSR). למידע נוסף על מצב העברה של DSR, כולל הוראות להפעלה שלו, ראו הגדרת מצב העברה של איזון עומסים.
מגדירים את מדיניות התנועה החיצונית ל-local בשירות
LoadBalancer, ומגדירים בהתאם את השירותים הקשורים ואת Ingress. בקטעים הבאים מוסבר איך להגדיר את האשכול לשימוש בשיטה הזו.
LoadBalancer Services
כשמשתמשים ב-externalTrafficPolicy: Local בשירותי LoadBalancer, צריך להגדיר את Pods של האפליקציה כך שיפעלו בדיוק בצמתים של מאזן העומסים. כדי לבצע את השינוי הזה, מוסיפים את ה-nodeSelector הבא לפודים של האפליקציה:
apiVersion: v1
kind: Pod
...
spec:
nodeSelector:
baremetal.cluster.gke.io/lbnode: "true"
...
NodePort Services
Kubernetes מבצע תרגום כתובת רשת (SNAT) לשירותי NodePort. כדי לשמור את כתובות ה-IP של מקור הלקוח, מגדירים את service.spec.externalTrafficPolicy ל-Local. Kubernetes לא יבצע יותר SNAT, אבל צריך לוודא שיש פודים שפועלים בדיוק בכתובת ה-IP של הצומת שבחרתם.
תעבורת נתונים נכנסת (Ingress)
אם האפליקציות שלכם הן שירותי HTTP, אתם יכולים להגדיר רכיבי Ingress כדי לראות את כתובות ה-IP של הלקוחות:
פותחים את השירות
istio-ingressלעריכה:kubectl edit service -n gke-system istio-ingressמוסיפים את
externalTrafficPolicy: Localאלspec, שומרים ויוצאים מהעורך.apiVersion: v1 kind: Service ... spec: ... externalTrafficPolicy: Localפותחים את הפריסה של
istio-ingressלעריכה:kubectl edit deployment -n gke-system istio-ingressמוסיפים את ה-
nodeSelectorהבא לפריסה, שומרים ויוצאים מהעורך.apiVersion: apps/v1 kind: Deployment ... spec: ... template: ... spec: ... nodeSelector: baremetal.cluster.gke.io/lbnode: "true" ...
עכשיו, כל השירותים שמאחורי Ingress רואים כותרת X-Forwarded-For עם כתובת ה-IP של הלקוח, כמו בדוגמה הבאה:
X-Forwarded-For: 21.0.104.4