דוגמה לשימוש ב-Cloud Service Mesh: פריסות של גרסה ראשונית (canary)

במדריך הזה נסביר איך לבצע פריסה של גרסה ראשונית (canary) באמצעות Cloud Service Mesh, תרחיש שימוש נפוץ לדוגמה.

מהי פריסה של גרסה ראשונית (canary)?

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

עלויות

במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

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

משתמשים חדשים של Google Cloud ? יכול להיות שאתם זכאים לתקופת ניסיון בחינם.

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

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

פריסת Online Boutique

  1. מגדירים את ההקשר הנוכחי של kubectl לאשכול שבו פרסתם את Online Boutique:

    gcloud container clusters get-credentials CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  2. יוצרים את מרחב השמות עבור אפליקציית הדוגמה ושער הכניסה:

    kubectl create namespace onlineboutique
    
  3. מתייגים את מרחב השמות onlineboutique כדי להחדיר אוטומטית שרתי proxy של Envoy. פועלים לפי השלבים במאמר איך מפעילים הוספה אוטומטית של קובצי sidecar.

  4. פורסים את האפליקציה לדוגמה. במדריך הזה נשתמש בפריסה של Online Boutique, אפליקציית הדגמה של מיקרו-שירות.

    kubectl apply \
    -n onlineboutique \
    -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-service-mesh-samples/main/docs/shared/online-boutique/kubernetes-manifests.yaml
    
  5. כדי להוסיף תווית version=v1 לפריסת productcatalog, מריצים את הפקודה הבאה:

    kubectl patch deployments/productcatalogservice -p '{"spec":{"template":{"metadata":{"labels":{"version":"v1"}}}}}' \
    -n onlineboutique
    

    כדי לראות את השירותים שפרסתם:

    kubectl get pods -n onlineboutique
    

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

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-m84m6               2/2     Running   0          2m7s
    cartservice-c77f6b866-m67vd              2/2     Running   0          2m8s
    checkoutservice-654c47f4b6-hqtqr         2/2     Running   0          2m10s
    currencyservice-59bc889674-jhk8z         2/2     Running   0          2m8s
    emailservice-5b9fff7cb8-8nqwz            2/2     Running   0          2m10s
    frontend-77b88cc7cb-mr4rp                2/2     Running   0          2m9s
    loadgenerator-6958f5bc8b-55q7w           2/2     Running   0          2m8s
    paymentservice-68dd9755bb-2jmb7          2/2     Running   0          2m9s
    productcatalogservice-84f95c95ff-c5kl6   2/2     Running   0          114s
    recommendationservice-64dc9dfbc8-xfs2t   2/2     Running   0          2m9s
    redis-cart-5b569cd47-cc2qd               2/2     Running   0          2m7s
    shippingservice-5488d5b6cb-lfhtt         2/2     Running   0          2m7s
    

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

  6. פריסה של VirtualService ו-DestinationRule לגרסה 1 של productcatalog:

    kubectl apply -f destination-vs-v1.yaml -n onlineboutique
    
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: productcatalogservice
    spec:
      host: productcatalogservice
      subsets:
      - labels:
          version: v1
        name: v1
    ---
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: productcatalogservice
    spec:
      hosts:
      - productcatalogservice
      http:
      - route:
        - destination:
            host: productcatalogservice
            subset: v1

    שימו לב שרק v1 מופיע במקורות המידע.

  7. נכנסים לאפליקציה בדפדפן באמצעות כתובת ה-IP החיצונית של ה-ingress:

    kubectl get services -n GATEWAY_NAMESPACE
    

בקטע הבא נסביר איך משתמשים בממשק המשתמש של Cloud Service Mesh כדי לראות את המדדים.

