הגדרת רשת מרובת אשכולות ב-GKE

במדריך הזה מוסבר איך לצרף שני אשכולות ל-Cloud Service Mesh יחיד באמצעות Mesh CA או Istio CA, ואיך להפעיל איזון עומסים בין אשכולות. אפשר להרחיב את התהליך הזה בקלות כדי לכלול מספר כלשהו של אשכולות ברשת.

הגדרה של Cloud Service Mesh מרובה אשכולות יכולה לפתור כמה תרחישים חשובים בארגונים, כמו קנה מידה, מיקום ובידוד. מידע נוסף מופיע במאמר תרחישי שימוש בריבוי אשכולות.

דרישות מוקדמות

במדריך הזה אנחנו יוצאים מנקודת הנחה שיש לכם שני אשכולות GKE או יותר Google Cloud שעומדים בדרישות הבאות:

הגדרת משתנים של פרויקט ושל אשכול

  1. יוצרים את משתני הסביבה הבאים עבור מזהה הפרויקט, האזור או האזור של האשכול, שם האשכול וההקשר.

    export PROJECT_1=PROJECT_ID_1
    export LOCATION_1=CLUSTER_LOCATION_1
    export CLUSTER_1=CLUSTER_NAME_1
    export CTX_1="gke_${PROJECT_1}_${LOCATION_1}_${CLUSTER_1}"
    
    export PROJECT_2=PROJECT_ID_2
    export LOCATION_2=CLUSTER_LOCATION_2
    export CLUSTER_2=CLUSTER_NAME_2
    export CTX_2="gke_${PROJECT_2}_${LOCATION_2}_${CLUSTER_2}"
    
  2. אם אלה אשכולות שנוצרו לאחרונה, חשוב לאחזר את פרטי הכניסה לכל אשכול באמצעות הפקודות הבאות gcloud, אחרת לא יהיה אפשר להשתמש ב-context שמשויך אליהם בשלבים הבאים של המדריך הזה.

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

    אזורי

    gcloud container clusters get-credentials ${CLUSTER_1} --region ${LOCATION_1}
    gcloud container clusters get-credentials ${CLUSTER_2} --region ${LOCATION_2}
    

    אזורי

    gcloud container clusters get-credentials ${CLUSTER_1} --zone ${LOCATION_1}
    gcloud container clusters get-credentials ${CLUSTER_2} --zone ${LOCATION_2}
    

יצירת כלל לחומת האש

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

  • משתמשים ברשתות משנה שונות עבור האשכולות ברשת ה-mesh.
  • ה-Pods פותחים יציאות אחרות מלבד 443 ו-15002.

מערכת GKE מוסיפה אוטומטית כללי חומת אש לכל צומת כדי לאפשר תעבורת נתונים באותה רשת משנה. אם הרשת שלכם מכילה כמה רשתות משנה, אתם צריכים להגדיר במפורש את כללי חומת האש כדי לאפשר תנועה בין רשתות משנה. צריך להוסיף כלל חומת אש חדש לכל רשת משנה כדי לאפשר את בלוקי CIDR של כתובות ה-IP של המקור ואת יציאות היעד של כל תעבורת הנתונים הנכנסת.

