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

במאמר הזה מוסבר איך להפעיל שירותים מרובי אשכולות (MCS) ואיך להשתמש בהם. באמצעות MCS, אפשר לגלות ולהפעיל שירותים של Kubernetes במספר אשכולות של Google Kubernetes Engine ‏ (GKE). ‫MCS עוזרת לכם ליצור אפליקציות עם זמינות גבוהה ועם פיזור גיאוגרפי, על ידי שיפור העמידות והגמישות של השירותים שלכם. כשמייצאים שירות באמצעות MCS, השירות הזה זמין בכל האשכולות בצי.

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

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

‫Google Cloud resources managed by MCS

‫MCS מנהל את הרכיבים הבאים של Google Cloud:

  • Cloud DNS: ‏MCS מגדיר אזורים ורשומות של Cloud DNS לכל שירות שמיוצא באשכולות של Fleet. כך תוכלו להתחבר לשירותים שפועלים באשכולות אחרים. האזורים והרשומות האלה נוצרים, נקראים, מתעדכנים ונמחקים על סמך השירותים שאתם בוחרים לייצא בין אשכולות.

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

  • מישור הבקרה של Traffic Director: MCS משתמש במישור הבקרה של Traffic Director כדי לעקוב אחרי נקודות קצה והתקינות שלהן בכל האשכולות.

דרישות

הדרישות של MCS הן:

  • כדי שמערכת MCS תפעל בצורה תקינה, מערכת GKE פורסת את ה-Pod‏ gke-mcs-importer לצמתים עם הרשאות RBAC מורחבות. ההרשאות האלה מאפשרות לכלי הייבוא לנהל נקודות קצה, שירותים ו-ServiceImports כדי להפיץ מטא-נתונים של שירותים בין אשכולות ב-Fleet. ליבואן אין הרשאה לצפות בפריסות או לשנות אותן.

  • ‫MCS תומך רק בייצוא שירותים מאשכולות GKE מקוריים של VPC ב- Google Cloud. מידע נוסף זמין במאמר יצירת אשכול המותאם ל-VPC. אי אפשר להשתמש באשכולות GKE רגילים שלא מותאמים ל-VPC.

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

    כדי להגדיר MCS ב-Fleet חוצה פרויקטים עם VPC משותף, פועלים לפי ההוראות במאמר הגדרת שירותים מרובי אשכולות עם VPC משותף.

  • למרות שאפשר להגדיר צי שמכסה כמה פרויקטים ב- Google Cloud וכמה רשתות VPC, צריך לייצא שירות יחיד עם כמה אשכולות מפרויקט יחיד ומרשת VPC יחידה.

  • אין תמיכה ב-MCS במדיניות רשת.

  • צריך להפעיל את התוסף HttpLoadBalancing באשכולות. מוודאים שהתוסף HttpLoadBalancing מופעל. התוסף HttpLoadBalancing מופעל כברירת מחדל ואין להשבית אותו.

תמחור

השימוש ב-Multi-cluster Services כלול בעמלת הניהול של אשכול GKE, ואין עלות נוספת לשימוש. צריך להפעיל את Traffic Director API, אבל לא חלים על MCS חיובים על נקודות קצה של Cloud Service Mesh.

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

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

  1. מתקינים את Google Cloud SDK.

  2. מפעילים את Google Kubernetes Engine API:

    הפעלת Google Kubernetes Engine API

  3. מחברים את רשתות ה-VPC באמצעות קישור בין רשתות VPC שכנות (peering), ‏ Cloud Interconnect או Cloud VPN.

  4. מפעילים את ממשקי ה-API של MCS,‏ Fleet (Hub),‏ מנהל המשאבים,‏ Traffic Director,‏ Cloud DNS ו-Connect Gateway:

    gcloud services enable \
        multiclusterservicediscovery.googleapis.com \
        gkehub.googleapis.com \
        cloudresourcemanager.googleapis.com \
        trafficdirector.googleapis.com \
        dns.googleapis.com \
        connectgateway.googleapis.com \
        --project=PROJECT_ID
    

    מחליפים את PROJECT_ID במזהה הפרויקט שבו אתם מתכננים לרשום את האשכולות ל-Fleet.

