פריסת מסד נתונים וקטורי של Elasticsearch ב-GKE

במדריך הזה נסביר איך פורסים אשכול של מסד נתונים וקטורי של Elasticsearch ב-Google Kubernetes Engine ‏ (GKE).

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

‫Elasticsearch הוא מסד נתונים וקטורי שמשלב פונקציות של חיפוש וניתוח. הוא כולל API בארכיטקטורת REST פתוח לניהול האשכול, ותומך בשאילתות מובנות, בשאילתות של טקסט מלא ובשאילתות מורכבות. ‫Elasticsearch מאפשרת לבצע חיפושים של ביטויים, חיפושים של מילים דומות וחיפושים של קידומות, עם הצעות להשלמה אוטומטית.

המדריך הזה מיועד לאדמינים ומומחי Cloud Architect של פלטפורמות ענן, למהנדסי ML ולמומחי MLOps (DevOps) שרוצים לפרוס אשכולות של מסדי נתונים של Elasticsearch ב-GKE.

יתרונות

היתרונות של Elasticsearch:

  • מגוון רחב של ספריות לשפות תכנות שונות ו-API פתוח לשילוב עם שירותים אחרים.
  • מדרגיות אופקית ותמיכה בחלוקה (sharding) ובשכפול (replication) שמפשטות את המדרגיות והזמינות הגבוהה.
  • איזון של אשכולות מרובי צמתים לניצול אופטימלי של המשאבים.
  • תמיכה ב-Container וב-Kubernetes לשילוב חלק בסביבות מודרניות של אפליקציות מבוססות-ענן.

מטרות

במדריך הזה תלמדו איך:

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

ארכיטקטורת פריסה

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

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

כדי לפתור את הבעיה הזו, אופרטור StatefulHA מבצע את הפעולות הבאות:

  • הפתרון מפחית את ההשהיה בתזמון מחדש, מטפל בהגדרות של מעבר לגיבוי ומקצר את זמן השחזור באמצעות הגדרות .forceDeleteStrategy: AfterNodeUnreachable.
  • עוזר להבטיח שאפליקציית StatefulSet משתמשת ב-RePD.
  • הרחבת GKE באמצעות משאב מותאם אישית HighAvailabilityApplication שנפרס באותו מרחב שמות כמו Elasticsearch. ההגדרה הזו מאפשרת לאופרטור StatefulHA לעקוב אחרי אירועי מעבר לגיבוי ולתת עליהם מענה.

הדיאגרמה הבאה מציגה אשכול Elasticsearch שפועל בכמה צמתים ותחומים באשכול GKE:

ארכיטקטורת פריסה של Elasticsearch

עלויות

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

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

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

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

השימוש ב-Elasticsearch הוא בחינם במסגרת רישיון ציבורי בצד השרת (SSPL).

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

