איזון עומסים בחבילה עם MetalLB

במאמר הזה מוסבר איך להגדיר את Google Distributed Cloud לשימוש באיזון עומסים בחבילה עם מאזן העומסים MetalLB. המסמך הזה מיועד למומחי רשתות שתפקידם לתכנן את הרשת של הארגון, להתקין ציוד רשת, להגדיר אותו ולתמוך בו. מידע נוסף על תפקידים נפוצים ודוגמאות למשימות שאנחנו מתייחסים אליהן ב Google Cloudתוכן זמין במאמר תפקידים נפוצים של משתמשים ומשימות ב-GKE.

ב-Google Distributed Cloud, ‏ MetalLB פועל במצב שכבה 2.

דוגמה להגדרה של MetalLB

דוגמה להגדרה של אשכולות שמופעל בהם מאזן העומסים MetalLB:

הגדרות של מאזן עומסים MetalLB.
הגדרה של מאזן עומסים MetalLB

בתרשים שלמעלה מוצגת פריסת MetalLB. ‫MetalLB פועל ישירות בצמתי האשכול. בדוגמה הזו, אשכול האדמין ואשכול המשתמשים נמצאים בשני רשתות VLAN נפרדות, וכל אשכול נמצא ברשת משנה נפרדת:

אשכול תת-רשת
קלאסטר אדמין 172.16.20.0/24
אשכול משתמשים 172.16.40.0/24

admin-cluster.yaml

החלק הבא בקובץ התצורה של אשכול אדמין מציג את התצורה שמופיעה בתרשים הקודם של:

  • מישור בקרה עם זמינות גבוהה

  • מאזן עומסים MetalLB

  • כתובת VIP ב-MetalLB לשרת Kubernetes API של אשכול האדמין

network:
  ...
  controlPlaneIPBlock:
    netmask: "255.255.255.0"
    gateway: "172.16.20.1"
    ips:
    - ip: "172.16.20.50"
      hostname: "admin-cp-1"
    - ip: "172.16.20.51"
      hostname: "admin-cp-2"
    - ip: "172.16.20.52"
      hostname: "admin-cp-3"
loadBalancer:
  kind: "MetalLB"
  ...
  vips:
    controlPlaneVIP: "172.16.20.100"
...
adminMaster:
  cpus: 4
  memoryMB: 16384
  replicas: 3

user-cluster.yaml

החלק הבא בקובץ התצורה של אשכול משתמשים מציג את התצורה של:

  • מאגר כתובות שהבקר של MetalLB יכול לבחור מתוכו ולהקצות לשירותים מסוג LoadBalancer. כתובת ה-VIP של ה-ingress נמצאת במאגר הזה.

  • כתובת ה-VIP שמוגדרת לשרת Kubernetes API של אשכול המשתמשים, וכתובת ה-VIP של ה-ingress שבחרתם להגדיר ל-ingress proxy.

  • מאגר צמתים שמופעל בו שימוש ב-MetalLB. ‫MetalLB ייפרס בצמתים במאגר הצמתים הזה.

enableControlplaneV2: true
...
network:
  hostConfig:
  ...

  ipMode:
    type: "static"
    ipBlockFilePath: "config-folder/user-cluster-ipblock.yaml"
...
  controlPlaneIPBlock:
    netmask: "255.255.255.0"
    gateway: "172.16.40.1"
    ips:
    - ip: "172.16.40.21"
      hostname: "user-cp"
loadBalancer:
  kind: MetalLB
  metalLB:
    addressPools:
    - name: "address-pool-1"
      addresses:
      - "172.16.40.101-172.16.40.112
      avoidBuggyIPs: true
  ...

  vips:
    controlPlaneVIP: "172.16.20.100"
    ingressVIP: "172.16.40.101"
...
nodePools:
- name: "node-pool-1"
  cpus: 4
  memoryMB: 8192
  replicas: 3
  enableLoadBalancer: true