הפעלת MCS בפרויקט

כדי להשתמש ב-MCS, צריך לרשום את אשכולות GKE שמשתתפים באותו צי. אחרי שמפעילים את התכונה MCS ב-Fleet, כל האשכולות יכולים לייצא שירותים בין אשכולות ב-Fleet.

הפעלת MCS באשכול GKE

  1. מפעילים את התכונה MCS ב-Fleet של הפרויקט:

    gcloud container fleet multi-cluster-services enable \
        --project PROJECT_ID
    

    מחליפים את PROJECT_ID במזהה הפרויקט שבו אתם מתכננים לרשום את האשכולות ל-Fleet. זה פרויקט Fleet המארח.

    הפעלת שירותים מרובי-אשכולות בפרויקט המארח של Fleet יוצרת את חשבון השירות service-PROJECT_NUMBER@gcp-sa-mcsd.iam.gserviceaccount.com או מוודאת שהוא קיים.

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

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

    gcloud container fleet memberships register MEMBERSHIP_NAME \
       --gke-cluster CLUSTER_LOCATION/CLUSTER_NAME \
       --enable-workload-identity \
       --project PROJECT_ID
    

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

    • MEMBERSHIP_NAME: שם החברות שבוחרים כדי לייצג באופן ייחודי את האשכול ב-Fleet. בדרך כלל, השם של חברות האשכול ב-Fleet הוא השם של האשכול, אבל יכול להיות שתצטרכו לציין שם חדש אם כבר קיים ב-Fleet אשכול אחר עם השם המקורי.
    • CLUSTER_LOCATION: האזור או האזור שבו נמצא האשכול.
    • CLUSTER_NAME: שם האשכול.
  3. צריך להעניק את ההרשאות הנדרשות לניהול זהויות והרשאות גישה (IAM) עבור הכלי MCS Importer:

    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member "principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/gke-mcs/sa/gke-mcs-importer" \
        --role "roles/compute.networkViewer"
    

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

    • PROJECT_ID: מזהה הפרויקט מפרויקט המארח של ה-Fleet.
    • PROJECT_NUMBER: מספר הפרויקט מפרויקט המארח של ה-Fleet.
  4. מוודאים שלכל אשכול ב-Fleet יש מרחב שמות לשיתוף שירותים. במקרה הצורך, יוצרים מרחב שמות באמצעות הפקודה הבאה:

    kubectl create ns NAMESPACE
    

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

  5. כדי לוודא ש-MCS מופעל, מריצים את הפקודה הבאה:

    gcloud container fleet multi-cluster-services describe \
        --project PROJECT_ID
    

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

    createTime: '2021-08-10T13:05:23.512044937Z'
    membershipStates:
      projects/PROJECT_ID/locations/global/memberships/MCS_NAME:
        state:
          code: OK
          description: Firewall successfully updated
          updateTime: '2021-08-10T13:14:45.173444870Z'
    name: projects/PROJECT_NAME/locations/global/features/multiclusterservicediscovery
    resourceState:
      state: ACTIVE
    spec: {}
    

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

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

אם רשמתם את אשכולות GKE ל-Fleet באמצעות חשבון שירות, תצטרכו לבצע שלבים נוספים כדי לאמת את חשבון השירות. ‫MCS פורס רכיב שנקרא gke-mcs-importer. הרכיב הזה מקבל עדכונים של נקודות קצה ממישור הבקרה של Traffic Director, ולכן כחלק מהפעלת MCS צריך לתת לחשבון השירות הרשאה לקרוא מידע מ-Cloud Service Mesh.

כשמשתמשים בחשבון שירות, אפשר להשתמש בחשבון השירות שמוגדר כברירת מחדל ב-Compute Engine או בחשבון השירות של הצומת:

שימוש ב-MCS

בקטעים הבאים מוסבר איך להשתמש ב-MCS. ‫MCS משתמש ב-Kubernetes multi-cluster services API.

רישום שירות לייצוא