במדריך הזה משתמשים ב-Cloud Shell כדי להריץ פקודות. ‫Cloud Shell היא סביבת מעטפת לניהול משאבים שמתארחים ב- Google Cloud. הוא מגיע עם כלי שורת הפקודה Google Cloud CLI, ‏ kubectl,‏ Helm ו- Terraform שכבר מותקנים בו. אם אתם לא משתמשים ב-Cloud Shell, אתם צריכים להתקין את Google Cloud CLI.

  1. נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. התקינו את ה-CLI של Google Cloud.

  3. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

  4. כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:

    gcloud init
  5. יוצרים או בוחרים Google Cloud פרויקט.

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

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים
    • יוצרים Google Cloud פרויקט:

      gcloud projects create PROJECT_ID

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

    • בוחרים את הפרויקט שיצרתם: Google Cloud

      gcloud config set project PROJECT_ID

      מחליפים את PROJECT_ID בשם הפרויקט ב- Google Cloud .

  6. מוודאים שהחיוב מופעל בפרויקט Google Cloud .

  7. מפעילים את ממשקי ה-API של Cloud Resource Manager,‏ Compute Engine,‏ GKE,‏ IAM Service Account Credentials ו-Backup for GKE, אם הם עדיין לא מופעלים:

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, נדרשת ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין בממשק Service Usage' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    gcloud services enable cloudresourcemanager.googleapis.com compute.googleapis.com container.googleapis.com iamcredentials.googleapis.com gkebackup.googleapis.com
  8. התקינו את ה-CLI של Google Cloud.

  9. אם אתם משתמשים בספק זהויות חיצוני (IdP), קודם אתם צריכים להיכנס ל-CLI של gcloud באמצעות המאגר המאוחד לניהול זהויות.

  10. כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:

    gcloud init
  11. יוצרים או בוחרים Google Cloud פרויקט.

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

    • Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
    • יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (roles/resourcemanager.projectCreator), שכולל את ההרשאה resourcemanager.projects.create. איך מקצים תפקידים
    • יוצרים Google Cloud פרויקט:

      gcloud projects create PROJECT_ID

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

    • בוחרים את הפרויקט שיצרתם: Google Cloud

      gcloud config set project PROJECT_ID

      מחליפים את PROJECT_ID בשם הפרויקט ב- Google Cloud .

  12. מוודאים שהחיוב מופעל בפרויקט Google Cloud .

  13. מפעילים את ממשקי ה-API של Cloud Resource Manager,‏ Compute Engine,‏ GKE,‏ IAM Service Account Credentials ו-Backup for GKE, אם הם עדיין לא מופעלים:

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, נדרשת ההרשאה serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין בממשק Service Usage' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים

    gcloud services enable cloudresourcemanager.googleapis.com compute.googleapis.com container.googleapis.com iamcredentials.googleapis.com gkebackup.googleapis.com
  14. מעניקים תפקידים לחשבון המשתמש. מריצים את הפקודה הבאה לכל אחד מהתפקידים הבאים ב-IAM: roles/storage.objectViewer, roles/container.admin, roles/iam.serviceAccountAdmin, roles/compute.admin, roles/gkebackup.admin, roles/monitoring.viewer

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

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

    • ‫PROJECT_ID: מזהה הפרויקט.
    • ‫USER_IDENTIFIER: המזהה של חשבון המשתמש . לדוגמה, myemail@example.com.
    • ‫ROLE: תפקיד ה-IAM שאתם מקצים לחשבון המשתמש.

מגדירים את הסביבה

כדי להגדיר את הסביבה באמצעות Cloud Shell:

  1. מגדירים משתני סביבה לפרויקט, לאזור ולקידומת של משאב אשכול Kubernetes:

    export PROJECT_ID=PROJECT_ID
    export KUBERNETES_CLUSTER_PREFIX=elasticsearch
    export REGION=us-central1
    
    • מחליפים את PROJECT_ID במזהה הפרויקט ב- Google Cloud.

    במדריך הזה נעשה שימוש באזור us-central1 כדי ליצור את משאבי הפריסה.

  2. בודקים את הגרסה של Helm:

    helm version
    

    אם הגרסה ישנה יותר מ-3.13, צריך לעדכן אותה:

    curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
    
  3. משכפלים את מאגר המקורות של הקוד לדוגמה מ-GitHub:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  4. כדי להתחיל ליצור משאבי פריסה, עוברים לספרייה elasticsearch:

    cd kubernetes-engine-samples/databases/elasticsearch
    

יצירת תשתית האשכול

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

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

טייס אוטומטי

בתרשים הבא מוצג אשכול GKE במצב Autopilot שנפרס בפרויקט.

אשכול GKE Autopilot

כדי לפרוס את תשתית האשכול, מריצים את הפקודות הבאות ב-Cloud Shell:

export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=terraform/gke-autopilot init
terraform -chdir=terraform/gke-autopilot apply \
-var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}

‫GKE מחליף את המשתנים הבאים בזמן הריצה:

  • ‫GOOGLE_OAUTH_ACCESS_TOKEN משתמש בפקודה gcloud auth print-access-token כדי לאחזר אסימון גישה שמאמת אינטראקציות עם ממשקי Google Cloud API שונים
  • ‫PROJECT_ID,‏ REGION ו-KUBERNETES_CLUSTER_PREFIX הם משתני הסביבה שמוגדרים בקטע הגדרת הסביבה ומוקצים למשתנים הרלוונטיים החדשים עבור אשכול Autopilot שאתם יוצרים.

כשמוצגת בקשה, מקלידים yes.

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

...
Apply complete! Resources: 9 added, 0 changed, 0 destroyed.

Outputs:

kubectl_connection_command = "gcloud container clusters get-credentials elasticsearch-cluster --region us-central1"

