עדכוני הגדרות למודרניזציה

במסמך הזה מתוארים עדכוני ההגדרות שאולי תצטרכו לבצע ב-Cloud Service Mesh המנוהל לפני שתעדכנו את הרשת למישור הבקרה TRAFFIC_DIRECTOR ממישור הבקרה ISTIOD.

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

מידע נוסף על תהליך העבודה של המודרניזציה זמין בדף מודרניזציה של מישור הבקרה המנוהל.

העברה של סודות מ-Istio ל-multicluster_mode

אין תמיכה בסודות מרובי-אשכולות כשמשתמשים במישור הבקרה TRAFFIC_DIRECTOR באשכול. במאמר הזה נסביר איך לעבור משימוש בסודות של Istio multi-cluster לשימוש ב-multicluster_mode.

סקירה כללית על ערכי Istio Secret לעומת API הצהרתי

גילוי נקודות קצה בקוד פתוח של Istio multi-cluster מתבצע באמצעות istioctl או כלים אחרים ליצירת Kubernetes Secret באשכול. הסוד הזה מאפשר לאשכול לאזן את עומס התעבורה לאשכול אחר ברשת. מישור הבקרה ISTIOD קורא את הסוד הזה ומתחיל לנתב את התעבורה לאותו אשכול אחר.

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

אם אתם משתמשים ב-Istio Secrets, מומלץ לעבור לשימוש ב-API הדקלרטיבי בהקדם האפשרי. שימו לב: ההגדרה multicluster_mode מכוונת כל אשכול להפנות תנועה ישירה לכל אשכול אחר ברשת. שימוש בסודות מאפשר הגדרה גמישה יותר, שבה אפשר להגדיר לכל אשכול לאיזה אשכול אחר ברשת הוא צריך להפנות תנועה. רשימה מלאה של ההבדלים בין התכונות הנתמכות של ממשק ה-API הדקלרטיבי לבין סודות של Istio מופיעה במאמר תכונות נתמכות באמצעות ממשקי Istio API.

מעבר מ-Istio secrets ל-declarative API

אם הקציתם את Cloud Service Mesh באמצעות ניהול אוטומטי עם fleet feature API, אתם לא צריכים לפעול לפי ההוראות האלה. השלבים האלה רלוונטיים רק אם הצטרפתם ל-asmcli --managed.

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

כדי לעבור משימוש בסודות של Istio ל-API הצהרתי, צריך לבצע את השלבים הבאים. מבצעים את השלבים הבאים בו-זמנית או ברצף מהיר:

  1. מפעילים את ה-API הדקלרטיבי לכל אשכול בצי שרוצים להפעיל בו גילוי של נקודות קצה מרובות אשכולות. לשם כך, מגדירים את multicluster_mode=connected. שימו לב: אם לא רוצים שהאשכול יהיה ניתן לגילוי, צריך להגדיר במפורש את הערך multicluster_mode=disconnected.

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

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

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

     kubectl patch configmap/asm-options -n istio-system --type merge -p '{"data":{"multicluster_mode":"disconnected"}}'
    
  2. מוחקים את הסודות הישנים.

    אחרי שמגדירים את multicluster_mode=connected באשכולות, לכל אשכול ייווצר סוד חדש לכל אשכול אחר שגם בו מוגדר multicluster_mode=connected. הסוד ממוקם במרחב השמות istio-system והפורמט שלו הוא:

    istio-remote-secret-projects-PROJECT_NAME-locations-LOCATION-memberships-MEMBERSHIPS
    

    בנוסף, תתווסף לכל סוד התווית istio.io/owned-by: mesh.googleapis.com.

    אחרי שיוצרים את הסודות החדשים, אפשר למחוק באופן ידני את הסודות שנוצרו באמצעות istioctl create-remote-secret:

    kubectl delete secret SECRET_NAME -n istio-system
    

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

הפעלת איחוד זהויות של עומסי עבודה ל-GKE

איחוד שירותי אימות הזהות של עומסי עבודה הוא השיטה המומלצת והמאובטחת לעומסי עבודה של Google Kubernetes Engine. הגישה הזו מאפשרת שימוש ב Google Cloud שירותים כמו Compute Engine,‏ BigQuery וממשקי API של למידת מכונה. איחוד שירותי אימות הזהות של עומסי עבודה לא דורש הגדרה ידנית או שיטות פחות מאובטחות כמו קובצי מפתחות של חשבונות שירות, כי הוא משתמש במדיניות IAM. לפרטים נוספים על איחוד שירותי אימות הזהויות של עומסי עבודה, אפשר לקרוא את המאמר איך פועל איחוד שירותי אימות הזהויות של עומסי עבודה ב-GKE.