כדי לרשום שירות לייצוא לאשכולות אחרים ב-Fleet, מבצעים את השלבים הבאים:

  1. יוצרים אובייקט ServiceExport בשם export.yaml:

    # export.yaml
    kind: ServiceExport
    apiVersion: net.gke.io/v1
    metadata:
     namespace: NAMESPACE
     name: SERVICE_EXPORT_NAME
    

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

    • NAMESPACE: מרחב השמות של אובייקט ServiceExport. מרחב השמות הזה צריך להיות זהה למרחב השמות של השירות שממנו מייצאים.
    • SERVICE_EXPORT_NAME: השם של שירות באשכול שרוצים לייצא לאשכולות אחרים ב-Fleet.
  2. כדי ליצור את המשאב ServiceExport, מריצים את הפקודה הבאה:

    kubectl apply -f export.yaml
    

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

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

שימוש בשירותים חוצי-אשכולות

‫MCS תומך רק ב-ClusterSetIP ובשירותים ללא ראש. אפשר להשתמש רק ברשומות DNS מסוג A.

אחרי שיוצרים אובייקט ServiceExport, שם הדומיין הבא מומר לשירות המיוצא מכל Pod בכל אשכול של Fleet:

 SERVICE_EXPORT_NAME.NAMESPACE.svc.clusterset.local

הפלט כולל את הערכים הבאים:

  • SERVICE_EXPORT_NAME ו-NAMESPACE: הערכים שאתם מגדירים באובייקט ServiceExport.

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

לדוגמה:

kind: ServiceImport
apiVersion: net.gke.io/v1
metadata:
 namespace: EXPORTED-SERVICE-NAMESPACE
 name: SERVICE-EXPORT-TARGET
status:
 ports:
 - name: https
   port: 443
   protocol: TCP
   targetPort: 443
 ips: CLUSTER_SET_IP

‫MCS יוצר אובייקט EndpointSlice כחלק מייבוא של Service לאשכול. בדיקת האובייקט הזה מאפשרת לעקוב אחרי התקדמות הייבוא של שירות.

כדי למצוא את השם של אובייקט EndpointSlice, מחפשים את הערך של ההערה net.gke.io/derived-service באובייקט ServiceImport שמתאים לשירות המיובא. לדוגמה:

kind: ServiceImport
apiVersion: net.gke.io/v1
annotations: net.gke.io/derived-service: DERIVED_SERVICE_NAME
metadata:
 namespace: EXPORTED-SERVICE-NAMESPACE
 name: SERVICE-EXPORT-TARGET

לאחר מכן, מחפשים את אובייקט EndpointSlice כדי לבדוק אם MCS כבר העביר את נקודות הקצה אל האשכול המייבא. אובייקט EndpointSlice נוצר באותו מרחב שמות כמו אובייקט ServiceImport, עם השם שמאוחסן בהערה net.gke.io/derived-service. לדוגמה:

kubectl get endpointslice -l kubernetes.io/service-name=DERIVED_SERVICE_NAME -n NAMESPACE

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

  • DERIVED_SERVICE_NAME: הערך של ההערה net.gke.io/derived-service באובייקט ServiceImport.
  • NAMESPACE: מרחב השמות של אובייקט ServiceExport.

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

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

 HOSTNAME.MEMBERSHIP_NAME.LOCATION.SERVICE_EXPORT_NAME.NAMESPACE.svc.clusterset.local

הפלט כולל את הערכים הבאים:

  • SERVICE_EXPORT_NAME ו-NAMESPACE: הערכים שאתם מגדירים באובייקט ServiceExport.
  • MEMBERSHIP_NAME: המזהה הייחודי ב-Fleet של האשכול שבו נמצא ה-Pod.
  • LOCATION: המיקום של החברות. חברי הפוד הם global, או שהמיקום שלהם הוא אחד מהאזורים או מהתחומים שבהם נמצא הפוד, כמו us-central1.
  • HOSTNAME: שם המארח של ה-Pod.

אפשר גם לפנות ל-Pod בקצה העורפי באמצעות שם מארח שיוצא מאשכול שנרשם ב-Membership גלובלי, באמצעות שם דומיין בפורמט הבא:

HOSTNAME.MEMBERSHIP_NAME.SERVICE_EXPORT_NAME.NAMESPACE.svc.clusterset.local

