העברה ל-Multi-cluster networking

Last reviewed 2022-02-17 UTC

רישות מרובה אשכולות הוא כלי חשוב שמאפשר תרחישי שימוש כמו זמינות גבוהה אזורית, קרבה למשתמשים ברחבי העולם לזמני אחזור נמוכים ובידוד ארגוני בין צוותים. ב-Google Kubernetes Engine (GKE) יש יכולות מובנות לרישות של כמה אשכולות, שאפשר להפעיל ולהשתמש בהן בקנה מידה נרחב בצי של אשכולות GKE. התכונה הזו גם מאפשרת לשלב בין GKE Standard ל-Autopilot, או להעביר ביניהם תשתית פרוסה, כדי לענות על הצרכים הארכיטקטוניים של כל אפליקציה.

באשכולות GKE Autopilot, ‏Google מנהלת את התשתית, כולל מישור הבקרה והצמתים. אם אתם רוצים להגדיר ולנהל את הצמתים בעצמכם, GKE מספק מצב רגיל. מידע נוסף על ההבדלים בין המצבים זמין במאמר בחירת מצב פעולה של אשכול.

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

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

שירותים מרובי אשכולות ושערים מרובי אשכולות

כדי לספק עמידות וזמינות גבוהה יותר לשירותים שלכם, Kubernetes יכול לפעול באמצעות מישור בקרה יחיד באזורי ענן שונים. ב-GKE יש גם שירותים מרובי אשכולות (MCS) שמספקים מנגנון לאיתור שירותים ולקריאה להם בין אשכולות. אפשר לגלות שירותים שמשתמשים בתכונה הזו ולגשת אליהם באשכולות עם כתובת IP וירטואלית, שתואמת להתנהגות של שירות ClusterIP שאפשר לגשת אליו באשכול. הגישה הזו מאפשרת ליהנות מהיתרונות הבאים:

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

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

‫GKE מספק הטמעה של Kubernetes Gateway API שמשתמשת בבקר GKE Gateway. ‫Gateway מאפשר ל-GKE לפרוס Google Cloud מאזני עומסים כדי לספק ניתוב תעבורה נכנסת (צפון-דרום) לשירותים שנפרסו ב-GKE. ב-GKE יש גם שערים מרובי אשכולות (MCG) שמרחיבים את בקר השערים של GKE כדי להקצות מאזני עומסים שמנתבים תעבורה לשירותים שנפרסו באשכולות GKE שונים.

בתרשים הבא אפשר לראות איך שילוב של MCS ו-MCG מאפשר לכם לנהל את ההיבטים המשלימים של פריסת השירות וניתוב התנועה ממישור בקרה יחיד:

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

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

סקירה כללית על מיגרציה

היכולות של GKE Multi-cluster networking מועילות לעומסי עבודה (workloads) עם פרופילים שונים. לדוגמה, יכול להיות שיש לכם רכיבים ללא מצב (stateless) עם תנועה לא אחידה (bursty) שאתם רוצים להעביר ל-Autopilot בגלל מודל העלויות היעיל יותר שלו.

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

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

פריסה ראשונית של אשכול יחיד

בתרשים הבא, אפליקציית Online Boutique נפרסת בהתחלה באשכול GKE Standard יחיד בשם std-west, ונחשפת באמצעות שירות LoadBalancer:

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

מעבר לשירותים מרובי אשכולות

בשלב הביניים הבא, יוצרים עוד שני אשכולות, והשירותים חסרי המצב נפרסים באזורים נוספים. יוצרים שני אשכולות GKE Autopilot בשמות auto-east ו-auto-central בשני אזורים נפרדים, שונים מאשכול GKE Standard היחיד std-west, ורושמים את האשכולות ב-Google Cloud fleet.

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

מייצאים את cartservice באשכול std-west במרחב השמות onlineboutique לאשכולות החדשים ב-fleet באמצעות ServiceExport. אתם פורסים את שירות החלק שפונה למשתמש של Online Boutique בכל שלושת האשכולות וחושפים אותו באמצעות שירות ClusterIP. לאחר מכן מייצאים את השירות לצי באמצעות ServiceExports. גם שירותים כמו שכבת התווכה של Online Boutique (כמו productcatalog,‏ shipping ו-adservice) נפרסים בכל שלושת האשכולות.