בקטע הבא מוסבר איך להפעיל איחוד שירותי אימות הזהות של עומסי עבודה.

הפעלת איחוד שירותי אימות הזהות של עומסי עבודה באשכולות

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

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

    gcloud container clusters describe CLUSTER_NAME \
      --format="value(workloadIdentityConfig.workloadPool)"
    

    מחליפים את CLUSTER_NAME בשם של אשכול GKE. אם עדיין לא ציינתם אזור או תחום ברירת מחדל ל-gcloud, יכול להיות שתצטרכו לציין גם את הדגל --region או --zone כשמריצים את הפקודה הזו.

  2. אם הפלט ריק, פועלים לפי ההוראות במאמר עדכון של אשכול קיים כדי להפעיל את זהות עומס העבודה באשכולות GKE קיימים.

הפעלת איחוד שירותי אימות הזהות של עומסי העבודה במאגרי צמתים

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

  1. הצגת רשימה של כל מאגרי הצמתים באשכול Standard. מריצים את הפקודה gcloud container node-pools list:

    gcloud container node-pools list --cluster CLUSTER_NAME
    

    מחליפים את CLUSTER_NAME בשם של אשכול GKE. אם עדיין לא ציינתם אזור או תחום ברירת מחדל ל-gcloud, יכול להיות שתצטרכו לציין גם את הדגל --region או --zone כשמריצים את הפקודה הזו.

  2. מוודאים שכל מאגר צמתים משתמש בשרת המטא-נתונים של GKE:

    gcloud container node-pools describe NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --format="value(config.workloadMetadataConfig.mode)"
    

    מחליפים את מה שכתוב בשדות הבאים:

    • NODEPOOL_NAME מחליפים בשם של מאגר הצמתים.
    • CLUSTER_NAME בשם של אשכול GKE.
  3. אם הפלט לא מכיל את GKE_METADATA, מעדכנים את מאגר הצמתים באמצעות המדריך עדכון של מאגר צמתים קיים.

הפעלה של ממשק רשת מנוהל של מאגר (CNI)

בקטע הזה מוסבר איך להפעיל CNI מנוהל עבור Cloud Service Mesh ב-Google Kubernetes Engine.

סקירה כללית של CNI מנוהל

ממשק רשת קונטיינרים (CNI) מנוהל הוא הטמעה של Istio CNI שמנוהלת על ידי Google. תוסף CNI מייעל את הרשת של ה-Pod על ידי הגדרת כללי iptables. האפשרות הזו מאפשרת להפנות תנועה בין אפליקציות ושרתי proxy של Envoy, וכך לא נדרשות הרשאות מיוחדות עבור init-container שנדרש לניהול iptables.

Istio CNI plugin מחליף את מאגר התגים istio-init. בעבר, קונטיינר istio-init היה אחראי להגדרת סביבת הרשת של ה-Pod כדי לאפשר יירוט של תעבורה עבור ה-sidecar של Istio. תוסף ה-CNI מבצע את אותה פונקציית הפניה מחדש של הרשת, אבל עם היתרון הנוסף של צמצום הצורך בהרשאות מורחבות, וכך משפר את האבטחה.

לכן, כדי לשפר את האבטחה והאמינות, וכדי לפשט את הניהול ואת פתרון הבעיות, נדרש CNI מנוהל בכל הפריסות של Managed Cloud Service Mesh.

ההשפעה על קונטיינרים של init

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

תהליך ההגדרה של ה-Pod עם CNI מנוהל הוא כזה:

  1. פלאגין ה-CNI מגדיר ממשקי רשת של פודים, מקצה כתובות IP לפודים ומפנה תעבורה ל-proxy של Istio sidecar, שעדיין לא הופעל.
  2. כל קונטיינרי ה-init מופעלים ומושלמים.
  3. פרוקסי קובץ העזר החיצוני של Istio מופעל לצד קונטיינרים של אפליקציות.