השבתת MCS

כדי להשבית את MCS, צריך לבצע את הפעולות הבאות:

  1. לכל אשכול ב-Fleet, מוחקים כל אובייקט ServiceExport שיצרתם:

    kubectl delete serviceexport SERVICE_EXPORT_NAME \
        -n NAMESPACE
    

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

    • SERVICE_EXPORT_NAME: השם של אובייקט ServiceExport.
    • NAMESPACE: מרחב השמות של אובייקט ServiceExport.

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

  2. ביטול הרישום של האשכולות ב-Fleet אם אין צורך לרשום אותם למטרה אחרת.

  3. השבתת התכונה multiclusterservicediscovery:

    gcloud container fleet multi-cluster-services disable \
        --project PROJECT_ID
    

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

    אימות המחיקה

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

    אם מוצגת ההודעה הבאה, התכונה מושבתת:

    Waiting for Feature Multi-cluster Services to be deleted...done.
    

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

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

    ההודעה הבאה מציינת שעדיין קיימים משאבים משויכים:

    Feature has associated resources that should be cleaned up before
    deletion. Check the Feature state details for more information. This check
    can be overridden by setting force=true.
    

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

    gcloud container fleet multi-cluster-services describe \
        --project PROJECT_ID
    

    בודקים את השדה description בפלט. יש שני תרחישים אפשריים:

    1. המשתמשים ServiceExports לא יוסרו.

      בהודעה מצוין שקיימים משאבי ServiceExport בצי:

      There are N ServiceExport in the Fleet.
      

      חשוב למחוק את כל המשאבים של ServiceExport. השבתת MCS תיכשל עד שכל ServiceExports יימחקו לחלוטין.

      ממתינים שעה ומריצים שוב את הפקודה:

      gcloud container fleet multi-cluster-services disable \
      --project PROJECT_ID
      
    2. משאבים מנוהלים לא מוסרים.

      בהודעה מצוין שהמשאבים יוסרו:

      There are no ServiceExports in the Fleet. Managed resources are in the
      process of being removed. See
      https://docs.cloud.google.com/kubernetes-engine/docs/how-to/multi-cluster-services#troubleshoot
      for more information.
      

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

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

      gcloud container fleet multi-cluster-services disable \
      --project PROJECT_ID
      

    השבתה מאולצת של התכונה

    אתם יכולים להשבית את התכונה multiclusterservicediscovery.

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

    gcloud container fleet multi-cluster-services disable --force \
        --project PROJECT_ID
    
  4. משביתים את ה-API של MCS:

    gcloud services disable multiclusterservicediscovery.googleapis.com \
        --project PROJECT_ID
    

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

מגבלות

מספר האשכולות, ה-Pods והיציאות של השירות

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

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

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

  • מספר ה-Pods שמאחורי Service יחיד: מומלץ להקפיד על פחות מ-250 Pods מאחורי Service יחיד. במקרה של עומסי עבודה סטטיים יחסית ומספר קטן של שירותים מרובי-אשכולות, יכול להיות שיהיה אפשר לחרוג משמעותית מהמספר הזה ולהגיע לאלפי נקודות קצה לכל שירות. בדומה לשירותים של אשכול יחיד, כל נקודות הקצה נמצאות במעקב של kube-proxy בכל צומת. אם חורגים מהמגבלה הזו, במיוחד כשמייצאים מכמה אשכולות בו-זמנית, יכול להיות שיהיה צורך בצמתים גדולים יותר.

  • מספר השירותים מרובי-אשכולות שמיוצאים בו-זמנית: מומלץ לייצא בו-זמנית עד 250 יציאות שירות ייחודיות.

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

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

    • שני שירותים עם אותו שם ויציאה, אבל מרחבי שמות שונים, לדוגמה (name, ns1, port-80) ו- (name, ns2, port-80) הם שתי יציאות שירות שונות, והן נספרות במסגרת המגבלה של 250 יציאות שירות ייחודיות.

    • שירות מיוצא שחושף שתי יציאות, 80 ו-443, נספר כנגד שתי יציאות מתוך המגבלה של 250 יציאות שירות ייחודיות, ללא קשר למספר האשכולות בצי שמייצאים את השירות הזה בו-זמנית.

    כל שירות מרובה-אשכולות נספר במסגרת מכסת שירותי ה-Backend, וכל אזור בכל אשכול מייצא יוצר קבוצת נקודות קצה ברשת (NEG). הגדלת המכסות האלה לא משנה את המגבלה שצוינה לגבי המספר הכולל של יציאות שירות ייחודיות.

