שימוש באיזון עומסים של Maglev ב-GKE Dataplane V2

במסמך הזה מוסבר איך להגדיר ולאמת איזון עומסים של Maglev בשירותים ב-GKE Dataplane V2.

‫Maglev הוא אלגוריתם גיבוב עקבי (consistent hashing) שמספק איזון עומסים עם תפוקה גבוהה וזמן אחזור קצר. ‫Maglev ממזער את נפילת המנות ואת שיבוש החיבור כשמבצעים שינוי גודל, עדכון או תזמון מחדש של Pods בבק-אנד. הוא עושה זאת על ידי הקפדה על כך שאותו זרם ימופה באופן עקבי לאותו בק-אנד.

מידע נוסף זמין במאמר המחקר בנושא אלגוריתם הגיבוב העקבי של Maglev.

אנחנו ממליצים להשתמש בתכונה הזו לעומסי עבודה עם חיבורים לטווח ארוך או לאפליקציות עם מצב (stateful) שבהן שינויים בשרת העורפי לא אמורים לשבש תהליכים קיימים.

מידע על תקורה של משאבים ושיקולים לגבי מדרגיות זמין במאמר מושגים של GKE Dataplane V2.

לפני שמתחילים

לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:

  • מפעילים את ממשק ה-API של Google Kubernetes Engine.
  • הפעלת Google Kubernetes Engine API
  • כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה gcloud components update כדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.

דרישות מוקדמות ומגבלות

  • גרסת GKE: ‎1.36.0-gke.2882000 ואילך
  • ‫GKE Dataplane V2: מופעל
  • מצבי אשכולות: Autopilot ו-Standard

יצירת אשכול GKE באמצעות GKE Dataplane V2

כדי להשתמש ב-Maglev, צריך אשכול GKE עם GKE Dataplane V2 מופעל.

טייס אוטומטי

באשכולות Autopilot,‏ GKE Dataplane V2 מופעל כברירת מחדל. כדי ליצור אשכול Autopilot ולאחזר את ההגדרה שלו, מריצים את הפקודה הבאה:

gcloud container clusters create-auto CLUSTER_NAME \
    --region=COMPUTE_REGION \
    --release-channel=rapid
gcloud container clusters get-credentials CLUSTER_NAME \
    --region=COMPUTE_REGION

רגילה

כדי להפעיל את GKE Dataplane V2 באשכול Standard, משתמשים בדגל --enable-dataplane-v2. כדי ליצור אשכול Standard ולאחזר את ההגדרה שלו, מריצים את הפקודה הבאה:

gcloud container clusters create CLUSTER_NAME \
    --zone=COMPUTE_ZONE \
    --enable-dataplane-v2 \
    --cluster-version=1.36.0-gke.2882000
gcloud container clusters get-credentials CLUSTER_NAME \
    --zone=COMPUTE_ZONE

פריסת אפליקציה לקצה העורפי

לפני שמגדירים את שירותי איזון העומסים, צריך לפרוס אפליקציית קצה עורפי לטיפול בתנועה. הפריסה הזו מפעילה חמש רפליקות של אפליקציית הדוגמה hello-app.

  1. שומרים את קובץ המניפסט הבא בשם echo-backend.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: echo-backend
    spec:
      replicas: 5
      selector:
        matchLabels:
          app: echo-backend
      template:
        metadata:
          labels:
            app: echo-backend
        spec:
          containers:
          - name: hello
            image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
            ports:
            - containerPort: 8080
    
  2. מחילים את המניפסט:

    kubectl apply -f echo-backend.yaml
    

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

אתם יכולים להגדיר את השירותים כך שישתמשו באלגוריתם לאיזון עומסים של Maglev או באלגוריתם ברירת המחדל לאיזון עומסים אקראי. שני השירותים מטרגטים את פריסת ה-echo-backend שנוצרה בשלב הקודם.

הגדרת שירות Maglev