ההוראות הבאות מאפשרות תקשורת בין כל האשכולות בפרויקט או רק בין $CLUSTER_1 לבין $CLUSTER_2.

  1. אוספים מידע על הרשת של האשכולות.

    כל האשכולות בפרויקט

    אם האשכולות נמצאים באותו פרויקט, אפשר להשתמש בפקודה הבאה כדי לאפשר תקשורת בין כל האשכולות בפרויקט. אם יש אשכולות בפרויקט שאתם לא רוצים לחשוף, אתם יכולים להשתמש בפקודה שבכרטיסייה Specific clusters (אשכולות ספציפיים).

    function join_by { local IFS="$1"; shift; echo "$*"; }
    ALL_CLUSTER_CIDRS=$(gcloud container clusters list --project $PROJECT_1 --format='value(clusterIpv4Cidr)' | sort | uniq)
    ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}"))
    ALL_CLUSTER_NETTAGS=$(gcloud compute instances list --project $PROJECT_1 --format='value(tags.items.[0])' | sort | uniq)
    ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
    

    אשכולות ספציפיים

    הפקודה הבאה מאפשרת תקשורת בין $CLUSTER_1 לבין $CLUSTER_2, ולא חושפת אשכולות אחרים בפרויקט.

    function join_by { local IFS="$1"; shift; echo "$*"; }
    ALL_CLUSTER_CIDRS=$(for P in $PROJECT_1 $PROJECT_2; do gcloud --project $P container clusters list --filter="name:($CLUSTER_1,$CLUSTER_2)" --format='value(clusterIpv4Cidr)'; done | sort | uniq)
    ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}"))
    ALL_CLUSTER_NETTAGS=$(for P in $PROJECT_1 $PROJECT_2; do gcloud --project $P compute instances list  --filter="name:($CLUSTER_1,$CLUSTER_2)" --format='value(tags.items.[0])' ; done | sort | uniq)
    ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
    
  2. יוצרים את הכלל לחומת האש.

    GKE

    gcloud compute firewall-rules create istio-multicluster-pods \
        --allow=tcp,udp,icmp,esp,ah,sctp \
        --direction=INGRESS \
        --priority=900 \
        --source-ranges="${ALL_CLUSTER_CIDRS}" \
        --target-tags="${ALL_CLUSTER_NETTAGS}" --quiet \
        --network=YOUR_NETWORK
    

    טייס אוטומטי

    TAGS=""
    for CLUSTER in ${CLUSTER_1} ${CLUSTER_2}
    do
        TAGS+=$(gcloud compute firewall-rules list --filter="Name:$CLUSTER*" --format="value(targetTags)" | uniq) && TAGS+=","
    done
    TAGS=${TAGS::-1}
    echo "Network tags for pod ranges are $TAGS"
    
    gcloud compute firewall-rules create asm-multicluster-pods \
        --allow=tcp,udp,icmp,esp,ah,sctp \
        --network=gke-cluster-vpc \
        --direction=INGRESS \
        --priority=900 --network=VPC_NAME \
        --source-ranges="${ALL_CLUSTER_CIDRS}" \
        --target-tags=$TAGS
    

הגדרת גילוי נקודות קצה

השלבים שנדרשים להגדרת איתור נקודות קצה תלויים בהעדפה שלכם: שימוש ב-declarative API בכל האשכולות בצי, או הפעלה ידנית של התכונה באשכולות ציבוריים או באשכולות פרטיים.

הפעלת גילוי נקודות קצה בין אשכולות ציבוריים או פרטיים באמצעות API הצהרתי (תצוגה מקדימה)

אתם יכולים להפעיל גילוי של נקודות קצה באשכולות ציבוריים או פרטיים ב-Fleet, על ידי החלת ההגדרה "multicluster_mode":"connected" ב-configmap‏ asm-options. בצבי קלאסטרים שבהם ההגדרה הזו מופעלת באותו צי, גילוי שירותים בין קלאסטרים מופעל אוטומטית בין כל הקלאסטרים.

השיטה הזו זמינה להתקנות מנוהלות של Cloud Service Mesh בכל ערוצי ההפצה. זו גם הדרך המומלצת להגדיר גילוי של נקודות קצה של כמה אשכולות אם הקצאתם Cloud Service Mesh מנוהל באמצעות התכונה הפעלת Cloud Service Mesh כשיוצרים אשכול GKE חדש במסוף Google Cloud .

לפני שממשיכים, צריך ליצור כלל לחומת האש.

אם יש לכם כמה פרויקטים, אתם צריכים להוסיף את FLEET_PROJECT_ID.svc.id.goog ל-trustDomainAliases באופן ידני ב-meshConfig של הגרסה, אם הוא עדיין לא מופיע שם.

הפעלה

אם asm-options configmap כבר קיים באשכול, צריך להפעיל את גילוי נקודות הקצה באשכול:

kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"connected"}}'

אם asm-options configmap עדיין לא קיים באשכול, צריך ליצור אותו עם הנתונים המשויכים ולהפעיל את גילוי נקודות הקצה באשכול:

