פריסות קנרית ב-GKE ובאשכולות GKE מצורפים באמצעות Gateway API networking

במאמר הזה מוסבר איך להגדיר פריסות קנריות ולהשתמש בהן כדי לפרוס את האפליקציות ב-GKE או באשכולות שמצורפים ל-GKE באמצעות Cloud Deploy עם Service mesh של Gateway API ב-Kubernetes.

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

איך פריסות קנריות פועלות ב-GKE ובאשכולות GKE מצורפים באמצעות Gateway API

  1. בנוסף להפניה אל Deployment ו-Service, צריך לספק משאב HTTPRoute עם backendRefs כלל שמפנה אל Service.

  2. ‫Cloud Deploy יוצר פריסה חדשה עם השם של הפריסה המקורית בתוספת -canary, ושירות חדש עם השם המקורי של השירות בתוספת -canary.

    גם סודות, מפות ConfigMap ו-Horizontal Pod Autoscalers מועתקים ומשנים את השם שלהם עם -canary.

  3. בכל שלב של קנרי, Cloud Deploy משנה את ה-HTTPRoute כדי לעדכן את המשקל בין הפודים של הפריסה המקורית לבין הפודים של פריסת הקנרי, על סמך אחוז המשקל של אותו שלב.

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

  4. במהלך שלב stable, הפריסה -canary מצטמצמת לאפס, והפריסה המקורית מתעדכנת לשימוש בפריסה של הגרסה החדשה.

    בנוסף, ה-HTTPRoute חוזר עכשיו למקור שסיפקתם.

    ‫Cloud Deploy לא משנה את הפריסה או השירות המקוריים עד לשלב stable.

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

ההוראות שמופיעות כאן כוללות רק את מה שספציפי להגדרת קנרי. במסמך פריסה לאשכול Google Kubernetes Engine מופיעות הוראות כלליות להגדרה ולהפעלה של צינור הפריסה.

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

בנוסף להרשאות אחרות של ניהול זהויות והרשאות גישה שנדרשות לשימוש ב-Cloud Deploy, אתם צריכים את ההרשאות הבאות כדי לבצע פעולות נוספות שעשויות להידרש לפריסה של גרסה ראשונית (canary):

  • clouddeploy.rollouts.advance
  • clouddeploy.rollouts.ignoreJob
  • clouddeploy.rollouts.cancel
  • clouddeploy.rollouts.retryJob
  • clouddeploy.jobRuns.get
  • clouddeploy.jobRuns.list
  • clouddeploy.jobRuns.terminate

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

הכנת skaffold.yaml

קובץ skaffold.yaml מגדיר איך מניפסטים של Kubernetes מעובדים ונפרסים. כדי לבצע פריסה של גרסה ראשונית (canary) ב-GKE או באשכולות שמצורפים ל-GKE, צריך לוודא שהקובץ skaffold.yaml מצביע בצורה נכונה על קובצי המניפסט ומגדיר את כל הארטיפקטים הנדרשים לבנייה. לא נדרשת הגדרה מיוחדת ל-skaffold.yaml שספציפית לגרסת קנרי, מעבר למה שנדרש עבור פריסה רגילה. אפשר גם להשתמש בפרופילים של Skaffold כדי לנהל וריאציות שונות של מניפסטים עבור שלבים מותאמים אישית של קנרי.

הכנת מניפסטים של Kubernetes

קבצי המניפסט של Kubernetes צריכים לכלול גם משאב Deployment וגם משאב Service. ב-Service צריך להגדיר selector שמתאים לתוויות של ה-pods שמנוהלים על ידי Deployment. תווית ברירת המחדל ש-Cloud Deploy מחפש היא app, אבל אפשר להגדיר אותה בצינור.

בנוסף ל-Deployment ול-Service, קובצי המניפסט חייבים לכלול משאב HTTPRoute שהוגדר לפיצול תנועה, עם הפניה ל-Service ולשער המשויך.

הגדרת קנרי אוטומטי