Pod שפועל בכל אשכול בצי יכול לגשת לService שיוצא על ידי שליחת בקשה למזהה ה-URI ClusterSet של השירות הזה. הבקשה מנותבת לנקודת קצה שמגבה את השירות.

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

הדיאגרמה הבאה ממחישה את שני השירותים מרובי-האשכולות. שירות הקצה הקדמי חסר המצב (stateless) נפרס בשלושה אשכולות, ושירות העגלה של הקצה האחורי (backend) עם מצב (stateful) נפרס באשכול אחד. בנוסף, הדיאגרמה מראה שבשלב הביניים הזה, תעבורת נתונים נכנסת לשירות הקצה הקדמי ממשיכה להיות מנותבת לאשכול GKE Standard המקורי ב-us-west1 באמצעות מאזן עומסי רשת חיצוני אזורי להעברת סיגנל ללא שינוי שנוצר על ידי שירות LoadBalancer frontend-external:

שירותי Multi-cluster פועלים בשלושה אשכולות GKE, אבל התנועה עדיין מופנית לאשכול אחד באמצעות שירות LoadBalancer חיצוני רגיל של HTTP.

מעבר לשער מרובה אשכולות

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

אשכול רביעי בשם config-central מתווסף לצי כדי לארח ולנהל את ההגדרה של משאבי Gateway ו-HTTPRoute שנוצרים כחלק מההגדרה הזו. המשאב HTTPRoute ממפה את הקידומת / לחלק הקדמי של ServiceImport. תעבורת הנתונים של חזית האתר של Online Boutique נשלחת לנקודת קצה תקינה באחד מהאזורים הזמינים. הגישה הזו מוסיפה לארכיטקטורת האפליקציה Online Boutique רכיבים של זמינות גבוהה.

בתרשים הבא, שער מרובה אשכולות פורס מאזן עומסים גלובלי ב-Cloud שמנתב תעבורה חיצונית לשירות frontend חסר מצב (stateless) שנפרס בכל אחד משלושת אשכולות האפליקציות בצי.

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

במצב הסופי, התבנית הזו מדגימה צימוד חלש בין החלקים של האפליקציה עם שמירת מצב (cartservice ו-redis-cart) לבין החלקים בלי שמירת מצב (frontend,‏ emailservice,‏ checkoutservice,‏ recommendationservice,‏ paymentservice,‏ productcatalogservice,‏ currencyservice,‏ shippingservice ו-adservice). הגישה הזו לא מתוארת בדף הזה, אבל היא מאפשרת להוסיף בעתיד חוסן וזמינות גבוהה לשכבת השירותים עם שמירת מצב.

מטרות

  • יצירה והגדרה של אשכולות GKE Standard ו-Autopilot.
  • פריסת Online Boutique באשכול GKE Standard אזורי.
  • ייצוא של כמה אשכולות Services.
  • פריסת מניפסטים באשכולות Standard ו-Autopilot.
  • להפעיל ולהגדיר שערים מרובי אשכולות.
  • בודקים את ההתנהגות של אפליקציה במספר אזורים.

עלויות

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

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

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

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

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

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

  • מומלץ להשתמש בפרויקט חדש כדי לתרגל את המדריך הזה, כי הדרך הכי קלה לנקות את הסביבה היא למחוק את הפרויקט בסיום.
  • במדריך הזה אנחנו יוצאים מנקודת הנחה שיש לכם את תפקיד הבעלים ב-IAM בGoogle Cloud פרויקט. בסביבות ייצור או בסביבות אמיתיות, מומלץ להגדיר את ההרשאות כך שיהיו מינימליות. למידע נוסף, קראו את המאמרים שימוש מאובטח ב-IAM ואימות מפורש של כל ניסיון גישה.
  • היכרות עם הארכיטקטורה של אפליקציית ההדגמה של מיקרו-שירותים Online Boutique.

הכנת הסביבה