‫Terraform יוצר את המשאבים הבאים:

  • רשת VPC מותאמת אישית ורשת משנה פרטית לצמתים של Kubernetes.
  • ‫Cloud Router כדי לגשת לאינטרנט דרך תרגום כתובת רשת (NAT).
  • אשכול GKE פרטי באזור us-central1.
  • ServiceAccount עם הרשאות רישום ביומן ומעקב עבור האשכול.
  • הגדרת השירות המנוהל של Google Cloud ל-Prometheus לצורך מעקב והתראות לגבי אשכולות.

רגילה

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

אשכול GKE Standard

כדי לפרוס את תשתית האשכול, מריצים את הפקודות הבאות ב-Cloud Shell:

export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
terraform -chdir=terraform/gke-standard init
terraform -chdir=terraform/gke-standard apply \
-var project_id=${PROJECT_ID} \
-var region=${REGION} \
-var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}

‫GKE מחליף את המשתנים הבאים בזמן הריצה:

  • ‫GOOGLE_OAUTH_ACCESS_TOKEN משתמש בפקודה gcloud auth print-access-token כדי לאחזר אסימון גישה שמאמת אינטראקציות עם ממשקי Google Cloud API שונים.
  • ‫PROJECT_ID, ‏REGION ו-KUBERNETES_CLUSTER_PREFIX הם משתני הסביבה שמוגדרים בקטע הגדרת הסביבה ומוקצים למשתנים הרלוונטיים החדשים עבור אשכול Standard שאתם יוצרים.

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

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

...
Apply complete! Resources: 10 added, 0 changed, 0 destroyed.

Outputs:

kubectl_connection_command = "gcloud container clusters get-credentials elasticsearch-cluster --region us-central1"

‫Terraform יוצר את המשאבים הבאים:

  • רשת VPC מותאמת אישית ורשת משנה פרטית לצמתים של Kubernetes.
  • ‫Cloud Router כדי לגשת לאינטרנט דרך תרגום כתובת רשת (NAT).
  • אשכול GKE פרטי באזור us-central1 עם התאמה אוטומטית של גודל האשכול (node autoscaling) (צומת אחד עד שני צמתים לכל אזור).
  • ServiceAccount עם הרשאות רישום ביומן ומעקב עבור האשכול.
  • הגדרת השירות המנוהל של Google Cloud ל-Prometheus לניטור של אשכולות ולהתראות.

התחברות לאשכול

מגדירים את kubectl כדי לאחזר פרטי כניסה ולתקשר עם אשכול GKE החדש:

gcloud container clusters get-credentials \
    ${KUBERNETES_CLUSTER_PREFIX}-cluster --location ${REGION}

פריסת מסד הנתונים של Elasticsearch ואופרטור StatefulHA

בקטע הזה פורסים את מסד הנתונים Elasticsearch (במצב אשכול) ואת האופרטור StatefulHA באשכול GKE באמצעות תרשים Helm של ECK Operator.

הפריסה יוצרת אשכול GKE עם ההגדרות הבאות:

  • שלוש רפליקות של צמתי Elasticsearch.
  • ‫DaemonSet כדי לשנות את הגדרות הזיכרון הווירטואלי, לאופטימיזציה של הביצועים של Elasticsearch. ‫DaemonSet הוא בקר Kubernetes שעוזר לוודא שעותק של Pod פועל בכל צומת באשכול.
  • הגדרה של NodeAffinity ו-PodAntiAffinity כדי להבטיח חלוקה נכונה בין צמתי Kubernetes, אופטימיזציה של השימוש במאגרי צמתים ומקסום הזמינות באזורים שונים.
  • אופרטור עם שמירת מצב HA שמנהל תהליכי יתירות כשל ומסייע להבטיח זמינות גבוהה. ‫StatefulSet הוא בקר Kubernetes ששומר על זהות ייחודית ומתמשכת לכל אחד מה-Pods שלו.
  • לצורך אימות, מסד הנתונים יוצר סודות של Kubernetes עם פרטי אימות, סיסמאות ואישורים.