kubectl --context ${CTX_1} create configmap asm-options -n istio-system --from-file <(echo '{"data":{"multicluster_mode":"connected"}}')

השבתה

כדי להשבית את גילוי נקודות הקצה באשכול:

kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"manual"}}'

אם מבטלים את הרישום של אשכול ב-Fleet בלי להשבית את איתור נקודות הקצה, יכול להיות שסודות יישארו באשכול. צריך לנקות באופן ידני את כל הסודות שנותרו.

  1. מריצים את הפקודה הבאה כדי למצוא סודות שצריך להסיר:

    kubectl get secrets -n istio-system -l istio.io/owned-by=mesh.googleapis.com,istio/multiCluster=true
    
  2. מחיקת כל סוד:

    kubectl delete secret SECRET_NAME -n istio-system
    

    חוזרים על השלב הזה לכל סוד שנותר.

הגדרת גילוי נקודות קצה בין אשכולות ציבוריים

כדי להגדיר גילוי נקודות קצה בין אשכולות GKE, מריצים את הפקודה asmcli create-mesh. הפקודה הזו:

  • רושם את כל האשכולות לאותו צי.
  • הגדרת הרשת כך שתהיה מהימנה לזהות של עומס העבודה ב-Fleet.
  • יוצרת סודות מרחוק.

אפשר לציין את ה-URI של כל אשכול או את הנתיב של קובץ kubeconfig.

‫URI של האשכול

בפקודה הבאה, מחליפים את FLEET_PROJECT_ID במזהה הפרויקט של פרויקט המארח של ה-Fleet, ואת ה-URI של האשכול בשם האשכול, באזור או באזור ובמזהה הפרויקט של כל אשכול. בדוגמה הזו מוצגים רק שני אשכולות, אבל אפשר להריץ את הפקודה כדי להפעיל גילוי של נקודות קצה באשכולות נוספים, בכפוף למספר המקסימלי של אשכולות שאפשר להוסיף לצי.

./asmcli create-mesh \
    FLEET_PROJECT_ID \
    ${PROJECT_1}/${LOCATION_1}/${CLUSTER_1} \
    ${PROJECT_2}/${LOCATION_2}/${CLUSTER_2}

קובץ kubeconfig

בפקודה הבאה, מחליפים את FLEET_PROJECT_ID במזהה הפרויקט של פרויקט המארח של ה-Fleet ואת PATH_TO_KUBECONFIG בנתיב לכל קובץ kubeconfig. בדוגמה הזו מוצגים רק שני אשכולות, אבל אפשר להריץ את הפקודה כדי להפעיל גילוי של נקודות קצה באשכולות נוספים, בכפוף למספר המקסימלי של אשכולות שאפשר להוסיף ל-Fleet.

./asmcli create-mesh \
    FLEET_PROJECT_ID \
    PATH_TO_KUBECONFIG_1 \
    PATH_TO_KUBECONFIG_2

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

  1. מגדירים סודות מרחוק כדי לאפשר לשרת ה-API לגשת לאשכול למישור הבקרה של Cloud Service Mesh באשכול השני. הפקודות משתנות בהתאם לסוג Cloud Service Mesh (בתוך האשכול או מנוהל):

    א. ב-Cloud Service Mesh בתוך האשכול, צריך להגדיר את כתובות ה-IP הפרטיות במקום כתובות ה-IP הציבוריות, כי אי אפשר לגשת לכתובות ה-IP הציבוריות:

    PRIV_IP=`gcloud container clusters describe "${CLUSTER_1}" --project "${PROJECT_1}" \
     --zone "${LOCATION_1}" --format "value(privateClusterConfig.privateEndpoint)"`
    
    ./istioctl x create-remote-secret --context=${CTX_1} --name=${CLUSTER_1} --server=https://${PRIV_IP} > ${CTX_1}.secret
    
    PRIV_IP=`gcloud container clusters describe "${CLUSTER_2}" --project "${PROJECT_2}" \
     --zone "${LOCATION_2}" --format "value(privateClusterConfig.privateEndpoint)"`
    
    ./istioctl x create-remote-secret --context=${CTX_2} --name=${CLUSTER_2} --server=https://${PRIV_IP} > ${CTX_2}.secret
    

    ב. ל-Managed Cloud Service Mesh:

    PUBLIC_IP=`gcloud container clusters describe "${CLUSTER_1}" --project "${PROJECT_1}" \
     --zone "${LOCATION_1}" --format "value(privateClusterConfig.publicEndpoint)"`
    
    ./istioctl x create-remote-secret --context=${CTX_1} --name=${CLUSTER_1} --server=https://${PUBLIC_IP} > ${CTX_1}.secret
    
    PUBLIC_IP=`gcloud container clusters describe "${CLUSTER_2}" --project "${PROJECT_2}" \
     --zone "${LOCATION_2}" --format "value(privateClusterConfig.publicEndpoint)"`
    
    ./istioctl x create-remote-secret --context=${CTX_2} --name=${CLUSTER_2} --server=https://${PUBLIC_IP} > ${CTX_2}.secret
    
  2. מחילים את הסודות החדשים על האשכולות:

    kubectl apply -f ${CTX_1}.secret --context=${CTX_2}
    
    kubectl apply -f ${CTX_2}.secret --context=${CTX_1}
    

