- הגדרה: ניתוק התוכנה מהחומרה כך שניתן להריץ מספר מערכות הפעלה בו-זמנית על אותה חומרה פיזית.
-
Dual Boot: בכל רגע רצה מערכת אחת, בוירטואליזציה המערכות רצות במקביל ומבודדות כברירת מחדל.
- VMM (Virtual Machine Monitor) או Hypervisor: שכבת תוכנה הממוקמת בין החומרה הפיזית למערכות ההפעלה. ה-VMM מנהל ומקצה את משאבי המחשב למכונות הוירטואליות.
- מערכת הפעלה מארחת (Host): המכונה הפיזית ומערכת ההפעלה המארחת (לפעמים המונח מתייחס בפועל ל-Hypervisor עצמו).
- מערכת הפעלה אורחת (Guest): המכונה הוירטואלית והמערכת שרצה בתוכה.
- מודל עבודה: בעוד שבמערכת רגילה ההיררכיה היא
חומרה -> מערכת הפעלה -> תהליכים, במערכת וירטואלית ה-Hypervisor חייב "לשקר" למערכת ההפעלה ולזייף מצב שבו האורח חושב שהוא שולט בחומרה. -
אינטואיציה: Hypervisor הוא כמו גרעין, ומכונות וירטואליות כמו תהליכים. ה-Hypervisor מתזמן מכונות וירטואליות, מקצה להם זיכרון ומבצע תיווך ושיתוף של פעולות I/O.
| סוג | שם | תיאור | דוגמאות |
|---|---|---|---|
| Type 1 | Bare-metal | ה-VMM רץ ישירות על החומרה הפיזית, ויש לו שליטה מלאה בה. | VMware ESX, Xen, Microsoft Hyper-V. |
| Type 2 | Hosted | ה-VMM רץ כתהליך מעל מערכת הפעלה מארחת (Host OS) רגילה, אשר אחראית על ניהול שאר הפעולות. גישה זו מונעת כפילות קוד (ה-OS מנהל תזמון קוד וזיכרון) ומספקת סביבת ניהול קלה (ניתן להשתמש ב-top או ב-SIGKILL מול ה-VM). |
VirtualBox, VMware Workstation, QEMU. |
| שילוב | Combination | ה-Hypervisor משלב מאפיינים משתי הגישות. | Linux/KVM + QEMU (במקרה זה, KVM הופך את לינוקס ל-Hypervisor, ו-QEMU רץ כתהליך שיכול לפעול עצמאית אך מואץ בעזרת KVM). |
- קונסולידציה: חיסכון בחומרה, חשמל וקירור על ידי איחוד שרתים פיזיים רבים, שמנוצלים רק חלקית, למכונות וירטואליות על שרת פיזי חזק אחד.
- בידוד ואבטחה: כל VM מבודד לחלוטין מהאחרים. קריסה ב-VM אחד לא משפיעה על השאר.
- ניידות: ניתן להקפיא מצב של VM, להעביר את קובץ המצב לשרת אחר, ולהמשיך את הריצה מאותה נקודה.
- פיתוח ובדיקות: וירטואליזציה מקלה על בדיקות טסטים והבטחת איכות (למשל, הדמיית מוצרים מבוזרים שדורשים עשרות מכונות כמו Firewall).
- פיתוח גרעין בטוח: ניתן לפתח ולנפות תקלות ב-OS מבלי לאתחל את המכונה הפיזית בכל תקלה (מקל על מפתחי גרעין).
- שימוש אישי ופרודוקטיביות: כמה מערכות על מחשב אחד (למשל Linux ו-Windows יחד) ובחירה בכלי הטוב ביותר למשימה.
- ניהול ותפעול: גיבוי/שחזור/שדרוג שרתים בקלות, Live Migration (העברת VM למכונה אחרת בזמן ריצה), והקמה מהירה של מכונות חדשות.
- ענן: בידוד בין לקוחות מתאפשר באמצעות וירטואליזציה. התשתית "אלסטית" ומאפשרת ללקוחות להגדיל או לכווץ את משאבי המחשוב שלהם בקלות לפי הצורך ולשלם לפי שימוש.
טכניקות עיקריות:
- אמולציה תוכנתית
- Trap-and-Emulate
- תרגום בינארי דינמי
- פרא-וירטואליזציה
- תמיכת חומרה
- ה-CPU מדומה במלואו בתוכנה: Fetch, Decode, Execute על מבני נתונים בזיכרון.
- יתרון: פשוט ליישום.
- חיסרון: איטי מאוד.
- דוגמה: מערכת BOCHS.
- רעיון: מערכת ההפעלה האורחת חושבת שהיא במצב הרשאות מלא, אך בפועל רצה במצב משתמש, וה-VMM במצב גרעין.
- Trap: פקודה פריבילגית גורמת חריגה שעוברת ל-VMM.
- Emulate: ה-VMM מדמה את הפעולה ומחזיר את השליטה ל-Guest OS.
- דוגמאות לפעולות "רגישות" המייצרות Trap: פסיקות של קריאות מערכת (כמו
int 0x80), פקודות לשינוי מרחב הזיכרון (כמוmovel <something>, %cr3), ופעולות קלט/פלט מסוימות.
ארכיטקטורת x86 הישנה (לפני 2005) לא תמכה ב-Trap-and-Emulate כראוי.
- דרישת וירטואליזציה: כל פקודה רגישה חייבת להיות פריבילגית (כלומר לזרוק Trap במצב משתמש).
- הבעיה ב-x86: היו פקודות רגישות שלא היו פריבילגיות, ולכן נכשלו או התנהגו בצורה לא צפויה.
-
דוגמה (
popf): אמורה לעדכן את דגל הפסיקותIF, אך ב-User Mode המעבד יעדכן רק דגליALUויתעלם מה-IF, בלי Trap.
כדי להתגבר על הבעיה פותחו 3 גישות מרכזיות:
- תרגום בינארי דינמי:
- בלוקים של קוד מתורגם נשמרים במטמון קוד (code cache) שממוין לפי כתובות. תרגום מתבצע "תוך כדי תנועה".
- פעולות בטוחות רצות ישירות על המעבד, בעוד שפעולות רגישות מתורגמות ל-Hypercalls מפורשות או לקוד בטוח.
-
דוגמה: VMWare, QEMU.
- פרא-וירטואליזציה:
- שינוי קוד ה-Guest כך שהוא מודע לוירטואליזציה.
- במקום פקודות חומרה רגישות משתמשים ב-Hypercalls (בדומה לקריאות מערכת).
-
דוגמה: פרויקט Xen.
- וירטואליזציה נתמכת חומרה:
- אינטל הגדירה תמיכה תחת השם VMX ו-AMD תחת השם SVM כדי לטפל בבעיה בחומרה.
- פקודות רגישות שקודם לא הפעילו Trap (כמו
popf) יטופלו כעת ברמת החומרה ויועברו כראוי אל ה-Hypervisor.
השיטה הנפוצה כיום:
- עבור המעבד (CPU): משתמשים ב-Trap and Emulate יחד עם תמיכת חומרה.
- עבור התקני הקלט/פלט (I/O): משתמשים בפרא-וירטואליזציה בסיוע ה-Hypervisor כדי לגשר על הפער הסמנטי.
כל מערכת הפעלה אורחת מנהלת טבלת דפים משלה, כמו במערכת רגילה, רק שה-"פיזי" שלה הוא מדומה. לכן כל גישת זיכרון עוברת שני שלבי תרגום:
- שלב 1 (בתוך ה-Guest):
GVA -> GPA- טבלת הדפים של האורח מתרגם כתובת וירטואלית לכתובת פיזית מדומה. - שלב 2 (ברמת המארח):
GPA -> HPA- ה-Hypervisor/חומרה מתרגם את ה-GPA לכתובת הפיזית האמיתית של המארח.
- מיפוי: ה-Hypervisor מתחזק shadow page table לכל תהליך ב-Guest שממפה ישירות
GVA -> HPA. - תחזוקה ואתגרים במימוש: ה-Hypervisor מגן על טבלאות הדפים של האורח מפני כתיבה. כל שינוי של
CR3גורר Trap, וה-Hypervisor צריך לתרגם ל-HPA ולעדכן. זהו מימוש מורכב מאוד מאחר שה-Hypervisor נדרש לתחזק בעצמו את ה-Access/Dirty bits בתוך ה-PTEs של האורח, ולתמוך בכל מצבי הזיכרון של x86 (Real mode, 32bit, PAE, 64bit). - פישוט: כדי לפשט את המימוש, ה-Hypervisor יכול להתחיל לבנות טבלת צל חדשה מאפס בכל פעם שיש החלפת הקשר ב-VM (כל שינוי ב-
CR3). - חיסרון: תקורת ביצועים גבוהה בגלל Traps רבים על פעולות הקשורות לטבלאות דפים.
- הערה: במצבים מסוימים, ייתכן ששימוש ב-Shadow PT יפיק ביצועים טובים או מהירים יותר מאשר שימוש בפתרונות חומרה כמו EPT.
- למה? כי ב-EPT החטאת TLB גוררת 2D Page Walk שעולה בעשרות גישות לזיכרון. לכן, ב-Workload עם הרבה החטאות TLB (תרגומים תדירים) אבל מעט שינויים ב-
CR3(מעט החלפות הקשר), ההליכה החד-מימדית (1D) של ה-Shadow PT תהיה יעילה יותר.
- Guest: מתחזק טבלת דפים
GVA -> GPAכרגיל. - Hypervisor: מתחזק טבלת
GPA -> HPAדרך EPT Pointer. - חומרה: מבצעת 2D Page Walk ומתרגמת אוטומטית בלי Traps על שינוי CR3.
- פסיקות ב-EPT: למרות שאין Traps על כל שינוי בטבלה, עדיין ייתכנו פסיקות (Interrupts/Exits) ל-Hypervisor בשני מקרים עיקריים:
- EPT violation: הכתובת הפיזית של האורח חסרה תרגום ב-EPT.
- EPT misconfiguration: תצורת EPT שגויה.
-
עלות החטאה ב-TLB Miss: למרות החיסכון ב-Traps על עדכוני CR3, ביצוע מטלת ה-2D Page Walk בחומרה עקב TLB Miss הוא יקר מאוד. התהליך ידרוש עשרות גישות לזיכרון כדי לתרגם כתובת וירטואלית בודדת, בשל המכפלה של היררכיית דפי ה-Guest עם היררכיית ה-EPT.
דרכי גישה להתקני I/O:
- אמולציה: ה-VMM מדמה התקן סטנדרטי; ה-Guest OS לא יודע שהוא וירטואלי.
- יתרון: אין צורך לשנות את ה-Guest, ומבטיח שהמכונה הווירטואלית ניידת ויכולה לרוץ על ספקי ענן שונים ללא בעיות דרייברים.
- חסרון: איטי, וה-Hypervisor נאלץ לדמות תוכנתית חומרה מורכבת שלא תוכננה לוירטואליזציה (כמו כרטיס
e1000).
- פרא-וירטואליזציה: מבוצע על ידי פרוטוקול מתואם ויעיל בין ה-Frontend (הפעולות של הדרייבר שמותקן במערכת האורחת) לבין ה-Backend (ה-Hypervisor).
- מנגנון חיסכון ב-Traps: במקום שהאורח יכתוב לאוגרים מדומים אחד-אחד וייצר Traps רבים (כמו באמולציה), הוא מבצע Hypercall יחיד שמעביר ל-Hypervisor את כתובת ההתחלה של ה-Buffer ואת אורכו.
- יתרון: ביצועים מהירים משמעותית מאמולציה.
- חסרון: פוגע בניידות (קשה יותר לעבור בין ספקי ענן שונים כי ה-VM צריך דרייבר התואם ל-Hypervisor הספציפי החבוי בענן).
-
הערה (Paravirtual I/O מול Guest): בניגוד לפרא-וירטואליזציה של ה-Guest שדורשת שינוי של כל מערכת ההפעלה האורחת, פרא-וירטואליזציה של I/O הפכה לנפוצה מאוד משום שהיא דורשת רק התקנת דרייבר בודד.
- העברה ישירה (Direct Device Assignment): הקצאת חומרה פיזית (כמו הענקת NIC פיזי שלם מהמארח) ל-VM באופן אקסקלוסיבי.
- יתרון: ביצועים גבוהים כמעט כמו חומרה אמיתית ללא התערבות ה-Hypervisor.
- חסרון: דורש כרטיס פיזי נפרד לכל אורח מעבר לאחד של המארח.
- תמיכת חומרה לריבוי התקנים (SRIOV): טכנולוגיית Single Root I/O Virtualization מאפשרת לכרטיס רשת אחד להיחשף למעבד כמספר התקנים פיזיים נפרדים. כל VM מקבל פונקציה וירטואלית משלו, וה-NIC מרבב ביניהם ברמת החומרה ללא מעורבות ה-Hypervisor בנתיב הנתונים.
החיסרון המשותף של Assignment ו-SRIOV: לא מאפשרים ל-Hypervisor לבצע "התערבות" בגישות הקלט-פלט. כלומר, מכיוון שה-Hypervisor נחסך מתהליך ה-I/O, לא מתאפשרות פעולות שדורשות אמצע, כולל: למדוד נפח מידע, הגנה והגבלת קצב גישה, ביצוע Live Migration וכו'.
- בעיה: התקני I/O מבצעים DMA וגישה ישירה לזיכרון, זה מסוכן בסביבה מרובת VMs.
- פתרון: IOMMU מתרגם כתובות I/O לכתובות פיזיות ומבודד DMA בין אורחים. בדומה ל-MMU שלו יש TLB, ל-IOMMU יש IOTLB משלו לייעול התרגומים.
-
הערה: שגיאת I/O page fault אינה נסבלת לרוב ולכן זיכרון שמשמש ל-DMA צריך להיות "נעול בזיכרון".
ככל שמתווספת תמיכת חומרה, כך נסגר הפער בביצועים שבין סביבה מרובת VMs לסביבה המריצה חומרת Bare-metal נטולת Hypervisor. ההתקדמות בביצועים מתרחשת לפי הסדר הבא:
- עומס על עיבוד. תמיכת החומרה במעבד פתרה את הפער הראשוני.
- עומס על זיכרון. תמיכה בחומרת MMU (כמו EPT) שיפרה עומסים הנובעים מתרגום דפים וזיכרון.
- עומס קלט/פלט. תמיכה בחומרה של התקני הקלט/פלט מסייעות לצמצם את הפער בסביבות של תעבורת קבצים ורשת.
- בהמשך חזרה והתפתחות מנגנונים נוספים כדי להקל על תקשורת ולקדם צימצום עיכובים כגון שימוש בפסיקות ללא יציאה.