כדי להשתמש בתרשים Helm לפריסת מסד הנתונים של Elasticsearch, פועלים לפי השלבים הבאים:

  1. מפעילים את התוסף StatefulHA:

    טייס אוטומטי

    ‫GKE מפעיל באופן אוטומטי את התוסף StatefulHA בזמן יצירת האשכול.

    רגילה

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

    gcloud container clusters update ${KUBERNETES_CLUSTER_PREFIX}-cluster \
        --project=${PROJECT_ID} \
        --location=${REGION} \
        --update-addons=StatefulHA=ENABLED
    

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

  2. יוצרים הגדרת משאב מותאם אישית (CRD) של Elastic Cloud on Kubernetes‏ (ECK):

    kubectl apply -f https://download.elastic.co/downloads/eck/2.11.1/crds.yaml
    
  3. פורסים את אופרטור ECK:

    kubectl apply -f https://download.elastic.co/downloads/eck/2.11.1/operator.yaml
    
  4. יוצרים את מרחב השמות elastic למסד הנתונים:

    kubectl create ns elastic
    
  5. מתקינים את המשאב HighAvailabilityApplication (HAA), שמגדיר כללי מעבר לגיבוי ולשיקום (failover) עבור Elasticsearch.

    kubectl apply -n elastic -f manifests/01-regional-pd/ha-app.yaml
    

    המניפסט ha-app.yaml מתאר את המשאב HighAvailabilityApplication:

    kind: HighAvailabilityApplication
    apiVersion: ha.gke.io/v1
    metadata:
      name: elasticsearch-ha-es-main
      namespace: elastic
    spec:
      resourceSelection:
        resourceKind: StatefulSet
      policy:
        storageSettings:
          requireRegionalStorage: false
        failoverSettings:
          forceDeleteStrategy: AfterNodeUnreachable
          afterNodeUnreachable:
            afterNodeUnreachableSeconds: 20 # 60 seconds total
  6. מחילים את קובץ המניפסט כדי ליצור דיסק SSD אזורי לאחסון מתמיד StorageClass:

    kubectl apply -n elastic -f manifests/01-regional-pd/regional-pd.yaml
    

    המניפסט regional-pd.yaml מתאר את דיסק ה-SSD המתמיד StorageClass:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    allowVolumeExpansion: true
    metadata:
      name: ha-regional
    parameters:
      replication-type: regional-pd
      type: pd-ssd
      availability-class: regional-hard-failover
    provisioner: pd.csi.storage.gke.io
    reclaimPolicy: Retain
    volumeBindingMode: WaitForFirstConsumer
  7. פורסים את משאב DaemonSet כדי להגדיר זיכרון וירטואלי בכל צומת:

    kubectl apply -n elastic -f manifests/02-elasticsearch/mmap-count.yaml
    

    במניפסט של mmap-count.yaml מפורט DaemonSet:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: max-map-count-setter
      labels:
        k8s-app: max-map-count-setter
    spec:
      selector:
        matchLabels:
          name: max-map-count-setter
      template:
        metadata:
          labels:
            name: max-map-count-setter
        spec:
          initContainers:
            - name: max-map-count-setter
              image: docker.io/bash:5.2.21
              resources:
                limits:
                  cpu: 100m
                  memory: 32Mi
              securityContext:
                privileged: true
                runAsUser: 0
              command: ['/usr/local/bin/bash', '-e', '-c', 'echo 262144 > /proc/sys/vm/max_map_count']
          containers:
            - name: sleep
              image: docker.io/bash:5.2.21
              command: ['sleep', 'infinity']
  8. מחילים את המניפסט כדי לפרוס את אשכול Elasticsearch:

    kubectl apply -n elastic -f manifests/02-elasticsearch/elasticsearch.yaml
    

    המניפסט elasticsearch.yaml מתאר את הפריסה:

    apiVersion: elasticsearch.k8s.elastic.co/v1
    kind: Elasticsearch
    metadata:
      name: elasticsearch-ha
    spec:
      version: 8.11.4
      nodeSets:
      - name: main
        count: 3
        volumeClaimTemplates:
        - metadata:
            name: elasticsearch-data 
          spec:
            accessModes:
            - ReadWriteOnce
            resources:
              requests:
                storage: 10Gi
            storageClassName: ha-regional
        config:
        podTemplate:
          metadata:
            labels:
              app.stateful/component: elasticsearch
          spec:
            initContainers:
            - name: max-map-count-check
              command: ['sh', '-c', "while true; do mmc=$(cat /proc/sys/vm/max_map_count); if [ ${mmc} -eq 262144 ]; then exit 0; fi; sleep 1; done"]
            containers:
            - name: metrics
              image: quay.io/prometheuscommunity/elasticsearch-exporter:v1.7.0
              command:
                - /bin/elasticsearch_exporter
                - --es.ssl-skip-verify
                - --es.uri=https://$(ES_USER):$(ES_PASSWORD)@localhost:9200
              securityContext:
                runAsNonRoot: true
                runAsGroup: 10000
                runAsUser: 10000
              resources:
                requests:
                  memory: "128Mi"
                  cpu: "25m"
                limits:
                  memory: "128Mi"
                  cpu: "100m"
              ports:
              - containerPort: 9114
              env:
              - name: ES_USER
                value: "elastic"
              - name: ES_PASSWORD
                valueFrom:
                  secretKeyRef:
                    name: elasticsearch-ha-es-elastic-user
                    key: elastic
            - name: elasticsearch
              resources:
                limits:
                  memory: 4Gi
                  cpu: 1
            affinity:
              nodeAffinity:
                preferredDuringSchedulingIgnoredDuringExecution:
                  - weight: 1
                    preference:
                      matchExpressions:
                      - key: app.stateful/component
                        operator: In
                        values:
                        - elasticsearch
              podAntiAffinity:
                preferredDuringSchedulingIgnoredDuringExecution:
                - weight: 1
                  podAffinityTerm:
                    labelSelector:
                      matchLabels:
                        app.stateful/component: elasticsearch
                    topologyKey: topology.kubernetes.io/zone

    מחכים כמה דקות עד שהפעלת אשכול Elasticsearch תושלם.

  9. בודקים את סטטוס הפריסה:

    kubectl get elasticsearch -n elastic --watch
    

    אם מסד הנתונים elasticsearch נפרס בהצלחה, הפלט אמור להיראות כך:

    NAME               HEALTH   NODES   VERSION   PHASE   AGE
    elasticsearch-ha   green    3       8.11.4    Ready   2m30s
    

    מחכים עד שHEALTH יופיע כ-green. אם צריך, מקישים על Ctrl+C כדי לצאת מהפקודה.

  10. פריסת איזון עומסים פנימי כדי לגשת למסד הנתונים של Elasticsearch שפועל באותו VPC כמו אשכול GKE:

    kubectl apply -n elastic -f manifests/02-elasticsearch/ilb.yaml
    

    במניפסט ilb.yaml מתואר שירות LoadBalancer:

    apiVersion: v1
    kind: Service
    metadata:
      annotations:
        #cloud.google.com/neg: '{"ingress": true}'
        networking.gke.io/load-balancer-type: "Internal"
      labels:
        app.kubernetes.io/name: elasticsearch
      name: elastic-ilb
    spec:
      ports:
      - name: https
        port: 9200
        protocol: TCP
        targetPort: 9200
      selector:
        common.k8s.elastic.co/type: elasticsearch
        elasticsearch.k8s.elastic.co/cluster-name: elasticsearch-ha
      type: LoadBalancer
  11. כדי לבדוק אם כללי המעבר לגיבוי חלים, מתארים את המשאב ומאשרים את Status: Message: Application is protected.

    kubectl describe highavailabilityapplication elasticsearch-ha-es-main -n elastic
    

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

    Status:
      Conditions:
        Last Transition Time:  2024-02-01T13:27:50Z
        Message:               Application is protected
        Observed Generation:   1
        Reason:                ApplicationProtected
        Status:                True
        Type:                  Protected
    Events:                    <none>
    
  12. אחרי ש-GKE מתחיל את עומסי העבודה, מוודאים ש-GKE יצר את עומסי העבודה של Elasticsearch:

    kubectl get pod,svc,statefulset,pdb,secret,daemonset -n elastic
    

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

    NAME                             READY   STATUS    RESTARTS   AGE
    pod/elasticsearch-ha-es-main-0   2/2     Running   0          7m16s
    pod/elasticsearch-ha-es-main-1   2/2     Running   0          7m16s
    pod/elasticsearch-ha-es-main-2   2/2     Running   0          7m16s
    pod/max-map-count-setter-28wt9   1/1     Running   0          7m27s
    pod/max-map-count-setter-cflsw   1/1     Running   0          7m27s
    pod/max-map-count-setter-gzq9k   1/1     Running   0          7m27s
    
    NAME                                        TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
    service/elasticsearch-ha-es-http            ClusterIP   10.52.8.28   <none>        9200/TCP   7m18s
    service/elasticsearch-ha-es-internal-http   ClusterIP   10.52.3.48   <none>        9200/TCP   7m18s
    service/elasticsearch-ha-es-main            ClusterIP   None         <none>        9200/TCP   7m16s
    service/elasticsearch-ha-es-transport       ClusterIP   None         <none>        9300/TCP   7m18s
    
    NAME                                        READY   AGE
    statefulset.apps/elasticsearch-ha-es-main   3/3     7m16s
    
    NAME                                                     MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
    poddisruptionbudget.policy/elasticsearch-ha-es-default   2               N/A               1                     7m16s
    
    NAME                                                 TYPE     DATA   AGE
    secret/elasticsearch-ha-es-elastic-user              Opaque   1      7m18s
    secret/elasticsearch-ha-es-file-settings             Opaque   1      7m16s
    secret/elasticsearch-ha-es-http-ca-internal          Opaque   2      7m17s
    secret/elasticsearch-ha-es-http-certs-internal       Opaque   3      7m17s
    secret/elasticsearch-ha-es-http-certs-public         Opaque   2      7m17s
    secret/elasticsearch-ha-es-internal-users            Opaque   4      7m18s
    secret/elasticsearch-ha-es-main-es-config            Opaque   1      7m16s
    secret/elasticsearch-ha-es-main-es-transport-certs   Opaque   7      7m16s
    secret/elasticsearch-ha-es-remote-ca                 Opaque   1      7m16s
    secret/elasticsearch-ha-es-transport-ca-internal     Opaque   2      7m16s
    secret/elasticsearch-ha-es-transport-certs-public    Opaque   1      7m16s
    secret/elasticsearch-ha-es-xpack-file-realm          Opaque   4      7m18s
    
    NAME                                  DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
    daemonset.apps/max-map-count-setter   6         6         6       6            6           <none>          13m
    