סוגי השירותים

‫MCS תומך רק ב-ClusterSetIP וב-Headless Services. שירותי NodePort ו-LoadBalancer לא נתמכים ועשויים להוביל להתנהגות לא צפויה.

שימוש בסוכן IPmasq עם MCS

מערכת MCS פועלת כצפוי כשמשתמשים בטווח ברירת מחדל או בטווח אחר של כתובות IP של Pod שלא מוסתרות.

אם משתמשים בטווח כתובות IP מותאם אישית של Pod או ב-ConfigMap של סוכן IPmasq מותאם אישית, אפשר להסתיר את תעבורת הנתונים של MCS. ההגדרה הזו מונעת את הפעולה של MCS כי כללי חומת האש מאפשרים רק תעבורה מכתובות IP של Pod.

כדי למנוע את הבעיה הזו, צריך להשתמש בטווח כתובות ה-IP של הפוד שמוגדר כברירת מחדל, או לציין את כל טווחי כתובות ה-IP של הפוד בשדה nonMasqueradeCIDRs של IPmasq agent ConfigMap. אם אתם משתמשים ב-Autopilot או שאתם חייבים להשתמש בטווח כתובות IP של Pod שאינו ברירת המחדל, ואין לכם אפשרות לציין את כל טווחי כתובות ה-IP של Pod ב-ConfigMap, אתם צריכים להשתמש במדיניות Egress NAT כדי להגדיר הסוואת כתובות IP.

שימוש חוזר במספרי יציאות בשירות MCS

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

ההתחייבות הזו רלוונטית גם בתוך שירות Kubernetes אחד וגם בכל שירותי Kubernetes עבור שירות MCS אחד.

MCS עם אשכולות בכמה פרויקטים

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

פתרון בעיות

בקטעים הבאים מפורטים טיפים לפתרון בעיות שקשורות ל-MCS.

צפייה בסטטוס של תכונות ב-MCS

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

gcloud container fleet multi-cluster-services describe

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

createTime: '2021-08-10T13:05:23.512044937Z'
membershipStates:
 projects/PROJECT_ID/locations/global/memberships/MCS_NAME:
   state:
     code: OK
     description: Firewall successfully updated
     updateTime: '2021-08-10T13:14:45.173444870Z'
name: projects/PROJECT_NAME/locations/global/features/multiclusterservicediscovery
resourceState:
 state: ACTIVE
spec: {}

הוא כולל, בין היתר, את הסטטוס הכללי של התכונה בקטע resourceState ואת הסטטוס של כל חברות בנפרד בקטע membershipStates.

אם הפעלתם את התכונה MCS בהתאם להוראות שבמאמר הפעלת MCS באשכול GKE, אבל הערך של resourceState.state הוא לא ACTIVE, פנו לתמיכה.

הסטטוס של כל חברות מורכב מהנתיב שלה ומהשדה state. האחרון מכיל את code ו-description, שיכולים לעזור בפתרון בעיות.

קודים במצבי החברות במועדון

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

  • OK: המינוי נוסף בהצלחה ל-MCS ומוכן לשימוש.

  • WARNING: מערכת MCS נמצאת בתהליך של התאמת הגדרות החברות. בשדה התיאור אפשר לספק מידע נוסף על הגורם לקוד הזה.

  • FAILED: המינוי הזה לא נוסף ל-MCS. מינויים אחרים בצי עם קוד OK לא מושפעים מהמינוי FAILED הזה. בשדה התיאור אפשר לספק מידע נוסף על הגורם לקוד הזה.

  • ERROR: חסרים משאבים בחברות הזו. מינויים אחרים בצי עם קוד OK לא מושפעים מהמינוי ERROR הזה. בשדה התיאור אפשר לספק מידע נוסף על הגורם לקוד הזה.