שימוש ב-Kubernetes Gateway API (עם Istio או כל הטמעה נתמכת) לפיצול מדויק של תנועה על בסיס אחוזים, שמנוהל על ידי הרשת/השער ומתוזמן על ידי Cloud Deploy.

  1. הגדרת משאבי Gateway API: מוודאים שהשער, Service mesh הבסיסית (למשל Istio) או בקר השער מוגדרים בצורה נכונה באשכולות.

  2. במניפסט של Kubernetes שסיפקתם ל-Cloud Deploy כשנוצר ה-Release, צריך לכלול את הפרטים הבאים:

    • HTTPRoute שמפנה למשאב Gateway

    • פריסה

    • שירות

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

    • ההגדרה של היעד זהה להגדרה של כל יעד אחר.

    • ההגדרה של צינור העברת הנתונים, ברצף ההתקדמות של היעד הספציפי, כוללת פסקה gatewayServiceMesh להפניה להגדרה של Kubernetes Gateway API HTTPRoute, וגם לפריסה ולשירות.

      strategy:
       canary:
         runtimeConfig:
           kubernetes:
             gatewayServiceMesh:
               httpRoute: "ROUTE"
               service: "SERVICE"
               deployment: "DEPLOYMENT"
               routeUpdateWaitTime: "WAIT_TIME"
               podSelectorLabel: "LABEL"
         canaryDeployment:
           percentages:
           - 50
      

      איפה...

      • ‫ROUTE היא הגדרת ה-httpRoute שמגדירה את התנהגות הניתוב הרצויה.

      • ‫SERVICE היא הגדרת השירות, שנדרשת ל-Cloud Deploy כדי לבצע פריסות קנרי ל-GKE ול-GKE attached clusters.

      • ‫DEPLOYMENT היא הגדרת הפריסה, שנדרשת ל-Cloud Deploy כדי לבצע פריסות קנרית ל-GKE ולאשכולות שמצורפים ל-GKE.

      • ‫WAIT_TIME הוא משך הזמן ש-Cloud Deploy ימתין עד שהשינויים במשאב HTTPRoute יתעדכנו, כדי למנוע בקשות שנפסלות. לדוגמה: routeUpdateWaitTime: 60s.

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

      • ‫LABEL היא תווית של בורר פודים. הערך הזה צריך להיות זהה לערך של בורר התוויות (label selector) בשירות ובפריסה של Kubernetes שמוגדרים במניפסט. הפעולה הזאת אופציונלית. ערך ברירת המחדל הוא app.

הגדרת קנרי אוטומטי בהתאמה אישית

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

כדי להגדיר את זה, צריך לכלול גם קטע runtimeConfig עם serviceNetworking וגם קטע customCanaryDeployment (שמגדיר את phaseConfigs) בתוך הבלוק strategy.canary. ‫Cloud Deploy ישתמש בפרופילי Skaffold שצוינו לעיבוד, אבל ישנה באופן אוטומטי את התעבורה בהתאם לruntimeConfig ולאחוזים של השלב.

serialPipeline:
  stages:
  - targetId: gke-prod
    profiles: []
    strategy:
      canary:
        # Include runtimeConfig for automatic traffic management
        runtimeConfig:
          kubernetes:
            gatewayServiceMesh:
              httpRoute: "my-route"
              service: "my-app"
              deployment: "my-deployment"  
        # Include customCanaryDeployment for phase customization
        customCanaryDeployment:
          phaseConfigs:
          - phaseId: "warmup"
            percentage: 10
            profiles: ["profile-a"] # Profile used for rendering this phase
            verify:
              tasks: []
            predeploy:
              tasks: []
            postdeploy:
              tasks: []
          - phaseId: "scaling"
            percentage: 50
            profiles: ["profile-b"] # Different profile for this phase
            verify:
              tasks: []
            predeploy:
              tasks: []
            postdeploy:
              tasks: []
          - phaseId: "stable"
            percentage: 100
            profiles: ["profile-b"] # Can reuse profiles
            verify:
              tasks: []
            predeploy:
              tasks: []
            postdeploy:
              tasks: []

פריסת HTTPRoute לאשכול אחר