פריסה והצגה של השירותים ב Google Cloud מסוף

  1. במסוף Google Cloud , נכנסים לדף GKE Enterprise Services.

    מעבר לשירותי GKE Enterprise

  2. כברירת מחדל, השירותים מוצגים בתצוגת טבלה.

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

    עומסי עבודה של כל השירותים

  3. בפינה השמאלית העליונה, לוחצים על Topology (טופולוגיה). כאן אפשר לראות את השירותים ואת האינטראקציה ביניהם.

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

    טופולוגיה של עומסי עבודה בכל השירותים

  4. חוזרים לתצוגת הטבלה.

  5. בטבלת השירותים, בוחרים באפשרות productcatalogservice. הפעולה הזו תעביר אתכם לסקירה כללית של השירות.

  6. בצד ימין של המסך, לוחצים על תנועה.

  7. מוודאים ש-100% מהתנועה הנכנסת אל productcatalogservice מגיעה לשירות של עומס העבודה.

    תנועה בשירות productcatalog

בקטע הבא נסביר איך ליצור גרסה 2 של שירות productcatalog.

פריסת שירות מגרסה 2

  1. במדריך הזה, productcatalogservice-v2 יציג זמן אחזור של 3 שניות בבקשות עם השדה EXTRA_LATENCY.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: productcatalogservice-v2
    spec:
      selector:
        matchLabels:
          app: productcatalogservice
      template:
        metadata:
          labels:
            app: productcatalogservice
            version: v2
        spec:
          containers:
          - env:
            - name: PORT
              value: '3550'
            - name: EXTRA_LATENCY
              value: 3s
            name: server
            image: gcr.io/google-samples/microservices-demo/productcatalogservice:v0.3.6
            livenessProbe:
              exec:
                command: ["/bin/grpc_health_probe", "-addr=:3550"]
            ports:
            - containerPort: 3550
            readinessProbe:
              exec:
                command: ["/bin/grpc_health_probe", "-addr=:3550"]
            resources:
              limits:
                cpu: 200m
                memory: 128Mi
              requests:
                cpu: 100m
                memory: 64Mi
          terminationGracePeriodSeconds: 5

    החלת המשאב הזה על מרחב השמות onlineboutique.

    kubectl apply -f productcatalog-v2.yaml -n onlineboutique
    
  2. בודקים את ה-pods של האפליקציה.

    kubectl get pods -n onlineboutique
    

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

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-85598d856b-8wqfd                  2/2     Running   0          25h
    cartservice-c77f6b866-7jwcr                 2/2     Running   0          25h
    checkoutservice-654c47f4b6-n8c6x            2/2     Running   0          25h
    currencyservice-59bc889674-l5xw2            2/2     Running   0          25h
    emailservice-5b9fff7cb8-jjr89               2/2     Running   0          25h
    frontend-77b88cc7cb-bwtk4                   2/2     Running   0          25h
    loadgenerator-6958f5bc8b-lqmnw              2/2     Running   0          25h
    paymentservice-68dd9755bb-dckrj             2/2     Running   0          25h
    productcatalogservice-84f95c95ff-ddhjv      2/2     Running   0          25h
    productcatalogservice-v2-6df4cf5475-9lwjb   2/2     Running   0          8s
    recommendationservice-64dc9dfbc8-7s7cx      2/2     Running   0          25h
    redis-cart-5b569cd47-vw7lw                  2/2     Running   0          25h
    shippingservice-5488d5b6cb-dj5gd            2/2     Running   0          25h
    

    שימו לב שמופיעים עכשיו שני productcatalogservices.

  3. ‫DestinationRule הוא הדרך לציין את קבוצות המשנה של שירות. בתרחיש הזה, יש קבוצת משנה לגרסה 1 וקבוצת משנה לגרסה 2 של productcatalogservice.

    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: productcatalogservice
    spec:
      host: productcatalogservice
      subsets:
      - labels:
          version: v1
        name: v1
      - labels:
          version: v2
        name: v2

    שימו לב לשדה labels. הגרסאות של productcatalogservice מובחנות אחרי שהתנועה מנותבת על ידי VirtualService.

    מחילים את DestinationRule:

    kubectl apply -f destination-v1-v2.yaml -n onlineboutique
    

