שימוש במאגר נתונים חיצוני של Cassandra

במאמר הזה מוסבר איך לחבר סביבת ריצה של Apigee Hybrid למאגר נתונים של Cassandra באשכול Kubernetes אחר. בהגדרה הזו, אין פודים של Cassandra באשכול זמן הריצה. השם של ההגדרה הזו הוא מצב מאגר נתונים חיצוני.

טופולוגיה של שני אשכולות

במצב External datastore נעשה שימוש בשני אשכולות Kubernetes:

  • אשכול Cassandra מפעיל את Cassandra ring. הוא לא מפעיל את רכיבי זמן הריצה ההיברידיים.
  • אשכול זמן הריצה מריץ את רכיבי זמן הריצה ההיברידיים, אבל אין בו פודים של Cassandra. רכיבי זמן הריצה מתחברים ל-Cassandra ring באשכול Cassandra דרך הרשת.

אופרטור Apigee פועל בשני האשכולות. מתקינים את cert-manager, את הגדרות המשאבים המותאמים אישית (CRD) של Apigee ואת תרשים apigee-operator בכל אשכול. בטבלה הבאה מפורטים הרכיבים בכל אשכול:

רכיב אשכול Cassandra אשכול זמן ריצה
cert-manager כן כן
‫CRD של Apigee והתרשים apigee-operator כן כן
תרשים apigee-datastore כן, עם ה-pods של Cassandra כן, עם replicaCount: 0 וללא פודים של Cassandra
כל התרשימים ההיברידיים האחרים, כמו apigee-telemetry, apigee-redis, apigee-ingress-manager, apigee-org, apigee-env ו-apigee-virtualhost לא כן

אופרטור Apigee מבצע עבודה שונה בכל אשכול:

  • ב-Cassandra cluster, האופרטור יוצר את ה-pods של Cassandra. הוא גם מנהל את מחזור החיים של Cassandra, למשל כשמגדילים את הטבעת.
  • באשכול זמן הריצה, האופרטור לא יוצר פודים של Cassandra. הוא יוצר Service ללא ממשק משתמש ואובייקט Endpoints שמפנים ל-Cassandra ring באשכול Cassandra. אם מפעילים סנכרון דינמי של נקודות קצה, האופרטור באשכול זמן הריצה קורא גם את נקודות הקצה של Cassandra מאשכול Cassandra.

סקירה כללית על ההגדרה

מבצעים את השלבים הבאים לפי הסדר. הרצף חשוב. רשות האישורים (CA) המשותפת צריכה להיות באוסף זמן הריצה לפני שאוסף זמן הריצה מנפיק אישורים. מידע נוסף זמין במאמר בנושא שיתוף אישור ה-CA של Apigee לפני התקנת האופרטור.

  1. ב-Cassandra cluster, מתקינים את cert-manager, את Apigee CRDs, את תרשים apigee-operator ואת תרשים apigee-datastore.
  2. מוודאים שה-pods של Cassandra באשכול Cassandra מוכנים.
  3. ב-runtime cluster, מתקינים את cert-manager.
  4. מעתיקים את הסוד apigee-ca מאשכול Cassandra לאשכול זמן הריצה. צריך לבצע את השלב הזה לפני שמתקינים את תרשים apigee-operator באשכול זמן הריצה.
  5. במקלט זמן הריצה, מתקינים את רכיבי זמן הריצה ההיברידי. משתמשים בהגדרות ברירת מחדל של מאגר נתונים חיצוני עבור התרשים apigee-datastore. משתמשים באותם פרטי כניסה של Cassandra כמו באשכול Cassandra.
  6. (מומלץ) מפעילים את הסנכרון הדינמי של נקודות הקצה.
  7. אימות החיבור.

לשלבים להתקנת כל תרשים, ראו התקנת Apigee hybrid באמצעות Helm.

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

צריך לוודא שהסביבה עומדת בדרישות הבאות:

  • חיבור לרשת ל-Cassandra. אשכול זמן הריצה צריך להתחבר ל-pods של Cassandra ביציאת TCP ‏9042. ממקמים את שני האשכולות ב-VPC משותף, או ברשתות עם חיבור פרטי ביניהן.
  • אזור אחד. ממקמים את שני האשכולות באותו אזור. זמן ההלוך ושוב בין האשכולות מתווסף לזמן התגובה של כל בקשה בזמן הריצה.
  • ‫cert-manager בשני האשכולות. בכל אשכול, cert-manager מנפיק את האישורים לחיבור mTLS בין זמן הריצה לבין Cassandra. מתקינים את cert-manager באשכול Cassandra ובאשכול זמן הריצה.
  • מסלול לכל Cassandra pod. מנהל ההתקן של לקוח Cassandra מתחבר ישירות לכל פוד של Cassandra. אשכול זמן הריצה צריך להתחבר לכתובת ה-IP של כל פוד של Cassandra, ולא רק לכתובת אחת. מאזן עומסים או כתובת IP וירטואלית אחת לפני הטבעת לא עומדים בדרישה הזו.
  • חיבור לרשת לשרת ה-API של Kubernetes. הדרישה הזו רלוונטית רק אם אתם משתמשים בסנכרון דינמי של נקודות קצה. אשכול זמן הריצה צריך להתחבר לשרת ה-API של Kubernetes באשכול Cassandra.