משאבי GKE הבאים נוצרים עבור אשכול Elasticsearch:

  • ‫Elasticsearch StatefulSet ששולט בשלוש רפליקות של Pod.
  • ‫DaemonSet להגדרת הגדרות של זיכרון וירטואלי.
  • שירותים להתחברות ל-Elasticsearch.
  • סודות עם פרטי כניסה של משתמש על ואישורים שקשורים לשירות.
  • ‫Pod של אופרטור HA עם שמירת מצב ומשאב HighlyAvailableApplication, עם מעקב פעיל אחרי אפליקציית Elasticsearch.

הרצת שאילתות באמצעות מחברת Vertex AI Colab Enterprise

בקטע הזה מוסבר איך ליצור הטמעות במסמכי Elasticsearch ולבצע שאילתות של חיפוש סמנטי באמצעות לקוח Python הרשמי של Elasticsearch במחברת Colab Enterprise. מסמך ב-Elasticsearch מורכב משדות שונים, שלכל אחד מהם יש ערך תואם.

מידע נוסף על Vertex AI Colab Enterprise זמין במאמרי העזרה של Colab Enterprise.

שיטה מומלצת:

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

בדוגמה הזו, משתמשים במערך נתונים מקובץ CSV שמכיל רשימה של ספרים בז'אנרים שונים. ‫Elasticsearch משמש כמנוע חיפוש, וה-Pod שיוצרים משמש כלקוח ששולח שאילתות למסד הנתונים של Elasticsearch.

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

