אחד הדברים שאני הכי אוהב לעשות, זה למצוא פתרונות לכל הדברים שאנשים אומרים שאי אפשר לעשות בתחום הסלולאר, או בתחום המחשוב הפרטי,או העסקי.
יש לנו את האנציקלופדיה הגדולה ביותר והיא חינם ואפשר להשתמש בה מסביב לשעון בכל מקום, וכולם מכירים אותה...לא אני לא מדבר על ויקיפדיה - Google
ברוכים הבאים לחלק 2 של המדריך לדוקר למתחילים בעברית, במדריך זה נעבור על פקודות בסיסיות לניהול קונטיינרים (במידה ואתם לא יודעים מה זה "קונטיינר" בהקשר של דוקר, נא לקרוא את החלק הראשון: כאן)
לפני שנרוץ להריץ פקודות, אני רוצה להזכיר לכם שתי מושגים חשובים, מה זה "Image" ומה זה "Container"?
"Image" = קובץ תבנית שמכיל מערכת + קבצים מוכנים להרצה, אפשר לקרוא לזה "מתכון" למערכת ההפעלה (מה צריך, כמה צריך איך צריך ומזה נוצרת מערכת הפעלה.
"Container" - הוא בעצם ה"מחשב" שנוצר מתוך ה"מתכון" שהוא ה Image, מדובר על מערכת הפעלה עם הדברים שצריך בשביל להריץ את השירות שאנחנו צריכים בלי כל מיני תוספות מלמעלה.
להלן הסעיפים שנעבור עליהם במדריך זה:
1) בדיקת מידע כללי על המערכת - docker info
2) יצירה, הרצה של קונטיינר, התחברות לתוך קונטיינר (עם הפרמטרים it- ו ai- ו d-) - docker run
3) הצגת מידע על קונטיינרים רצים כרגע במערכת - docker ps
4) הצגת מידע על כל הקונטיינרים שיש כולל אלה שלא רצים - docker ps -a
5) איך לעצור קונטיינר? - docker stop
6) איך "להקפיא" קונטיינר בדוקר? - docker pause
7) איך להפעיל קונטיינר שכבר עצרנו? - docker start
8) איך למחוק קונטיינר? - docker rm
9) איך למחוק "docker rmi - ?"Image
10) איך להציג את כל ה Imagים הקיימים לנו במערכת? - docker images
11) איך להוריד Image למחשב בלי להפעיל אותו? - docker pull
1. בדיקת מידע כללי על המערכת - docker info
לא נראה לי שצריך הסבר יותר מדי, הפקודה הזאת פשוט מראה מידע על הסביבה שבה אנחנו עובדים:
2. יצירה והרצה של קונטיינר - docker run
במידה ואנחנו נרצה להריץ איזשהו קונטיינר, נריץ את הפקודה docker run, במידה ואין IMAGE של מה שאנחנו צריכים במערכת שלנו, Docker ילך ל "Docker hub" (מאגר עולמי של אימג'ים), ויוריד אותו (יבצע פעולת Pull) למחשב, לאחר מכן יבנה מזה קונטיינר, ויריץ את מה שצריך (סרוויס, סקריפט, פקודה וכד') ולאחר מכן "יכבה" ובעצם יצא מהקונטיינר, לכן חשוב להבין מה בדיוק אתם מבצעים, לצורך הדגמה אנחנו נעבוד עם קונטיינר ששמו Alpine (קונטיינר קטן מאוד שמעולה לתרגולים).
מאחר ואין לכם את הקונטיינר על המחשב, נריץ את הפקודה docker run alpine ונראה כיצד המערכת מחפשת את ה Image הזה על המחשב שלכם, מאחר ואין לכם, היא תתחיל להוריד אותו.
ניתן להריץ את הקונטיינר בשתי צורות:
2.א סתם להוריד ולהריץ אותו בלי שנוכל לעשות משהו - שזה בדיוק מה שתעשה הפקודה docker run alpine ובעצם לאחר שנריץ את הפקודה, הדוקר יוריד את ה IMAGE למחשב שלנו, יפעיל ויכבה אותו ואז הוא יהיה בסטטוס Exited.
2.ב בשביל שנוכל לראות שהוא עשה משהו - אנחנו ניתן לו פקודה לבצע, לדוגמא להגיד "Hello from Alpine".
נעשה את זה בעזרת הפקודה: "docker run alpine echo "Hello from Alpine.
בפקודה "docker run" יש המון פרמטרים, בעצם מתוך הפקודה הזאת ניתן לשנות כל הגדרה, כולל התחברות לתוך הקונטיינר עצמו, רק שכאן ההתחברות מתבצע בצורה שונה ממה שאנחנו מכירים כאשר אנחנו עובדים עם מכונות וירטואליות.
במקרה שלנו בשביל שנקבל לאחר ההרצה שורת פקודה שנוכל לבצע משהו בתוך הקונטיינר, נוסיף את הפרמטרים it- (יש גם ia-, עליו נפרט בהמשך, כאן רק נפרש את המשמעות שלו) שאלו בעצם שתי פרמטרים שכל אחד מהם עושה משהו אחר, אך בשילוב מתקבלת תוצאה מאוד חשובה, הפרמטרים האלה בעצם יתנו לנו שורת פקודה שנוכל לעבוד בתוך הקונטיינר.
docker run -it alpine sh
(בתוך alpine אין BASH (סביבת פקודה של לינוקס) יש שם SH, לכן כתבתי SH בסוף)
וניתן לראות את זה שאני בשורת הפקודה, והרצתי את הפקודה ls.
להלן הפרמטרים שאפשר להשתמש במקרה הזה והפרוש שלהם:
"i" - שהוא בעצם "Interactive" ובעצם בצורה הזאת ניתן להקליד דברים לתוך הקונטיינר - הבעיה שלא רואים תגובה.
"t" - שהוא בעצם "Terminal" - יפתח לכם מסך עם שורת פקודה בלי שתוכלו להקליד שום דבר, לכן צריך לשלב את שתיהם.
"a" - שהוא בעצם "Attach" - ברגע שהרצתם פקודה והקונטיינר במצב Exited (שזה בעצם "כבוי"), אין אפשרות להתחבר אליו עם it-, ולכן צריך להתחבר עם ai- (אנחנו נראה את זה בהמשך)
2.ג איך לגרום לקונטיינר להעלות לבד לאחר הפעלה מחדש?
במידה ובוצע הפעלה מחדש למחשב, נרצה שהקונטיינר שלנו יעלה לבד, לצורך כך נשתמש בפרמטר "restart":
docker run -d --name alpaka_restart --restart=always alpine
בפרמטר הזה צריך להשתמש בתהליך הרצת הקונטיינר, בנוסף אם לא תתנו לקונטיינר שום פקודה או פעולה שהוא צריך לעשות ללא הפסקה, בסוף הפעולה הזאת הקונטיינר פשוט "יכבה" לכן ניתן להוסיף משהו בסגנון הזה "tail -f /dev/null" הפקודה הזאת לא עושה שום דבר מיוחד, רק גורמת לקונטיינר להישאר חי, אם מחברים את הכל זה נראה כך:
docker run -d --name alpaka_restart --restart=always alpine tail -f /dev/null
להלן כל הפרמטרים:
`no` - (ברירת מחדל) – לא מנסה להפעיל מחדש
`always` - תמיד מנסה להפעיל מחדש – גם אחרי ריבוט
`on-failure` - יפעיל מחדש רק אם הקונטיינר נפל (Exited עם קוד שגיאה)
`unless-stopped` - יפעיל מחדש כל עוד לא עצרת אותו בעצמך
במידה ונרצה לשנות את "מדניות" ההפעלה מחדש נשתמש ב docker update:
docker update --restart no container_name
(Docker update - יודע לעשות עוד הרבה דברים, אנחנו נלמד עליו בהרחבה בחלק 4)
2.ד האם אפשר לקרוא לקונטיינר בכל שם שבא לנו?
התשובה היא כן, בעזרת הפרמטר name-- ואני אשתמש בו כאן
אני אריץ את זה בכל הצורות בשביל שתוכלו לראות את ההבדלים, נתחיל: docker run --name alpaka_its_cool alpine:
מאחר ומדובר על Image מאוד קטן, לא ראינו אפילו את תהליך ההורדה, ומאחר ולא הוספנו בסוף שום פקודה, הדוקר הוריד את מה שרצינו, יצר את הקונטיינר, ראה שלא נתנו לו שום פקודה להריץ, ופשוט יצא, ניתן לבדוק את זה בעזרת פקודה שעליה נלמד בסעיף הבא, כרגע אני אבצע הורדה של הדוקר ואבקש ממנו לבצע פקודה כלשהי, כמו להציג טקסט על המסך:
מה שקורה מאחורי הקלעים, ביקשנו מדוקר להוריד את הקונטיינר Alpine לקרוא לו בשם "Alpaka_its_cool" (כן יש לי קטע עם אלפקות, לא יודע למה), להפעיל בתוך הקונטיינר שורת פקודה ולהציג לנו במסך את המשפט: "!LeiderTech.co.il are the best" (כמובן שאני אובייקטיבי לחלוטין כן... 🤣).
2.ה איך לעבוד על קונטיינר בדוקר?
במצב הזה יש שתי סיטואציות, הראשונה, הרצנו docker run ואז אנחנו רוצים להתחבר ישר ולעבוד, השניה זה אחרי שכבר הורדנו את הקונטיינר ואני רוצים להתחבר אליו לעבוד, אני אראה את שתי הדוגמאות:
2.ו נריץ את הפקודה: docker run -it --name alpaka_its_cool alpine sh (ה SH בסוף זאת שורת פקודה "מצומצמת" בתוך Alpine).
נוכל לראות שאנחנו בתוך שורת פקודה, בתוך הקונטיינר:
בעצם כאן נוכל לבצע את כלל הפקודות שניתן לבצע בתוך לינוקס כמה דוגמאות:
בשביל לצאת, נריץ את exit ונחזור למכונה הרגילה שלנו:
2.א.א) איך להתחבר לקונטיינר אחרי שכבר הורדנו אותו בדוקר?
במקרה שלנו בעצם ביצענו פקודה ויצאנו מהדוקר, אם נבדוק את הסטטוס שלו (אנחנו נלמד לעשות את זה בהמשך), נקבל שהוא במצב Exited, שזה בעצם סוג של "מכובה" (במקרה הזה, כי לא נתנו לו לרוץ ולבצע פעולות כאלה ואחרות), לכן בשביל להתחבר אליו, צריך להתחיל אותו שוב, נעשה את זה בעזרת הפקודה הזאת:
docker start -ai alpaka_its_cool
ונוכל לראות שאנחנו שוב בתוך שורת הפקודה בקונטיינר:
2.א.ב) איך יוצרים קונטיינר שירוץ ברקע?
במידה ואנחנו יוצרים קונטיינר ורוצים שהוא פשוט יעבוד לנו ברקע, אנחנו נשתמש בפרמטר שנקרא "מנותק" d- שהפרוש שלו הוא "Detached", מה שהוא עושה בעצם זה להריץ את הפקודה שאנחנו רוצים בתור הקונטיינר ולנתק אותנו מהסשן, מהחיבור לקונטיינר, ואז הקונטיינר רץ לו ברקע ומבצע את מה שאנחנו צריכים, ניתן כאן פקודה לדוגמא שתגרום לדוקר שלנו להריץ סתם ככה משהו ברקע:
docker run -d --name leidertech alpine tail -f /dev/null
הפעולה בוצעה, ובעצם הקונטיינר רץ ברקע:
עכשיו ננסה להריץ את אותה הפקודה בלי d-:
ובעצם עכשיו אנחנו "תקועים" עם פקודת הרצה של הקונטיינר ולא יכולים לעשות כלום
בשביל לצאת מהמצב הזה נלחץ על ctrl+c (לפעמים צריך כמה פעמים ברצף) ואז נחזור לשורת הפקודה שלנו:
הקונטיינר עצמו ימשיך לרוץ ברקע
3.הצגת מידע על קונטיינרים רצים כרגע במערכת בדוקר
בשביל להציג מידע על הקונטיינרים הרצים לנו במערכת נריץ את docker ps:
הפרוש של העמודות:
CONTAINER ID - המזהה של הקונטיינר
IMAGE - מה שם האימג' שירד מדוקר האב (במקרה שלנו זה משם)
COMMAND - מה בעצם כרגע מבצע הקונטיינר - במקרה הזה הוא הפקודה שרצה עכשיו
CREATED - מתי נוצר הקונטיינר?
STATUS - מה המצב שלו? רץ, לא רץ?
PORTS - האם יש הפניית פורטים (נלמד על זה בחלק 4)
NAMES - מה השם של הקונטיינר? (האם ניתן לתת שם שאנחנו רוצים? כן אני אראה בהמשך)
3.א איך להציג רק עמודות ספציפיות עם docker ps?
כפי שניתן לראות, נוכל להציג את הקונטיינר שרץ לנו עכשיו במערכת, עכשיו שאלת השאלות, האם אני יכול לבחור אילו עמודות אני רוצה להציג, התשובה היא כן, בעזרת הפרמטר format--, הסינטקס קצת מעצבן, אבל דיי ברור האמת, בדוגמא הבאה אני אבחר להציג רק כמה עמודות:
כפי שניתן לראות העמודות הן בהתאם, להלן כלל העמודות שניתן להציג:
{{.ID}}
מזהה הקונטיינר
{{.Image}}
שם ה־image
{{.Command}}
הפקודה שהורצה
{{.CreatedAt}}
מתי נוצר הקונטיינר
{{.RunningFor}}
כמה זמן הוא רץ
{{.Status}}
סטטוס נוכחי (Up/Exited)
{{.Ports}}
הפורטים שנפתחו
{{.Names}}
השם של הקונטיינר
4. הצגת מידע על כל הקונטיינרים שיש כולל אלה שלא רצים בדוקר
להבדיל מהפקודה הקודמת, בפקודה הזאת נוכל להציג את כלל הקונטיינרים שיש לנו, גם כאלה שלא רצים (Exited):
לצורך דוגמא נציג רק את אלה שהם בסטטוס EXITED, הפקודה: "docker ps -a --filter "status=exited
ניתן להשתמש בכל הפרמטרים הללו:
--all, -a מציג את כל הקונטיינרים, גם כאלה שכבר נעצרו
--filter, -f מסנן תוצאות לפי תנאי (למשל לפי סטטוס או שם)
--format מציג רק את העמודות שאתה רוצה, בעיצוב שאתה מגדיר
--last, -n מציג רק את הקונטיינרים האחרונים, לפי מספר
--latest, -l מציג רק את הקונטיינר האחרון שנוצר
--no-trunc מונע קיצוץ של טקסטים ארוכים (כמו מזהים)
--quiet, -q מציג רק את מזהי הקונטיינרים (Container IDs) בלי מידע נוסף
--size, -s מציג מידע על גודל הדיסק שכל קונטיינר תופס
5. איך לעצור קונטיינר בדוקר?
לצורך עצירת קונטיינר נשתמש בפקודה docker stop, לצורך דוגמא, אני מריץ כרגע 5 קונטיינרים:
אני אעצור את test1, הפקודה: docker stop test1, נקבל תגובה "test1" , שזה אומר שהקונטיינר נעצר:
לאחר מכן נריץ את docker ps -a בשביל לראות את כל הקונטיינרים שלנו, ונראה ש test1 הוא Exited:
5.א האם אפשר לעצור כמה קונטיינרים ביחד בדוקר?
התשובה היא כן, בצורה הבאה: docker stop test2 test3 test4, קיבלנו שוב את שמות הקונטיינרים שעצרנו, זאת אומרת שהכל בסדר:
שוב נריץ את docker ps -a, ונראה שהם כולם במצב Exited:
5.ב איך לתזמן כיבוי של קונטיינר בדוקר?
ניתן לשלב את הפרמטר t- ולאחר מכן כמה שניות ואת שם הקונטיינר שאנחנו רוצים לעצור בצורה הבא:
docker stop -t 3 container_name
מה שיקרה, זה שלאחר 3 שניות הקונטיינר יקבל פקודת כיבוי.
5.ג איך לעצור ולמחוק קונטיינר בפקודה אחת בדוקר?
נגיד ויש לנו קונטיינר שאנחנו לא נצטרך אותו, יש אפשרות לבצע עצירה ואז מחיקה, בעזרת הדגל f- (בכוח - force)
לצורך דוגמא יצרתי קונטיינר בשם test83 שאני לא צריך אותו יותר, אריץ פקודה שתעצור ותמחק את הקונטיינר:
נריץ את הפקודה: docker rm -f test83
קיבלנו תגובה מדוקר וניתן לראות שהוא לא מופיע יותר ברשימה:
6. איך "להקפיא" קונטיינר בדוקר או בעצם לעשות לו Pause?
נתחיל עם השאלה הפשוטה ביותר, מה ההבדל בין Pause לבין Stop?, אז בעצם הסיטואציה מאוד פשוטה, כאשר אנחנו מבצעים עצירה של קונטיינר, המערכת עוצרת כל מה שזז שם, ומכבה את הקונטיינר, ובעצם כאילו "כיבינו" את המחשב.
במצב של Pause, מה שקורה בעצם זה "סוגר" את התוכנה, אבל המערכת הפעלה עצמה (המחשב) ממשיך לרוץ.
ביצוע "הקפאה" מתבצע בעזרת הפקודה docker pause container_name:
ניתן לראות שהוא עצר:
בשביל "להוציא" אותו מהקפאה נריץ את הפקודה : docker unpause container_name
ונראה שהקונטיינר חזר לפעול:
ניתן לעצור כמה קונטיינרים ביחד על ידי הפקודה הזאת:
docker pause cont1 cont2 cont3
ו"להפשיר" על ידי docker unpause cont1 cont2 cont3
7. איך להריץ קונטיינר שעצרנו (שעשינו לו Stop) בדוקר?
בשביל להפעיל קונטיינר נשתמש בפקודה docker start ושם הקונטיינר בסוף - docker start test1:
נריץ את docker ps -a (אפשר גם בלי a-) ונראה שהוא רץ:
7.א האם אפשר להפעיל כמה קונטיינרים ביחד בדוקר?
כן, ניתן להפעיל כמה קונטיינרים ביחד, בדומה לפקודה הקודמת עם STOP, נשתמש הפעם ב START:
docker start test1 test2 test3
נריץ את docker ps -a (ניתן גם בלי a-) בשביל לבדוק את המצב:
ניתן לראות שכולם למעלה.
לידע כללי מה קורה מאחורי הקלעים ברגע שמריצים את - docker start, הוא לא יבצע שום דבר חדש, אלה ימשיך להריץ את הדבר האחרון שנתנו לו, פקודה, שירות תוכנה וכד', בעמודה "Command" ניתן לראות מה אנחנו מריצים, כאן נתתי לו סתם דוגמא שתרוץ בשביל שהוא לא יפסיק.
8. איך למחוק קונטיינר בדוקר?
מחיקת קונטיינר מתבצע בעזרת הפקודה docker rm continer_name, אבל אי אפשר סתם למחוק אותו,
כי אי אפשר סתם ככה למחוק קונטיינר, צריך קודם לעצור אותו ורק לאחר מכן למחוק אותו, אבל מאחר ואנחנו אנשי מחשוב ואני לא אוהב לבצע כל דבר 50 פעם, אנחנו נשלב שתי פקודות בתוך פקודה אחת בעזרת הסימן "&" אם אנחנו נכתוב את הסימן הזה פעמיים "&&", המשמעות של הסימן הזה בלינוקס, הוא "רק אם הצלחת להריץ את הפקודה הראשונה ולא התפוצץ המחשב והכל בסדר, תריץ את השניה", אז נריץ את הפקודה בצורה הזאת: docker stop test1 && docker rm test1
לא קיבלתי שום שגיאה, אלה פלט תקין:
ונבדוק מה רץ לנו עכשיו עם docker ps -a (אפשר גם בלי a-):
ניתן לראות שאין את test1 יותר (בעמודה מצד ימין).
9. איך למחוק Image בדוקר?
אז כפי שהסברנו בהתחלה, Image הוא מה שנבנה עליו הקונטיינר, לכן אי אפשר למחוק אותו ישר, ויש סדר פעולות שצריך לבצע. בעיקרון מחיקת ה Image מתבצעת בעזרת הפקודה docker rmi image_name
להלן סדר הפעולות שצריך לבצע בשביל למחוק את ה Image:
1) לעצור את הקונטיינר במידה והוא רץ, 2) למחוק את הקונטיינר, 3) למחוק את ה IMAGE, ניתן לבצע את זה בשלוש
פקודות שניתן להריץ אחת אחרי השניה:
1) לעצור את הקונטיינר - docker stop container_name
2) למחוק את הקונטיינר- docker rm container_name
3) למחוק את האימג' - docker rmi image_name
אבל זה המון מדי לכתוב ולכן אנחנו נאגד את כל זה לפקודה אחת ארוכה בעזרת הסימן שראינו בסעיף הקודם "&&"
במקרה שלנו, הפקודה הנ"ל לא תעזור כי כל עוד יש עוד קונטיינרים שמבוססים על Alpine, אני לא אוכל למחוק אותו. כאן ניתן לראות את זה בעמודה IMAGE שהם כולם "Alpine", לכן במקרה שלנו אני אצטרך להשתמש בפקודה מאוד מסוכנת, לעצור את הכל, למחוק את כל הקונטיינרים ואז אוכל למחוק את כל ה IMAGEים.
להשתמש בזה בזהירות !!!פקודה מסוכנת מאוד - לעצור את כל הקונטיינרים למחוק אותם ולמחוק את ה IMAGEים שלהם:
-- format - מציג את הפלט לפי תבנית מותאמת אישית (כמו ב־docker ps) - גם פה הסינטקס קצת קשה, אז הינה דוגמא:"docker images --format "{{.Repository}}:{{.Tag}} ({{.Size}})
--no-trunc - מציג את כל המזהים (image ID, command...) במלואם, בלי קיצורים
--quiet, -q - מציג רק את מזהי ה־image (IMAGE ID), בלי טבלה
11. איך להוריד Image של דוקר למחשב בלי להפעיל אותו?
הורדה של Image מתבצעת בעזרת הפקודה docker pull what_to_pull, מה שיקרה בפועל, זה שהמערכת פשוט תוריד להם אימג' הכי עדכני שיש למערכת שהציינתם למחשב וזהו, ורק אם תרצו לעשות איתו משהו תצטרכו להריץ אותו עם docker run כפי שלמדנו בסעיף על docker run.
תשימו לב לזה שכתוב "Latest" - המערכת משכה את הגירסה האחרונה שיש לאובונטו במאגר של דוקר, ורק שמרה לנו אותו במחשב בלי לעשות כלום.
שימו לב, נריץ את docker images ונקבל חמישה אימג'ים:
ורצים לנו 4 קונטיינרים:
11.א איך לבחור איזו גירסת Image להוריד?
בדוקר יש פרמטר שנקרא tag שהוא בעצם אחראי על להגיד למערכת, איזו גירסה אנחנו רוצים להוריד, ואנחנו עכשיו נשתמש בו בשביל להוריד 3 גרסאות שונות של Image, הסינטקס: docker pull image:tag:
כאן ניתן לראות את ההבדלים בין הגרסאות השונות של האימג'ים:
להלן פרמטרים של הפקודה:
-a, --all-tags - מושך את כל ה־tags (כל הגרסאות) של ה־image
--platform - מושך גרסה לארכיטקטורה מסוימת (למשל linux/amd64)
אהלן חברים, וברוכים הבאים לחלק הרביעי במדריך "דוקר למתחילים בעברית"!
בחלק הזה נמשיך להעמיק בעבודה עם קונטיינרים ואימג'ים – נלמד איך לראות אילו תהליכים רצים כרגע בתוך קונטיינר, איך לזהות אילו שינויים קרו לו, ואיך לשדרג או לשנות את ההגדרות שלו בלי למחוק אותו.
נתקדם גם ליכולות מתקדמות יותר כמו ייצוא וייבוא של קונטיינרים, העלאה של אימג'ים ל-Docker Hub, יצירת קיצורי דרך (Aliases) שיחסכו לכם זמן, בדיקת היסטוריית שכבות של אימג', שמירת אימג'ים כקבצים ניידים, טעינת אימג'ים מגיבוי, ושימוש חכם ב-Labels לניהול מידע.
בקיצור – שלב קריטי בדרך להפוך למשתמש Docker מקצועי באמת.
¿?רגע - לפני שאתם ממשיכים קראתם את שתי החלקים הראשונים!!!¿?
שימו לב !לפני שאתם ממשיכים לעבור על החלק הרביעי, תעברו על שלושת החלקים הראשונים כדי שתבינו על מה מדובר מאחר ובמקרה של דוקר, חשוב מאוד להבין את המושגים ומה בדיוק אנחנו עושים כי הדברים יכולים להיות מבלבלים.
ניתן לעבור על כל החלקים בעמוד המיועד לדוקר בבלוג: מדריך דוקר למתחילים בעברית - כל החלקים
1) איך לראות מה רץ בתוך קונטיינר ממש עכשיו? – docker top
2) איך לדעת אילו שינויים נעשו בקבצים בתוך הקונטיינר? – docker diff
3) איך משנים הגדרות של קונטיינר קיים בלי למחוק ולהריץ אותו מחדש? – docker update
4) איך מייצאים או מייבאים קונטיינר? – docker export ו־docker import
5) איך מעלים את ה Image שיצרנו ל־"Docker Hub" - הפקודה Docker Push
6) איך רואים את ההיסטוריה של כל שכבות ה־Image? - הפקודה docker history
7) איך שומרים Image כקובץ שאפשר להעביר או לגבות? – docker save
8) איך טוענים image תמונה מקובץ ששמרנו קודם? – docker load
9) איך משתמשים ב־Labels בתוך Docker – בשביל להוסיף מידע על קונטיינר, Image או רשת
1. איך לראות מה רץ בתוך קונטיינר ממש עכשיו? – docker top
לפעמים אנחנו לא זוכרים איזו פקודה בדיוק הרצנו בתוך קונטיינר, או שאנחנו רוצים לבדוק מה רץ שם עכשיו. בשביל זה יש את הפקודה docker top, שמציגה את התהליכים שפועלים כרגע בתוך הקונטיינר. למרות שזה נראה כאילו היא מריצה את הפקודה ps מתוך הקונטיינר, בעצם היא לא באמת עושה את זה – אלא מסתכלת מבחוץ (מהמחשב הראשי) ורואה אילו תהליכים שייכים לקונטיינר הזה. לכן הפלט בדרך כלל נראה אותו דבר בין קונטיינרים, גם אם הם מבוססים על מערכות שונות. אם בכל זאת רוצים לראות מה קורה "מבפנים", אפשר להשתמש ב־docker exec (עליו למדנו בחלק הקוד) ולהריץ את הפקודה ps מתוך הקונטיינר עצמו, בדוגמא כאן אבצע בדיקה על קונטיינר אחד שיש לי - leidertech_host_network_test:
docker top leidertech_host_network_test
2. איך לדעת אילו שינויים נעשו בקבצים בתוך הקונטיינר? – docker diff
קונטיינר הוא דבר "חי" ומתבצעים בו שינויים, ולא תמיד אנחנו זוכרים איזה שינויים ביצענו, בדיוק בשביל זה קיימת הפקודה docker diff, היא מראה קבצים שנוספו, קבצים שנמחקו, וקבצים שבוצע בהם שינוי על ידי סימון מיוחד, מיד נראה דוגמא ולאחר מכן אפרש את הסימונים: docker diff leidertech_host_network_test
הסימנים בתחילת השורה, אלו הסימנים שהזכרתי קודם - להלן הפרוש שלהם:
A - קובץ שנוסף (Added)
C - קובץ ששונה (Changed)
D - קובץ שנמחק (Deleted)
מעבר לזה, אין שום פרמטרים נוספים, במידה ולא בוצעו שינויים לא תקבלו שום תגובה מהמערכת, כפי שניתן לראות כאן:
3. איך משנים הגדרות של קונטיינר קיים בלי למחוק ולהריץ אותו מחדש? – docker update
בעזרת הפקודה docker update ניתן לבצע שינויים בקונטיינר ללא צורך בלעצור אותו.
להלן מה ניתן לשנות:
להגביל זכרון - דוגמא docker update --memory 512m my_container חשוב לזכור- במידה ובזמן יצירת הקונטיינר לא הגבלתם זכרון, צריך ליצור הגבלה של זכרון וגם הגבלה של זכרון swap (מה שבוינדוס נקרא Virtual Memory)
להגדיר את כמות Swap שהקונטיינר יכול להשתמש בה דוגמא : docker update --memory-swap 1g my_container
4. איך מייצאים או מייבאים קונטיינר? – docker export ו־docker import
4.א איך מייצאים קונטיים בדוקר? docker export
לפעמים נרצה לשתף קונטיינר, להעביר אותו למחשב אחר או פשוט לגבות אותו. בדיוק בשביל זה יש את הפקודה docker export, שמאפשרת לייצא קונטיינר לקובץ. הקובץ שנוצר הוא מסוג tar, שזה סוג הקבצים הדחוסים שיותר נפוץ בלינוקס (כמו zip או rar). ככה אפשר לשמור את הקונטיינר כקובץ אחד מסודר, ואחר כך לייבא אותו בקלות עם docker import.
לצורך הדוגמא נבצע יצוא של הקונטיינר לקבוץ בשם cont1 לתוך תיקייה בשם Containers על שולחן העבודה, יצוא מתבצע בעזרת הסימן "<" מאחר והיצוא הוא לתוך קובץ ניתן גם להשתמש ב "o-" (שזה Output), כמו שמייצאים נגיד פלט משורת פקודה: דוגמא עם הסימן של החץ -
לאחר מכן בעזרת הפקודה ls -l ~/Desktop/Containers אציג את התוכן של התיקייה בלי באמת לעבור אליה (טריק מגניב שלינוקס יודע לעשות - למדנו על זה במדריך של לינוקס למתחילים - פה: לינק)
וכפי שניתן לראות, באמת נוצר הקובץ.
4.ב איך לבצע יבוא לקונטיינר? docker import
לצורך התרגול, אני אמחק את הקונטיינר test1 ואז אבצע יבוא מהקובץ שייצרתי:
1. נעצור את הקונטיינר עם docker stop container_name
2. נמחק את הקונטיינר בשביל שנוכל לייבא אותו עם docker rm contianer_name
3. נבצע יבוא לקובץ שלנו מתוך התיקייה עם docker import path_to_file new_new_image_file
4. עכשיו לאחר שיצרנו IMAGE שממנו נוכל לבנות את הקונטיינר, נבנה אותו ונריץ אותו בעזרת הפקודה:
docker run -d --name restored_container restored_image
(החלק שהוספתי בסוף "tail -f /dev/null" הוא בשביל לגרום לקונטיינר להמשיך לרוץ ברקע ולא להכבות אתם לא חייבים להשתמש בו)
והינה כל השלבים ביחד:
נריץ את docker ps בשביל לבדוק שהקונטיינר באמת "חי":
וניתן לראות שהקונטיינר חזר עם השם החדש שנתנו לו.
5. איך מעלים את ה Image שיצרנו ל־"Docker Hub" - הפקודה Docker Push
במידה ואנחנו רוצים להעלות את ה-Image שלנו ל DOCKER HUB או לכל ריפוסיטורי אחר, למטרה של שיתוף עם אנשים אחרים, קולגות או סתם לפרסם את ה IMAGE שלנו בעולם, נשתמש ב docker push בשביל להעלות את מה שיצרנו לאינטרנט, במקרה הזה ל Docker Hub.
חשוב לזכור - בשביל שזה יעבוד, אתם צריכים ליצור חשבון ב Docker Hub -זה בחינם. יצירת חשבון מתבצע באתר הרשמי של Docker בכתובת הזאת: לינק
לאחר מכן בשורת הפקודה נכתוב את הפקודה docker login בשביל לבצע כניסה לחשבון שלנו.
נקבל הודעה כזאת של התחברות דרך דפדפן אינטרנט:
אם אתם לא עובדים בצורה שבה אני עובד, אתם יכולים ללחוץ על הקישור והוא יעבוד לכם בלי בעיה, במידה ואתם מחוברים עם שורת פקודה כמוני, בצעו את הפקודה הבאה: docker login -u your_dockerhub_username
ניתן להקליד את הסיסמא שלכם בלי בעיה - היא לא תופיע על מסך, במידה ועשיתם הכל נכון, תקבלו הודעה שהחיבור הצליח:
עכשיו החלק המעניין, להעלות את מה שאנחנו רוצים לדוקר האב עצמו, אז בעצם השלבים הם די פשוטים:
בוחרים את האימג' שאנחנו רוצים:
"מתייגים" אותו עם גירסה מתאימה, כותבים לו את השם של החשבון שלנו ב Docker Hub.
מעלים את האימג'
בודקים שהאימג' הגיע בשלום ליעד שלו (לך תדע אולי עשו לו בעיות בביקורת גבולות - רשעים ארורים !)
שלב ראשון - נבחר איזה אימג' אנחנו רוצים להעלות, קודם אבדוק מה יש לי עם docker images:
אני אבחר דווקא את האימג' השמנמן ביותר זה שנקרא nginx.
שלב שני - נצטרך להגדיר לו את כל הפרמטרים האלה בפקודה אחת - לפי הדוגמא הזאת:
docker tag original-image-namedockerhub-username/new-image-name:tag
גירסה - ניתן להעלות את אותו האימג' עם כמה גירסאות שונות - זה טוב בשביל לשמור על סדר
לאיזה חשבון האימג' יעלה
מה שמו של האימג' שיהיה ברגע שיגיע ל Docker hub
במקרה שלי זה יראה כך: docker tag nginx leidertech/nginx-custom:latest:
והשלב השלישי - להעלות את האימג' ל Docker Hub הפקודה: docker push leidertech/nginx-custom:latest
ועכשיו נבדוק אצלי בחשבון שבעצם האימג' נמצא אצלי בחשבון:
נגיד ועשיתי שינוי לאותו אימג' ואני רוצה לתת לו עכשיו גריסה שונה, אז אני אכתוב את אותה הפקודה אבל את הסוף זאת אומרת את ה TAG אשנה : docker tag nginx leidertech/nginx-custom:leidertec_test
נלך ל Docker Hub ונוכל לראות כאן את שתי האימג'ים שהעלנו:
6.איך רואים את ההיסטוריה של כל שכבות ה־Image? - הפקודה docker history
מאחר וכל IMAGE בנוי משכבות (קבצים, הגדרות, ספריות, תוכנות וכד'), לפעמים נרצה לדעת איך האימג' נבנה – בשביל לקבל "תמונת מצב" יותר טובה: באיזה שלב נוספו הקבצים, איזו פקודה יצרה כל שכבה, וכמה מקום היא תופסת. בדיוק בשביל זה נשתמש ב־docker history, שמראה לנו את ההיסטוריה של כל שכבה ושכבה בתוך האימג'. בקיצור – אנחנו רואים את הפעולות שהריץ מי שבנה את האימג', שלב אחר שלב.
פרוש של העמודות:
Image – מזהה של השכבה (Layer ID). אם מופיע במקום זה missing, זה פשוט אומר ש־Docker לא שומר את המידע הזה אצלך במחשב – לרוב כי השכבה הגיעה ממקום חיצוני או שהיא חלק מהבסיס של האימג'. זה לגמרי תקין ואין מה לדאוג מזה.
CREATED – מתי השכבה נוצרה (למשל: 9 days ago)
CREATED BY – איזו פקודה יצרה את השכבה (למשל: RUN, COPY, ENV)
מטא-דאטה (Meta data) - מה-Dockerfile (אנחנו נלמד מה זה DOCKER FILE בחלקים הבאים):
CMD – מה מורץ כברירת מחדל.
ENTRYPOINT – הפקודה הראשית.
ENV – משתני סביבה.
EXPOSE – פורטים פתוחים.
VOLUME – נקודות אחסון.
WORKDIR – תיקיית העבודה.
LABEL – תוויות מידע (כמו יוצר ה-image).
USER – המשתמש שבו יופעל הקונטיינר.
SHELL – אם הוגדר shell אחר (למשל [ "bash", "-c" ]).
config.json – הגדרות כלליות של ה-image.
repositories file – משייך את התגיות ל־image ID.
הסינטקס של הפקודה עם נתיב:
docker save -o full-path-to-output-file.tarimage-name:tag
במידה ולא תרשמו את הפרמטר -o (שזה Output), הקובץ לא יישמר – אלא סתם תודפס לכם שגיאה. לכן צריך לכתוב נתיב. במידה ולא תרשמו נתיב, ובעצם תכתבו את הפקודה בצורה הזאת:
docker save -o myimage.tar leidertech/nginx-custom:latest
מה שיקרה, הוא שהקובץ ישמר בתיקייה שאתם נמצאים בה כרגע, לכן עדיף תמיד לכתוב את כל הנתיב - כפי שתראו בדוגמא.
במקרה שלי, אני אשמור Image תיקייה שיצרתי על שולחן העבודה בשם Docker_images:
docker save -o /home/lev/Desktop/Docker_images/leidertech_saved_image.tar leidertech/nginx-custom:latest
בעצם לא קיבלנו שום שגיאה, סימן שהכל עבר תקין, עכשיו נבדוק בתיקייה:
8. איך טוענים מחדש Image מקובץ ששמרנו קודם? – docker load
אחרי שבסעיף הקודם שמרנו את ה Image לקובץ והעברנו את הקובץ למחשב אחר לדוגמא, נרצה לטעון אותו חזרה, בדיוק למטרה הזאת יש את הפקודה Docker Load שבעצם טוענת (עושה סוג של יבוא לקובץ) את ה Image לתוך המערכת שלנו, בפקודה הזאת יש רק שתי פרמטרים, אחד הוא "i-" (שזה בעצם "input"), שבעצם מאפשר להגיד את הנתיב המלא שבו נמצא הקובץ, במידה ולא תציינו את הנתיב של הקובץ, המערכת תתחיל לחפש אותו בתיקייה שבה אתם נמצאים, הפרמטר השני הוא פרמטר "q-" (שזה בעצם "Quite") במקום לכתוב לכם המון המון פלט ומידע, הוא יעשה את זה עם פחות פלט.
הינה דוגמא לפרמטר i-:
docker load -i [path/to/your/file.tar]
ובעצם דוגמא לפרמטר השני:
docker load -i [path/to/your/file.tar] --quiet
כעת ניתן שתי דוגמאות, בראשונה אכתוב את הפקודה בלי לרשום את הנתיב ובשניה כן ארשום את הנתיב:
הפקודה עצמה ללא הנתיב:
docker load -i leidertech_saved_image.tar
בעזרת docker images נבדוק אילו אימג'ים יש לי כרגע במערכת:
ועכשיו נוכל לראות את ההבדל, וניתן לראות שיש שתי אימג'ים שהם אותו דבר:
נשאלת השאלה, מה יקרה במידה ואני טוען Image שכבר קיים במערכת?
במצב הזה, דוקר בודק את ה-Image ID ואת השם (Repository ו-Tag):
אם ה-Image ID והשם (כולל ה-TAG) זהים – דוקר לא טוען מחדש את הקובץ.
אם ה-Image ID זהה, אבל ה-TAG שונה – דוקר יוסיף TAG חדש ל-Image הקיים.
בשביל שזה יהיה ברור יותר:
ID וה-TAG זהים → דוקר מתעלם מהטעינה (כבר קיים).
ID זהה, TAG אחר → דוקר מוסיף עוד שם (עוד תגית) ל-Image.
9. איך משתמשים ב־Labels בתוך Docker – בשביל להוסיף מידע על קונטיינר, Image או רשת
נתחיל מהשאלה העיקרית – מה זה בכלל LABEL ולמה אנחנו צריכים אותו?
"Label" הוא מין תגית קטנה שאפשר להוסיף ל-Image, קונטיינר או רשת, כדי לשמור עליה מידע נוסף.
למשל: מי יצר את ה-Image, מתי הוא נוצר, ומי בכלל צריך אותו?
בקיצור – זה בשביל הידע הכללי שלנו. כי אם יש לכם 500 Images, אני בספק שבעוד חודשיים תזכרו מי מהם שייך למה.
להלן כמה דוגמאות:
הוספת Label ל-Image בזמן בנייה (אנחנו נלמד על BUILD בחלק הבא) docker build --label author="Lev Leider" -t myimage .
הוספת Label לקונטיינר בזמן הרצה: docker run --label project="family_reminder_app" -d nginx