הדרכה: פריסת מכונה וירטואלית קיימת באשכול באמצעות VM Runtime ב-GDC

במאמר הזה מוסבר איך לפרוס עומס עבודה שמבוסס על מכונה וירטואלית (VM) בהתקנה של תוכנת Distributed Cloud רק עבור Bare Metal באמצעות VM Runtime ב-GDC. עומס העבודה שמשמש במדריך הזה הוא אפליקציית נקודת המכירה לדוגמה. האפליקציה הזו מייצגת מסוף של נקודת מכירה טיפוסי שפועל על חומרה מקומית בחנות קמעונאית.

במסמך הזה, תעבירו את האפליקציה הזו ממכונה וירטואלית לאשכול ותגשו לחלק הקדמי של האפליקציה באינטרנט. כדי להעביר מכונה וירטואלית קיימת אל האשכול, צריך קודם ליצור תמונת דיסק של המכונה הווירטואלית הזו. לאחר מכן, התמונה צריכה להיות מאוחסנת במאגר שהאשכול יכול לגשת אליו. לבסוף, אפשר להשתמש בכתובת ה-URL של התמונה כדי ליצור את המכונה הווירטואלית. ‫VM Runtime on GDC מצפה שהתמונות יהיו בפורמט qcow2. אם תספקו סוג אחר של תמונה, היא תומר אוטומטית לפורמט qcow2. כדי להימנע מהמרות חוזרות ולאפשר שימוש חוזר, אפשר להמיר תמונה של דיסק וירטואלי ולארח את התמונה qcow2.

במאמר הזה נעשה שימוש בתמונה שהוכנה מראש של מכונה וירטואלית (VM) של Compute Engine, שבה עומס העבודה פועל כשירות systemd. אפשר לפעול לפי אותם השלבים כדי לפרוס אפליקציה משלכם.

מטרות

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

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

  • גישה לאשכול Bare Metal בגרסה 1.12.0 ואילך, שנוצר לפי המדריך Install with Manual Loadbalancer. במאמר הזה מוגדרים משאבי רשת כדי שתוכלו לגשת לעומס העבודה שפועל בתוך המכונה הווירטואלית דרך דפדפן. אם אתם לא רוצים את ההתנהגות הזו, אתם יכולים לפעול לפי ההוראות במאמר הזה ולהשתמש בכל התקנה של תוכנת Distributed Cloud רק לשרת פיזי.
  • תחנת עבודה שעומדת בדרישות הבאות:
    • יש לו גישה לאשכול באמצעות ה-CLI של bmctl.
    • יש לו גישה לאשכול באמצעות ה-CLI של kubectl.

הפעלת VM Runtime ב-GDC והתקנת הפלאגין virtctl

ה-VM Runtime בהגדרת משאב בהתאמה אישית של GDC הוא חלק מכל האשכולות של Bare Metal מאז גרסה 1.10. מופע של המשאב המותאם אישית VMRuntime כבר נוצר במהלך ההתקנה. אבל הוא מושבת כברירת מחדל.

  1. הפעלת VM Runtime ב-GDC:

    sudo bmctl enable vmruntime --kubeconfig KUBECONFIG_PATH
    
    • ‫KUBECONFIG_PATH: הנתיב של קובץ ה-kubeconfig של אשכול משתמשים.
  2. בודקים שVMRuntime מופעל:

    kubectl wait --for=jsonpath='{.status.ready}'=true vmruntime vmruntime
    

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

    vmruntime.vm.cluster.gke.io/vmruntime condition met
    
  3. מתקינים את הפלאגין virtctl ל-kubectl:

    sudo -E bmctl install virtctl
    

    בדוגמה הבאה של הפלט מוצג שתהליך ההתקנה של הפלאגין virtctl הושלם:

    Please check the logs at bmctl-workspace/log/install-virtctl-20220831-182135/install-virtctl.log
    [2022-08-31 18:21:35+0000] Install virtctl succeeded
    
  4. כדי לוודא שהפלאגין virtctl הותקן:

    kubectl virt
    

    בדוגמה הבאה של הפלט אפשר לראות שהפלאגין virtctl זמין לשימוש עם kubectl:

    Available Commands:
      addvolume         add a volume to a running VM
      completion        generate the autocompletion script for the specified shell
      config            Config subcommands.
      console           Connect to a console of a virtual machine instance.
      create            Create subcommands.
      delete            Delete  subcommands.
    ...
    

פריסת עומס העבודה שמבוסס על מכונה וירטואלית

כשפורסים מכונה וירטואלית בהתקנה של תוכנת Distributed Cloud רק ל-Bare Metal, VM Runtime ב-GDC מצפה לתמונת מכונה וירטואלית. התמונה הזו משמשת כדיסק האתחול של המכונה הווירטואלית שנפרסה.