ההגדרה בדוגמה הקודמת מציינת קבוצה של כתובות שזמינות לשירותים. כשמפתח אפליקציה יוצר שירות מסוג LoadBalancer באשכול המשתמשים, בקר MetalLB בוחר כתובת IP ממאגר הכתובות הזה.

user-cluster-ipblock.yaml

בדוגמה הבאה של קובץ חסימת כתובות IP מוצגת ההקצאה של כתובות IP לצמתי העובדים באשכול המשתמשים. זה כולל כתובת IP נוספת לשימוש במהלך שדרוגים, עדכונים ותיקונים אוטומטיים של אשכולות.

blocks:
- netmask: "255.255.255.0"
  gateway: "17.16.40.1"
  ips:
  - ip: 172.16.40.22
    hostname: user-vm-1
  - ip: 172.16.40.23
    hostname: user-vm-2
  - ip: 172.16.40.24
    hostname: user-vm-3
  - ip: 172.16.40.25
    hostname: user-vm-4
  - ip: 172.16.40.26
    hostname: user-vm-5
  - ip: 172.16.40.27
    hostname: user-vm-6

הגדרת MetalLB

פתיחת יציאות בחומת האש

‫MetalLB משתמש בספריית memberlist של Go כדי לבצע בחירת מנהיג. הספרייה memberlist משתמשת ביציאת TCP‏ 7946 וביציאת UDP‏ 7946 להחלפת מידע. מוודאים שיש גישה ליציאות האלה לתנועה נכנסת ויוצאת בכל הצמתים של איזון העומסים.

הפעלת MetalLB באשכול אדמין חדש

בקובץ ההגדרות של אשכול האדמין, מגדירים את loadBalancer.kind ל-"MetalLB".

loadBalancer:
  kind: "MetalLB"

ממלאים את שאר הפרטים בקובץ ההגדרות של אשכול האדמין ויוצרים את אשכול האדמין כמו שמתואר במאמר יצירת אשכול אדמין.

ציון מאגרי כתובות

הבקר של MetalLB מקצה כתובות IP לשירותים. כשמפתח אפליקציות יוצר Service מסוג LoadBalancer באשכול משתמשים, בקר MetalLB מקצה באופן אוטומטי כתובת IP ל-Service. הבקר MetalLB בוחר כתובת IP ממאגר כתובות שאתם מציינים.

כדי לוודא שיש מספיק כתובות IP באשכול המשתמשים, כדאי לקחת בחשבון את המספר המקסימלי של שירותי LoadBalancer שצפויים להיות פעילים. לאחר מכן, מציינים מספיק כתובות IP בקטע loadBalancer.metalLB.addressPools בקובץ התצורה של אשכול המשתמשים.

הכתובות במאגר צריכות להיות בפורמט CIDR או בפורמט טווח. כדי לציין כתובת יחידה, משתמשים ב-CIDR של /32. לדוגמה:

addresses:
  -   "192.0.2.0/26"
  -   "192.0.2.64-192.0.2.72"
  -   "192.0.2.75/32"

החרגה של כתובות IP שמשמשות למטרות אחרות

אל תכללו את כתובות ה-IP הבאות במאגר כתובות כלשהו:

אם צריך לשנות את הכתובות במאגר אחרי שיוצרים את האשכול, אפשר להשתמש ב-gkectl update cluster. מידע נוסף זמין במאמר בנושא עדכון MetalLB.

הפעלת MetalLB עבור אשכול משתמשים חדש