הגדרת רשתות מורשות לאשכולות פרטיים

ההוראות שבקטע הזה רלוונטיות רק אם כל התנאים הבאים מתקיימים ברשת שלכם:

כשפורסים כמה אשכולות פרטיים, מישור הבקרה של Cloud Service Mesh בכל אשכול צריך לקרוא למישור הבקרה של GKE באשכולות המרוחקים. כדי לאפשר תנועה, צריך להוסיף את טווח הכתובות של ה-Pod באשכול שקורא לאשכולים המרוחקים לרשתות המורשות של האשכולים המרוחקים.

  1. מקבלים את בלוק ה-CIDR של כתובות ה-IP של ה-Pods לכל אשכול:

    POD_IP_CIDR_1=`gcloud container clusters describe ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1} \
      --format "value(ipAllocationPolicy.clusterIpv4CidrBlock)"`
    
    POD_IP_CIDR_2=`gcloud container clusters describe ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2} \
      --format "value(ipAllocationPolicy.clusterIpv4CidrBlock)"`
    
  2. מוסיפים את בלוקי ה-CIDR של כתובות ה-IP של הפודים באשכול Kubernetes לאשכולות המרוחקים:

    EXISTING_CIDR_1=`gcloud container clusters describe ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1} \
     --format "value(masterAuthorizedNetworksConfig.cidrBlocks.cidrBlock)"`
    gcloud container clusters update ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1} \
    --enable-master-authorized-networks \
    --master-authorized-networks ${POD_IP_CIDR_2},${EXISTING_CIDR_1//;/,}
    
    EXISTING_CIDR_2=`gcloud container clusters describe ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2} \
     --format "value(masterAuthorizedNetworksConfig.cidrBlocks.cidrBlock)"`
    gcloud container clusters update ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2} \
    --enable-master-authorized-networks \
    --master-authorized-networks ${POD_IP_CIDR_1},${EXISTING_CIDR_2//;/,}
    

    מידע נוסף זמין במאמר בנושא יצירת אשכול עם רשתות מורשות.

  3. מוודאים שהרשתות המורשות מעודכנות:

    gcloud container clusters describe ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1} \
     --format "value(masterAuthorizedNetworksConfig.cidrBlocks.cidrBlock)"
    
    gcloud container clusters describe ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2} \
     --format "value(masterAuthorizedNetworksConfig.cidrBlocks.cidrBlock)"
    

הפעלת גישה גלובלית למישור הבקרה

ההוראות שבקטע הזה רלוונטיות רק אם כל התנאים הבאים מתקיימים ברשת שלכם:

  • אתם משתמשים באשכולות פרטיים.
  • אתם משתמשים באזורים שונים עבור האשכולות ברשת שלכם.