במדריך הזה תשתמשו ב-Cloud Shell כדי להזין פקודות. ‫Cloud Shell מאפשר גישה לשורת הפקודה בGoogle Cloud מסוף וכולל את Google Cloud SDK וכלים אחרים, כמו Google Cloud CLI. ‫Cloud Shell מופיע כחלון בחלק התחתון של מסוףGoogle Cloud . יכול להיות שייקח כמה דקות עד שהחלון יופעל, אבל הוא יופיע מיד.

  1. מפעילים את Cloud Shell במסוף Google Cloud .

    הפעלת Cloud Shell

  2. ב-Cloud Shell, מגדירים את משתני הסביבה שמשמשים במדריך הזה. מחליפים את PROJECT_ID במזהה הפרויקט שלכם:

    export PROJECT=PROJECT_ID
    gcloud config set project ${PROJECT}
    
  3. מפעילים את השירותים שנדרשים לביצוע השלבים בדף הזה:

    gcloud services enable \
        gkehub.googleapis.com \
        multiclusteringress.googleapis.com \
        dns.googleapis.com \
        trafficdirector.googleapis.com \
        cloudresourcemanager.googleapis.com \
        multiclusterservicediscovery.googleapis.com \
        container.googleapis.com
    
    gcloud container fleet multi-cluster-services enable
    

    שירות Multi-cluster Services מנהל Google Cloud רכיבים כמו Cloud DNS, כללי חומת אש ו-Cloud Service Mesh, ולכן צריך להפעיל גם את ממשקי ה-API האלה. מידע נוסף זמין במאמר סקירה כללית על Cloud Service Mesh.

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

    Operation "operations/acf.p2-822685001869-ee4ebe78-6dd8-465e-b0fd-3b0e5f964bad"
    finished successfully.
    
    Waiting for Feature Multi-cluster Services to be created...done.
    
  4. מוודאים שבקטע 'שירותים מרובי-אשכולות' מופיע הסטטוס ACTIVE:

    gcloud container fleet multi-cluster-services describe
    

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

    createTime: '2021-11-30T21:59:25.245190894Z'
    name: projects/PROJECT_ID/locations/global/features/multiclusterservicediscovery
    resourceState:
      state: ACTIVE
    spec: {}
    updateTime: '2021-11-30T21:59:27.459063070Z'
    

    אם הערך של state הוא לא ACTIVE, אפשר לעיין בפרטים לפתרון בעיות בשירותים מרובי-אשכולות.