יצירת תבנית בזמן ריצה

כדי ליצור תבנית של סביבת זמן ריצה ב-Colab Enterprise:

  1. במסוף Google Cloud , עוברים לדף Runtime Templates של Colab Enterprise ומוודאים שהפרויקט שלכם נבחר:

    מעבר אל Runtime Templates

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

  3. בקטע Runtime basics:

    • בשדה שם מוצג, מזינים elastic-connect.
    • ברשימה הנפתחת אזור, בוחרים באפשרות us-central1. זהו אותו אזור כמו באשכול GKE.
  4. בקטע Configure compute (הגדרת מחשוב):

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

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

יצירת סביבת ריצה

כדי ליצור סביבת זמן ריצה ב-Colab Enterprise:

  1. ברשימת תבניות זמן הריצה של התבנית שיצרתם, בעמודה פעולות, לוחצים על ואז על יצירת זמן ריצה. מופיעה החלונית Create Vertex AI Runtime.

  2. כדי ליצור סביבת ריצה על סמך התבנית, לוחצים על יצירה.

  3. בכרטיסייה Runtimes (זמני ריצה) שנפתחת, מחכים שהסטטוס ישתנה ל-Healthy (תקין).

ייבוא המחברת

כדי לייבא את ה-notebook ב-Colab Enterprise:

  1. עוברים לכרטיסייה המחברות שלי ולוחצים על ייבוא. החלונית Import notebooks תופיע.

  2. בקטע מקור לייבוא, בוחרים באפשרות כתובת URL.

  3. בקטע כתובות URL של מחברות, מזינים את הקישור הבא:

    https://raw.githubusercontent.com/GoogleCloudPlatform/kubernetes-engine-samples/main/databases/elasticsearch/manifests/03-notebook/vector-database.ipynb
    
  4. לוחצים על Import.

