קצת על דוקר…

רקע כללי

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

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

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

תטען את קובץ הדוקר ותפעיל אותו, והכל יעבוד.

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

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

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

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

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

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

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

מבנה ה - DockerFile

בדוקר בניגוד לVM - אין קובץ ISO מוכן. אנחנו מקבלים קובץ DockerFile, אבל הוא רק ה”מתכון” לImage - שבנוי משכבות שונות. דוגמא בסיסית:

DockerFile

FROM ubuntu:22.04
RUN apt-get update && apt-get install -y python3
COPY app.py /app.py
CMD ["python3", "/app.py"]

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

ה - Layers

נפרק את הקובץ הזה לשכבות (Layers) כדי להבין גם את הנושא הזה:

[ubuntu base]
   ↓
[python installed]
   ↓
[app.py]

יש פה 3 שכבות, כל אחת מהן בנפרד Read-Only, ועל גביהן, בסוף, אני מריץ את הפקודה שאני רוצה. וזה גאוני!

כל שכבה אינה מושפעת מחברתה, מה שנותן לי את היכולת לשתף שכבות בין קונטיינרים שונים. כלומר, לא רק שחסכתי את הקרנל הנפרד לכל פרוייקט, אלא החיסכון נרחב אפילו יותר. נניח שיש לי 3 פרוייקטים שונים. בכולם אני צריך אובונטו - אז בכולם יהיה את אותה שכבת אובונטו אחת. אבל בשכבה הבאה, רק שניים צריכים פייתון. השלישי בכלל צריך Node.js. אז השניים ישתמשו באותו פייתון - והשלישי, רק בNode.js, בלי לצרוך משאבים\להיות מושפע מהפייתון. מתוך השניים שצריכים פייתון, באחד אני אריץ את app.py, ובשני - את פרוייקט הפייתון השני שלי, שוב, בלי השפעה אחד על השני.