יצירה והגדרה של אשכולות GKE

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

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

  1. יוצרים אשכולות GKE במצבים Standard ו-Autopilot ורושמים את האשכולות בצי של הפרויקט:

    gcloud container clusters create std-west \
        --location us-west1-a \
        --num-nodes=6 \
        --enable-ip-alias \
        --release-channel regular \
        --workload-pool=${PROJECT}.svc.id.goog \
        --gateway-api=standard \
        --enable-fleet \
        --async \
    
    gcloud container clusters create-auto auto-east \
        --location us-east1 \
        --release-channel regular \
        --enable-fleet \
        --async
    
    gcloud container clusters create-auto auto-central \
        --location us-central1 \
        --release-channel regular \
        --enable-fleet \
        --async
    
    gcloud container clusters create config-central \
        --location us-central1 \
        --num-nodes=1 \
        --enable-ip-alias \
        --release-channel regular \
        --workload-pool=${PROJECT}.svc.id.goog \
        --gateway-api=standard \
        --enable-fleet \
        --async
    

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

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

    watch -n 20 --difference=permanent "gcloud container clusters list"
    

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

    NAME: auto-central
    LOCATION: us-central1
    MASTER_VERSION: 1.21.5-gke.1802
    MASTER_IP: 107.178.213.138
    MACHINE_TYPE: e2-medium
    NODE_VERSION: 1.21.5-gke.1802
    NUM_NODES: 3
    STATUS: PROVISIONING
    
    NAME: config-central
    LOCATION: us-central1
    MASTER_VERSION: 1.21.5-gke.1802
    MASTER_IP:
    MACHINE_TYPE: e2-medium
    NODE_VERSION: 1.21.5-gke.1802
    NUM_NODES: 9
    STATUS: PROVISIONING
    
    NAME: auto-east
    LOCATION: us-east1
    MASTER_VERSION: 1.21.5-gke.1802
    MASTER_IP: 35.229.88.209
    MACHINE_TYPE: e2-medium
    NODE_VERSION: 1.21.5-gke.1802
    NUM_NODES: 3
    STATUS: PROVISIONING
    
    NAME: std-west
    LOCATION: us-west1-a
    MASTER_VERSION: 1.21.5-gke.1802
    MASTER_IP: 35.197.93.113
    MACHINE_TYPE: e2-medium
    NODE_VERSION: 1.21.5-gke.1802
    NUM_NODES: 6
    STATUS: PROVISIONING
    
  3. אחרי שכל האשכולות נמצאים במצב RUNNING, מקישים על CTRL-C כדי להפסיק את הפקודה.

  4. מוסיפים קישור למדיניות ניהול זהויות והרשאות גישה (IAM) שמעניק לחשבון השירות של MCS בפרויקט המארח של צי הרכבים את התפקיד Network User בפרויקט שלו:

    gcloud projects add-iam-policy-binding ${PROJECT} \
        --member "serviceAccount:${PROJECT}.svc.id.goog[gke-mcs/gke-mcs-importer]" \
        --role "roles/compute.networkViewer"
    

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

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

    - members:
      - serviceAccount:PROJECT_ID.svc.id.goog[gke-mcs/gke-mcs-importer]
      role: roles/compute.networkViewer
    [...]
    
  5. יוצרים קישור IAM בפרויקט המארח של הצי שמקצה את התפקיד GKE Service Agent לחשבון השירות של צי GKE בפרויקט:

    gcloud projects add-iam-policy-binding ${PROJECT} \
        --member "serviceAccount:service-{${PROJECT}}@gcp-sa-gkehub.iam.gserviceaccount.com" \
        --role roles/gkehub.serviceAgent
    
  6. יוצרים קישור IAM בפרויקט המארח של ה-fleet, שמקצה את התפקיד "סוכן שירות של MCS" לחשבון השירות של MCS בפרויקט:

    gcloud projects add-iam-policy-binding ${PROJECT} \
        --member "serviceAccount:service-{${PROJECT}}@gcp-sa-mcsd.iam.gserviceaccount.com" \
        --role roles/multiclusterservicediscovery.serviceAgent
    
  7. מתחברים לאשכולות ויוצרים רשומות kubeconfig:

    gcloud container clusters get-credentials std-west \
        --location us-west1-a --project $PROJECT
    
    gcloud container clusters get-credentials auto-east \
        --location us-east1 --project $PROJECT
    
    gcloud container clusters get-credentials auto-central \
        --location us-central1 --project $PROJECT
    
    gcloud container clusters get-credentials config-central \
        --location us-central1 --project $PROJECT
    

    הפלט של כל פקודה דומה לדוגמה הבאה:

    Fetching cluster endpoint and auth data.
    kubeconfig entry generated for std-west.
    
  8. כדי שיהיה קל יותר לעבוד עם ההקשרים בהמשך הדף הזה, כדאי לשנות את השם שלהם באשכולות:

    kubectl config rename-context \
        gke_${PROJECT}_us-west1-a_std-west \
        std-west
    
    kubectl config rename-context \
        gke_${PROJECT}_us-east1_auto-east \
        auto-east
    
    kubectl config rename-context \
        gke_${PROJECT}_us-central1_auto-central \
        auto-central
    
    kubectl config rename-context \
        gke_${PROJECT}_us-central1_config-central \
        config-central
    

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

פריסת Online Boutique ב-GKE Standard

בשלב הראשון של פריסת ההדגמה, פורסים את כל קבוצת שירותי האפליקציה של Online Boutique באשכול GKE Standard יחיד, std-west, ב-us-west1.

  1. יוצרים את מרחב השמות onlineboutique ב-std-west:

    kubectl create namespace onlineboutique --context std-west
    

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

    namespace/onlineboutique created
    
  2. משכפלים את המאגר של Online Boutique ב-GitHub ומגדירים משתנה WORKDIR:

    cd ~
    
    git clone --branch release/v0.4.1 \
        https://github.com/GoogleCloudPlatform/microservices-demo.git
    
    cd microservices-demo/release && export WORKDIR=`pwd`
    
  3. פריסת Online Boutique ב-std-west. התהליך הזה יוצר את Deployments ואת Services לכל המיקרו-שירותים של Online Boutique, וכולל שירות מסוג LoadBalancer שחושף חיצונית את שירות ה-frontend של Online Boutique:

    cd $WORKDIR
    
    kubectl apply -f kubernetes-manifests.yaml \
        -n onlineboutique --context=std-west
    
  4. מחכים ששירות LoadBalancer יקבל כתובת IP חיצונית:

    watch -n 20 --difference=permanent \
         "kubectl get svc frontend-external -n onlineboutique --context=std-west"
    

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

    NAME                TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    frontend-external   LoadBalancer   10.60.5.62   <pending>     80:30359/TCP   43s
    

    כשה-Service מוכן, בעמודה EXTERNAL-IP מוצגת כתובת ה-IP הציבורית של מאזן העומסים.

  5. אחרי שמאזן העומסים Service מוכן, מקבלים את כתובת ה-IP החיצונית שלו ומשתמשים ב-curl כדי לוודא שהקצה הקדמי מוכן. אם הפקודה הזו של curl מחזירה שגיאה, כדאי לחכות כמה רגעים לפני שמנסים שוב:

      curl $(kubectl get svc frontend-external \
          -n onlineboutique --context=std-west \
          -o=jsonpath="{.status.loadBalancer.ingress[0].ip}") | \
            grep -e Cluster -e Zone -e Pod
    

    הפלט של פקודת curl שבוצעה בהצלחה אמור להיראות כך:

    <b>Cluster: </b>std-west<br/>
    <b>Zone: </b>us-west1-a<br/>
    <b>Pod: </b>frontend-b7bddcc97-wdjsk
    