במדריך הזה נסביר איך להעביר עומס עבודה שמבוסס על מכונה וירטואלית ב-Compute Engine לאשכול. נוצרה מכונה וירטואלית של Compute Engine, והאפליקציה לדוגמה של נקודת המכירה (POS) הוגדרה לפעול כשירות systemd. נוצר קובץ אימג' של הדיסק של מכונת ה-VM הזו, יחד עם עומס העבודה של אפליקציית ה-PoS ב- Google Cloud. לאחר מכן יוצאה התמונה לקטגוריה של Cloud Storage כקובץ תמונה qcow2. בשלבים הבאים תשתמשו בתמונה qcow2 שהכנתם מראש.

קוד המקור במסמך הזה זמין במאגר anthos-samples ב-GitHub. משתמשים במשאבים ממאגר המידע הזה כדי להשלים את השלבים הבאים.

  1. פריסה של MySQL StatefulSet. אפליקציית נקודת המכירה מצפה להתחבר למסד נתונים מסוג MySQL כדי לאחסן נתוני מלאי ופרטי תשלום. מאגר המידע של מערכת הקופה כולל קובץ מניפסט לדוגמה שפורס MySQLStatefulSet, מגדיר ConfigMap משויך ו-KubernetesService. התג ConfigMap מגדיר את פרטי הכניסה למופע MySQL, שהם אותם פרטי כניסה שמועברים לאפליקציית נקודת המכירה.

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/point-of-sale/main/k8-manifests/common/mysql-db.yaml
    
  2. פורסים את עומס העבודה של ה-VM באמצעות תמונת qcow2 שהוכנה מראש:

    kubectl virt create vm pos-vm \
        --boot-disk-size=80Gi \
        --memory=4Gi \
        --vcpu=2 \
        --image=https://storage.googleapis.com/pos-vm-images/pos-vm.qcow2
    

    הפקודה הזו יוצרת קובץ YAML שנקרא על שם ה-VM (google-virtctl/pos-vm.yaml). אפשר לבדוק את הקובץ כדי לראות את ההגדרה של VirtualMachine ושל VirtualMachineDisk. במקום להשתמש בתוסף virtctl, אפשר לפרוס את עומס העבודה של מכונת ה-VM באמצעות הגדרות של Kubernetes Resource Model ‏ (KRM), כמו שרואים בקובץ ה-YAML שנוצר.

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

    Constructing manifest for vm "pos-vm":
    Manifest for vm "pos-vm" is saved to /home/tfadmin/google-virtctl/pos-vm.yaml
    Applying manifest for vm "pos-vm"
    Created gvm "pos-vm"
    
  3. בודקים את סטטוס יצירת המכונה הווירטואלית.

    משאב VirtualMachine מזוהה על ידי משאב vm.cluster.gke.io/v1.VirtualMachine ב-VM Runtime ב-GDC. הקיצור שלו הוא gvm.

    כשיוצרים מכונת VM, נוצרים שני המשאבים הבאים:

    • ‫VirtualMachineDisk הוא דיסק אחסון מתמיד שאליו מיובא התוכן של תמונת ה-VM.
    • ‫VirtualMachine היא מכונת ה-VM עצמה. ה-DataVolume מותקן ב-VirtualMachine לפני שהמכונה הווירטואלית מופעלת.

    בודקים את הסטטוס של VirtualMachineDisk. הפונקציה VirtualMachineDisk יוצרת באופן פנימי משאב DataVolume. קובץ האימג' של ה-VM מיובא אל DataVolume, שמוטמע ב-VM:

    kubectl get datavolume
    

    בדוגמה הבאה של פלט אפשר לראות את תחילת הייבוא של התמונה:

    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    ImportScheduled   N/A                   8s
    
  4. בודקים את הסטטוס של VirtualMachine. הסטטוס של VirtualMachine הוא Provisioning עד שהייבוא של DataVolume מסתיים:

    kubectl get gvm
    

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

    NAME      STATUS         AGE     IP
    pos-vm    Provisioning   1m
    
  5. מחכים עד שתמונת המכונה הווירטואלית תיווָא במלואה אל DataVolume. ממשיכים לצפות בהתקדמות הייבוא של התמונה:

    kubectl get datavolume -w
    

    בדוגמה הבאה של פלט אפשר לראות את ייבוא תמונת הדיסק:

    NAME              PHASE              PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv   ImportInProgress   0.00%                 14s
    ...
    ...
    pos-vm-boot-dv   ImportInProgress   0.00%                 31s
    pos-vm-boot-dv   ImportInProgress   1.02%                 33s
    pos-vm-boot-dv   ImportInProgress   1.02%                 35s
    ...
    

    כשהייבוא מסתיים ונוצר DataVolume, הפלט שמוצג בדוגמה הבאה מראה את PHASE של Succeeded :

    kubectl get datavolume
    
    NAME              PHASE             PROGRESS   RESTARTS   AGE
    pos-vm-boot-dv    Succeeded         100.0%                14m18s
    
  6. מוודאים שVirtualMachine נוצר בהצלחה:

    kubectl get gvm
    

    אם היצירה הצליחה, STATUS יציג RUNNING, כמו בדוגמה הבאה, יחד עם כתובת ה-IP של מכונת ה-VM:

    NAME      STATUS    AGE     IP
    pos-vm    Running   40m     192.168.3.250
    

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

