2014-10-04

להבין Virtualization

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

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

וירטואליזציה[א] היא לא טכנולוגיה חדשה: היא זמינה החל משנת 1972, אולם רק בעשור האחרון היא זכתה לאימוץ נרחב. כיום היא אחד מהיסודות החשובים של מחשוב הענן.

רעיון הוירטואליזציה קיים ברמות הפשטה שונות:
  • זיכרון וירטואלי - הוא מימוש של וירטואליזציה לזיכרון. הוא מבצע multiplexing (חלוקת משאב פיסי אמיתי לכמה תהליכים אורחים במקביל) וגם emulation (בכך שהוא מנהל כתובות מדומות של הזיכרון הוירטואלי עמם התהליכים האורחים עובדים).
  • מנגנון ה LVM של לינוקס (קיצור של Logical Volume Manager) הוא דוגמה לוירטואליזציה של הדיסק. האופי שלו הוא אחר: הוא מבצע aggregation בכך שהוא גורם לכמה דיסקים פיסיים להראות כמו דיסק לוגי יחיד. זו עדיין וירטואליזציה.
  • מנגנון ה NAT (קיצור של Network Address Translation) של פרוטוקול IP, המשמש רכיבי רשת כמו proxy או reverse proxy בכדי להסתיר כתובות רשת אמיתיות של מחשבים - הוא דוגמה לוירטואליזציה של הרשת.
  • X-Server או VNC של לינוקס / Remote Desktop של חלונות - הם דוגמאות לוירטואליציה של ה Desktop. זהו עולם דיי עשיר עם פתרונות כמו App-V של מייקורוסופט ש"מזרים" אפליקציה שרצה בשרת מרוחק - למחשב השולחני המקומי (זו בעצם Application Virtualization).