עכשיו יש לכם גרסה של Online Boutique באזור יחיד שפועלת ב-us-west1-a. אפשר גם להשתמש בדפדפן אינטרנט כדי לנווט לכתובת ה-IP החיצונית שהוקצתה לשירות frontend-external ב-LoadBalancer, כדי לגשת לאפליקציה ולראות איך היא פועלת. הפריסה הראשונית היחידה מוצגת בתרשים הבא:

אשכול GKE במצב Standard שמריץ את כל השירותים שנחשפים באמצעות שירות רגיל של איזון עומסים חיצוני מסוג HTTP.

ייצוא cartservice כשירות מרובה אשכולות

בקטע הזה מתחילים להוסיף רכיבים של זמינות גבוהה לאפליקציה. מייצאים את ה-backend‏ cartservice כשירות מרובה אשכולות לאשכולות GKE Autopilot.

  1. יוצרים את מרחב השמות onlineboutique באשכולות שנותרו:

    kubectl create namespace onlineboutique --context auto-east
    
    kubectl create namespace onlineboutique --context auto-central
    
    kubectl create namespace onlineboutique --context config-central
    

    הפלט של כל פקודה דומה לדוגמה הבאה:

    namespace/onlineboutique created
    
  2. מייצאים את cartservice מהאשכול std-west לכל שאר האשכולות ב-ClusterSet. האובייקט ServiceExport רושם את השירות cartservice, עם שירותים מרובי אשכולות של GKE, לייצוא לכל האשכולות ב-Fleet שבהם קיים מרחב השמות onlineboutique. פרטים נוספים זמינים במאמר בנושא רישום שירות לייצוא.

    cat <<EOF>> $WORKDIR/cartservice-export.yaml
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
     namespace: onlineboutique
     name: cartservice
    
    EOF
    
    kubectl apply -f $WORKDIR/cartservice-export.yaml \
        -n onlineboutique --context=std-west
    

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

בקטע הזה תחיל שני קובצי מניפסט שנבחרו בקפידה כדי לפרוס את התבנית של כמה אשכולות. קובצי המניפסט האלה מכילים חלקים נבחרים מתוך kubernetes-manifests.yaml שהחלתם קודם על אשכול std-west:

  • המניפסט הראשון משמש לחלק הקצה Deployment, Service ו-ServiceExport.
  • המניפסט השני משמש לפריסת תוכנת הביניים Services(emailservice,‏ checkoutservice,‏ recommendationservice,‏ paymentservice,‏ productcatalogservice,‏ currencyservice,‏ shippingservice ו-adservice) בכל האזורים שבהם פועל frontend. אם הבקשה נשארת באזור המקומי כמה שיותר זמן, אתם נמנעים מחיובים מיותרים על תנועה ברשת בין אזורים.

אפשר לגשת ל-Service שיוצא באמצעות Pod שפועל בכל אשכול בצי, על ידי שליחת בקשה למזהה ה-URI של השירות ClusterSet בפורמט SERVICE_NAME.NAMESPACE.svc.clusterset.local. לדוגמה, Deployments של frontend בכל שלושת האשכולות לדוגמה יכולים לצרוך את cartservice במרחב השמות onlineboutique, על ידי שליחת בקשה אל cartservice.onlineboutique.svc.clusterset.local.