כדי לאפשר למישור הבקרה של Cloud Service Mesh בכל אשכול לקרוא למישור הבקרה של GKE באשכולות מרוחקים, צריך להפעיל גישה גלובלית למישור הבקרה.

  1. הפעלת גישה גלובלית למישור הבקרה:

    gcloud container clusters update ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1} \
     --enable-master-global-access
    
    gcloud container clusters update ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2} \
     --enable-master-global-access
    
  2. מוודאים שהגישה הגלובלית למישור הבקרה מופעלת:

    gcloud container clusters describe ${CLUSTER_1} --project ${PROJECT_1} --zone ${LOCATION_1}
    
    gcloud container clusters describe ${CLUSTER_2} --project ${PROJECT_2} --zone ${LOCATION_2}
    

    בקטע privateClusterConfig בפלט מוצג הסטטוס של masterGlobalAccessConfig.

אימות הקישוריות בין כמה אשכולות

בקטע הזה מוסבר איך לפרוס את שירותי הדוגמה HelloWorld ו-Sleep בסביבה מרובת אשכולות כדי לוודא שאיזון העומסים בין האשכולות פועל.

הגדרת משתנה לספריית הדוגמאות

  1. עוברים למיקום שבו asmcli הורד, ומריצים את הפקודה הבאה כדי להגדיר את ASM_VERSION

    export ASM_VERSION="$(./asmcli --version)"
    
  2. מגדירים תיקייה פעילה לדוגמאות שבהן משתמשים כדי לוודא שאיזון העומסים בין אשכולות פועל. הדוגמאות ממוקמות בספריית משנה בספרייה --output_dir שציינתם בפקודה asmcli install. בפקודה הבאה, משנים את OUTPUT_DIR לספרייה שציינתם ב---output_dir.

    export SAMPLES_DIR=OUTPUT_DIR/istio-${ASM_VERSION%+*}
    

הפעלת הזרקה של sidecar

  1. מאתרים את ערך תווית הגרסה, שבו תשתמשו בשלבים הבאים. השלב תלוי בסוג Cloud Service Mesh (מנוהל או בתוך האשכול).

    מנוהל

    משתמשים בפקודה הבאה כדי לאתר את תווית הגרסה, שבה תשתמשו בשלבים הבאים.

    kubectl get controlplanerevision -n istio-system

    הפלט אמור להיראות כך:

     NAME                RECONCILED   STALLED   AGE
     asm-managed-rapid   True         False     89d
     

    בפלט, בעמודה NAME, מציינים את הערך של תווית הגרסה. בדוגמה הזו, הערך הוא asm-managed-rapid. משתמשים בערך של הגרסה בשלבים שבקטע הבא.

    באשכול

    משתמשים בפקודה הבאה כדי לאתר את תווית הגרסה, שבה תשתמשו בשלבים הבאים.

    kubectl -n istio-system get pods -l app=istiod --show-labels

    הפלט אמור להיראות כך:

     NAME                                READY   STATUS    RESTARTS   AGE   LABELS
     istiod-asm-173-3-5788d57586-bljj4   1/1     Running   0          23h   app=istiod,istio.io/rev=asm-173-3,istio=istiod,pod-template-hash=5788d57586
     istiod-asm-173-3-5788d57586-vsklm   1/1     Running   1          23h   app=istiod,istio.io/rev=asm-173-3,istio=istiod,pod-template-hash=5788d57586
     

    בפלט, בעמודה LABELS, מציינים את הערך של istiodתווית הגרסה, שמופיע אחרי הקידומת istio.io/rev=. בדוגמה הזו, הערך הוא asm-173-3. משתמשים בערך של הגרסה בשלבים שבקטע הבא.

התקנת השירות HelloWorld

  1. יוצרים את מרחב השמות לדוגמה ואת הגדרת השירות בכל אשכול. בפקודה הבאה, מחליפים את REVISION בistiodתווית הגרסה שרשמתם בשלב הקודם.

    for CTX in ${CTX_1} ${CTX_2}
    do
        kubectl create --context=${CTX} namespace sample
        kubectl label --context=${CTX} namespace sample \
            istio-injection- istio.io/rev=REVISION --overwrite
    done
    

    כאשר REVISION הוא תווית הגרסה istiod שציינתם קודם.

    הפלט שיתקבל:

    label "istio-injection" not found.
    namespace/sample labeled
    

    אפשר להתעלם מההודעה label "istio-injection" not found.

  2. יוצרים את השירות HelloWorld בשני האשכולות:

    kubectl create --context=${CTX_1} \
        -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
        -l service=helloworld -n sample
    
    kubectl create --context=${CTX_2} \
        -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
        -l service=helloworld -n sample
    