לכן, אם קובץ init container מנסה ליצור חיבורים יוצאים לרשת או להתחבר לשירותים בתוך הרשת, יכול להיות שהבקשות מה-init container ייפסלו או ינותבו בצורה שגויה. הסיבה לכך היא שפרוקסי ה-sidecar של Istio, שמנהל את התנועה ברשת עבור ה-pod, לא פועל כשמתבצעות הבקשות. פרטים נוספים זמינים במסמכי התיעוד של Istio CNI.

הפעלת CNI מנוהל באשכול

כדי להפעיל CNI מנוהל באשכול, פועלים לפי השלבים שמפורטים בקטע הזה.

  1. מסירים את התלות ברשת מהקונטיינר של init. כדאי לשקול את החלופות הבאות:

    • שינוי הלוגיקה או המאגרים של האפליקציה: אתם יכולים לשנות את השירותים כדי להסיר את התלות במאגרי init שדורשים בקשות לרשת או לבצע פעולות רשת במאגרי האפליקציה, אחרי שקובץ העזר החיצוני הופעל.
    • שימוש ב-ConfigMaps או בסודות של Kubernetes: אחסון נתוני התצורה שאוחזרו על ידי בקשת הרשת ב-ConfigMaps או בסודות של Kubernetes, והעברתם למאגרי האפליקציות. פתרונות חלופיים מפורטים במסמכי התיעוד של Istio.
  2. מפעילים CNI מנוהל באשכול:

    1. מבצעים את שינויי ההגדרה הבאים:

      1. מריצים את הפקודה הבאה כדי לאתר את controlPlaneRevision.

        kubectl get controlplanerevision -n istio-system
        
      2. במשאב המותאם אישית (CR) של ControlPlaneRevision (CPR), מגדירים את התווית mesh.cloud.google.com/managed-cni-enabled לערך true.

        kubectl label controlplanerevision CPR_NAME \
            -n istio-system mesh.cloud.google.com/managed-cni-enabled=true \
            --overwrite
        

        מחליפים את CPR_NAME בערך שמופיע בעמודה NAME בפלט מהשלב הקודם.

      3. ב-ConfigMap‏ asm-options, מגדירים את הערך ASM_OPTS ל-CNI=on.

        kubectl patch configmap asm-options -n istio-system \
            -p '{"data":{"ASM_OPTS":"CNI=on"}}'
        
      4. במשאב המותאם אישית (CR) של ControlPlaneRevision (CPR), מגדירים את התווית mesh.cloud.google.com/force-reprovision לערך true. הפעולה הזו מפעילה מחדש את מישור הבקרה.

        kubectl label controlplanerevision CPR_NAME \
            -n istio-system mesh.cloud.google.com/force-reprovision=true \
            --overwrite
        
    2. בודקים את מצב התכונה. מאחזרים את מצב התכונה באמצעות הפקודה הבאה:

      gcloud container fleet mesh describe --project FLEET_PROJECT_ID
      

      מחליפים את FLEET_PROJECT_ID במזהה של פרויקט המארח של Fleet. בדרך כלל, השם של FLEET_PROJECT_ID זהה לשם הפרויקט.

      • מוודאים שהתנאי MANAGED_CNI_NOT_ENABLED הוסר מ-servicemesh.conditions.
      • הערה: יכולות לעבור 15-20 דקות עד שהסטטוס יתעדכן. כדאי להמתין כמה דקות ולהריץ מחדש את הפקודה.
    3. אחרי שהסטטוס של התכונה controlPlaneManagement.state יהיה Active במצב התכונה של האשכול, מפעילים מחדש את ה-pods.

מעבר משימוש בינארי לא סטנדרטי ב-Sidecar

בקטע הזה מוצעות דרכים להפוך את הפריסות לתואמות לתמונת ה-proxy של Envoy ללא הפצה.

תמונות של קובץ עזר חיצוני (sidecar) של Envoy proxy ללא הפצה

‫Cloud Service Mesh משתמש בשני סוגים של קובצי אימג' של Envoy proxy sidecar על סמך הגדרת מישור הבקרה, קובץ אימג' מבוסס Ubuntu שמכיל קבצים בינאריים שונים וקובץ אימג' Distroless. תמונות בסיס ללא הפצה הן תמונות מינימליות של קונטיינרים שבהן יש עדיפות לאבטחה ולאופטימיזציה של משאבים, כי הן כוללות רק רכיבים חיוניים. השטח החשוף להתקפה מצטמצם כדי למנוע פגיעויות. מידע נוסף מופיע במאמר בנושא תמונת proxy ללא הפצה.

תאימות בינארית