תיאורים במצבי החברות

כדי לראות מידע על מצב המינוי ב-MCS, בודקים את השדה state.description. בשדה הזה מופיע מידע על הפרויקט ועל הגדרת ה-Hub, וגם על הסטטוס של ה-Fleet והחברות. כדי לראות מידע על שירותים ספציפיים ועל ההגדרות שלהם, צריך לעיין בשדה Status.Conditions באובייקט ServiceExport. מידע נוסף זמין בקטע בדיקת ServiceExport.

השדה state.description מכיל את הפרטים הבאים:

  • Firewall successfully created: ההודעה הזו מציינת שכלל חומת האש של החבר נוצר או עודכן בהצלחה. הקוד של המינוי הוא OK.

  • Firewall creation pending: ההודעה הזו מציינת שכלל חומת האש של החבר ממתין ליצירה או לעדכון. קוד המועדון הוא WARNING. יכול להיות שיהיו בעיות בעדכון של החברות האלה ובחיבור שלהן לשירותים חדשים ולחברויות חדשות בכמה אשכולות שנוספו בזמן שכלל חומת האש נמצא בהמתנה.

  • GKE Cluster missing: ההודעה הזו מציינת שאשכול GKE הרשום לא זמין או שהוא נמחק. קוד המועדון הוא ERROR. צריך לבטל את הרישום של החברות הזו ב-Fleet באופן ידני אחרי שמוחקים אשכול GKE.

  • Project that member lives in is missing required permissions and/or has not enabled all required APIs - additional setup steps are required: ההודעה הזו מציינת שיש שגיאות פנימיות מסוג StatusForbidden ‏ (403), וקוד החברות הוא FAILED. השגיאה הזו מתרחשת בתרחישים הבאים:

    • לא הפעלתם את ממשקי ה-API הנדרשים בפרויקט של החבר.

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

      gcloud services enable multiclusterservicediscovery.googleapis.com --project PROJECT_ID
      gcloud services enable dns.googleapis.com --project PROJECT_ID
      gcloud services enable trafficdirector.googleapis.com --project PROJECT_ID
      gcloud services enable cloudresourcemanager.googleapis.com --project PROJECT_ID
      

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

    • לחשבון השירות mcsd או gkehub נדרשות הרשאות נוספות בפרויקט של החבר.

      חשבונות השירות mcsd ו-gkehub אמורים להיווצר אוטומטית בפרויקט המארח של Fleet עם כל ההרשאות הנדרשות. כדי לוודא שחשבונות השירות קיימים, מריצים את הפקודות הבאות:

      gcloud projects get-iam-policy PROJECT_ID | grep gcp-sa-mcsd
      gcloud projects get-iam-policy PROJECT_ID | grep gcp-sa-gkehub
      

      מחליפים את PROJECT_ID במזהה הפרויקט של פרויקט המארח של הצי.

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

  • Multiple VPCs detected in the hub - VPC must be peered with other VPCs for successful connectivity: ההודעה הזו מופיעה כשמבצעים רישום של אשכולות שמתארחים ב-VPC שונים לאותו Fleet. סטטוס המינוי הוא OK. רשת ה-VPC של אשכול מוגדרת על ידי המאפיין network של NetworkConfig. שירותים מרובי אשכולות דורשים רשת שטוחה, ורשתות ה-VPC האלה צריכות להיות בפירינג פעיל כדי שהשירותים מרובי האשכולות יוכלו להתחבר זה לזה בצורה תקינה. מידע נוסף זמין במאמר בנושא חיבור בין שתי רשתות.

  • Member does not exist in the same project as hub - additional setup steps are required, errors may occur if not completed.: ההודעה הזו מזכירה לכם שנדרשים שלבי הגדרה נוספים עבור אשכולות חוצי-פרויקטים. סטטוס המינוי הוא OK. חברות בפרויקטים מוגדרת כאשכול חברים שלא נמצא באותו פרויקט כמו ה-Fleet. מידע נוסף זמין במאמר בנושא הגדרה בין פרויקטים.

  • Non-GKE clusters are currently not supported: בהודעה הזו מוזכר ש-MCS תומך רק באשכולות GKE. אי אפשר להוסיף ל-MCS אשכולות שאינם GKE. סטטוס המינוי הוא FAILED.

