אופטימיזציה של תמונות Docker: מקטינים את הגודל ומאיצים את הפריסה

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

היכולות שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1331
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    784
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

אופטימיזציה של תמונות Docker: היכן התשתית מאבדת זמן

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

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

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

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

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

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

מה משתנה לאחר עיבוד הבנייה: מהירות ויציבות

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

גודל התמונה ומהירות ההורדה

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

הארטיפקט קטן פי כמה, ההורדה לכל נוד וההכנה להרצה לוקחות פחות זמן — האצת הפריסה מורגשת כבר בריליס הראשון.

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

סוג הכשלים בגלל פערי סביבות נעלם

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

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

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

השוואת גישות לבניית תמונות: מה ומתי מתאים

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

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

קריטריונים לבחירה

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

מצב היברידי

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

סדר העבודות: מאודיט הבנייה ועד מסירת נהלים

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

תכנון

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

בנייה, בדיקה, מסירה

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

קונפיגורציות, סכמות ונהלים: מה מוסרים לצוות

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

קונפיגורציה וסכמת בנייה

  • Dockerfile רב-שלבי עם הפרדה בין בנייה לזמן ריצה: לתמונה הסופית נכנסים רק ארטיפקטים ותלויות זמן ריצה.
  • .dockerignore וסדר הוראות שבו שכבות שמשתנות לעתים רחוקות נשמרות במטמון, ותיקון קוד לא גורר בנייה מחדש של תלויות.
  • קונפיגורציית בנייה בצינור: פרמטרים של הבילדר, תיוג לפי קומיט ותג סביבה, בדיקת התמונה לחולשות לפני פרסום.
  • סכמת בנייה ואספקה — דיאגרמה «קומיט → בנייה → בדיקות → רישום → סביבה» עם נקודות rollback מסומנות.
  • תמונות בסיס: המשפחה הנבחרת, שיטת הצמדת גרסה לפי digest וסדר ההחלפה.

רישום, תיעוד ונהלים

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

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

קייס: איך עיבוד מחדש של הבנייה שינה מדדי תפעול

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

מדדי פתיחה

  • בנייה מלאה — 14 דקות, מהן 9 להתקנת תלויות מחדש.
  • שיעור בניות מוצלחות — 6 מתוך 10: הצינור נפל על הורדת חבילות ועל חוסר משאבים.
  • זמן rollback — כ-40 דקות, כי התמונה הקודמת נבנתה מחדש, והתג נדרס.
  • השבתה באירוע — עד שעה, עד שהארטיפקט החדש עבר בדיקות.

תוצאת היישום

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

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

מה לעשות אם הבנייה כבר רצה במעגל עבודה?

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

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

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

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

שאלות טכניות נפוצות על עיבוד מחדש של הבנייה

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

איך בנייה חיה במעגל סגור בלי מראות חיצוניות?

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

האם נצטרך לשנות את קוד האפליקציה?

ברוב המקרים התיקונים מוגבלים לקובץ הבנייה ולסדר השכבות — הלוגיקה של האפליקציה לא נפגעת. הקוד משתנה רק במקומות שבהם תימצא תלות מיותרת או ארטיפקט כבד שאפשר להוציא מהתמונה הסופית.

מה קורה עם rollback לריליס קודם?

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

כמה יקטן גודל התמונה וזמן הבנייה?

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

מי מתחזק את הבנייה לאחר המסירה?

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

בואו נדבר על המשימה: נשלח הערכה ותוכנית עבודה

כדי שההערכה תהיה עניינית ולא «על העין», אנחנו צריכים מינימום נתוני מקור על הבנייה שלכם. אנחנו מסתכלים על Dockerfile והשכבות, המטמון, תמונות הבסיס, הרישום והפייפליין, ואחר כך חוזרים עם תוכנית יישום ולוחות זמנים — לפי שלבים, עם נקודות rollback. להלן מה שמאיץ את הבדיקה; ייתכן שמשהו חסר, וחלק נשלים בשיחה.

  • סכמת הבנייה הנוכחית: Dockerfile (או כמה), סדר השכבות, בנייה multi-stage, איך בנוי המטמון ומה מבטל אותו כרגע.
  • מגבלות המעגל: היכן נשמרות התמונות, האם יש רישום פרטי, דרישות אבטחה וחתימה, מגבלות גודל ארטיפקט, זמינות תמונות בסיס חיצוניות.
  • דרישות לזמני פריסה: זמן בנייה ופריסה נוכחי, מה נחשב סביר, עד כמה קריטי cold start וזמן rollback לריליס קודם.
  • תפקידים והרשאות: מי הבעלים של הפייפליין, מי מאשר שינויים בתמונות בסיס ובמדיניות הרישום, למי מוסרים את התוצאה.
  • אפקט מצופה: מה חשוב יותר — לקצר את גודל התמונות, להאיץ בנייה בזכות מטמון או להפחית סיכוני חולשות; איך מתכננים למדוד זאת.
  • מגבלות סביבה: ארכיטקטורות (amd64/arm64), מערכת הפעלה, אורקסטרטור, מצב הרצה, דרישות לאי-פגיעה בפרודקשן.
  • מה כבר ניסיתם ולמה לא עבד — זה חוסך לנו שלב של השערות.

כתבו בשתי מילים מה המשימה שלכם ומה מהרשימה נמצא בהישג יד — נחזור עם הערכה, תוכנית יישום ולוחות זמנים לפי שלבים.