השיטה המומלצת היא להגביל את התוכן של זמן ריצה של קונטיינר רק לחבילות הנדרשות. הגישה הזו משפרת את האבטחה ואת יחס האות לרעש של סורקי חשיפות ופגיעויות נפוצות (CVE). תמונת ה-Sidecar ללא הפצה כוללת קבוצה מינימלית של תלות, ללא קובצי הפעלה, ספריות וכלי ניפוי באגים לא חיוניים. לכן אי אפשר להריץ פקודת מעטפת או להשתמש ב-curl, ב-ping או בכלי ניפוי באגים אחרים כמו kubectl exec בתוך הקונטיינר.

התאמת אשכולות לתמונות distroless

אם לא מצאתם פתרון לתרחיש השימוש הספציפי שלכם, תוכלו לפנות אל Google Cloud התמיכה בקבלת תמיכה.

מעבר אל Istio Ingress Gateway

בקטע הזה מוסבר איך לבצע מיגרציה אל Istio Ingress Gateway. יש שתי שיטות להעברה אל Istio Ingress Gateway:

  1. העברה בשלבים עם חלוקת תנועה

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

  2. העברה ישירה

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

בדוגמאות הבאות להעברה מניחים שיש לכם שירות HTTP ‏ (httpbin) שפועל במרחב השמות של האפליקציה (ברירת מחדל) וחשוף חיצונית באמצעות Kubernetes Gateway API. ההגדרות הרלוונטיות הן:

  • שער: k8-api-gateway (במרחב השמות istio-ingress) – מוגדר להאזין לתנועת HTTP ביציאה 80 לכל שם מארח שמסתיים ב-.example.com.
  • ‫HTTPRoute: ‏ httpbin-route (במרחב השמות default) – מכוון כל בקשת HTTP עם שם המארח httpbin.example.com ונתיב שמתחיל ב-/get לשירות httpbin במרחב השמות default.
  • אפשר לגשת לאפליקציית httpbin באמצעות כתובת ה-IP החיצונית 34.57.246.68.

דיאגרמת שער בסיסית

העברה בשלבים עם חלוקת תנועה

הקצאת שער חדש לתעבורת נתונים נכנסת (ingress) של Istio

  1. מבצעים פריסה של שער Ingress חדש לפי השלבים שמפורטים בקטע בנושא פריסת שער לדוגמה, ומתאימים אישית את הגדרות הדוגמה לדרישות שלכם. הדוגמאות במאגר anthos-service-mesh מיועדות לפריסת שירות istio-ingressgateway loadBalancer ותרמילי ingress-gateway התואמים.

    משאב שער לדוגמה (istio-ingressgateway.yaml)

     apiVersion: networking.istio.io/v1beta1
     kind: Gateway
     metadata:
       name: istio-api-gateway
       namespace: GATEWAY_NAMESPACE
     spec:
       selector:
         istio: ingressgateway  # The selector should match the ingress-gateway pod labels.
       servers:
       - port:
           number: 80
           name: http
           protocol: HTTP
         hosts:   # or specific hostnames if needed
         - "httpbin.example.com"
    
  2. החלת ההגדרה Gateway לניהול התנועה:

    kubectl apply -f istio-ingressgateway.yaml -n GATEWAY_NAMESPACE
    

    מוודאים שהערך spec.selector במשאב Gateway תואם לתוויות של תרמילי ingress-gateway. לדוגמה, אם ל-pods של ingress-gateway יש את התווית istio=ingressgateway, בהגדרת השער צריך לבחור גם את התווית istio=ingressgateway.

הגדרת ניתוב ראשוני לשער החדש

  1. מגדירים את כללי הניתוב הראשוניים לאפליקציה באמצעות VirtualService של Istio.

    דוגמה ל-VirtualService ‏ (my-app-vs-new.yaml):

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: httpbin-vs
      namespace: APPLICATION_NAMESPACE
    spec:
        gateways:
        - istio-ingress/istio-api-gateway  # Replace with <gateway-namespace/gateway-name>
        hosts:
        - httpbin.example.com
        http:
        - match:
          - uri:
              prefix: /get
          route:
          - destination:
              host: httpbin
              port:
                number: 8000
    
  2. מחילים את VirtualService:

    kubectl apply -f my-app-vs-new.yaml -n MY_APP_NAMESPACE
    