לכן, בכל מניפסט, שם המארח של cartservice עודכן ל-URI של ClusterSet. השלב הזה קריטי. אם שם המארח של השירות הזה לא מעודכן, שירות ה-frontend יבקש מ-kube-dns את cartservice במקום את cartservice.onlineboutique.svc.clusterset.local. ההתנהגות הזו תגרום לשגיאות HTTP Status 500 באשכולות שבהם גרסה מקומית של cartservice לא זמינה, ותגרום לפודים של frontend להיות לא תקינים.

  1. מגדירים משתנה סביבה למאגר ב-GitHub שמכיל את קובצי המניפסט:

    export MANIFEST_REPO_PATH=https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/master/gateway/docs/cluster-migration
    
  2. מחילים את המניפסטים כדי לפרוס את שכבת ה-frontend לכל שלושת אשכולות העומס:

    kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-frontend-manifests.yaml \
        -n onlineboutique --context=std-west
    
    kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-frontend-manifests.yaml \
        -n onlineboutique --context=auto-east
    
    kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-frontend-manifests.yaml \
        -n onlineboutique --context=auto-central
    
  3. מחילים את המניפסטים כדי לפרוס את שכבת התווכה בכל שלושת אשכולות עומס העבודה:

    kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-middleware-manifests.yaml \
        -n onlineboutique --context=std-west
    
    kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-middleware-manifests.yaml \
        -n onlineboutique --context=auto-east
    
    kubectl apply -f ${MANIFEST_REPO_PATH}/onlineboutique-middleware-manifests.yaml \
        -n onlineboutique --context=auto-central
    

החלק הקדמי Deployment, Service ו-ServiceExport פעילים עכשיו באשכולות std-west, ‏auto-east ו-auto-central. בנוסף, בכל אשכול פועלים שירותי תווכה (middleware) של Online Boutique באופן מקומי. עם זאת, התנועה החיצונית עדיין מנותבת רק אל Service שפועל באשכול הראשוני ב-us-west1, כמו שמוצג בתרשים הבא:

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

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

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