התחברות לסביבת זמן הריצה והרצת שאילתות

כדי להתחבר לסביבת זמן הריצה ולהריץ שאילתות:

  1. במחברת, ליד הלחצן Connect (התחברות), לוחצים על Additional connection options (אפשרויות חיבור נוספות). מופיעה החלונית Connect to Vertex AI Runtime.

  2. בוחרים באפשרות Connect to a runtime (התחברות לסביבת זמן ריצה) ואז באפשרות Connect to an existing Runtime (התחברות לסביבת זמן ריצה קיימת).

  3. בוחרים את זמן הריצה שהפעלתם ולוחצים על Connect (חיבור).

  4. כדי להריץ את התאים ב-notebook, לוחצים על הלחצן Run cell לצד כל תא קוד.

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

צפייה במדדי Prometheus עבור האשכול

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

בתרשים הבא אפשר לראות איך Prometheus אוסף מדדים לגבי האשכול:

איסוף מדדים של Prometheus

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

  • ‫Pods של Elasticsearch שחושפים מדדים בנתיב / ובפורט 9114. המדדים האלה מסופקים על ידי קונטיינר ה-sidecar שנקרא metrics ומכיל את elasticsearch_exporter.
  • אוספים שמבוססים על Prometheus ומעבדים את המדדים מ-Pod של Elasticsearch.
  • משאב PodMonitoring ששולח את המדדים ל-Cloud Monitoring.

הגדרת האשכול מגדירה קונטיינר sidecar עם כלי לייצוא מדדים בפורמט Prometheus:

apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: elasticsearch-ha
spec:
  ...
  nodeSets:
  - name: main
    ...
    podTemplate:
      spec:
        containers:
        ...
        - name: metrics
          image: quay.io/prometheuscommunity/elasticsearch-exporter:v1.7.0
          command:
          - /bin/elasticsearch_exporter
          - --es.ssl-skip-verify
          - --es.uri=https://$(ES_USER):$(ES_PASSWORD)@localhost:9200
          ...
          env:
          - name: ES_USER
            value: "elastic"
          - name: ES_PASSWORD
            valueFrom:
            secretKeyRef:
              name: elasticsearch-ha-es-elastic-user
              key: elastic

כדי לייצא את המדדים ולראות אותם:

  1. יוצרים את משאב PodMonitoring כדי לגרד מדדים לפי labelSelector:

    kubectl apply -n elastic -f manifests/04-prometheus-metrics/pod-monitoring.yaml
    

    המניפסט pod-monitoring.yaml מתאר את המשאב PodMonitoring:

    apiVersion: monitoring.googleapis.com/v1
    kind: PodMonitoring
    metadata:
      name: elasticsearch
    spec:
      selector:
        matchLabels:
          app.stateful/component: elasticsearch
          elasticsearch.k8s.elastic.co/cluster-name: elasticsearch-ha
      endpoints:
      - port: 9114
        interval: 30s
        path: /metrics

    אחרי כמה דקות, לוח הבקרה המובנה Elasticsearch Prometheus Overview מוצג.

  2. כדי לראות עוד גרפים שקשורים לנתונים, מייבאים לוח בקרה מותאם אישית של Cloud Monitoring עם ההגדרות שמוגדרות ב-dashboard.json:

    gcloud --project "${PROJECT_ID}" monitoring dashboards create --config-from-file monitoring/dashboard.json
    
  3. אחרי שהפקודה מורצת בהצלחה, עוברים אל לוחות הבקרה ב-Cloud Monitoring:

    מעבר לסקירה הכללית של מרכזי השליטה

  4. ברשימת לוחות הבקרה, פותחים את לוח הבקרה ElasticSearch Overview. יכול להיות שיחלפו דקה או שתיים עד שהמדדים ייאספו ויוצגו.

    בלוח הבקרה מוצג מספר של מדדי מפתח:

    • מדדים
    • מסמכים ורסיסים
    • פעולות בהמתנה
    • הרצת צמתים עם סטטוס התקינות שלהם

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

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