פריסת HelloWorld v1 ו-v2 לכל אשכול

  1. פריסת HelloWorld v1 אל CLUSTER_1 ופריסת v2 אל CLUSTER_2, מה שיעזור בהמשך לאמת את איזון העומסים בין האשכולות:

    kubectl create --context=${CTX_1} \
      -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
      -l version=v1 -n sample
    kubectl create --context=${CTX_2} \
      -f ${SAMPLES_DIR}/samples/helloworld/helloworld.yaml \
      -l version=v2 -n sample
  2. מריצים את הפקודות הבאות כדי לוודא ש-HelloWorld v1 ו-v2 פועלים. מוודאים שהפלט דומה לזה שמוצג.:

    kubectl get pod --context=${CTX_1} -n sample
    NAME                            READY     STATUS    RESTARTS   AGE
    helloworld-v1-86f77cd7bd-cpxhv  2/2       Running   0          40s
    kubectl get pod --context=${CTX_2} -n sample
    NAME                            READY     STATUS    RESTARTS   AGE
    helloworld-v2-758dd55874-6x4t8  2/2       Running   0          40s

פריסת שירות השינה

  1. פורסים את שירות Sleep בשני האשכולות. ה-Pod הזה יוצר תנועת רשת מלאכותית למטרות הדגמה:

    for CTX in ${CTX_1} ${CTX_2}
    do
        kubectl apply --context=${CTX} \
            -f ${SAMPLES_DIR}/samples/sleep/sleep.yaml -n sample
    done
    
  2. ממתינים עד שהשירות Sleep יופעל בכל אשכול. מוודאים שהפלט דומה לזה שמוצג:

    kubectl get pod --context=${CTX_1} -n sample -l app=sleep
    NAME                             READY   STATUS    RESTARTS   AGE
    sleep-754684654f-n6bzf           2/2     Running   0          5s
    kubectl get pod --context=${CTX_2} -n sample -l app=sleep
    NAME                             READY   STATUS    RESTARTS   AGE
    sleep-754684654f-dzl9j           2/2     Running   0          5s

אימות איזון עומסים בין אשכולות

מתקשרים לשירות HelloWorld כמה פעמים ובודקים את הפלט כדי לוודא שמתקבלות תשובות מתחלפות מגרסה 1 ומגרסה 2:

  1. מתקשרים לשירות HelloWorld:

    kubectl exec --context="${CTX_1}" -n sample -c sleep \
        "$(kubectl get pod --context="${CTX_1}" -n sample -l \
        app=sleep -o jsonpath='{.items[0].metadata.name}')" \
        -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'
    

    הפלט אמור להיראות כך:

    Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8
    Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv
    ...
  2. מתקשרים שוב לשירות HelloWorld:

    kubectl exec --context="${CTX_2}" -n sample -c sleep \
        "$(kubectl get pod --context="${CTX_2}" -n sample -l \
        app=sleep -o jsonpath='{.items[0].metadata.name}')" \
        -- /bin/sh -c 'for i in $(seq 1 20); do curl -sS helloworld.sample:5000/hello; done'
    

    הפלט אמור להיראות כך:

    Hello version: v2, instance: helloworld-v2-758dd55874-6x4t8
    Hello version: v1, instance: helloworld-v1-86f77cd7bd-cpxhv
    ...

האימות של Cloud Service Mesh עם איזון עומסים ומרובה אשכולות הסתיים בהצלחה.

ניקוי שירות HelloWorld

אחרי שמסיימים לאמת את איזון העומסים, מסירים את שירות HelloWorld ואת שירות Sleep מהאשכול.

kubectl delete ns sample --context ${CTX_1}
kubectl delete ns sample --context ${CTX_2}