כדי להפעיל איזון עומסים של Maglev, מוסיפים את ההערה gke.networking.io/lb-algorithm: "maglev" למטא-נתונים של השירות במהלך היצירה.

  1. שומרים את קובץ המניפסט הבא בשם maglev-service.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: maglev-service
      annotations:
        gke.networking.io/lb-algorithm: "maglev"
    spec:
      selector:
        app: echo-backend
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    
  2. מחילים את המניפסט:

    kubectl apply -f maglev-service.yaml
    

הגדרת שירות אקראי

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

  1. שומרים את קובץ המניפסט הבא בשם random-service.yaml:

    apiVersion: v1
    kind: Service
    metadata:
      name: random-service
      annotations:
        gke.networking.io/lb-algorithm: "random"
    spec:
      selector:
        app: echo-backend
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    
  2. מחילים את המניפסט:

    kubectl apply -f random-service.yaml
    

אימות עקביות התנועה

כדי לאמת את ההבדלים בעקביות הניתוב בין Maglev לבין איזון עומסים אקראי, אפשר לפרוס פודים של לקוחות לבדיקה ששולחים תעבורה מיציאת מקור קבועה.

אימות העקביות של התנועה ב-Maglev

‫Maglev מנתב בקשות מאותו יציאת מקור באופן עקבי לאותו Pod של קצה עורפי.

  1. שומרים את המניפסט הבא בתור client-maglev.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: client-maglev
    spec:
      restartPolicy: Never
      containers:
      - name: curl
        image: curlimages/curl:8.2.0
        command: ["/bin/sh", "-c"]
        args:
        - |
          while true; do
            curl -s -H "Connection: close" http://maglev-service:80 --local-port 54321 | grep Hostname
            sleep 0.5
          done
    

    הדגל --local-port מאלץ את יציאת המקור, והכותרת Connection: close עוזרת לוודא שהלקוח יכול לעשות שימוש חוזר ביציאת המקור באופן מיידי לבקשות הבאות.

  2. החלת המניפסט:

    kubectl apply -f client-maglev.yaml
    
  3. בזמן שה-Pod פועל, בודקים את היומנים:

    kubectl logs client-maglev
    

    הפלט המצופה:

    הפלט מראה את אותו שם מארח שמופיע שוב ושוב, מה שמצביע על כך שכל התנועה מהלקוח מנותבת באופן עקבי לאותו Pod של קצה עורפי:

    Hostname: echo-backend-5c78f66dbf-abcde
    Hostname: echo-backend-5c78f66dbf-abcde
    

אימות של חלוקת תנועה אקראית (ברירת מחדל)

שירות ברירת המחדל מפיץ תנועה מאותה יציאת מקור בין Pods שונים של קצה עורפי.

  1. שומרים את קובץ המניפסט הבא בשם client-random.yaml:

    apiVersion: v1
    kind: Pod
    metadata:
      name: client-random
    spec:
      restartPolicy: Never
      containers:
      - name: curl
        image: curlimages/curl:8.2.0
        command: ["/bin/sh", "-c"]
        args:
        - |
          while true; do
            curl -s -H "Connection: close" http://random-service:80 --local-port 54321 | grep Hostname
            sleep 0.5
          done
    
  2. החלת המניפסט:

    kubectl apply -f client-random.yaml
    
  3. בזמן שה-Pod פועל, בודקים את היומנים:

    kubectl logs client-random
    

    הפלט המצופה:

    הפלט מציג כמה שמות מארחים שונים, מה שמצביע על כך שהתנועה מתחלקת בין כמה תרמילים:

    Hostname: echo-backend-5c78f66dbf-abcde
    Hostname: echo-backend-5c78f66dbf-fghij
    Hostname: echo-backend-5c78f66dbf-klmno
    ...
    

הסרת המשאבים

כדי לנקות את המשאבים שבהם השתמשתם במדריך הזה, מריצים את הפקודות הבאות:

  1. מוחקים את ה-Pods, ה-Services וה-Deployment של הלקוח:

    kubectl delete service maglev-service random-service
    kubectl delete deployment echo-backend
    kubectl delete pod client-maglev client-random
    
  2. מוחקים את אשכולות GKE:

טייס אוטומטי

gcloud container clusters delete CLUSTER_NAME --region=COMPUTE_REGION

רגילה

gcloud container clusters delete CLUSTER_NAME --zone=COMPUTE_ZONE