שיתוף אישור ה-CA של Apigee לפני התקנת האופרטור

מתקינים את cert-manager באשכול זמן הריצה. אחר כך מעתיקים את הסוד של רשות האישורים מאשכול Cassandra לאשכול זמן הריצה:

kubectl --context CASSANDRA_CLUSTER -n cert-manager get secret apigee-ca -o yaml \
  | grep -v -E '^\s+(resourceVersion|uid|creationTimestamp|selfLink):' \
  | kubectl --context RUNTIME_CLUSTER -n cert-manager apply -f -

מחליפים את הערכים הבאים:

  • ‫CASSANDRA_CLUSTER: הקשר של kubectl באשכול Cassandra.
  • ‫RUNTIME_CLUSTER: הקשר של kubectl של אשכול זמן הריצה.

הפקודה grep מסירה את שדות המטא-נתונים ששייכים לאשכול Cassandra. שרת ה-API של Kubernetes לא יוצר אובייקט עם ערך resourceVersion.

התקנות באזורים גיאוגרפיים נרחבים יותר פועלות לפי אותו עיקרון של רשות אישורים משותפת. שלב דומה להעתקה מופיע במאמר בנושא החלפת אישור ה-CA הבסיסי. למידע על הגדרת mTLS ב-Cassandra, ראו הגדרת אימות ב-Cassandra.

שימוש באותם פרטי כניסה ל-Cassandra בשני האשכולות

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

  • מגדירים את אותם שמות משתמש וסיסמאות ב-cassandra.auth: default, admin, ddl, dml, jmx ו-jolokia.
  • מגדירים את cassandra.auth.secret. בכל אשכול, הסוד צריך להכיל את אותם משתמשים וסיסמאות. איך יוצרים את הסוד
  • מגדירים את cassandra.auth.secretProviderClass ל-SecretProviderClass שקורא את אותו מאגר סודות. אפשר לעיין במאמר בנושא אחסון סודות של Cassandra ב-Hashicorp Vault.

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

הגדרת מאגר נתונים חיצוני

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

cassandra:
  # No Cassandra pods in the runtime cluster.
  replicaCount: 0
  properties:
    # A comma-separated list of the Cassandra pod IP addresses.
    externalHost: "CASSANDRA_IP_ADDRESSES"
  storage:
    # Required, even with replicaCount: 0.
    storageSize: "10Gi"

כאשר:

  • ‫CASSANDRA_IP_ADDRESSES: רשימה מופרדת בפסיקים של כתובות ה-IP של ה-pods של Cassandra באשכול Cassandra. לדוגמה: 10.0.0.1:9042,10.0.0.2:9042,10.0.0.3:9042. הסיומת :9042 היא אופציונלית. כדי לקבל את הרשימה, מריצים את הפקודה הבאה:
    kubectl --context CASSANDRA_CLUSTER -n APIGEE_NAMESPACE get pods -l app=apigee-cassandra \
      -o jsonpath='{.items[*].status.podIP}' | tr ' ' ','
  • ‫APIGEE_NAMESPACE הוא מרחב השמות של Apigee. ערך ברירת המחדל הוא apigee.
  • ‫replicaCount: 0 אומר למפעיל לא ליצור פודים של Cassandra באשכול זמן הריצה. המפעיל יוצר שירות ללא ממשק משתמש ואובייקט Endpoints שמפנים לכתובות externalHost.
  • ‫cassandra.properties.externalHost היא רשימה מופרדת בפסיקים של כתובות IP של Cassandra. לכל כתובת יכול להיות סיומת :port, אבל האופרטור מתעלם מהיציאה ותמיד משתמש ביציאה 9042. האופרטור מקבל רק כתובות IP. הוא מתעלם משמות מארחים ומשמות DNS, וכותב אזהרה ביומן שלו לגבי כל רשומה שהמערכת מתעלמת ממנה.
  • cassandra.storage.storageSize הוא חובה, אבל אשכול זמן הריצה לא יוצר נפחי אחסון מתמיד עבור Cassandra. ה-webhook של ApigeeDatastore אימות תמיד בודק את storageSize. צריך להשתמש בכמות תקינה, למשל 10Gi.

כתובת ה-IP של ה-Pod משתנה כשמגדילים את הטבעת וכש-Kubernetes מתזמן מחדש את ה-Pod. ואז הרשימה ב-externalHost תהיה שגויה. לכן מומלץ להשתמש בסנכרון דינמי של נקודות קצה. סנכרון דינמי של נקודות קצה שומר על רשימת כתובות ה-IP של פודים של Cassandra מעודכנת באופן אוטומטי. משתמשים ב-externalHost לבד רק להתקנה פשוטה או להגדרה הראשונה.

שמירה על עדכניות של נקודות הקצה באמצעות סנכרון דינמי של נקודות קצה

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

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

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

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

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

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