בפוסט זה ארצה להתמקד בויאטואליזציה של החומרה כולה (זיכרון, דיסק, רשת, וכו') - מה שרוב האנשים מכירים פשוט כ "Virtual Machine" או "VM".




במהלך הפוסט אנסה לענות על שאלות כגון:
  1. כיצד, בפועל, טכנולוגיות הוירטואליזציה חוסכות לארגון ה IT כסף רב?
  2. מה ההבדל בין hypervisors מ"טיפוס 1" ל hypervisors מ"טיפוס 2"? וכיצד בוחרים את העדיף לסיטואציה?
  3. מהי Paravirtuallization ומהם Linux Containers (שעושים כ"כ הרבה רעש בשנתיים האחרונות)??
  4. למה לקח כ"כ הרבה זמן לויטרטואליזציה לתפוס מקום מרכזי בתעשייה? אתם יודעים, כמעט 40 שנה?
  5. מי הם Popek ו Goldberg - ומה הקשר שלהם לכל הסיפור?


מוטיבציה


אנסה להעביר את המוטיבציה בעזרת סיפור קצר. בסיפור שלנו יהיה ארגון עם Data Center שכולל כמה שרתים שונים:
  • שרת קבצים (shares)
  • שרת ווב
  • שרת e-commerce
  • שרת דואר (Exchange)

(לצורך פשטות הסיפור אתאר רק 4 שרתים. בסביבה אמיתית סביר שיהיו הרבה יותר).


מקור: VMWare


במשך השנים נוצר הסטנדרט בו כל שרת רץ על "קופסה" (כלומר: מחשב פיסי) משלו.
ניסיונות שהיו במשך השנים להריץ כמה תוכנות שרת על אותו שרת פיסי (מה שנקרא "server consolidation") נגמרו לרוב בחוסר שביעות-רצון של האחראים על תוכנות השרת (גם אם אותו האדם אחראי על שתי מערכות שונות). מדוע?
  • Sandboxing: תקלה בשרת הדואר יכולה לגרום לקריסה של מערכת ההפעלה - ולא רוצים ששרת הווב או המסחר האלקטרוני לא יהיו זמינים בגללו. אולי שרת הדואר דורש עדכון של מערכת ההפעלה שגורם לבעיה חדשה בשרת הקבצים?
  • אמינות: כאשר כל שרת רץ על עותק שלו של מערכת ההפעלה - פשוט יש פחות תקלות. שני שרתים דורשים הגדרות תצורה מעט שונות - שלא אופטימליות או מוכרות עבור תוכנת השרת השנייה.
המציאות בפועל הייתה שאנשי ה IT דרשו מהארגון "קופסה לכל שרת" כתנאי עבודה בסיסי.
הקצאה של "קופסה לכל תוכנת שרת" סיפקה את היתרונות המצופים:
  • זמינות: שדרוג / עדכון של תוכנת שרת אחד, לא משפיעה על שרתים אחרים. 
  • דרישות סביבה שונות: שרת הדואר רץ על "חלונות", שרת המסחר על איזו גרסה של UNIX ושאר השרתים רצים על לינוקס בכלל. דרישות חומרה בד"כ אפשר לכנס בקלות רבה יותר.
  • יתרונות אבטחה: קבלת הרשאות root על מחשב אחד, לא משפיעה על הגישה למחשבים האחרים.
כל זה טוב ויפה - אבל יקר. 
יקר בכלל הכפילות של החומרה שחלק גדול מהזמן נמצאת ב Utilization נמוך. אם שרת הווב, דורש לשעה בחודש כח עיבוד X, יש לספק לו כח עיבוד זה גם אם שאר החודש הוא זקוק לכח עיבוד של X/12 או אפילו X/60.

בנוסף: כשקונים שרת פיסי עבור תוכנה חדשה - כמה חומרה יש לקנות? האם מתכננים לחודש הראשון של השימוש או לשנה אח"כ? בתעשייה נוצרה פרקטיקה בשם Sizing שמטרתה להעריך כמה חומרה תידרש, פרקטיקה מאוד לא מדויקת בה טעות של עד פי 2 - נחשבת כהצלחה.

שרתים פיסיים שרוב זמנם עובדים על כ CPU 10% - היו תמונה מקובלת.

לעלות החומרה יש עלויות נגזרות נוספות:
  • צריכת חשמל + צריכת החשמל של מערכות המיזוג שנגזרת ממנה (עלות משמעותית)
  • שטח אכסון (נדל"ן - עלות משמעותית בערים צפופות)
  • עלות איש ה IT שעליו לנטר את המערכות ולתחזק את החומרה (התקנה, גיבויים, טיפול בתקלות, ...)

עונתיות בשימוש במשאב מחשוב




הערך של וירטואליזציה


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

מה קורה כאשר השרת הפיסי כושל? האם לא פגענו בזמינות של השרתים שלנו? ברגע שחומרת המחשב המשותף קורסת - יושבתו מיידית כל ה VMs שרצים עליה!!

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

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

אתחול של VM הוא מהיר מאתחול של שרת פיסי, מה שמפחית את ה Mean Time To Recover (בקיצור: MTTR) של המערכת. האתחולים המהירים (בעת תקלות תוכנה) מתקזזים עם תקלות החומרה (הנדירות יחסית) של חומרת השרת המשותף - כך שבדרך כלל, וירטואליזציה דווקא מוסיפה לזמינות של כלל המערכת.

הרצה של תוכנה על וירטואליזציה מספקת יתרונות נוספים:
  • היכולת "להרים" שרתים בקלות מפשטת את עבודת ה IT.
  • בזמן שדרוג, ניתן בקלות להרים VM עם גרסה חדשה יותר של התוכנה, במקביל לגרסה הישנה. ניתן להפעיל את המערכות זמן-מה במקביל ו"לכבות" את הגרסה הישנה רק לאחר שנצפתה עבודה תקינה של הגרסה החדשה.
  • שיפור הזמינות ע"י חלוקה: אם ניקח מערכת שהיא easily scalable, למשל שרת ווב, ובמקום VM אחד נציב שני VMs שלו על אותה מכונה פיסית - נקבל זמינות משופרת. אם VM אחד קרס בשל בעיית תוכנה, ה VM השני יכול להמשיך ולספק שירות. כל זאת - עם אותה החומרה (אבל קצת יותר זיכרון).
  • Checkpoints: טכנולוגיית הוירטואליזציה מאפשרת לקחת snapshot של VM מסוים, ואז לשמור את ההעתק בצד - או לשכפל אותו ל VM נוסף. יכולות אלו מקלות מאוד על עבודת ה IT. יכולות אלו מקלות מאוד גם על פיתוח תוכנה: לבדוק את התוכנה על מערכות הפעלה שונות בגרסאות שונות, או מפתח אחד שמתקין את הגרסה החדשה ביותר - ומשכפל אותה שתהיה זמינה לכל חבריו לצוות.



איך וירטואליזציה עובדת

הסביבה שמריצה וירטואליזציה של מכונה נקראת Virtual Machine Monitor (בקיצור: VMM) או Hypervisor. מקור השם Hypervisor טמון בהרשאות מערכת ההפעלה שניתנות לה: בעוד ההרשאות הגבוהות במערכת ההפעלה שייכות למשתמש העל (supervisor) - ל VMM נדרשו הרשאות גבוהות אפילו יותר, דרגה מעל ה supervisor, כלומר hypervisor.

הציפייה מ Hypervisor היא שהוא ימלא 3 דרישות עיקריות:
  1. Fidelity - התוכנה תרוץ על ה VM בדיוק כפי שהיא רצה על מערכת הפעלה שמותקנת ישירות על החומרה.
  2. Safety - תוכנה שרצה על VM תהיה מבודדת מתוכנה שרצה על VM אחר על אותו מחשב פיסי. פעולות שיעשה VM אחד (ניהול משאבים של מערכת ההפעלה, למשל) - לא יפגע בפעילות התקינה של ה VM השני.
  3. Efficiency - התוכנה על ה VM לא תרוץ "הרבה יותר לאט" מאשר על הרצה ישירות על החומרה הפיסית. 

מקורה של הגדרה זו היא במסמך שפרסמו עוד ב 1974 Popek ו Goldberg - חוקרים אמריקאים שהיו חלוצים בנושא הוירטואליזציה. הם גם הגדירו את התנאים שמאפשרים וירטואליזציה. בגדול הם הגדירו 2 קבוצות של פקודות המעבד (instructions):
  • sensitive - פקודות שמבצעיות פעולות IO.
  • privileged - פקודות שיגרמו ל trap אם נקראו ב user mode.
כידוע לכם (אני מניח), למעבדים יש 2 מצבי עבודה: user mode ו kernel mode. ה user mode נועד לתוכנות שרצות על מערכת ההפעלה (ולחלקים של מערכת ההפעלה) וה kernel mode נועד ל kernel של מערכת ההפעלה ורק בו ניתן לגשת ל I/O או לזיכרון ישירות. לכל mode יש סט פקודות זמין מעט שונה. אם פעולה של kernel mode נקראת ב user mode מתרחש אירוע בשם trap שגורם למעבד לעבור מצב ל kernel mode ואז להפעיל את הפקודה המבוקשת. מנגנון זה מאפשר לתוכנה לרוץ באופן ישיר על המעבד, בלי מעורבות של מערכת ההפעלה, ועדיין למערכת ההפעלה - לשלוט על כל הגישות לחומרה.


Popek ו Goldberg הראו ש Fidelity בוירטואליזציה יתרחש רק כאשר הפקודות שהן sensitive הם subset של הפקודות שהן privileged (מצב שלא היה קיים במעבדי אינטל - נושא עליו נדבר בהמשך).

דרך פשוטה ראשונה למשמש hypervisor היא כ interpreter שיפרשן כל פקודת שפת-מכונה של הקוד שרץ, ויחליט מה "בטוח" ולשלוח למעבד / מערכת ההפעלה - ובמה הוא רוצה להתערב ולשנות אותו. למשל: פקודת INC (כלומר: Increment) היא בטוחה, פקודה להשבתה של interrupt מסוים מהחומרה - היא לא, כי ייתכן שה interrupt הזה נועד ל VM אחר. בעזרת interpreter נוכל להשיג את דרישות הבטיחות והבידוד - אבל הביצועים יהיו גרועים.

דרך יותר מעשית, והיא בעצם הדרך המקובלת היא להגדיר את ה Hypervisor כ"מערכת ההפעלה של מערכת ההפעלה":

הדוגמה הספציפית היא ל type1 hypervisors אבל העקרונות נכונים גם עבור type 2 hypervisors עליהם נדבר בהמשך.

ה hypervisor "משתלט" על ה kernel mode של המעבד - כי עליו לתפוס את כל הגישות לחומרה, ומריץ את מערכת ההפעלה המתארחת (Guest OS) ב user mode. פנימית עושים הבחנה בין מערכת ההפעלה שזוכה ל virtual kernel mode (כלומר: מדמים לה שהיא רצה ב kernel mode - למרות שהיא לא) ול virtual user mode - מה שמערכת ההפעלה המתארחת מצפה שיהיה user mode.
הערה: במעבדי אינטל ספציפית יש 4 modes של ריצה שנקראים ring 0 (המקביל ל kernel mode) עד ring 3 (המקביל ל user mode). מימושים רבים של VMM מעל ארכיטקטורת אינטל פשוט משתמשים ב ring 1 בכדי לתאר את ה virtual kernel mode, כאשר virtual user model פשוט נותר ring 3. יש כאלו שמתארים את ה hypervisor כ ring -1 - אבל לא נכנס לפינה הזו בפוסט....

כאשר הקוד ב virtual kernel mode (שחושב שהוא ב kernel mode) מפעיל פקודה שהיא privileged אזי יש trap שמעביר את השליטה ל hypervisor.
כאשר הקוד ב virtual kernel mode מפעיל פקודה שהיא sensitive אבל לא privileged (כלומר: לא גורמת ל trap) אזי תהיה שגיאה וסביר שמערכת ההפעלה תקרוס. אאוץ!

מצב זה (בו יש פקודות sensitive שניגשות לחומרה, אך לא privileged - לא גורמות ל trap) היה קיים בכמה מארכיטקטורות המעבדים הזמינים בעולם, בניהן הארכיטקטורה הנפוצה ביותר בעולם - i386 של אינטל. אחד מהערכים של אינטל הוא תאימות לאחור (שנוכל על המעבד החדש להריץ אותן תוכנות שרצו על מעבדים ישנים) - מה שגרם למצב בו ארכיטקטורה זו שלא מתאימה לוירטואליזציה השתמרה במשך כמעט 30 שנה. ואיפה סביר יותר שתצמח טכנולוגיית הוירטואליזציה - על מחשבים פשוטים וזולים (אינטל) או מערכות מחשבי-ענק של IBM?

הבעיה נפתרה לבסוף בשנת 2005 כאשר אינטל, בשיתוף פעולה לא-שגרתי עם AMD, הוסיפו סט פקודות למעבד שפותר את המצב. באינטל מעבדים אלו מסומנים כ VT (כלומר: Virtualization Technology) וב AMD השם הוא AMD-V - אבל בעצם זה אותו הדבר.

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

הערה: אינטל עדיין מוכרת דגמים בודדים של מעבדים ללא VT - אני מניח שעבור מערכות בהן שינוי זה פוגע בתאימות לאחור.


מה עשו בעולם האינטל עד הופעת ה VT (ספציפית VT-x)?
חברת VMWare הציעה פתרון וירטואליזציה כבר בשנת 1999. הפתרון של VMWare סרק את קוד המכונה שנטען ל VM ושינה אותו כך שלא יקראו פקודות sensitive ב user space. אולי זה נעשה ע"י הרצת פקודה privileged תפלה קודם לכן - אולי בדרכים אחרות. פתרון נחשב פחות יעיל - אך הוא אפשר להריץ וירטואליזציה על מעבדי אינטל ללא VT (לא היו כאלה ב 1999).

חלק גדול מפתרונות הוירטואליזציה היום (VMWare, VirtualBox, KVM, וכו') יודעים לעבוד גם עם VT-x וגם בלי יכולת זו - ואז הם מבצעים fallback של שכתוב קוד המכונה למצב שמאפשר וירטואליזציה.

הפתרון לשכתב את קוד המכונה לאי-שימוש בפקודות sensitive נחשב (מסיבות הגיונית) לפוגע Efficiency של הקוד הרץ על ה VM.
אם תשאלו בפורום מקצועי את השאלה: "מה קורה אם אני מריץ את ה VMM שלי ללא VT-x", סביר שתשובה שתקבלו היא "אז ה VM יזחל כמו עגלה!".

שני חבר'ה מ VMWare הראו במאמר שפרסמו ב 2006 שמסקנה זו איננה כ"כ נכונה. לכתוב קוד המכונה לפקודות לא sensitive יש אמנם עלות, אך הוא מפחית את השימוש ב traps במעבד. אירועי ה trap במעבד גורמים ל context switch שמייתר חלק מה caches של המעבד ומשבש חלק ממנגנוני ה prediction, והפחתה שלהם - יכולה להאיץ את הריצה.

מסיבה זו - היעילות היא לא עניין של שחור או לבן, ולמרות שוירטואליזציה מבוססת חומרה יעילה יותר בד"כ, יהיו מקרי שימוש ותסריטים בהם דווקא וירטואליזציה מבוססת שכתוב התוכנה - היא יעילה יותר. אם תמצאו בדיקות ביצועים השוואתיות תראו שיש בד"כ יתרון קטן, אך לא דרמטי, להרצה על VT-X - בשונה ממה שניתן להבין מ"דיון פתוח" בנושא. שווה לציין שה Benchmarks בנושא זה (כמו נושאים רבים אחרים) - תלויות מאוד בתסריט והתצורה שנבדקו.

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


מקור: אינטל




סוגי Hypervisors


Goldberg, אותו הזכרנו קודם, הוא גם זה שהגדיר את ההבחנה בין Type 1 Hypervisors ל Type 2 Hypervisors.


Type 1 Hypervisors משמשים כמעין מערכת הפעלה והם התוכנה היחידה שרצה מעל החומרה / kernel mode. הם פשוטים ובד"כ אמינים יותר ממערכות ההפעלה[ב] (תכונה שנגזרת מכך יש להם הרבה פחות שורות קוד), והמפתחים שלהם יכולים לבצע אופטימיזציות שלא ניתן לעשות ב Type 2 Hypervisors. לרוב נראה אותם בסביבת השרת - היכן שאמינות ויעילות חשובות יותר

Type 2 Hypervisors הם תוכנה רגילה שרצה על מערכת הפעלה מסוימת (לינוקס, חלונות, וכו'), אולי במקביל לתוכנות אחרות, ועדיין מספקת הפשטה של החומרה למערכת הפעלה המתארחת. Hypervisors אלו תלויים (לטובה, ולעתים כמגבלה) בשירותים שזמינים במערכת ההפעלה המארחת (Host OS). כאשר אנו כמפתחים משתמשים בתוכנת וירטואליזציה כדי להריץ VM - זהו כנראה Type 2 Hypervisors.


למשל, בעולם של VMWare קל למפות את שני סוגי ה Hypervisors השונים:
  • ESX Server (ה hypervisor של חבילת vSphere) - הוא בעצם Type 1 Hypervisors.
  • VMWare Workstation / Player ו Fusion (למק) - הם בעצם Type 2 Hypervisors.
באופן דומה ניתן לומר שגם VirtualBox (של סאן, עכשיו אורקל) הוא Type 2 hypervisors ו Hyper-V של מייקורוספט נחשב כ Type 1 hypervisor (הוא משולב במערכת ההפעלה).

KVM (קיצור של Kernel based Virtual Machine), שהוא VMM בשימוש נרחב בעולם הלינוקס, הוא שנוי-במחלוקת מבחינת ההגדרה. הוא נארז כחבילה במערכת ההפעלה (כמו תוכנה hosted) ומקבל ממנה שירותים, אך יש לו גישה ישירה לחומרה (כמו type 1 hypervisor) - וכנראה שהוא נהנה מיתרונות דומים. ההגדרה, כמו הרבה הגדרות - היא טובה עד נקודה מסוימת.


Paravirtualization

עוד סוג של Hypervisors שקיימים הוא Hypervisors של Paravirtualization ("מעבר-לוירטואליזציה"). סוג זה של Hypervisors מנסה לשפר את ה Efficiency של הרצת ה VM, על חשבון מעט מה Fidelity. הרעיון הוא שהתוכנה שרצה על ה VM תהיה מודעת לכך שהיא שרצה בוירטואליזציה. ידע זה יתורגם לכמה קריאות API (נקראות Hypercalls) שבהן היא תשתמש במקרים מסוימים - שיאפשרו תהליך יעיל יותר של ההרצה. לרוב, מי שמודע לכך שהוא מתארח על סביבת ה Paravirtualization הוא מערכת ההפעלה המתארחת (ולא התוכנה שרצה עליה) והיא משתמש ב hypercalls לפעולות כמו עדכון הזיכרון הוירטואלי - פעולות שיכולות להיות פשוטות ומהירות יותר במידה והן נעשות בתיאום עם ה hypervisor.

 עוד נושא שמנסים להתמודד איתו ב Paravirtualization הוא העניין של "זמן אמיתי". מערכת ההפעלה המתארחת חושבת שהיא רצה על החומרה, ולא מודעת לכך שהיא משתפת את המעבד / I/O עם מערכות הפעלה אחרות - מה שגורם לפער בתפיסת הזמן (time) שלה. אם היא מסנכרת את תפיסת הזמן שלה בעזרת ה API (היעיל) של ה Paravirtualization Hypervisor - בעיה זו יכולה להיפתר.

Hypervisor ידוע שעובד ב Paravirtualization הוא Xen של חברת Citrix, הזמין גם בגרסה חינמית (אך ללא עדכונים אוטומטיים).




מקור: VMWare




Operating System-level virtualization


בנוסף לנושא ה Efficiency של ה VM, שתמיד נמוך מהרצה ישירה על החומרה, עניין שמתסכל את המשתמשים בוירטואליזציה הוא נושא ניצולת המשאבים. הבעיה לא גדולה אם אני מריץ VM אחד על המחשב הפיסי, אך מה אם אני מריץ עשרה?
נאמר שאני מריץ 10 VMs של לינוקס בגרסה זהה - זה אומר שכל השירותים של מערכת ההפעלה רצים 10 פעמים, הקוד שלהם נטען לזיכרון 10 פעמים, ומבני הנתונים שהם מנהלים - מנוהלים 10 פעמים. זהו מחיר ה isolation בין ה VMs - וזה מחיר יקר.

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

את הניסיונות לפתור את בעיית המשאבים - מנסים לפתור ה Linux Containers: להיות משהו יותר רזה מ VMM, אך יותר מקיף מניהול תהליכים במערכת ההפעלה, שה isolation שלהם מוגבל, וחלוקת המשאבים (למשל priority של תהליך) - לא מדויקת.

המסע ל Linux Containers התחיל במנגנון בשם chroot שהוצג על Unix7 בשנת 1979 (כבר אמרנו בפתיחה שוירטואליזציה היא לא דבר חדש). chroot יצר סביבת ריצה מעט שונה לכל תהליך - והתמקד בשיקולי אבטחה בין תהליכים. הוא בעצם שינה את ה root folder של כל תהליך כך שיראה רק אותו שלו של התיקיות, ולא יוכל להשפיע על תהליכים אחרים (ע"י גישה לקבצים שלהם, למשל). הסביבה שנוצרה לתהליך נקראה chroot jail, שם שליווה עוד פתרונות דומים אחרים (למשל FreeBSD Jail - "כלא BSD החופשי" :) )

עם השנים, היכולות התפתחו, והמיצוב נעשה ידידותי יותר: לא עוד jail אלא container.
מערכת ההפעלה לינוקס פיתחה יכולות ברמת הקרנל בכדי לתמוך באותם containers: בהתחלה cgroups (אריזת כמה תהליכים לקבוצה והקצאת משאבים מבוקרת לקבוצה) ולאחרונה LXC (קיצור של LinuX Containers, מבוסס על cgroups).

ה containers לא מקבלים את רמת ה isolation של VM ("מערכת הפעלה שלמה בשבילי"): הם משתפים את מערכת ההפעלה, הגרסה שלה, הדרייברים שלה עם שאר התהליכים שרצים. אבל הם מקבלים מרחב זיכרון, רשת, ודיסק משלהם וכן מרחב הגדרות של מערכת ההפעלה משלהם (עד כמה שאפשר. נקודה חשובה ליציבות). כמו כן יש הקצאה שוויונית יותר של המשאבים בין ה containers השונים.

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

תמורת פשרות הללו מקבלים Efficiency כמעט של מערכת ללא וירטואליזציה בכלל, וניצולת משאבים טובה הרבה יותר (דיסק, זיכרון, וכו') מכיוון שרצה רק מערכת הפעלה אחת. ה mitigation לקריסת מערכת ההפעלה הוא בד"כ להריץ על containers יישומים ב cluster על גבי כמה מחשבים פיסיים שונים, או להריץ תהליכים שה availability שלהם הוא לא קריטי.

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









Docker


LXC הוא בסיס טוב ל"וירטואליזציה רזה", אך הוא עדיין בסיסי לשימוש. מעליו צמחו פתרונות שונים לניהול workflows וניהול שוטף של העבודה. ללא ספק, הכלי שצמח הכי מהר בתחום זה הוא Docker. אם אתם עובדים בסביבת ענן / DevOps ולא שמעתם את השם הזה עד עכשיו - תבדקו את המקורות מהם אתם מתעדכנים.

הקהילה (development community) של Docker היא מהמתפתחות במהירות הגבוהה ביותר בעולם הקוד הפתוח. בעת כתיבת הפוסט הפרויקט הוא בן משנה וחצי (החל במרס 2013), אך שימו לב לפופולריות שלו ב Github:



כ Benchmark (הוגן, אני מקווה) בחרתי ב Chef - פרויקט באותו הדומיין פחות או יותר (אוטומציה של ניהול תצורה), פופולרי למדי, ושקיים כבר כ 5 שנים:




אין דברים כאלו!

ההתלהבות מ Docker היא קצת מעבר ל Github עצמו:
  • האגדה מספרת, שחברי הפרויקט החלו לעבוד ב Github בצורה ציבורית - ופתאום שמו לב שיש להם עשרות תורמים שהם לא מכירים (לרוב פרויקטי ה Open Source יש תורם משמעותי אחד).
  • יש כבר סטארט-אפים שסובבים סביב Docker: רשימת 10 הסטארט-אפים הטובים ביותר הבנויים מסביב ל Docker.
  • יש כבר כמה חברות שהחליטו לאמץ אותו כרכיב מרכזי בתשתית שלהן (למשל eBay, Rackspace, או Cloudflare).

Docker קרוי על שם מכולות ההובלה המשמשות (גם/בעיקר) להובלה ימית. מספרים שהמצאת המכולה הסטדנרטית שינתה את ההובלה הימית מקצה לקצה: במקום "התמחות" בתובלה של חפצים מסוג מסוים - כמעט כולם מתמחים בהכל ע"י כך שהם מעבירים רק מכולות. המכולות מכתיבות את מבנה הספינות, את מבנה הנמלים את גודל המשאיות וכו'. הסטנדרט הזה אולי קצת מגביל פה ושם - אבל בעיקר מאוד מועיל: מאז שהופיעו המכולות מחיר ההובלה צנח ותהליכי ההובלה נעשו פשוטים יותר.

Docker מאפשר:
  • לבנות containers של הקוד שלכם מתוך סקריפט.
  • לנהל את הגרסאות השונות של ה containers ב repositories שונים.
  • לבצע deploy קל container על שרת שהוגדר.
  • להעביר בקלות container רץ משרת אחד לשרת אחר (עבוד Continuous Delivery, פיזור עומסים, או סתם כדי להעביר אותו לסביבה מעודכנת יותר).
Docker עוזר לנהל כמה מהמגבלות של Linux Containers ולהפוך אותן למגבלות קטנות יותר. סביבות ניהול משוכללות כבר קיימות לפתרונות וירטואליזציה (למשל VMWare vSphere), אך לא כ"כ ל Linux Containers - ובחינם. Docker הוא הבסיס לכזו סביבה, ויש לא מעט סטארט-אפים שמנסים להפוך אותו לסביבת ניהול שלמה. כפי שאמרנו Docker מתבסס היום על LXC, אבל בפרויקט כבר מדברים על אפשור היכולות שלו עבור סביבות וירטואליזציה שונות כגון Xen, KVM, או אפילו Hyper-V (של מייקרוסופט).

הציפיות מ Docker הן דומות לאלו שהיינו מצפים היו ממכולות התובלה: לשנות את פני ניהול ה Data Center בצורה שתהפוך אותו לדבר שונה ממה שאנו מכירים אותו היום.







סיכום


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

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

למרות הדימוי ה"בשל" שיש לטכנולוגיות הוירטואליזציה - יש גם הרבה חידושים. התפר בין וירטואליזציה ל Operations הולך ומתטשטש ויש פתרונות שונים - לצרכים שונים.
היום בו יהיה VM אחד דומיננטי בו כולם ישתמשו (למשל VMWare) - נראה רחוק מתמיד.

עוד נושא קרוב, שלא דיברנו עליו בכלל הוא SDN - קיצור של Software Defined Network, תחום שעוסק בוירטואליזציה ואוטומציה של הניהול (המורכב) של הרשת. נשאיר משהו לפוסטים עתידיים.


שיהיה בהצלחה!





---


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

[ב] מאמר מפורסם בנושא הוא "?Are Virtual Machine Monitors Microkernels Done Right"





18 תגובות:

  1. אנונימי5/10/14 21:43

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

    השבמחק
    תשובות
    1. היי אנונימי,

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

      פתרונות יותר מקיפים - הם מסובכים לתחזוקה. מישהו שעובד איתי מחזיק שרת רציני בבית ועושה Desktop Virtualization מה Laptops שלו ושל אישתו (ואולי עוד איזו תחנה רגילה) - כלומר: כל חומרה שתבחר - יהיה שולחן העבודה שלך כפי שאתה רגיל אליו עם גיבויים סדירים וכו'.

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

      ליאור

      מחק
  2. אחלה פוסט, תודה!

    השבמחק
  3. אנונימי9/10/14 00:30

    Hey,
    Nice post, pleasure reading as usual.
    Looking forward for the post on virtualization as it is used with the different cloud providers.
    Meaning, the different technical aspect between aws ec2 machine and their aws workspace for instance.
    Same goes for azure, softlayer and all the others that follow.
    Sorry for the English as I don’t have Hebrew keyboard here at work.

    Keep on writing!

    Ofer Guttman

    השבמחק
  4. אחלה פוסט, אבל...

    "ה mitigation לקריסת מערכת ההפעלה הוא בד"כ להריץ על containers יישומים ב cluster על גבי כמה מחשבים פיסיים שונים, או להריץ תהליכים שה availability שלהם לא קריטי."
    -----------------------
    תגיד את זה לIBM,heroku,pivotal ועוד שמשתמשים בcontainerים בסביבות הPaaS שלהם...
    אין שום הבדל בין קריסה של hypervisor ביחד עם כל הVMים שלו לבין קריסה של מ"ה עם כל הcontainerים שלו, חוץ מהעובדה שיש הרבה יותר containerים מVMים, אבל אין שום מניעה להשתמש בהם בproduction.

    כמו-כן, אני חושב שקצת פספסת את המטרה של docker במשפט: "להעביר בקלות container רץ משרת אחד לשרת אחר (עבוד Continuous Delivery, פיזור עומסים, או סתם כדי להעביר אותו לסביבה מעודכנת יותר)." וגם המשפט "Docker עוזר לנהל כמה מהמגבלות של Linux Containers ולהפוך אותן למגבלות קטנות יותר" לא אומר יותר מדי, אז ברשותך ארחיב בתגובה:

    העניין בdocker הוא סטנדרטיזציה של deployment באופן מוחלט.
    בעבר מפתחים היו כותבים אפליציית שרת ואז כותבים גם מדריך התקנה לאפליקציה הזאת עבור אנשים שרוצים להריץ את זה אצלם, או שהיו כותבים סקריפטים של התקנות עבור deployments (איך אומרים את זה בעברית בכלל?) לענן.
    אבל חלק גדול מהאפליקציה דורשות סביבה מיוחדת (נניח בruby- צריכים גרסה מסויימת של ruby, להתקין gems ספציפיים, או בnode.js צריכים modules מסויימים וכו') ולהתקין את האפליקציה היה הופך להיות תהליך מסובך וסיזיפי.
    מה שdocker מאפשר למפתח האפליקציה הוא לשלוח את האפליקציה ביחד עם מערכת הקבצים שלה וביחד עם מערכת ההפעלה שלה, כלומר המפתח שולח "קופסא" שכל מה שצריך לעשות כדי "להתקין ולהריץ" זה להריץ docker run והאפליקציה מורצת בתוך הסביבה שהמפתח שלה בנה לה, בלי שום צורך להתקין שום דבר בשביל זה.

    השבמחק
    תשובות
    1. היי devop,

      ההבדל הוא ש Hypervisor קורס פחות ממערכת ההפעלה. אם מערכת ההפעלה המתארחת קרסה - ה VMs האחרים שורדים. ב Containers - כולם משתפים מערכת הפעלה אחת, לטוב ולרע. הבעיה הזו נעשית זניחה כאשר יש cluster של אותה תוכנה, בו יש כמה nodes על מחשבים פיסיים שונים - וזה המצב של מערכות ה PaaS שהזכרת (גם גוגל, ככל הידוע לי, עובדים הרבה עם linux containers בענן שלהם). שים לב שהנחת היסוד אצלם היא ש VMs (או containers) קורסים, והם מבקשים ממך להערך לכך.

      לגבי docker:
      אשמח אם תאיר את עיני - אבל הערך הראשי נראה לי כלי האוטומציה (cli וה repositories למשל) ולא דווקא ניהול התלויות של ה container. הרי מצד אחד יכולתי להגדיר את התלויות שלי מקומיות (למשל npm modules) ואז לארוז הכל ב Zip ולזרוק אותו במחשב אחר (אותה מערכת ההפעלה) - ולהפעיל. מה שונה Docker בצורה מהותית כאן? מה שהכנתי וארזתי - הוא מה שאקבל.
      מצד שני ב docker עדיין יש לך dockerfile שהוא סוג של סקריפט שעדיין עושה npm install (עבור ה json.package שנארז) או apt-get בכדי להביא ל container שמותקן את התלויות הרצויות. יכולתי לעשות את זה כ shell script קודם לכן, רק שזה (כמו שאמרת) סטנדרטי - ואז אני יכול להשתמש בכלי אוטומציה כדי ליצור הרבה containers כאלו בצורה קלה, אבל ההתקנה נראית לי אותו סדר גודל של הכנה / עבודה. אני מפספס משהו?

      ליאור

      מחק
  5. 1) למה בהכרח הVMים האחרים שורדים? אני לא מבין איך בנוי ESX או hypervisorים אחרים, אבל אין שום דבר בתוכנה שם שיכול להקריס את כל הVMים ?

    2) לגבי cluster - אני לא חושב שcluster זה הביטוי הכי טוב שצריך להשתמש בו כאן. זה נכון שבד"כ מעלים מספר instanceים של אותה אפליקציה, אבל האפליקציות שמעלים על containerים בPaaS ממש לא נועדו כדי להרכיב cluster.
    הרי clusterים מאופיינים בתקשורת מהירה מאוד בין הרכיבים השונים שלהם, ובד"כ גם משתפים ביניהם איחסון (למשל- RAC וclusterים של מיקרוסופט) ובעוד שהאפליקציות על PaaS הן נוטות להיות רזות ואפילו בעלי גישה למערכת קבצים נדיפה.
    אולי המילה הזאת עברה שינוי בשנים האחרונות? בעוונותיי התרחקתי לאט לאט מהתשתיות לכוון הקוד אז יכול להיות שאני כבר לא מעודכן.

    3) docker זה דבר חדש יחסית, בעוד שPaaS עם lxc/cgroups היה קיים מקודם, וגם אז היו מערכות בשוק שהיו מזהות אוטומטית תלויות ומקנפגות דברים- בין אם זה לעשות npm install פשוט או לקנפג את הserver.xml אם זה אפליקציית tomcat ואז לפרוש את הwar.
    וזה אכן היה עובד לגבי רוב המקרים, אבל זה לא עובד במקרים מסויימים (מנסיון, יש לפעמים מקרי קצה הזויים ביותר) וגם לא תמיד אתה יכול לדעת מה מערכת ההפעלה של הcontainerים בPaaS. עם docker אתה יכול להתקין הכל אצלך במחשב, ולהריץ את הimage בכל שרת אחר שיש עליו docker וזה עובד.
    מספיק שהגרסה של התוכנה שתותקן בcontainer שונה טיפה ואתה עלול להתקל בבאג שיקח לך הרבה מאוד זמן לעלות עליו, וגם לרוע המזל לא כל ספקי הPaaS מספקים ממשק נוח לtroubleshooting (הנה השוואה בין סוגים שונים- [1], שווה לראות)
    עם docker מובטח לך שאם זה עובד במחשב שלך, זה יעבוד גם במחשב אחר. כמו java בין מ"ה אבל שבאמת מקיים ;-)

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

    [1]
    https://www.youtube.com/watch?v=k3TazUmv7Fg

    השבמחק
    תשובות
    1. היי devop - תודה על התגובה!

      1) כך ה hypervisor בנוי: לאפשר ל VM אחד לקרוס ולשאר להמשיך לעבוד. ברור שתקלות מסויימות ב hypervisor יגרמו לקריסה כוללת, אבל מכיוון שקוד ה hypervisor יחסית קטן ופשוט - תקלות אלו הן לא-נפוצות.

      2) זה עניין של מינוח. הכוונה היא גם ל cluster (או קבוצת שירותים) שהם stateless ו/או בלתי תלוייים זה-בזה כמובן. הרעיון הוא שקריסה של אחד לא פוגעת בהמשכיות השירות.

      לגבי docker - תודה על ההבהרות.

      ליאור

      מחק
  6. מאמר מושקע ומחכים.
    הזכרת את נושא המקורות ("תבדקו את המקורות מהם אתם מתעדכנים") זה חכיה נחמד אם תוכל לפרסם בסוף הפוסטים שלך גם מקורות שאפשר להירשם אליהם לצורך המשך מעקב אחרי הנושא המדובר.
    תודה!

    השבמחק
    תשובות
    1. תודה. אשתדל לעשות זאת - אבל זה לא תמיד כ"כ פשוט.

      המקורות מהם אני נוהג לשאוב את רוב המידע הם מאוד כלליים (בלוגים, האקרניוז, גיקטיים, ספרים, וכו' - אני יכול לפרסם את העיקריים). כשאני כותב פוסט אני משלים בגוגל הרבה פיסות מידע, חלקן מאוד ממוקדות (למשל stackoverflow על שאלה ספציפית שעולה בזמן הכתיבה).
      על Docker למשל - שמעתי ממקורות רבים (ולכן ההערה. מי שקורא הרבה חדשות טכנולוגיה, סביר שנתקל בשם הזה כבר כמה פעמים).
      על וירטואליזציה - עמלתי רבות לאסוף גרגר מידע אחרי גרגר מידע, זה היה אחד הפוסטים הקשים לכתיבה, אני חושב שהכוונה לכתוב אותו עלתה לפני כחצי שנה - פשוט התקשתי למצוא חומר.
      לא מצאתי את ה Vitalization news ולא AllThingsVirtualized. כלומר: שום אתר שנתן סקירות רוחב על הנושא. עברתי על הרבה מאוד חומר פרסומי לא מספיק מעמיק, והרבה דיוני עומק מאוד ממוקדים (xen vs. kvm, או הסבר על הדרך בה VMWare מבצעת אופטימיזציה ל virtual memory של חלונות). כל רמת ה"אמצע" - הייתה ממש חסרה.

      בד"כ כלל כן ישנם מקורות בהם אני משתמש שיותר קרובים לרמת ההפשטה בה אני עוסק. הם לא תמיד "מדהימים" - אבל יכול להוסיף אותם.

      ליאור

      מחק
    2. היי,

      קודם כל ראיתי שפירסמת פוסט על המקורות שלך, תודה :)

      ובנוגע לוירטואליזציה. אני מעוניין להרים אצלי במשרד שרת עם מספר VM-ים שישמשו כשרתי Web למערכות אינטרנטיות שונות שאנחנו בונים בעיקר עם Windows/IIS אבל לא רק..

      האם אני יכול להתקין משהו כזה על מחשב רגיל? או שצריך שרת מיוחד עם חומרה שיודעת לאפשר את חלוקת המשאבים שלה בין ה-VMs (מעבר ליכולת ה-VT שציינת). למשל עם הכרטיס רשת שמהווה כתובת MAC יחידה כשלמעשה הוא שער לכמה שרתים עם כמה כתובות IP..

      איזה פלטפורמה הכי מתאימה למטרה הזו מבחינת קלות ההתקנה והתפעול וכמובן שיהיה Open Source חינמי..

      תודה

      מחק
    3. היי אריאל,

      למטרות פיתוח - אין בעייה להשתמש במחשב פשוט. ייתכן ותצטרך להוסיף RAM כדי להריץ עליו כמה שרתים בצורה סבירה (נאמר 16GB RAM כדי להריץ 3-4 VMs, בעוד 4GB RAM היה מספק לשרת יחיד) .
      אין צורך בחומרה מיוחדת. תוכנת הוירטואליזציה תגרום לכרטיס הרשת (הרגיל) שלך להראות כמו כמה - זה חלק מהטריק שלה. ports של IP למשל - זה סתם שירות של מערכת ההפעלה, ולא משהו "חומרתי" ברשת - אין בעיה "לדמות".
      כתובת MAC לדוגמה (שזה תכונת חומרה מובהקת) - גם ניתן "לזייף". למשל טווח הכתובות MAC הבא שמור ע"י היצרנים לצורך וירטואליזציה:
      x2-xx-xx-xx-xx-xx
      x6-xx-xx-xx-xx-xx
      xA-xx-xx-xx-xx-xx
      xE-xx-xx-xx-xx-xx

      כלומר: תוכנת הוירטואליזציה יכולה להגריל MAC addresses בטווח עבור ה VMs - בצורה בטוחה.

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

      בקיצר: כל עוד אין עומס עבודה על השרתים - אין בעיה.

      מקווה שעזרתי,
      ליאור

      מחק
    4. לגבי פלטפורמות:
      אני מניח שאתה עובד עם "חלונות" כמערכת ההפעלה המארחת? אם יש לך גרסת שרת של חלונות, אני מניח ש Hyper-V תהיה קלה לעבודה (כי מייקרוסופט טובה באינטגרציה). מעולם לא ניסיתי לעבוד איתה.
      עוד אופציות פופולריות ל"חלונות" הן VMWare (בחינם יש רק נגן, לא תוכל לקחת snapshots) או VirtualBox.
      על לינוקס, הגרסה החופשית והנפוצה ביותר ל VM היא ככל הנראה KVM (והיא יכולה לארח שרתי "חלונות" - החל מגרסת NT4).

      ליאור

      מחק
    5. תודה! עזרת לי מאד.

      מחק
  7. אנונימי31/10/14 20:55

    תודה רבה על הפוסט המעולה הזה!!!
    ההשקעה בכתיבתו ניכרת ונראה שסוף סוף הבנתי קצת יותר בויטואליזציה

    השבמחק
  8. אנונימי18/2/15 12:14

    תודה!! מעניין מאוד. כל הכבוד!

    השבמחק
  9. יש לך שגיאת כתיב, תיקון:
    "פקודת Privileged טפלה".
    תפל = חסר טעם. "ללא מלח".
    טפל = בדרגת חשיבות פחות יותר, שולי.
    מה דעתך?

    השבמחק