בדיקה של ServiceExport

כדי לראות את הסטטוס של שירות מסוים ואת השגיאות האפשריות, בודקים את השדה Status.Conditions במשאב ServiceExport של השירות הזה:

kubectl describe serviceexports PROJECT_ID -n NAMESPACE

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

Name:         SERVICE_NAME
Namespace:    NAMESPACE
Labels:       <none>
Annotations:  <none>
API Version:  net.gke.io/v1
Kind:         ServiceExport
Metadata:
  Creation Timestamp:  2024-09-06T15:57:40Z
  Finalizers:
    serviceexport.net.gke.io
  Generation:        2
  Resource Version:  856599
  UID:               8ac44d88-4c08-4b3d-8524-976efc455e4e
Status:
  Conditions:
    Last Transition Time:  2024-09-06T16:01:53Z
    Status:                True
    Type:                  Initialized
    Last Transition Time:  2024-09-06T16:02:48Z
    Status:                True
    Type:                  Exported
Events:                    <none>

כשהבקר של MCS מזהה משאב ServiceExport, הוא מוסיף את התנאים הבאים לשדה Status.Conditions:

  • Initialized: הערך הוא True אם בקר ה-MCS אסף את השירות שמיוצג על ידי ServiceExport וניסה לבצע התאמה.

  • Exported: הערך הוא True אם השירות שמיוצג על ידי ServiceExport אומת בהצלחה.

כל תנאי מכיל את השדות Type, Status ו-LastTransitionTime שהם שדות חובה. בזמן שהבקר של MCS מבצע התאמה ואימות של השירות, השדה Status של התנאי המתאים משתנה מ-False ל-True.

שגיאות

אם מתרחשת שגיאה באימות, בקר המדיניות מגדיר את השדה Status של התנאי Exported לערך False, ומוסיף את השדה Reason ואת השדה Message עם מידע נוסף על השגיאה. השדה Reason יכול לקבל אחד מהערכים הבאים:

  • NoMatchingService: לא נמצא שירות שתואם לשם ולמרחב השמות של ServiceExport באשכול הנתון.
    בודקים אם שירות Kubernetes שרוצים לייצא קיים באותו אשכול. בודקים אם השם ומרחב השמות בשני המקורות (Service ו-ServiceExport) זהים לחלוטין.

  • Conflict: כבר קיים שירות מיוצא עם אותו שם ומרחב שמות שלא תואם לזה שמיוצא על ידי ServiceExport, או שהוא מיוצא מרשת או מפרויקט אחרים, וזה לא מותר. אפשר לעיין במגבלות.
    בודקים את השדה Message לפרטים, ובודקים את הקטע מגבלות אם צריך. מוודאים שהשם ומרחב השמות של Service ושל ServiceExport זהים, וכל המשאבים נוצרים באותה רשת או באותו פרויקט.

  • ReadinessProbeError: מוגדר readinessProbe במאגר ב-Pod שתומך בשירות. ‫Kubernetes ReadinessProbes מתורגמים ל-Google cloud HealthChecks וחייבים לעמוד באותן הגבלות.

    הערה: מערכת MCS משתמשת ביציאה שמוגדרת בהגדרה readinessProbe של קונטיינר כיציאה הסמכותית לבדיקות תקינות שמועברות למישור הבקרה של Traffic Director. ‫MCS בוחר את הקונטיינר הראשון ב-Pod המצטבר הכי ישן שחושף את targetPort של השירות, גם אם readinessProbe של הקונטיינר הזה מוגש ביציאה אחרת. אם יציאת targetPort שונה מיציאת readinessProbe, צריך לוודא שיש גישה ליציאת readinessProbe והיא מוגדרת בצורה נכונה, כי היציאה הזו קובעת את סטטוס התקינות של השירות ב-Cloud Service Mesh.

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

    • PeriodSeconds corresponds to CheckInterval
    • TimeoutSeconds corresponds to Timeout
    • SuccessThreshold corresponds to HealthyThreshold
    • FailureThreshold corresponds to UnhealthyThreshold

    כדי להתאים את ReadinessProbes למגבלות של HealthCheck, מערכת MCS מיישמת את הפעולות הבאות:

    • הערכים PeriodSeconds ו-TimeoutSeconds מוגבלים ל-300 שניות. חריגה מהמגבלה הזו תגרום לשגיאה.
    • הערכים SuccessThreshold ו-FailureThreshold מוגבלים ל-10 שניות. חריגה מהמגבלה הזו תגרום לשגיאה.
    • אם הערך של TimeoutSeconds גדול מהערך של PeriodSeconds, תדווח שגיאה ויצירת המשאב (או כל המשאבים) תיכשל.

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

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

  • PodsError: שגיאה שנתקלה במהלך אחזור ה-Pod או ה-Pods של ה-Backend‏
    . השגיאה הזו קשורה בדרך כלל לבעיה בתשתית הענן של Google. אם הבעיה נמשכת, צריך לפנות לתמיכה של Google Cloud.

  • EndpointsError: שגיאה שנתקלה במהלך צבירת נקודות קצה (Endpoints) עבור שירות ללא ראש (Headless Service)
    . בדרך כלל השגיאה הזו קשורה לבעיה בתשתית ענן של Google Cloud. אם הבעיה נמשכת, צריך לפנות לתמיכה של Google Cloud.

