הגדרת CI/CD למיקרו-שירותים: צינורות עצמאיים

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

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

שאלות נפוצות

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

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

צינורות CI/CD בלתי תלויים: היכן נשברת הבנייה המשותפת

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

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

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

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

מה נותן פיצול הבנייה: מהירות, בידוד, יכולת חיזוי

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

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

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

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

ב-GitLab CI זה מתבטא בכללי הפעלה לפי נתיבים ובסביבות נפרדות לכל שירות; אותה מודל ניתן לשחזר בכל כלי בנייה בוגר.

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

דרכים לארגון צינורות: השוואת אפשרויות

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

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

אפשרות מתי מתאימה מגבלות הגישה
צינור משותף 3-5 שירותים עם סטאק אחיד וקצב שחרורים משותף תיקון של שלב אחד נוגע בכל השירותים; כשל בנייה חוסם את האחרים
צינור תבניתי עם ירושה עשרות שירותים, תקן בדיקות אחיד וטריגרים שונים תאימות לאחור של התבנית: שינוי שובר בשלב דורש הגירה של כל היורשים
צינור נפרד לכל שירות צוותים אוטונומיים, סטאקים שונים, שחרור בלתי תלוי כפילות תיאורי שלבים; פער בגרסאות בדיקות בין השירותים
מונורפו עם סינון שירותים מושפעים שירותים רבים במאגר אחד, תיקונים משותפים תכופים נדרש ניתוח מדויק של גרף תלויות: טעות נותנת שחרור שהוחמץ או בניות מיותרות

מה לבדוק לפני הבחירה

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

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

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

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

מה נשאר במאגר: תצורות, סכמות, תקנונים

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

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

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

מקרה בוחן: כיצד צינורות נפרדים האיצו שחרורים פי 8

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

מה הראו המדדים לפני

ריצה מלאה נמשכה כ-48 דקות, ואם לפניו עמדו בניות של אחרים — ההמתנה נמתחה עד 3-4 שעות. חלון השחרור נפתח פעם בשבועיים, ותיקון דחוף חיכה לו יחד עם האחרים. שיעור השחרורים המוצלחים עמד על 62%: בדיקה שבורה אחת בכל שירות חסמה את כל החבילה, ולכן החזירו את השחרור לאחור כולו.

מה שינו

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

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

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

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

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

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

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

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

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

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

ספקות טכניים נפוצים לגבי בניות נפרדות

צינורות CI/CD בלתי תלויים מעלים אצל לקוחות אותן שאלות הנדסיות — לא "האם תוכלו", אלא על ההתנהגות במאגר הקוד שלהם ובצוות שלהם.

מה לעשות עם ספריות משותפות שכמעט כל השירותים תלויים בהן?

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

האם נדרש מתקן בדיקות נפרד לכל שירות?

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

הגדרות הבנייה לא יתפצלו בין השירותים?

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

מה עם תמיכה לאחר המסירה?

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

נדון במשימה: ננתח צינורות ונחזור עם תוכנית

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

מה יידרש מכם להתחלה:

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

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