שחזור של מכונה וירטואלית שלא ניתן לגשת אליה

אם אין לכם גישה ל-VM של Linux מסיבה כלשהי, אתם יכולים לנסות לחלץ את ה-VM באמצעות השלבים הבאים.

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

התפקידים הנדרשים

כדי לקבל את ההרשאות שדרושות לחילוץ VM, בקשו מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט:

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

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

ההרשאות הנדרשות

כדי לחלץ VM, צריך את ההרשאות הבאות:

  • ‫compute.instances.create בפרויקט
  • ‫compute.disks.create בפרויקט
  • ‫compute.instances.get בפרויקט
  • compute.disks.createSnapshot בדיסקים
  • compute.instances.attachDisk במכונה וירטואלית חדשה
  • compute.disks.use בדיסק
  • ‫compute.instances.start במכונה וירטואלית חדשה ובלתי נגישה
  • ‫compute.instances.stop במכונה וירטואלית חדשה ובלתי נגישה

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

חילוץ של VM

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

  1. (אופציונלי) עוצרים את ה-VM שאין אליו גישה.
  2. יוצרים קובץ snapshot מדיסק האתחול של המכונה הווירטואלית שלא ניתן לגשת אליה. אם מערכת הקבצים הבסיסית מפוצלת בין כמה דיסקים, צריך ליצור קובץ Snapshot לכל דיסק.
  3. יוצרים מכונה וירטואלית לחילוץ באמצעות קובץ אימג' ציבורי תואם של Linux. כדי למנוע התנגשויות בין מזהי UUID של דיסקים, שעלולות לגרום ל-VM החילוץ לבצע אתחול מהדיסק של ה-VM שאין אליו גישה, Google ממליצה להשתמש בקובץ אימג' של מערכת הפעלה שונה מזה של ה-VM שאין אליו גישה. אם אתם מתכננים להריץ את chroot או כלים לתיקון מערכת קבצים ספציפיים למערכת ההפעלה, בחרו קובץ אימג' אחר מאותה משפחה של מערכת ההפעלה.

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

  4. מוודאים שהמכונה הווירטואלית לחילוץ פועלת, ושאפשר להתחבר אליה באמצעות SSH.

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

    1. נכנסים לדף VM instances במסוף Google Cloud .

      כניסה לדף VM instances

    2. לוחצים על השם של ה-VM לחילוץ שיצרתם.

    3. לוחצים על עריכה.

    4. בקטע Additional disks, לוחצים על Add new disk ומבצעים את הפעולות הבאות:

      1. מוסיפים את שם הדיסק, למשל my-recovery-disk
      2. בקטע Source type, בוחרים בכרטיסייה Snapshot.
      3. בתפריט הנפתח Source snapshot, בוחרים את קובץ ה-snapshot של המכונה הווירטואלית המקורית שיצרתם קודם לכן בשלבים האלה.
      4. לוחצים על סיום.
    5. לוחצים על Save.

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

    lsblk -d -o NAME,SERIAL

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

     NAME SERIAL
     sda  rescue-vm
     sdb  my-recovery-disk
     

    בדוגמה הזו, rescue-vm הוא דיסק האתחול של ה-VM לחילוץ ו-my-recovery-disk הוא דיסק האתחול מה-snapshot של ה-VM שאין אליו גישה. שימו לב ל-NAME של המכונה הווירטואלית שאין אליה גישה, כי תצטרכו אותו בשלב הבא.

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

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

      fdisk -l /dev/NAME -o Device,Size,Type
      

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

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

      Disk /dev/sdb: 10 GiB, 10737418240 bytes, 20971520 sectors
      Disk model: PersistentDisk
      Units: sectors of 1 * 512 = 512 bytes
      Sector size (logical/physical): 512 bytes / 4096 bytes
      I/O size (minimum/optimal): 4096 bytes / 4096 bytes
      Disklabel type: gpt
      Disk identifier: B31430F1-F041-4555-96B9-B2F43DC057AD
      
      Device     Size Type
      /dev/sdb1    2M BIOS boot
      /dev/sdb2   20M EFI System
      /dev/sdb3   10G Linux filesystem
      

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

      file -sL /dev/PARTITION_NAME
      

      מחליפים את NAME בשם המחיצה.

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

      • אין מערכת קבצים: אם הפלט מציג רק data, המחיצה לא מכילה מערכת קבצים. פלט לדוגמה:

        /dev/sdb1: data
        
      • מערכת קבצים של EFI: אם הפלט מתאר סקטור אתחול של DOS/MBR, למחיצה יש מערכת קבצים של EFI. פלט לדוגמה:

        dev/sdb2: DOS/MBR boot sector, code offset 0x3c+2, OEM-ID "mkfs.fat", sectors/cluster 4, reserved sectors
        4, root entries 512, sectors 40960 (volumes <=32 MB), Media descriptor 0xf8, sectors/FAT 40, sectors/
        track 32, heads 64, serial number 0xf2af2664, label: "EFI        ", FAT (16 bit)
        
      • מערכת קבצים של Linux: אם הפלט מתאר נתונים של מערכת קבצים, המחיצה היא מערכת קבצים של Linux. פלט לדוגמה:

        /dev/sdb3: SGI XFS filesystem data (blksz 4096, inosz 512, v2 dirs)
        

      שימו לב לשם המחיצה של מערכת הקבצים של Linux.

    2. יוצרים נקודת טעינה ב-/rescue:

      sudo mkdir /rescue
    3. מגדירים את המחיצה של מערכת הקבצים של Linux ל-/rescue:

      sudo mount PARTITION_NAME /rescue
      

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

      אם בדיסק יש מחיצת /boot נפרדת או מחיצת מערכת EFI (כמו /dev/sdb2 בפלט הקודם), צריך לטעון אותן לפני הכניסה לסביבת chroot. כך אפשר לגשת לקובצי הליבה (kernel) ומנהל האתחול (bootloader):

      # Run only if your disk has a separate /boot partition:
      sudo mount /dev/BOOT_PARTITION_NAME /rescue/boot
      
      # Run only if your disk has an EFI System Partition (UEFI VMs):
      sudo mount /dev/EFI_PARTITION_NAME /rescue/boot/efi
      

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

      • ‫BOOT_PARTITION_NAME: שם המחיצה של המחיצה הנפרדת /boot, אם היא קיימת (לדוגמה, sdb1).
      • ‫EFI_PARTITION_NAME: שם המחיצה של מחיצת המערכת של EFI במכונות וירטואליות של UEFI (לדוגמה, sdb2).
    4. טוענים את מערכות הקבצים הווירטואליות ואת ההתקנים כדי שתוכלו לשנות את תיקיית השורש של מערכת הקבצים באמצעות הפקודה chroot:

      sudo mount -t proc /proc /rescue/proc
      sudo mount -t sysfs /sys /rescue/sys
      sudo mount -o bind /dev /rescue/dev
      sudo mount -o bind /dev/pts /rescue/dev/pts
      sudo mount -o bind /run /rescue/run
      
    5. משנים את תיקיית השורש למערכת הקבצים שנטענה:

      sudo chroot /rescue
      

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

    אם ה-VM לא מצליח לבצע אתחול עם שגיאת GRUB module not found, צריך לתקן את תוכנת האתחול של GRUB מתוך סביבת chroot. השלבים תלויים בסוג הקושחה של ה-VM:

    • מכונות וירטואליות של BIOS מדור קודם (i386-pc) (למשל, כשהקונסולה הטורית מציגה את ההודעה file '/grub2/i386-pc/increment.mod' not found):

      • ‫RHEL,‏ CentOS,‏ Rocky Linux ו-SUSE:
      grub2-install --target=i386-pc /dev/NAME
      grub2-mkconfig -o /boot/grub2/grub.cfg
      
      • ‫Debian ו-Ubuntu:
      grub-install --target=i386-pc /dev/NAME
      update-grub
      

      מחליפים את NAME בשם המכשיר של הדיסק המלא של דיסק השחזור שצורף קודם (לדוגמה, sdb, לא מספר מחיצה כמו sdb1).

    • מכונות וירטואליות מסוג UEFI ומכונות וירטואליות מוגנות (צריך לוודא ש-/rescue/boot/efi נטען קודם. אל תפעילו את grub2-install במכונות וירטואליות מסוג UEFI RHEL,‏ CentOS או Rocky Linux כי הוא מחליף את ה-shim החתום של האתחול המאובטח):

      • ‫RHEL,‏ CentOS ו-Rocky Linux (משתמשים ב-yum במקום ב-dnf ב-CentOS 7 וב-RHEL 7):
      dnf reinstall -y shim-* grub2-efi-* grub2-common
      grub2-mkconfig -o /boot/grub2/grub.cfg
      
      • SUSE:
      shim-install --config-file=/boot/grub2/grub.cfg
      grub2-mkconfig -o /boot/grub2/grub.cfg
      
      • ‫Debian ו-Ubuntu:
      grub-install --efi-directory=/boot/efi --no-nvram
      update-grub
      