חלוקת התנועה בין גרסה 1 לגרסה 2

  1. VirtualService היא הדרך להפנות אחוז קטן מהתנועה ישירות לגרסה 2 של productcatalogservice.

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: productcatalogservice
    spec:
      hosts:
      - productcatalogservice
      http:
      - route:
        - destination:
            host: productcatalogservice
            subset: v1
          weight: 75
        - destination:
            host: productcatalogservice
            subset: v2
          weight: 25

    בשדה subset מצוינת הגרסה, ובשדה weight מצוין אחוז חלוקת התנועה. ‫75% מהתנועה יופנו לגרסה 1 של productcatalog, ו-25% יופנו לגרסה 2.

    מחילים את VirtualService:

    kubectl apply -f vs-split-traffic.yaml -n onlineboutique
    

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

בקטע הבא נסביר על חלוקת התנועה במסוף GKE Enterprise Google Cloud .

התבוננות בחלוקת התנועה ב Google Cloud מסוף

  1. חוזרים למסוף Google Cloud ועוברים לדף GKE Enterprise Services. מעבר אל GKE Enterprise Services

  2. בפינה השמאלית העליונה, לוחצים על Topology (טופולוגיה).

    מרחיבים את עומס העבודה productcatalogservice. יוצגו פריסות של productcatalogservice ושל productcatalogservice-v2.

    productcatalog svc v1 v2 traffic tpoplogy

  3. חוזרים לתצוגת הטבלה. לוחצים על productcatalogservice בטבלת השירותים. חוזרים אל תנועה בסרגל הניווט הימני.

  4. שימו לב שהתנועה הנכנסת מחולקת בין גרסה 1 לגרסה 2 לפי האחוז שצוין בקובץ VirtualService, ושיש 2 עומסי עבודה של שירות productcatalog.

    בצד שמאל של המסך יופיעו המדדים Requests (בקשות), Error Rate (שיעור השגיאות) ו-Latency (זמן האחזור). בעזרת Cloud Service Mesh, כל שירות יכלול את המדדים האלה כדי לספק לכם ניראות.

    productcatalog svc v1 v2 traffic

השקה או חזרה לגרסה קודמת

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

השקה

אחרי שאתם מרוצים מההתנהגות של שירות v2, מגדילים בהדרגה את התעבורה לשירות v2. בסופו של דבר, אפשר להפנות 100% מהתנועה לשירות החדש.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: productcatalogservice
spec:
  hosts:
  - productcatalogservice
  http:
  - route:
    - destination:
        host: productcatalogservice
        subset: v2

כדי להפנות את כל התנועה לגרסה 2 של productcatalogservice:

kubectl apply -f vs-v2.yaml -n onlineboutique

חזרה לגרסה קודמת

אם אתם צריכים לחזור לשירות v1, פשוט מחילים את destination-vs-v1.yaml מהשלב הקודם. התנועה תופנה רק לגרסה 1 של productcatalogservice.

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: productcatalogservice
spec:
  hosts:
  - productcatalogservice
  http:
  - route:
    - destination:
        host: productcatalogservice
        subset: v1

כדי להפנות את כל התנועה לגרסה 1 של productcatalogservice:

kubectl apply -f vs-v1.yaml -n onlineboutique

הסרת המשאבים

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

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

מחיקת הפרויקט

  1. ב-Cloud Shell, מוחקים את הפרויקט:

    gcloud projects delete PROJECT_ID
    

מחיקת המשאבים

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

    gcloud container clusters delete  CLUSTER_NAME  \
    --project=PROJECT_ID \
    --zone=CLUSTER_LOCATION 
    
  • אם רוצים לשמור את האשכול ולהסיר את הדוגמה Online Boutique:

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

      kubectl delete -f namespace onlineboutique
      

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

      namespace "onlineboutique" deleted
      
    2. מחיקת רשומות השירות:

      kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/istio-manifests/frontend.yaml -n onlineboutique
      kubectl delete -f https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/istio-manifests/frontend-gateway.yaml -n onlineboutique
      

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

      serviceentry.networking.istio.io "allow-egress-googleapis" deleted
      serviceentry.networking.istio.io "allow-egress-google-metadata" deleted
      

המאמרים הבאים