‫
cassandra:
  replicaCount: 0
  properties:
    # The first endpoints, and the fallback if a read fails.
    externalHost: "CASSANDRA_IP_ADDRESSES"
    externalEndpointsSync:
      # A secret in the runtime cluster. Its "kubeconfig" key holds the
      # kubeconfig for the Cassandra cluster.
      secretRef: apigee-remote-cass-kubeconfig
      # The namespace of the Cassandra headless Service in the Cassandra cluster.
      namespace: apigee
      # The Cassandra headless Service in the Cassandra cluster.
      serviceName: apigee-cassandra-default
      # The interval between reads, in seconds. The default is 30.
      intervalSeconds: 30
  storage:
    storageSize: "10Gi"

יצירת חשבון שירות לקריאה בלבד באשכול Cassandra

האופרטור באשכול זמן הריצה משתמש ב-kubeconfig כדי להתחבר לאשכול Cassandra. קובץ ה-kubeconfig הזה צריך להשתמש בחשבון שירות לקריאה בלבד עם הרשאות מינימליות. לחשבון השירות הזה יש הרשאת קריאה בלבד בנקודות הקצה של Cassandra. היא לא יכולה לשנות משאבים באשכול Cassandra.

ב-Cassandra cluster, יוצרים את המשאבים הבאים:

  • חשבון שירות, לדוגמה apigee-endpoint-reader.
  • תפקיד וקישור תפקיד במרחב השמות של Cassandra. התפקיד מעניק רק את הפעלים get,‏ list ו-watch במשאבי הליבה endpoints. אל תשתמשו בפעלים אחרים, כמו create,‏ update,‏ patch או delete. לא לתת גישה למשאבים אחרים.
  • סוד טוקן לטווח ארוך של ServiceAccount.

לאחר מכן יוצרים קובץ kubeconfig לשרת ה-API של Kubernetes באשכול Cassandra. קובץ ה-kubeconfig הזה חייב להשתמש באסימון של חשבון השירות. באשכול זמן הריצה, יוצרים סוד עם השם שהגדרתם ב-externalEndpointsSync.secretRef. מציבים את kubeconfig במפתח kubeconfig:

kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE create secret generic \
  apigee-remote-cass-kubeconfig --from-file=kubeconfig=READER_KUBECONFIG_FILE

מחליפים את READER_KUBECONFIG_FILE בנתיב לקובץ kubeconfig של חשבון השירות לקריאה בלבד.

קובץ ה-kubeconfig מכיל אסימון לטווח ארוך. חשוב לשמור על הסוד הזה כמו על פרטי הכניסה האחרים שלכם.

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

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

האופרטור באוסף זמן הריצה מספק את האותות הבאים:

  • המצב EndpointSyncDegraded בסטטוס של משאב ApigeeDatastore. התנאי הופך ל-True אחרי שלוש קריאות רצופות שנכשלו. הסיבה היא RemoteReadFailed או NoReadyRemoteEndpoints. אחרי קריאה מוצלחת, התנאי הופך ל-False עם הסיבה SyncSucceeded.
  • המדד external_endpoint_sync_last_success_timestamp. המדד הזה הוא הזמן של הקריאה האחרונה שהצליחה, בשניות של יוניקס.
  • המדד external_endpoint_sync_failures_total. המדד הזה סופר את הקריאות שנכשלו.

לשני המדדים יש את התוויות namespace ו-name של המשאב ApigeeDatastore. האופרטור מציג אותם בנקודת הקצה של המדדים שלו.

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

kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get apigeedatastore default \
  -o jsonpath='{.status.conditions}'

מומלץ להגדיר התראה על התנאי EndpointSyncDegraded. הסטטוס של ApigeeDatastore נשמר גם כשהמפעיל מפעיל מחדש את המכונה. רק קריאה מוצלחת מגדירה את התנאי ל-False.

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

  • time() - external_endpoint_sync_last_success_timestamp > 300
  • absent(external_endpoint_sync_last_success_timestamp)

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

אימות החיבור

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

  1. מוודאים שאין פודים של Cassandra באשכול זמן הריצה:

    kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get pods -l app=apigee-cassandra

    הפלט הוא No resources found.

  2. מוודאים שאובייקט נקודות הקצה מצביע על טבעת Cassandra:

    kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get endpoints apigee-cassandra-default

    בעמודה ENDPOINTS מוצגות כתובות ה-IP של Cassandra. אם משתמשים בסנכרון דינמי של נקודות קצה, אלה כתובות ה-IP של ה-pods של Cassandra שמוכנים באשכול Cassandra.

  3. מוודאים שעבודות ההגדרה של Cassandra הושלמו:

    kubectl --context RUNTIME_CLUSTER -n APIGEE_NAMESPACE get jobs \
      | grep -E 'apigee-cassandra-(schema|user)-setup'

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

שינוי קנה המידה של טבעת Cassandra

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

הכללים שחלים על טבעת Cassandra חלים גם על אשכול זמן הריצה:

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

מידע נוסף זמין במאמר בנושא שינוי קנה המידה של Cassandra.

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