בשדה Message מופיע הקשר נוסף לגבי השגיאה.

בעיות נפוצות בהרשאות

  • ממשקי ה-API הנדרשים לא מופעלים בפרויקט.

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

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

  • לחשבון השירות mcsd או gkehub אין הרשאות מספיקות

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

    ב-Fleet של פרויקטים שונים, צריך ליצור עוד קישורי IAM. פועלים לפי הקטע המתאים יצירת הרשאות IAM במאמר הגדרת שירותים מרובי אשכולות באמצעות VPC משותף.

בעיות מוכרות

שירותי MCS עם כמה יציאות

קיימת בעיה ידועה בשירותים מרובי-אשכולות עם כמה יציאות (TCP/UDP) ב-GKE Dataplane V2, שבה חלק מנקודות הקצה לא מתוכנתות ב-dataplane. הבעיה הזו משפיעה על גרסאות GKE מוקדמות יותר מ-‎1.26.3-gke.400.

כפתרון עקיף, כשמשתמשים ב-GKE Dataplane V2, צריך להשתמש בכמה MCS עם יציאה אחת במקום ב-MCS אחד עם כמה יציאות.

שימוש חוזר במספר יציאה בשירות MCS אחד

אי אפשר להשתמש שוב באותו מספר יציאה בשירות MCS, גם אם הפרוטוקולים שונים.

ההתחייבות הזו רלוונטית גם בתוך שירות Kubernetes אחד וגם בכל שירותי Kubernetes עבור שירות MCS אחד.

בדיקת התקינות משתמשת ביציאת ברירת המחדל במקום ב-containerPort

כשפורסים Service עם שדה targetPort שמפנה ליציאה עם שם ב-Deployment, ‏ MCS מגדיר את יציאת ברירת המחדל לבדיקת תקינות במקום היציאה שצוינה containerPort.

כדי למנוע את הבעיה הזו, משתמשים בערכים מספריים בשדה Service ‏ports.targetPort ובשדה Deployment ‏readinessProbe.httpGet.port במקום בערכים עם שמות.

הערה: בשלב הזה, מערכת MCS גוזרת את יציאת בדיקת התקינות של שירותים מיוצאים רק מ-readinessProbe של ה-Pod.

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

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

חשוב לשמור על תקינות ההגדרות של כל שירות. אם שירות MCS לא מתעדכן, צריך לוודא שאף ServiceExport באף אחד מהאשכולות באף אחד ממרחבי השמות לא מדווח על ReadinessProbeError כסיבה לכך שסטטוס התנאי Exported הוא False. כאן מוסבר איך בודקים את התנאים.ServiceExports

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