בשלבים הבאים, תשתמשו באשכול config-central כדי לארח את ההגדרות של משאבי Gateway.

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

    gcloud container fleet memberships list --project=$PROJECT
    

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

    NAME: auto-central
    EXTERNAL_ID: 21537493-32ea-4a41-990d-02be2c1b319f
    
    NAME: config-central
    EXTERNAL_ID: 4369423e-ea7b-482d-a0eb-93b560e67b98
    
    NAME: std-west
    EXTERNAL_ID: 7fcb048b-c796-476b-9698-001a00f91ab3
    
    NAME: auto-east
    EXTERNAL_ID: aae2d2ff-b861-4a38-bcaf-612f14810012
    
  2. מתקינים את הגדרת המשאב בהתאמה אישית של Gateway API באשכול config-central:

    kubectl --context=config-central kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.5.0" \
        | kubectl apply -f -
    

    בשלב הזה מתקינים את הגדרות המשאבים בהתאמה אישית של Gateway API, כולל המשאבים GatewayClass, ‏ Gateway ו-HTTPRoute. הגדרות המשאבים בהתאמה אישית מנוהלות על ידי קבוצת האינטרס המיוחדת של רשת Kubernetes. אחרי ההתקנה, אתם יכולים להשתמש ב-GKE Gateway controller.

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

    gcloud container fleet ingress enable \
        --config-membership=config-central \
        --project=$PROJECT
    
    gcloud container fleet ingress describe --project=$PROJECT
    

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

    createTime: '2021-12-08T23:10:52.505888854Z'
    name: projects/PROJECT_ID/locations/global/features/multiclusteringress
    resourceState:
      state: ACTIVE
    spec:
      multiclusteringress:
        configMembership: projects/zl-mcs-expf61cbd13/locations/global/memberships/config-central
    state:
      state:
        code: OK
        description: Ready to use
        updateTime: '2021-12-08T23:11:37.994971649Z'
    updateTime: '2021-12-08T23:11:38.098244178Z'
    

    אם הערך של state הוא לא ACTIVE, אפשר לעיין במאמר פתרון בעיות ופעולות ב-Multi Cluster Ingress.

  4. מוודאים ש-GatewayClasses זמינים באשכול config-central:

    kubectl get gatewayclasses --context=config-central
    

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

    NAME                                  CONTROLLER                  AGE
    gke-l7-global-external-managed        networking.gke.io/gateway   18s
    gke-l7-global-external-managed-mc     networking.gke.io/gateway   19s
    gke-l7-regional-external-managed      networking.gke.io/gateway   18s
    gke-l7-regional-external-managed-mc   networking.gke.io/gateway   19s
    gke-l7-gxlb                           networking.gke.io/gateway   74s
    gke-l7-gxlb-mc                        networking.gke.io/gateway   16s
    gke-l7-rilb                           networking.gke.io/gateway   74s
    gke-l7-rilb-mc                        networking.gke.io/gateway   16s
    

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

  5. פורסים את המשאב external-http Gateway ב-config-central:

    cat <<EOF>> $WORKDIR/external-http-gateway.yaml
    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
      namespace: onlineboutique
    spec:
      gatewayClassName: gke-l7-global-external-managed-mc
      listeners:
      - protocol: HTTP
        port: 80
        name: http
    EOF
    
    kubectl apply -f external-http-gateway.yaml \
        -n onlineboutique --context=config-central
    

    כפי שמצוין בשדה gatewayClassName, המשאב הזה הוא מסוג GatewayClass gke-l7-global-external-managed-mc שמנהל את Cloud Load Balancing החיצוני בשכבה 7, וחושף את האפליקציה מרובת האשכולות

  6. פורסים את HTTPRoute בשם public-frontend-route ב-config-central:

    cat <<EOF>> $WORKDIR/public-frontend-route.yaml
    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: public-frontend-route
      namespace: onlineboutique
    spec:
      parentRefs:
      - name: "external-http"
      hostnames:
      - "store.example.com"
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /
        backendRefs:
        - name: frontend
          group: net.gke.io
          kind: ServiceImport
          port: 80
    EOF
    
    kubectl apply -f public-frontend-route.yaml \
        -n onlineboutique --context=config-central
    

    כשפורסים את משאב HTTPRoute, נוצר משאב חיצוני של Cloud Load Balancing בשכבה 7, והקצה הקדמי של ServiceImport נחשף. הקצה הקדמי מגובה על ידי שירותי הקצה הקדמי שפועלים באשכולות std-west,‏ auto-east ו-auto-central.

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

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

  7. צריך לחכות עד שמאזן העומסים יהיה מוכן עם כתובת IP חיצונית שהוקצתה לפני שממשיכים לשלב הבא. יכולות לחלוף עד 10 דקות עד להקצאת כתובת ה-IP. אפשר לעקוב אחרי ההתקדמות באמצעות לולאת צפייה. למאזן העומסים יש שם בתבנית כמו gkemcg-onlineboutique-external-http-k09mfhk74gop:

    watch -n 20 --difference=permanent \
        "gcloud compute forwarding-rules list \
            | grep -A 5 NAME..*external-http"
    

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

    NAME: gkemcg-onlineboutique-external-http-k09mfhk74gop
    REGION:
    IP_ADDRESS: 34.149.29.176
    IP_PROTOCOL: TCP
    TARGET: gkemcg-onlineboutique-external-http-k09mfhk74gop
    
  8. אחרי שמאזן העומסים מוכן, מריצים את הפקודה הבאה ב-Cloud Shell כדי לייצא את כתובת ה-IP החיצונית של מאזן העומסים שנוצר באמצעות המניפסטים external-http-gateway.yaml ו-public-frontend-route.yaml:

    export EXTERNAL_LB_IP=$(kubectl --context=config-central \
                                -n onlineboutique get gateway external-http \
                                -o=jsonpath='{.status.addresses[0].value}')
    
  9. כששולחים בקשה למאזן העומסים עם הכותרות המתאימות, הוא מחזיר את תוכן ה-HTML שמוצג על ידי שירות הקצה הקדמי. לדוגמה, אם הגדרתם את משאב HTTPRoute למיפוי של שם המארח store.example.com ל-frontend ServiceImport, אתם צריכים לספק את הכותרת HOST כשאתם שולחים את בקשת ה-HTTP. אם הדוגמה הבאה של curl מחזירה שגיאה, צריך להמתין כמה דקות ולנסות שוב:

    curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \
        grep -e Cluster -e Zone -e Pod
    

    הפלט של פקודת curl שבוצעה בהצלחה אמור להיראות כך:

    <b>Cluster: </b>auto-central<br/>
    <b>Zone: </b>us-central1-f<br/>
    <b>Pod: </b>frontend-7c7d596ddc-jdh8f
    

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

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