התמונה שמשמשת את ה-VM כוללת את האפליקציה לדוגמה של נקודת המכירה. האפליקציה מוגדרת להתחיל אוטומטית בזמן האתחול כשירות systemd. אפשר לראות את קובצי ההגדרות של שירותי systemd בספרייה pos-systemd-services.

  1. מתחברים למסוף של ה-VM. מריצים את הפקודה הבאה ומקישים על Enter⏎ אחרי שמופיעה ההודעה Successfully connected to pos-vm…:

    kubectl virt console pos-vm
    

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

    Successfully connected to pos-vm console. The escape sequence is ^]
    
    pos-from-public-image login:
    

    משתמשים בחשבון המשתמש ובסיסמה הבאים. החשבון הזה הוגדר בתוך המכונה הווירטואלית המקורית שממנה נוצרה התמונה של VM Runtime ב-GDC VirtualMachine.

    • שם המשתמש להתחברות: abmuser
    • סיסמה: abmworks
  2. בודקים את הסטטוס של שירותי אפליקציית נקודת המכירה. אפליקציית הקופה כוללת שלושה שירותים: API, מלאי ותשלומים. כל השירותים האלה פועלים כשירותי מערכת.

    שלושת השירותים מתחברים זה לזה דרך localhost. עם זאת, האפליקציה מתחברת למסד הנתונים של MySQL באמצעות שירות Kubernetes של mysql-db שנוצר בשלב הקודם. ההתנהגות הזו אומרת שהמכונה הווירטואלית מחוברת אוטומטית לאותה רשת כמו Pods ו-Services, מה שמאפשר תקשורת חלקה בין עומסי העבודה של המכונה הווירטואלית לבין אפליקציות אחרות שמבוססות על קונטיינרים. לא צריך לעשות שום דבר נוסף כדי להפוך את Kubernetes‏ Services לנגיש מהמכונות הווירטואליות שנפרסו באמצעות VM Runtime ב-GDC.

    sudo systemctl status pos*
    

    בדוגמה הבאה של הפלט מוצג הסטטוס של שלושת השירותים ושירות מערכת הבסיס, pos.service:

    ● pos_payments.service - Payments service of the Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos_payments.service; enabled; vendor >
        Active: active (running) since Tue 2022-06-21 18:55:30 UTC; 1h 10min ago
      Main PID: 750 (payments.sh)
          Tasks: 27 (limit: 4664)
        Memory: 295.1M
        CGroup: /system.slice/pos_payments.service
                ├─750 /bin/sh /pos/scripts/payments.sh
                └─760 java -jar /pos/jars/payments.jar --server.port=8083
    
    ● pos_inventory.service - Inventory service of the Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos_inventory.service; enabled; vendor>
        Active: active (running) since Tue 2022-06-21 18:55:30 UTC; 1h 10min ago
      Main PID: 749 (inventory.sh)
          Tasks: 27 (limit: 4664)
        Memory: 272.6M
        CGroup: /system.slice/pos_inventory.service
                ├─749 /bin/sh /pos/scripts/inventory.sh
                └─759 java -jar /pos/jars/inventory.jar --server.port=8082
    
    ● pos.service - Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos.service; enabled; vendor preset: e>
        Active: active (exited) since Tue 2022-06-21 18:55:30 UTC; 1h 10min ago
      Main PID: 743 (code=exited, status=0/SUCCESS)
          Tasks: 0 (limit: 4664)
        Memory: 0B
        CGroup: /system.slice/pos.service
    
    Jun 21 18:55:30 pos-vm systemd[1]: Starting Point of Sale Application...
    Jun 21 18:55:30 pos-vm systemd[1]: Finished Point of Sale Application.
    
    ● pos_apiserver.service - API Server of the Point of Sale Application
        Loaded: loaded (/etc/systemd/system/pos_apiserver.service; enabled; vendor>
        Active: active (running) since Tue 2022-06-21 18:55:31 UTC; 1h 10min ago
      Main PID: 751 (api-server.sh)
          Tasks: 26 (limit: 4664)
        Memory: 203.1M
        CGroup: /system.slice/pos_apiserver.service
                ├─751 /bin/sh /pos/scripts/api-server.sh
                └─755 java -jar /pos/jars/api-server.jar --server.port=8081
    
  3. יוצאים מה-VM. כדי לצאת מהחיבור למסוף, משתמשים ברצף בריחה ^] על ידי הקשה על Ctrl + ].