בקובץ התצורה של אשכול המשתמשים:

  • מגדירים את loadBalancer.kind להיות "MetalLB".
  • מציינים מאגר כתובות אחד או יותר לשירותים. כתובת ה-VIP של הכניסה חייבת להיות באחת מהמאגרים האלה.
  • מגדירים את enableLoadBalancer ל-true לפחות במאגר צמתים אחד באשכול. כשמגדירים את השדה הזה ל-true, הרכיב MetalLB speaker יכול לפעול בצמתים במאגר. שימו לב: במהלך שדרוגים, הגרסה של מאגר הצמתים של מאזן העומסים חייבת להיות זהה לגרסה של האשכול. אין תמיכה בהטיה בגרסאות של מאגרי צמתים של מאזן עומסים.

    שימו לב להבדלים הבאים בהתנהגות של השדה enableLoadBalancer כשמגדירים את enableAdvancedCluster לערך true (האפשרות 'אשכול מתקדם' מופעלת): בגרסה 1.31, כשהאפשרות 'אשכול מתקדם' מופעלת, לשדה הזה אין השפעה כי הרכיב MetalLB speaker תמיד פועל בצמתי מישור הבקרה של אשכול המשתמש. בגרסה 1.32, כשהאפשרות advanced cluster מופעלת, המגבלה הזו מוסרת, ואתם צריכים לציין לפחות מאגר צמתים אחד שבו פועל הרכיב MetalLB speaker.

ממלאים את שאר הפרטים בקובץ ההגדרות של אשכול המשתמשים ויוצרים את אשכול המשתמשים כמו שמתואר במאמר יצירת אשכול משתמשים.

הקצאה ידנית של כתובות למקרי חירום

אם לא רוצים שבקר MetalLB יקצה אוטומטית כתובות IP ממאגר מסוים לשירותים, צריך להגדיר את השדה manualAssign של המאגר לערך true. לאחר מכן, מפתח יכול ליצור שירות מסוג LoadBalancer ולציין באופן ידני אחת מהכתובות ממאגר הכתובות. לדוגמה:

loadBalancer:
  metalLB:
    addressPools:
    - name: "my-address-pool-2"
      addresses:
      - "192.0.2.73-192.0.2.80"
      manualAssign: true

איך להימנע מכתובות IP עם באגים

אם מגדירים את השדה avoidBuggyIPs של מאגר כתובות ל-true, בקר MetalLB לא ישתמש בכתובות מהמאגר שמסתיימות ב-‎ .0 או ב-‎ .255. כך נמנעת הבעיה של מכשירים צרכניים עם באגים שגורמים להפסקת התעבורה שנשלחת לכתובות ה-IP המיוחדות האלה. לדוגמה:

loadBalancer:
  metalLB:
    addressPools:
    - name: "my-address-pool-1"
      addresses:
      - "192.0.2.0/24"
      avoidBuggyIPs: true

יצירת שירות מסוג LoadBalancer

אלה שני קובצי מניפסט: אחד לפריסה ואחד לשירות:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      greeting: hello
  replicas: 3
  template:
    metadata:
      labels:
        greeting: hello
    spec:
      containers:
      - name: hello
        image: gcr.io/google-samples/hello-app:2.0
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  selector:
    greeting: hello
  ports:
  - name: metal-lb-example-port
    protocol: TCP
    port: 60000
    targetPort: 8080

שימו לב שבמניפסט של השירות לא מצוינת כתובת IP חיצונית. הבקר של MetalLB יבחר כתובת IP חיצונית ממאגר הכתובות שציינתם בקובץ ההגדרות של אשכול המשתמשים.

שומרים את קובצי המניפסט בקובץ בשם my-dep-svc.yaml. לאחר מכן יוצרים את אובייקטי הפריסה והשירות:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-dep-svc.yaml

צפייה בשירות:

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get service my-service --output wide

בפלט מוצגת כתובת ה-IP החיצונית שהוקצתה אוטומטית לשירות. לדוגמה:

NAME         TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)           AGE   SELECTOR
my-service   LoadBalancer   10.96.2.166   192.0.2.2   60000:31914/TCP   28s

מוודאים שכתובת ה-IP החיצונית שהוקצתה נלקחה ממאגר הכתובות שצוין בקובץ ההגדרות של אשכול המשתמשים. לדוגמה, הכתובת 192.0.2.2 נמצאת במאגר הכתובות הבא:

metalLB:
  addressPools:
  - name: "address-pool-1"
    addresses:
     - "192.0.2.0/24"
     - "198.51.100.1-198.51.100.3"

התקשרות לשירות:

curl EXTERNAL_IP_ADDRESS:60000

הפלט יציג את ההודעה Hello, world!:

Hello, world!
Version: 2.0.0

עדכון MetalLB

אחרי שיוצרים את האשכול, אפשר לעדכן את מאגרי הכתובות של MetalLB ואת השדה enableLoadBalancer במאגרי הצמתים. מבצעים את השינויים הרצויים בקובץ התצורה של אשכול המשתמשים, ואז קוראים לפקודה gkectl update cluster:

gkectl update cluster --kubeconfig ADMIN_CLUSTER_KUBECONFIG --config USER_CLUSTER_CONFIG

‫MetalLB Pods ו-ConfigMap

הבקר MetalLB פועל כפריסה, והרכיב MetalLB speaker פועל כ-DaemonSet בצמתים במאגרי צמתים שההגדרה enableLoadBalancer שלהם היא true. ה-Controller של MetalLB מנהל את כתובות ה-IP שמוקצות לשירותים. רכיב ה-speaker של MetalLB מבצע בחירות של מנהיג ומכריז על כתובות VIP של שירותים.

הצגת כל רכיבי ה-Pod של MetalLB:

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get pods --namespace kube-system --selector app=metallb

אפשר להשתמש ביומנים מ-Pods של MetalLB כדי לפתור בעיות.

ההגדרה של MetalLB מאוחסנת ב-ConfigMap בפורמט שמוכר ל-MetalLB. אל תשנו את ה-ConfigMap ישירות. במקום זאת, צריך להשתמש ב-gkectl update cluster כמו שמתואר למעלה. כדי להציג את ConfigMap לצורך פתרון בעיות:

kubectl --kubeconfig USER_CLUSTER_KUBECONIFG get configmap metallb-config --namespace kube-system

יתרונות השימוש ב-MetalLB

  • ‫MetalLB פועל ישירות בצמתי האשכול, כך שלא נדרשים מכונות וירטואליות נוספות.

  • בקר MetalLB מבצע ניהול של כתובות IP עבור שירותים, כך שלא צריך לבחור כתובת IP לכל שירות באופן ידני.

  • מופעים פעילים של MetalLB לשירותים שונים יכולים לפעול בצמתים שונים.

  • אפשר לשתף כתובת IP בין שירותים שונים.

השוואה בין MetalLB לבין F5 BIG-IP ו-Seesaw

  • כתובות ה-VIP צריכות להיות באותה רשת משנה כמו צמתי האשכול. זו גם דרישה ל-Seesaw, אבל לא ל-F5 BIG-IP.

  • אין מדדים לגבי תנועה.

  • אין מעבר גיבוי אוטומטי ללא הפרעה; החיבורים הקיימים מאופסים במהלך מעבר הגיבוי האוטומטי.

  • תנועה חיצונית אל ה-Pods של שירות מסוים עוברת דרך צומת יחיד שמריץ את הרכיב speaker של MetalLB. המשמעות היא שכתובת ה-IP של הלקוח בדרך כלל לא גלויה לקונטיינרים שפועלים ב-Pod.

  • ‫ Cisco Application Centric Infrastructure (ACI) עם Dataplane IP Learning לא תואם למאזני עומסים של Seesaw ו-MetalLB. מומלץ להשתמש באיזון עומסים ידני או להשבית את Dataplane IP Learning כשמשתמשים ב-Seesaw או ב-MetalLB בתור מאזן העומסים. בנוסף, Seesaw נמצא במצב תחזוקה. החל מגרסה 1.32 של Google Distributed Cloud, השדרוגים חסומים לאשכולות שמשתמשים ב-Seesaw. כדי לשדרג לגרסה 1.32, צריך להעביר את האשכולות לתכונות המומלצות.