כדי לבדוק את ההתנהגות של האפליקציה במספר אזורים, צריך ליצור תעבורה שמגיעה מהאזורים השונים שבהם פרסתם אשכולות. יוצרים שלושה פודים קטנים, אחד בכל אחד מאשכולות ההצגה (std-west,‏ auto-east ו-auto-central), שבהם תוכלו להשתמש כדי לשלוח בקשות HTTP לנקודת הקצה של מאזן העומסים. בתוצאות אפשר לראות איזה ממשק קצה (frontend) של Pod מגיב.

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

    kubectl run --context=std-west \
                --image=radial/busyboxplus:curl client-west \
                -- sh -c 'while sleep 3600; do :; done'
    
    kubectl run --context=auto-east \
                --image=radial/busyboxplus:curl client-east \
                -- sh -c 'while sleep 3600; do :; done'
    
    kubectl run --context=auto-central \
                --image=radial/busyboxplus:curl client-central \
                -- sh -c 'while sleep 3600; do :; done'
    
  2. אחרי שה-pods פועלים, משתמשים בפקודת curl כדי לשלוח בקשה לנקודת הקצה של מאזן העומסים מהלקוח Pod באשכול std-west, ובודקים את התגובה:

    kubectl exec -it --context=std-west client-west \
        -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \
               grep -e Cluster -e Zone -e Pod
    

    הפלט של פקודת curl שבוצעה בהצלחה אמור להיראות כך:

    <b>Cluster: </b>std-west<br/>
    <b>Zone: </b>us-west1-a<br/>
    <b>Pod: </b>frontend-7cf48b79cf-trzc4
    
  3. מריצים את אותה בקשת curl מהלקוח Pod באשכול auto-east, ומסתכלים על התגובה:

    kubectl exec -it --context=auto-east client-east \
        -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \
               grep -e Cluster -e Zone -e Pod
    

    הפלט של פקודת curl שבוצעה בהצלחה אמור להיראות כך:

    <b>Cluster: </b>auto-east<br/>
    <b>Zone: </b>us-east1-d<br/>
    <b>Pod: </b>frontend-6784b6df98-scdws
    

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

     Error from server (BadRequest): pod client-east does not have a host assigned
    
  4. מריצים את ה-curl מהלקוח Pod באשכול auto-central ובודקים את התגובה:

    kubectl exec -it --context=auto-central client-central \
        -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \
            grep -e Cluster -e Zone -e Pod
    

    הפלט של פקודת curl שבוצעה בהצלחה אמור להיראות כך:

    <b>Cluster: </b>auto-central<br/>
    <b>Zone: </b>us-central1-b<br/>
    <b>Pod: </b>frontend-6784b6df98-x2fv4
    

    התוצאות האלה מאשרות שהתנועה מנותבת אל התאים המתאימים במיקומים הקרובים ביותר למקור הבקשה.

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

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

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

  1. מריצים את פקודת ה-curl מ-client-west Pod באשכול std-west, ורואים שהתוצאה מגיעה מהחלק הקדמי ב-us-west1:

    kubectl exec -it --context=std-west client-west \
        -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP  | \
               grep -e Cluster -e Zone -e Pod
    

    הפלט של פקודת curl שבוצעה בהצלחה אמור להיראות כך:

    <b>Cluster: </b>std-west<br/>
    <b>Zone: </b>us-west1-a<br/>
    <b>Pod: </b>frontend-7cf48b79cf-trzc4
    
  2. מוחקים את frontend Deployment באשכול std-west:

    kubectl delete deploy frontend \
        -n onlineboutique --context=std-west
    

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

    deployment.apps "frontend" deleted
    
  3. שולחים בקשה נוספת מ-client-west Pod באשכול std-west. אתם אמורים לראות תגובה מאחד מה-frontend Deployments שנותרו, שנמצא באשכולות auto-east או auto-central:

    kubectl exec -it --context=std-west client-west \
        -- curl -H 'HOST: store.example.com' $EXTERNAL_LB_IP | \
               grep -e Cluster -e Zone -e Pod
    

    פלט שדומה לדוגמה הבאה מציין את המיקום של Pod תקין שמגיב לבקשה הזו:

    <b>Cluster: </b>auto-central<br/>
    <b>Zone: </b>us-central1-b<br/>
    <b>Pod: </b>frontend-6784b6df98-x2fv4
    

    או

    <b>Cluster: </b>auto-east<br/>
    <b>Zone: </b>us-east1-d<br/>
    <b>Pod: </b>frontend-6784b6df98-scdws
    

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

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

הסרת המשאבים

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

  1. במסוף Google Cloud , נכנסים לדף Manage resources.

    כניסה לדף Manage resources

  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

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