התקנת הסביבה

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

1. מה זה דוקר

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

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

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

הרצת כל רכיב בתוך Container מאפשרת לנו לעשות בדיוק את זה:

  1. קונטיינר נוצר מתוך תבנית שנקראת Image ויצירת קונטיינר היא תהליך מאוד מהיר.
  2. קונטיינר מקבל מבחוץ את כל המידע שהוא צריך בשביל לעבוד וכך קונטיינרים יכולים לשתף מידע ביניהם בצורה מבוקרת.
  3. קונטיינר איננו מערכת הפעלה מלאה ודורש רק את המשאבים שצריך בשביל היישום שהוא מריץ. הקונטיינר משתמש בכל משאבי המכונה בדיוק כמו אפליקציה מקומית שרצה על השרת.

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

2. התקנה והפעלת קונטיינרים

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

וקונטיינר הוא הפעלה של אימג' מסוים.

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

$ docker ps

בדיוק כמו שהפקודה ps מראה את כל התהליכים.

3. התקנת דוקר

בשביל שנוכל להתחיל לייצר קונטיינרים צריך תחילה להתקין את דוקר או ליתר דיוק את המנוע Docker Engine. מנוע זה הוא שמריץ את הקונטיינרים. אפשר לבחור התקנה למערכת ההפעלה שלכם מהדף הזה:

https://hub.docker.com/search/?type=edition&offering=community

אם אתם עובדים כמוני על מכונת Windows, תרצו להתקין תוכנה שנקראת Docker Desktop. תוכנה זו כוללת את המנוע של דוקר ועוד כלי עזר שנשתמש בהם בפיתוח. לדוקר יש גם אינגרציה טובה עם WSL, אז אחרי התקנת Docker Desktop מומלץ להיכנס לממשק ההגדרות שלו, ללחוץ שם על אייקון גלגל השיניים ושם לסמן Use the WSL 2 based engine.

אחרי ההתקנה תרצו לוודא שדוקר עובד לכם כמו שצריך. כנסו ל CMD או ל Terminal וכתבו:

$ docker --version
Docker version 20.10.6, build 370c289

במהלך הקורס אני אעבוד עם Docker Desktop שמותקן אצלי על מערכת ההפעלה חלונות. בגלל שאני אוהב לעבוד מתוך WSL אני נכנס אחרי התקנת Docker Desktop למסך ההגדרות ומוודא שהאינטגרציה עם WSL מופעלת. אחרי כל ההתקנות אתם צריכים להגיע למצב שגם מתוך CMD וגם מתוך WSL אפשר לכתוב docker version ולקבל את הגירסה הנכונה.

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

נתחיל בהתקנה של האימג' מתוך הריפוזיטורי הזה:

https://github.com/docker-library/hello-world

האימג' עצמו נבנה וזמין במאגר של דוקר שנקרא Dockerhub וזה הקישור אליו שם:

https://hub.docker.com/_/hello-world

יש בו תוכנית קטנה בשם hello שמדפיסה הודעת ברכה על המסך. הפקודה הבאה מורידה את האימג' מדוקר האב, יוצרת ממנו קונטיינר ומפעילה את הקונטיינר:

$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete 
Digest: sha256:2557e3c07ed1e38f26e389462d03ed943586f744621577a99efb77324b0fe535
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

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

$ docker image  ls

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
hello-world         latest              fce289e99eb9        7 weeks ago         1.84kB

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

$ docker ps -a

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
4cb8496372d3        hello-world         "/hello"            7 minutes ago       Exited (0) 3 minutes ago                       reverent_sanderson
73177b43ff6d        hello-world         "/hello"            7 minutes ago       Exited (0) 7 minutes ago                       focused_bose

ה -a אומר לפקודה להוסיף גם את הקונטיינרים שעכשיו סגורים. שימו לב שאצלי יש שני קונטיינרים לאותו אימג' בגלל שהפעלתי את docker run פעמיים.

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

$ docker start -a 4cb8496372d3

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

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

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

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
4cb8496372d3        hello-world         "/hello"            9 minutes ago       Exited (0) 18 seconds ago                       reverent_sanderson
73177b43ff6d        hello-world         "/hello"            9 minutes ago       Exited (0) 9 minutes ago                        focused_bose

לעומת זאת אם תפעילו שוב את docker run תיצרו קונטיינר חדש עבור האימג':

$ docker run hello-world
...
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
ff88c7e43750        hello-world         "/hello"            7 seconds ago       Exited (0) 6 seconds ago                        zealous_khayyam
4cb8496372d3        hello-world         "/hello"            11 minutes ago      Exited (0) 2 minutes ago                        reverent_sanderson
73177b43ff6d        hello-world         "/hello"            11 minutes ago      Exited (0) 11 minutes ago                       focused_bose

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

4. סיכום

העבודה עם דוקר מציעה לנו את היתרונות הבאים:

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

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

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


קישור להורדת כל תיקיית הדוגמאות כקובץ זיפ: https://github.com/tocodeil/docker-course-examples/archive/refs/heads/main.zip

קישור לצפיה אונליין בתיקיית הדוגמאות: https://github.com/tocodeil/docker-course-examples

קישור להתקנת Docker Desktop:

https://www.docker.com/products/docker-desktop

הפקודות שראינו בוידאו:

# Download image "hello-world" and run a new container from it
$ docker run hello-world

# Show all running containers
$ docker ps

# Show all running (and stopped) containers
$ docker ps -a

# Show all images
$ docker image ls