גישה לשירות העורפי (httpbin) דרך שער Istio Ingress Gateway שנפרס לאחרונה

  1. מגדירים את משתנה הסביבה Ingress Host לכתובת ה-IP החיצונית שמשויכת למאזן העומסים istio-ingressgateway שנפרס לאחרונה:

    export INGRESS_HOST=$(kubectl -n GATEWAY_NAMESPACE get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    
  2. מוודאים שאפשר לגשת לאפליקציה (httpbin) באמצעות השער החדש:

    curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"
    

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

    HTTP/1.1 200 OK
    

תהליך הבקשה עם שער הכניסה החדש של Istio

שינוי של Ingress קיים לצורך פיצול תנועה

אחרי שמוודאים שההגדרה של השער החדש (למשל, istio-api-gateway) הושלמה בהצלחה, אפשר להתחיל להפנות חלק מהתנועה דרכו. כדי לעשות את זה, צריך לעדכן את HTTPRoute הנוכחי כדי להפנות אחוז קטן של תנועה לשער החדש, בזמן שהחלק הגדול יותר ממשיך להשתמש בשער הקיים (k8-api-gateway).

  1. פותחים את ה-HTTPRoute לעריכה:

    kubectl edit httproute httpbin-route -n MY_APP_NAMESPACE
    
  2. מוסיפים הפניה חדשה לקצה העורפי שמפנה לשירות מאזן העומסים של שער Ingress החדש עם משקל התחלתי של 10%, ומעדכנים את המשקל של הקצה העורפי של השער הישן.

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin-route
      namespace: MY_APP_NAMESPACE  # your application's namespace
    spec:
      parentRefs:
      - name: k8-api-gateway
        namespace: istio-ingress
      hostnames: ["httpbin.example.com"]
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /get
        backendRefs:
        - name: httpbin
          port: 8000
          weight: 90
        - name: istio-ingressgateway # Newly deployed load balancer service
          namespace: GATEWAY_NAMESPACE
          port: 80
          weight: 10
    
  3. נותנים הרשאה להפניה בין מרחבי שמות באמצעות מתן הרשאה להפניה.

    כדי לאפשר ל-HTTPRoute במרחב השמות של האפליקציה (ברירת מחדל) לגשת לשירות loadbalancer במרחב השמות של שער הכניסה (istio-ingress), יכול להיות שתצטרכו ליצור הרשאת הפניה. המשאב הזה משמש כאמצעי בקרה לאבטחה, ומגדיר באופן מפורש אילו הפניות בין מרחבי שמות מותרות.

    בדוגמה הבאה istio-ingress-grant.yaml מתואר מענק הרשאה מסוג הפניה:

    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: ReferenceGrant
    metadata:
      name: istio-ingressgateway-grant
      namespace: istio-ingress # Namespace of the referenced resource
    spec:
      from:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute 
        namespace: MY_APP_NAMESPACE # Namespace of the referencing resource
      to:
      - group: ""               # Core Kubernetes API group for Services
        kind: Service
        name: istio-ingressgateway # Loadbalancer Service of the new ingress gateway
    
  4. החלת מענק הגישה:

    kubectl apply -f istio-ingress-grant.yaml -n GATEWAY_NAMESPACE
    
  5. אימות בקשות לכתובת IP חיצונית קיימת (לדוגמה, ‫34.57.246.68) לא נכשלות. בדוגמה הבאה check-traffic-flow.sh מתואר סקריפט לבדיקת כשלים בבקשות:

    # Update the following values based on your application setup
    external_ip="34.57.246.68" # Replace with existing external IP
    url="http://$external_ip/get"
    host_name="httpbin.example.com"
    
    # Counter for successful requests
    success_count=0
    
    # Loop 50 times
    for i in {1..50}; do
      # Perform the curl request and capture the status code
      status_code=$(curl -s -HHost:"$host_name" -o /dev/null -w "%{http_code}" "$url")
      # Check if the request was successful (status code 200)
      if [ "$status_code" -eq 200 ]; then
        ((success_count++))  # Increment the success counter
      else
        echo "Request $i: Failed with status code $status_code"
      fi
    done
    
    # After the loop, check if all requests were successful
    if [ "$success_count" -eq 50 ]; then
      echo "All 50 requests were successful!"
    else
      echo "Some requests failed.  Successful requests: $success_count"
    fi
    
  6. מריצים את הסקריפט כדי לוודא שאף בקשה לא נכשלת, ללא קשר לנתיב התנועה:

    chmod +x check-traffic-flow.sh
    ./check-traffic-flow.sh
    

בקשת זרימה עם חלוקת התנועה בין שער קיים לשער חדש של Istio Ingress

הגדלה הדרגתית של אחוז התנועה

אם לא רואים כשלים בבקשות עבור כתובת ה-IP החיצונית הקיימת (לדוגמה, 34.57.246.68), מעבירים בהדרגה יותר תנועה ל-Istio Ingress Gateway החדש על ידי שינוי המשקלים של ה-backend ב-HTTPRoute. מגדילים את המשקל של istio-ingressgateway ומקטינים את המשקל של השער הישן במרווחים קטנים, כמו 10%, 20% וכן הלאה.

כדי לעדכן את HTTPRoute הקיים, משתמשים בפקודה הבאה:

kubectl edit httproute httpbin-route -n MY_APP_NAMESPACE

העברה מלאה של התנועה והסרה של השער הישן

  1. כשהביצועים של שער הכניסה החדש של Istio יהיו יציבים והטיפול בבקשות יהיה מוצלח, תעבירו אליו את כלל התנועה. מעדכנים את HTTPRoute כדי להגדיר את המשקל של העורף של השער הישן ל-0 ואת המשקל של העורף של השער החדש ל-100.

  2. אחרי שתעבורת הנתונים תנותב באופן מלא לשער החדש, צריך לעדכן את רשומות ה-DNS החיצוניות של שם המארח של האפליקציה (לדוגמה, httpbin.example.com) כך שיצביעו על כתובת ה-IP החיצונית של שירות מאזן העומסים שנוצר בשלב הקצאת שער חדש של Istio Ingress.

  3. לבסוף, מוחקים את השער הישן ואת המשאבים שמשויכים אליו:

    kubectl delete gateway OLD_GATEWAY -n GATEWAY_NAMESPACE
    kubectl delete service OLD_GATEWAY_SERVICE -n GATEWAY_NAMESPACE
    

העברה ישירה

הקצאת שער חדש לתעבורת נתונים נכנסת (ingress) של Istio

  1. מבצעים פריסה של שער Ingress חדש לפי השלבים שמפורטים בקטע בנושא פריסת שער לדוגמה, ומתאימים אישית את הגדרות הדוגמה לדרישות שלכם. הדוגמאות במאגר anthos-service-mesh מיועדות לפריסת שירות istio-ingressgateway loadBalancer ותרמילי ingress-gateway התואמים.

    משאב שער לדוגמה (istio-ingressgateway.yaml)

     apiVersion: networking.istio.io/v1beta1
     kind: Gateway
     metadata:
       name: istio-api-gateway
       namespace: GATEWAY_NAMESPACE
     spec:
       selector:
         istio: ingressgateway  # The selector should match the ingress-gateway pod labels.
       servers:
       - port:
           number: 80
           name: http
           protocol: HTTP
         hosts:   # or specific hostnames if needed
         - "httpbin.example.com"
    
  2. החלת ההגדרה Gateway לניהול התנועה:

    kubectl apply -f istio-ingressgateway.yaml -n GATEWAY_NAMESPACE
    

    מוודאים שהערך spec.selector במשאב Gateway תואם לתוויות של תרמילי ingress-gateway. לדוגמה, אם ל-pods של ingress-gateway יש את התווית istio=ingressgateway, בהגדרת השער צריך לבחור גם את התווית istio=ingressgateway.

הגדרת ניתוב ראשוני לשער החדש

  1. מגדירים את כללי הניתוב הראשוניים לאפליקציה באמצעות VirtualService של Istio.

    דוגמה ל-VirtualService ‏ (my-app-vs-new.yaml):

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: httpbin-vs
      namespace: APPLICATION_NAMESPACE
    spec:
        gateways:
        - istio-ingress/istio-api-gateway  # Replace with <gateway-namespace/gateway-name>
        hosts:
        - httpbin.example.com
        http:
        - match:
          - uri:
              prefix: /get
          route:
          - destination:
              host: httpbin
              port:
                number: 8000
    
  2. מחילים את VirtualService:

    kubectl apply -f my-app-vs-new.yaml -n MY_APP_NAMESPACE
    

גישה לשירות העורפי (httpbin) דרך שער Istio Ingress Gateway שנפרס לאחרונה

  1. מגדירים את משתנה הסביבה Ingress Host לכתובת ה-IP החיצונית שמשויכת למאזן העומסים istio-ingressgateway שנפרס לאחרונה:

    export INGRESS_HOST=$(kubectl -n GATEWAY_NAMESPACE get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    
  2. מוודאים שאפשר לגשת לאפליקציה (httpbin) באמצעות השער החדש:

    curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/get"
    

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

    HTTP/1.1 200 OK
    

תהליך הבקשה עם שער הכניסה החדש של Istio

בדיקה ומעקב אחרי שער חדש

  1. בודקים את כל כללי הניתוב, מאמתים את הגדרת ה-TLS, את מדיניות האבטחה ותכונות אחרות. מבצעים בדיקות עומס כדי לוודא שהשער החדש יכול להתמודד עם התנועה הצפויה.

  2. אחרי שבודקים את השער החדש באופן מלא, מעדכנים את רשומות ה-DNS החיצוניות של שם המארח של האפליקציה (לדוגמה, httpbin.example.com) כך שיפנו לכתובת ה-IP החיצונית של שירות מאזן העומסים שנוצר בהקצאת שער חדש של Istio Ingress.

  3. כדי לוודא שהיציבות נשמרת עם Istio Ingress Gateway החדש, כדאי לעקוב אחרי מדדים מרכזיים כמו שיעור ההצלחה של הבקשות, זמן האחזור, שיעורי השגיאות וניצול המשאבים של פודים באפליקציה. אחרי שהמצב יתייצב, תוכלו למחוק את השער הישן ואת המשאבים שמשויכים אליו.

    kubectl delete gateway OLD_GATEWAY -n GATEWAY_NAMESPACE
    kubectl delete service OLD_GATEWAY_SERVICE -n GATEWAY_NAMESPACE
    

שיקולים חשובים: אם האפליקציה שלכם דורשת HTTPS, חשוב לוודא שאישורי ה-TLS וההגדרות מוגדרים בצורה נכונה ב-Istio Ingress Gateway החדש. פרטים נוספים זמינים במאמר בנושא הגדרת סיום TLS בשער כניסה.

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

בעבר, Cloud Service Mesh תמך בצירוף באמצעות asmcli (הוצא משימוש), שלא חסם הקצאה של כמה מישורי בקרה. ‫Cloud Service Mesh אוכף עכשיו את השיטה המומלצת של פריסת ערוץ אחד בלבד לכל אשכול שתואם לערוץ האשכול, ולא תומך בשימוש בכמה ערוצים פרוסים באותו אשכול.

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

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

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

    gcloud container fleet mesh describe
    

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

    ...
    projects/.../locations/global/memberships/my-membership:
        servicemesh:
          conditions:
          - code: UNSUPPORTED_MULTIPLE_CONTROL_PLANES
            details: 'Using multiple control planes is not supported. Please remove a control plane from your cluster.'
            documentationLink: https://cloud.google.com/service-mesh/docs/migrate/modernization-configuration-updates#multiple_control_planes
            severity: WARNING
          controlPlaneManagement:
            details:
            - code: REVISION_READY
              details: 'Ready: asm-managed-stable'
            implementation: ISTIOD
            state: ACTIVE
    ...
    
  2. אם מופיע התנאי UNSUPPORTED_MULTIPLE_CONTROL_PLANES, צריך לקבוע אילו ערוצים קיימים באשכול:

    kubectl get controlplanerevisions -n istio-system
    

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

    NAME                 RECONCILED   STALLED   AGE
    asm-managed-stable   True         False     97d
    asm-managed          True         False     97d
    asm-managed-rapid    True         False     97d
    

    בדוגמה הזו, שלושת הערוצים הוקצו:

    • ‫asm-managed-stable -> STABLE
    • ‫asm-managed -> REGULAR
    • ‫asm-managed-rapid -> RAPID

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

    אם מופיעות 2 תוצאות או יותר, צריך לבצע את שאר השלבים כדי להסיר את הערוצים העודפים.

איחוד עומסי עבודה לערוץ אחד

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

  1. כדי לראות את כל התוויות שבהן אתם משתמשים באשכול:

    kubectl get namespaces -l istio.io/rev=RELEASE_CHANNEL
    

    בהתאם לפלט מהפקודה הקודמת, מחליפים את RELEASE_CHANNEL ב-asm-managed-stable, ב-asm-managed או ב-asm-managed-rapid. חוזרים על השלב הזה לכל ערוץ שהוקצה.

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

    NAME      STATUS   AGE
    default   Active   110d
    

    שימו לב שבדוגמה הזו, מרחב השמות שמוגדר כברירת מחדל מוזרק לערוץ הרגיל.

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

  2. משנים את התוויות כך שרק ערוץ אחד יהיה בשימוש:

    • במקרים מסוימים אפשר גם להוסיף פודים ישירות באמצעות התווית sidecar.istio.io/inject. חשוב לבדוק גם את השימוש הזה.
    • אפשר להתעלם מתוויות istio-injection=enabled בשלב הזה. מרחבי שמות עם התווית הזו ישתנו אוטומטית כך שיתאימו לערוץ שיישארו באשכול.
    • כשבוחרים ערוץ להשאיר, כדאי לבחור את הערוץ שזהה לערוץ של אשכול GKE. אם הערוץ הזה לא קיים, בוחרים אחד מהערוצים הפעילים.
    • לא משנה איזה ערוץ בוחרים. הגרסה של רשת ה-mesh שתקבלו נקבעת לפי ערוץ האשכול GKE, ולא לפי ערוץ ה-mesh.
    • בודקים את ההגדרה של meshconfig בין כל הערוצים הפעילים שנמצאים בשימוש כדי לוודא שאין הבדלים ביניהם. כל ערוץ משתמש במפת הגדרות נפרדת להגדרה, ולכן איחוד של שני ערוצים לערוץ אחד אמור להבטיח התנהגות עקבית בין שני הערוצים.kubectl get configmap istio-asm-managed{-rapid | -stable} -n istio-system -o yaml
    kubectl label namespace NAMESPACE istio.io/rev- istio-injection=enabled --overwrite
    

    מחליפים את NAMESPACE בשם של מרחב השמות.

    השיטה המומלצת היא להשתמש ב-istio-injection=enabled. אבל אם אתם לא רוצים להשתמש בתווית הזו, אתם יכולים להשתמש גם בistio.io/rev=RELEASE_CHANNEL.

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

הסרת הערוצים הנוספים

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

  1. מוחקים את המשאב הנוסף ControlPlaneRevision:

    kubectl delete controlplanerevision RELEASE_CHANNEL -n istio-system
    

    מחליפים את RELEASE_CHANNEL ב-asm-managed-stable, ב-asm-managed או ב-asm-managed-rapid.

  2. מחיקת MutatingWebhookConfiguration:

    kubectl delete mutatingwebhookconfiguration istiod-RELEASE_CHANNEL
    
  3. מחיקת ה-configmap של meshconfig:

    kubectl delete configmap istio-RELEASE_CHANNEL
    

הפעלת ניהול אוטומטי

  1. מריצים את הפקודה הבאה כדי להפעיל ניהול אוטומטי:

    gcloud container fleet mesh update \
        --management automatic \
        --memberships MEMBERSHIP_NAME \
        --project PROJECT_ID \
        --location MEMBERSHIP_LOCATION
    

    מחליפים את מה שכתוב בשדות הבאים:

    • MEMBERSHIP_NAME הוא שם החברות שמופיע כשאימתתם שהאשכול שלכם רשום בצי.
    • PROJECT_ID הוא מזהה הפרויקט.
    • MEMBERSHIP_LOCATION הוא המיקום של המינוי (אזור או global). אפשר לבדוק את המיקום של המינוי באמצעות gcloud container fleet memberships list --project PROJECT_ID.
  2. מוודאים שהניהול האוטומטי מופעל:

    gcloud container fleet mesh describe
    

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

    ...
    membershipSpecs:
      projects/.../locations/us-central1/memberships/my-member:
        mesh:
          management: MANAGEMENT_AUTOMATIC
    membershipStates:
      projects/.../locations/us-central1/memberships/my-member:
        servicemesh:
          conditions:
          - code: VPCSC_GA_SUPPORTED
            details: This control plane supports VPC-SC GA.
            documentationLink: http://cloud.google.com/service-mesh/docs/managed/vpc-sc
            severity: INFO
          controlPlaneManagement:
            details:
            - code: REVISION_READY
              details: 'Ready: asm-managed'
            implementation: TRAFFIC_DIRECTOR
            state: ACTIVE
          dataPlaneManagement:
            details:
            - code: OK
              details: Service is running.
            state: ACTIVE
        state:
          code: OK
          description: |-
            Revision ready for use: asm-managed.
            All Canonical Services have been reconciled successfully.
    ...