אם הגדרתם קנרי באמצעות Service mesh של Gateway API, אתם יכולים לציין אשכול חלופי שאינו אשכול היעד, שבו תפרסו את ה-HTTPRoute.

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

  1. מגדירים את associatedEntities ביעד.

    כל ישות היא אשכול שבו Cloud Deploy יפרוס את ה-HTTPRoute, ואופציונלית את שירות Kubernetes. בהגדרת היעד, כוללים קטע associatedEntities:

    associatedEntities:
      [KEY]:
        gkeClusters:
        - cluster: [PATH]
          dnsEndpoint: [true|false]
          internalIp: [true|false]
          proxyUrl:
    

    כאשר:

    • ‫KEY הוא שם שרירותי לקבוצה הזו של ישויות משויכות. תשתמשו בשם הזה כדי להפנות לישויות מ-routeDestinations בהגדרת הקנרי.

    • ‫PATH הוא נתיב המשאב שמזהה את אשכול GKE שבו ייפרס HTTPRoute (ואופציונלית גם Service).

    • ‫dnsEndpoint מציין אם להשתמש בנקודת הקצה של ה-DNS של האשכול או לא, אם מוגדרות כמה נקודות קצה. ערך ברירת המחדל הוא false.

    • ‫internalIp מציין אם להשתמש בכתובת ה-IP הפנימית של האשכול (כתובת IP פרטית) אם מוגדרות כמה נקודות קצה. ערך ברירת המחדל הוא false.

    אפשר לכלול כמה אשכולות שרוצים, עם או בלי internalIp.

  2. מגדירים את routeDestinations בהגדרת הקנרי.

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

    routeDestinations:
      destinationIds: ["KEY"]
      propagateService: [true|false]
    

    כאשר:

    • ‫KEY הוא השם שהגדרתם ביעד, ב-associatedEntities. משתמשים בשם הזה כדי להפנות לישויות מ-routeDestinations בהגדרת הקנרי.

      אפשר גם לציין את הערך @self כדי לפרוס את ה-HTTPRoute לאשכול היעד בנוסף ליעד המשויך.

    • ‫propagateService מציין אם רוצים לפרוס את השירות לאשכול המשויך, בנוסף ל-HTTPRoute. ברירת המחדל היא false.

הפעלת קנרי של GKE או של GKE Attached Clusters

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

    
    gcloud deploy apply --file=delivery-pipeline.yaml --region=REGION
    gcloud deploy apply --file=gke-targets.yaml --region=REGION
    

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

  2. יצירת גרסת הפצה: מתחילים את הפריסה ומזינים את שם התמונה.

    
    gcloud deploy releases create RELEASE_NAME \
                                    --delivery-pipeline=PIPELINE_NAME \
                                    --region=REGION
      # e.g., --images=my-cloudrun-service=gcr.io/my-project/my-app:v1.1
      # Add --skaffold-file or --source if not using default Skaffold config discovery
    

    צינור העברת הנתונים שזוהה על ידי PIPELINE_NAME מכיל את ההגדרה האוטומטית או המותאמת אישית של קנרי שמתוארת במסמך הזה.

  3. קידום גרסת הגישוש:

    ‫CLI של gcloud

    gcloud deploy rollouts advance ROLLOUT_NAME \
                                --release=RELEASE_NAME \
                                --delivery-pipeline=PIPELINE_NAME \
                                --region=REGION
    

    כאשר:

    ‫ROLLOUT_NAME הוא השם של ההשקה הנוכחית שרוצים להעביר לשלב הבא.

    ‫RELEASE_NAME הוא שם הגרסה שההשקה הזו היא חלק ממנה.

    ‫PIPELINE_NAME הוא השם של צינור ההפצה שבו אתם משתמשים כדי לנהל את הפריסה של הגרסה הזו.

    ‫REGION הוא שם האזור שבו נוצרה הגרסה, למשל us-central1. זהו שדה חובה.

    מידע נוסף על הפקודה gcloud deploy rollouts advance זמין במאמר בנושא Google Cloud SDK.

    מסוף Google Cloud

    1. פותחים את הדף Delivery pipelines.

    2. לוחצים על צינור עיבוד הנתונים שמופיע ברשימת צינורות עיבוד הנתונים להעברה.

      בדף הפרטים של צינור ההפצה מוצג ייצוג גרפי של ההתקדמות בצינור ההפצה.

    3. בכרטיסייה השקות, בקטע פרטים של צינור ההפצה, לוחצים על שם ההשקה.

      יוצג דף הפרטים של ההשקה.

      פרטי ההשקה במסוף Google Cloud

      שימו לב שבדוגמה הזו, ההשקה כוללת שלב canary-50 ושלב stable. יכול להיות שההשקה שלכם תכלול יותר שלבים או שלבים שונים.

    4. לוחצים על הפצה מתקדמת.

      ההשקה מתקדמת לשלב הבא.

שלבים שדילגו עליהם

אם פורסים קנרי והאפליקציה עדיין לא נפרסה בסביבת זמן הריצה הזו, Cloud Deploy מדלג על שלב הקנרי ומריץ את השלב היציב. במאמר דילוג על שלבים בפעם הראשונה מוסבר למה זה קורה.

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