במדריך הזה מוגדרת תוכנית גיבוי לאשכול GKE כדי לבצע גיבויים של כל עומסי העבודה, כולל Secrets ו-Volumes, מדי יום בשעה 3:00. כדי להבטיח ניהול יעיל של האחסון, גיבויים בני יותר משלושה ימים נמחקים באופן אוטומטי.

  1. מפעילים את התכונה 'גיבוי ל-GKE' באשכול:

    gcloud container clusters update ${KUBERNETES_CLUSTER_PREFIX}-cluster \
        --project=${PROJECT_ID} \
        --location=${REGION} \
        --update-addons=BackupRestore=ENABLED
    
  2. יוצרים תוכנית גיבוי עם תזמון יומי לכל מרחבי השמות באשכול:

    gcloud beta container backup-restore backup-plans create ${KUBERNETES_CLUSTER_PREFIX}-cluster-backup \
        --project=${PROJECT_ID} \
        --location=${REGION} \
        --cluster="projects/${PROJECT_ID}/locations/${REGION}/clusters/${KUBERNETES_CLUSTER_PREFIX}-cluster" \
        --all-namespaces \
        --include-secrets \
        --include-volume-data \
        --cron-schedule="0 3 * * *" \
        --backup-retain-days=3
    

    הפקודה משתמשת במשתני הסביבה הרלוונטיים בזמן הריצה.

    הפורמט של שם האשכול הוא יחסי לפרויקט ולאזור שלכם, באופן הבא:

    projects/PROJECT_ID/locations/REGION/clusters/CLUSTER_NAME
    

    כשמופיעה הבקשה, מקלידים y.הפלט אמור להיראות כך:

    Create request issued for: [elasticsearch-cluster-backup]
    Waiting for operation [projects/PROJECT_ID/locations/us-central1/operations/operation-1706528750815-610142ffdc9ac-71be4a05-f61c99fc] to complete...⠹
    

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

    Created backup plan [elasticsearch-cluster-backup].
    
  3. תוכנית הגיבוי החדשה שנוצרה elasticsearch-cluster-backup מופיעה במסוף Backup for GKE.

    מעבר לגיבוי ל-GKE

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

הסרת המשאבים

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

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

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

כדי למחוק Google Cloud פרויקט:

gcloud projects delete PROJECT_ID

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

מחיקת משאבים בודדים

  1. מגדירים משתני סביבה.

    export PROJECT_ID=${PROJECT_ID}
    export KUBERNETES_CLUSTER_PREFIX=elasticsearch
    export REGION=us-central1
    
  2. מריצים את הפקודה terraform destroy:

    export GOOGLE_OAUTH_ACCESS_TOKEN=$(gcloud auth print-access-token)
    terraform  -chdir=terraform/FOLDER destroy \
    -var project_id=${PROJECT_ID} \
    -var region=${REGION} \
    -var cluster_prefix=${KUBERNETES_CLUSTER_PREFIX}
    

    מחליפים את FOLDER ב-gke-autopilot או ב-gke-standard, בהתאם לסוג אשכול GKE שיצרתם.

    כשמוצגת בקשה, מקלידים yes.

  3. חיפוש כל הדיסקים שלא צורפו:

    export disk_list=$(gcloud compute disks list --filter="-users:* AND labels.name=${KUBERNETES_CLUSTER_PREFIX}-cluster" --format "value[separator=|](name,region)")
    
  4. מוחקים את הדיסקים:

    for i in $disk_list; do
     disk_name=$(echo $i| cut -d'|' -f1)
     disk_region=$(echo $i| cut -d'|' -f2|sed 's|.*/||')
     echo "Deleting $disk_name"
     gcloud compute disks delete $disk_name --region $disk_region --quiet
    done
    
  5. מחיקת המאגר ב-GitHub:

    rm -r ~/kubernetes-engine-samples/
    

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