ביטול השינויים והפעלה מחדש של ה-VM שאין אליו גישה

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

  1. אחרי שמסיימים לפתור את הבעיות, יוצאים מהסביבה של chroot:

     exit
     

  2. מנתקים את מערכות הקבצים הווירטואליות, המכשירים ומערכת הקבצים של ה-VM הלא נגיש מה-VM לחילוץ:

    אם טענתם מחיצת EFI או מחיצת /boot נפרדת, צריך לבטל את הטעינה של /rescue/boot/efi ואז של /rescue/boot לפני שמבטלים את הטעינה של מערכת הקבצים ברמה הבסיסית (sudo umount /rescue).

     cd /
     sudo umount /rescue/run
     sudo umount /rescue/dev/pts
     sudo umount /rescue/dev
     sudo umount /rescue/sys
     sudo umount /rescue/proc
     sudo umount /rescue
     

  3. נכנסים לדף VM instances במסוף Google Cloud .

    כניסה לדף VM instances

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

    2. לוחצים על עריכה.

    3. בקטע Additional disks, לוחצים על בדיסק שנוצר בשלבים הקודמים כדי לנתק את הדיסק הנוסף מה-VM לחילוץ.

    4. לוחצים על Save.

  4. נכנסים לדף VM instances במסוף Google Cloud .

    כניסה לדף VM instances

    1. אם המכונה הווירטואלית הלא נגישה עדיין פועלת, עוצרים את ה-VM.

    2. לוחצים על השם של המכונה הווירטואלית שעצרתם ולוחצים על Edit.

    3. בקטע Boot disk, לוחצים על Detach boot disk כדי לנתק את דיסק האתחול הקיים מה-VM שאין אליה גישה.

    4. אחר כך לוחצים על CONFIGURE BOOT DISK כדי לצרף את הדיסק שיצרתם ותיקנתם קודם לכן בקטע חילוץ VM שבדף הזה.

      1. בקטע דיסק אתחול, לוחצים על הכרטיסייה Existing disks.
      2. ברשימה הנפתחת, בוחרים את הדיסק שיצרתם בקטע הקודם, לדוגמה my-recovery-disk.
      3. לוחצים על בחירה ואז על שמירה.
    5. מפעילים את ה-VM.

  5. עכשיו אמורה להיות לכם אפשרות להתחבר למכונה הווירטואלית באמצעות SSH.