גישה לעומס העבודה (workload) שמבוסס על מכונה וירטואלית

אם הגדרתם את האשכול לפי המדריך Install with Manual Loadbalancer, כבר נוצר משאב Ingress בשם pos-ingress. המשאב הזה מנתב את התנועה מכתובת ה-IP החיצונית של מאזן העומסים של Ingress לשירות של שרת ה-API של אפליקציית הדוגמה של נקודת המכירה.

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

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-samples/main/anthos-bm-gcp-terraform/resources/manifests/pos-ingress.yaml
    
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: pos-ingress
    spec:
      rules:
      - http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: api-server-svc
                port:
                  number: 8080
  2. יוצרים Kubernetes Service שמנתב תנועה למכונה הווירטואלית. התנועה מנותבת מהמשאב Ingress אל Service:

    kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/anthos-samples/main/anthos-vmruntime/pos-service.yaml
    

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

    service/api-server-svc created
    
    apiVersion: v1
    kind: Service
    metadata:
      name: api-server-svc
    spec:
      selector:
        kubevirt/vm: pos-vm
      ports:
      - protocol: TCP
        port: 8080
        targetPort: 8081
  3. מקבלים את כתובת ה-IP החיצונית של מאזן העומסים Ingress. מאזן העומסים Ingress מנתב את התנועה על סמך הכללים של משאב Ingress. כבר יש לכם כלל pos-ingress להעברת בקשות לשרת ה-API Service. ה-Service הזה מעביר את הבקשות למכונה הווירטואלית:

    INGRESS_IP=$(kubectl get ingress/pos-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    echo $INGRESS_IP
    

    בדוגמה הבאה של פלט אפשר לראות את כתובת ה-IP של איזון העומסים Ingress:

    172.29.249.159 # you might have a different IP address
    
  4. ניגשים לאפליקציה באמצעות כתובת ה-IP של מאזן העומסים של Ingress בדפדפן. בצילומי המסך הבאים אפשר לראות קיוסק של נקודת מכירה עם שני פריטים. אפשר ללחוץ על הפריטים, יותר מפעם אחת אם רוצים להזמין כמה פריטים, ולבצע הזמנה באמצעות הלחצן תשלום. הניסיון הזה מראה שפרסתם בהצלחה עומס עבודה מבוסס-מכונה וירטואלית באשכול באמצעות VM Runtime ב-GDC.

ממשק המשתמש של אפליקציית נקודת מכירה
ממשק המשתמש של אפליקציית נקודת מכירה (לחצו על התמונה כדי להגדיל)

הסרת המשאבים

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

מחק את הכל

  • מוחקים את זמן הריצה של מכונת ה-VM ב-GDC VirtualMachine יחד עם כל המשאבים:

    kubectl virt delete vm pos-vm --all
    

    בדוגמה הבאה של פלט אפשר לראות את אישור המחיקה:

    vm "pos-vm" used the following resources:
        gvm: pos-vm
        VirtualMachineDisk: pos-vm-boot-dv
    Start deleting the resources:
        Deleted gvm "pos-vm".
        Deleted VirtualMachineDisk "pos-vm-boot-dv".
    

מחיקה רק של המכונה הווירטואלית

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

    kubectl virt delete vm pos-vm
    

    בדוגמה הבאה של פלט אפשר לראות את אישור המחיקה:

    vm "pos-vm" used the following resources:
        gvm: pos-vm
        VirtualMachineDisk: pos-vm-boot-dv
    Start deleting the resources:
        Deleted gvm "pos-vm".
    

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

  • המכונה הווירטואלית המקורית שבה נעשה שימוש במדריך הזה היא מכונה ב-Compute Engine שמופעלת בה Ubuntu 20.04 LTS. התמונה של מכונת ה-VM הזו נגישה לציבור דרך קטגוריית Cloud Storage‏ pos-vm-images. מידע נוסף על אופן ההגדרה של המכונה הווירטואלית ועל אופן יצירת התמונה שלה זמין בהוראות במאגר של מערכת ה-POS.
  • כשיוצרים מכונה וירטואלית באשכול באמצעות הפקודה kubectl virt create vm pos-vm, נוצר קובץ YAML שנקרא על שם המכונה הווירטואלית (google-virtctl/pos-vm.yaml). אפשר לבדוק את הקובץ כדי לראות את ההגדרה של VirtualMachine ושל VirtualMachineDisk. במקום להשתמש בפלאגין virtctl, אפשר לפרוס מכונה וירטואלית באמצעות הגדרות KRM, כמו שמופיע בקובץ ה-YAML שנוצר.