פיתוח Helm charts לפריסה ב-Kubernetes: איפה זה נשבר
כל עוד אין Helm charts, הפריסה ב-Kubernetes נשענת על מניפסטים ידניים ועל הזיכרון של מהנדס אחד. מישהו זוכר שבסביבת הבדיקות התמונה מתויגת אחרת, ובסביבת הייצור צריך סט נפרד של משתני סביבה.
התיקונים מבוצעים באמצעות kubectl apply ישירות לאשכול, תוך עקיפת המאגר, — ובמאגר נשאר לא מה שבאמת עובד.
לאחר מכן הסביבות מתפצלות. ההבדל בין סביבת הבדיקות לסביבת הייצור מצטבר בפרטים קטנים: מגבלות משאבים, מספר עותקים (replicas), כתובות של שירותים חיצוניים, בדיקות מוכנות מופעלות, סדר יישום של ConfigMap ו-Secret.
כעבור כמה שבועות אף אחד לא יכול להסביר בבירור במה שונה האשכול החי מזה המתואר בקבצים, והעברת כל שינוי הופכת למשימה נפרדת עם סקירה ידנית.
היקר מכל הוא החזרה לאחור של מהדורה (release). פקודת החזרה לאחור מחזירה רק את מה ש-Helm זוכר במצבו, — תיקונים ידניים לאחר ההתקנה נשארים באשכול וממשיכים לשבור את ההתנהגות.
את האירוע (incident) מנתחים ידנית: משווים את ההיסטוריה של המניפסטים שהוחלו, אירועי האשכול ולוגים של פודים, כדי להבין איזה שינוי בדיוק גרם לתקלה.
התוצאה צפויה: הפריסה (deployment) אורכת שעות, התוצאה תלויה במי שתורן, והשחזור של הגרסה הקודמת הוא לא פקודה אחת, אלא חקירה. נסביר כיצד זה נסגר: מה מתארים ב-charts, כיצד מפרידים ערכים לפי סביבות, ובזכות מה החזרה לאחור של מהדורה הופכת לרפרודוקטיבית.
מה משתנה לאחר המעבר לפריסה דקלרטיבית
לאחר המעבר לפריסה דקלרטיבית, מצב האפליקציה מתואר בקבצי ערכים (values), ולא ברצף של פעולות ידניות. האשכול מיושר למצב המתואר בפקודה אחת — ומשתנים מדדים מדידים: זמן הפריסה, חלון זמן ההשבתה (downtime), שיעור האירועים בגלל אי-התאמות בין הסביבות.
זמן הפריסה מתקצר: התבניות (templates) מכווננות, ורק הפרמטרים משתנים. החזרה לאחור מפסיקה להיות פעולת שחזור נפרדת — המהדורה הקודמת נשמרת рядом, והחזרה אליה אורכת אותו זמן כמו פריסה רגילה, במקום הרכבה ידנית מחדש של מניפסטים.
נעלם סוג שלם של כשלים — אי-התאמה בין סביבות. סט אחד של תבניות וקבצי ערכים נפרדים עבור סביבת הבדיקות וסביבת הייצור אומרים שההבדלים מתוארים במפורש במאגר, ולא נשמרים בראש של המהנדס שתיקן את האשכול ידנית.
זמן ההשבתה של השירות הופך לצפוי. בדיקות מוכנות לא מכניסות תעבורה לקונטיינר לא מחומם, מדיניות העדכון קובעת כמה עותקים מוצאים מכלל פעולה בו-זמנית, ומשימות קדם-התקנה מסתיימות לפני תחילת הפריסה.
עבור שירותים חסרי מצב, חלון ההשבתה מצטמצם לאפס, ועבור מאגרי נתונים הוא מחושב מראש ונבדק בסביבת הבדיקות.
יכולת השחזור של הסביבות מפסיקה להיות תלויה במי ומתי הקים את הסביבה: אותו chart פורש סביבה חדשה בצורה זהה. מכאן גם רשימת אפקטים קצרה — זמן פריסה והחזרה לאחור מהיר, היעדר אי-התאמות בין סביבות, חלון השבתה ידוע, וקונפיגורציה חוזרת בכל פריסה.
אפשרויות לארגון מהדורות: השוואת גישות
הגישה לפריסה כמעט תמיד צומחת מהפתרון העובד הראשון — וזה ניכר במגבלות שמצטברות לאחר מכן. להלן ארבע אפשרויות, שביניהן צוותים באמת בוחרים כאשר מספר האפליקציות גדול מאשכול אחד, ומספר הסביבות גדול מאחת.
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| מניפסטים ידניים ו-apply ידני | שירות אחד, אשכול אחד, מהנדס אחד | המצב הרצוי לא מתועד בשום מקום: סביבות מתפצלות, החזרה לאחור — תיקון ידני |
| סקריפטים עצמאיים לפריסה | צריך להציב משתני סביבה בקבצים מוכנים | הסקריפט מתאר תהליך, לא תוצאה, ומצטבר חריגים לכל שירות |
| chart אחד לאפליקציה, values נפרדים לפי סביבות | מספר סביבות, מהדורות תכופות של מוצר אחד | דורש משמעת ב-values: תנאים מורכבים בתבניות מניפסטים נקראים בקושי |
| chart עם תלויות ו-charts ספרייה משותפים | מספר צוותים, משאבים משותפים, כללים אחידים | יש לתעד גרסאות של תלויות ולעקוב אחרי התאמתן |
בפועל, לעיתים רחוקות אנחנו מתחילים charts 'מאפס': קודם כל תבניות מניפסטים מתארות את מה שכבר נפרס ידנית, כדי שהמצב הרצוי יתאים למצב בפועל. לאחר מכן חלקים משותפים — מדיניות רשת, סודות, תורים — מוצאים לתלויות של charts, והאפליקציה מפסיקה לשכפל קבצים של אחרים.
סקריפטים עצמאיים לפריסה בדרך כלל נעלמים אחרונים: אותם מחליף chart עם בדיקות helm lint ו-dry-run לפני היישום. זה נותן החזרה לאחור צפויה למהדורה הקודמת ותוצאה זהה בכל הסביבות.
שלבי העבודה: מביקורת מניפסטים ועד מסירה
את העבודה מנהלים באיטרציות: כל שלב מסתיים בארטיפקט שניתן לבדוק, והשלב הבא מתחיל רק לאחר שהקודם אושר. כך שגיאה בסכמת המהדורה לא צפה כבר בפרודקשן, כשמחירה — השבתת השירות.
- ספירת מלאי של שירותים וביקורת מניפסטים. אוספים את כל מה שפרוס באשכול, כולל מה שהותקן ידנית. מפרידים אובייקטים למשותפים לכל השירותים ולייחודיים, מתעדים כפילויות וערכים 'שזזו' בסביבות נפרדות — זו המפה של התבנית העתידית.
- תכנון סכמת המהדורה. מחליטים היכן יהיה chart מטרייה אחד, והיכן עצמאיים, מה חי בתור תלות, כיצד ערכים עוברים בירושה לפי סביבות. מתאמים שמות משאבים, כך שמהדורה של שירות אחד לא תמחק את זה של השכן.
- הגדרת תבניות. מוציאים את החוזר על עצמו לפרגמנטים משותפים, מתארים סכמת ערכים עם בדיקת תקינותם לפני היישום. הערות עם סכומי בקרה של קונפיגורציות סוגרות מצב שבו האפליקציה ממשיכה לעבוד על הגדרות ישנות לאחר עדכון.
- בדיקת החזרה לאחור. לומדים לחזור לאחור במודע: מסתכלים על היסטוריית המהדורות, מצב המיגרציות וה-hooks, מבינים מה בדיוק יחזור לאחור יחד עם האפליקציה, ומה יישאר. אם שלב לא חוזר — משנים את הסכמה, ולא כותבים הוראה.
- הרצה בסביבת בדיקות. מריצים מחזור מלא 'התקנה — עדכון — החזרה לאחור' בסביבת בדיקות הקרובה לייצור בהרכב המשאבים. המהדורה נחשבת אטומית: כאשר בדיקת מוכנות נכשלת, הסכמה חוזרת למהדורה הקודמת בעצמה.
- מסירת תיעוד. מוסרים תיאור של ה-charts, סכמת ערכים עם הסברים, סדר המהדורה והחזרה לאחור, כללי ניהול גרסאות. התיעוד חי במאגר לצד התבניות, ולא כקובץ נפרד.
- הדרכת צוות וליווי מהדורות ראשונות. עוברים עם המהנדסים שלכם את המהדורה הראשונה, מנתחים ניתוח של הרצות כושלות ותיקוני ערכים. לאחר מכן הצוות מנהל את המהדורות בעצמו — לנו נשארות התייעצויות לגבי הסכמה.
מארז אספקה: charts, סכמות ותקנות
מארז האספקה אינו ארכיון עם תבניות, אלא מערכת עבודה שבה הלקוח יכול להוציא מהדורות ללא השתתפותנו. אנו מוסרים את כל הדרוש לבנייה, בדיקה ופריסה: ממבנה המאגר ועד הוראות למשמרת התורנית.
- מאגר charts עם היסטוריית שינויים: מקור אמת אחד לכל הסביבות, הסתעפות למהדורות וסקירת תיקונים דרך בקשות merge.
- פרמטריזציה של סביבות: סביבת הבדיקות וסביבת הייצור נבדלות רק בקובץ ערכים, ולא בהעתקת תבניות — אי-ההתאמה בין הסביבות מפסיקה להצטבר.
- סכמות תלויות: אילו charts קשורים זה לזה, מה נמשך ממאגר משותף, היכן שירותים חיצוניים וסדר הופעתם.
- מדיניות גישה: מי עורך את ערכי סביבת הייצור, למי יש רק קריאה, כיצד מופרדות התפקידים באשכול ומי מאשר שינויים.
- תקנון מהדורה: רצף הפריסה, בדיקות חובה לפני פרסום, קריטריונים לעצירת הוצאה.
- תקנון החזרה לאחור: חזרה למהדורה הקודמת בפקודה אחת, מה קורה לנתונים ולמיגרציות, תוך כמה זמן הסביבה חוזרת למצב עבודה.
- תיעוד פריסה והוראות למשמרת תורנית: כשלים אופייניים, אבחון, למי להסלים, מה מותר ואסור לעשות ידנית.
כל סעיף מתואם עם צוות הלקוח בקבלה, ולא נמסר 'בתיקייה'. המהנדסים של הלקוח עוברים ניתוח של קונפיגורציות והרצת ניסיון בעצמם — לאחר מכן המארז נחשב כמאושר.
מקרה בוחן: מחזור המהדורה ב-Helm התקצר מיומיים לשעה
נקודת התחלה
שירות של שנים-עשר רכיבים — API, עובדים, משימות מתוכננות, מיגרציות סכמה — נפרס כמערכת של מניפסטים ידניים, משוכפלים בארבע סביבות. תיקונים בספרייה אחת לא הגיעו לאחרות: אי-ההתאמות הצטברו, והמהדורה הפכה לריטואל של יומיים עם השוואת קבצים ידנית.
החזרה לאחור ארכה לא פחות מארבעים דקות ובוצעה על ידי החלה הפוכה של אותם מניפסטים — כלומר כל מצב חירום נשא בחובו סיכון לשגיאה חדשה.
מה שינינו ומה קיבלנו
הרכבנו charts פרמטריים Helm: chart ספרייה עם תבניות ל-deployment, service, ingress, בדיקות מוכנות וסקיילינג אוטומטי, ומעליהן — charts דקים של שירותים, שבהם בקובץ הערכים נשארים רק image, מגבלות ומשתני סביבה. ההבדלים בין הסביבות מתוארים בסטים נפרדים של ערכים, סודות מגיעים ממאגר חיצוני ולא נכנסים למאגר.
לפני היישום, התבניות עוברות רינדור ומושוות למצב הנוכחי של המהדורה, לכן שגיאת קונפיגורציה נתפסת לפני הפרודקשן. המהדורה — פקודת יישום אחת ועד שעה ממיזוג התיקון ועד סביבה עובדת יחד עם הרצת בדיקות; השלבים הידניים הפכו לשניים במקום שלושים. החזרה לאחור — דקות: חזרה למהדורה הקודמת כולה, ולא הרכבה מחדש של סט קבצים.
נעלם סוג שלם של כשלים הקשור לאי-התאמה בין סביבות: הקונפיגורציה מתוארת על ידי מקור אחד, וההבדלים בין הסביבות נראים לעין לפני היישום.
מה לעשות אם באשכול כבר פרוסים מניפסטים ידניים
אין דרך נכונה אחת: הבחירה תלויה במספר השירותים על מניפסטים ידניים ובתדירות התיקונים שלהם. העיקרון הכללי — לא לבנות מחדש סביבה עובדת, אלא להתאים אותה ל-charts כך שהשירותים לא ייווצרו מחדש ולא יאבדו מצב.
לכן הצעד הראשון הוא ספירת מלאי: אילו אובייקטים נוצרו ידנית, מי שינה אותם ובמה הפרמטרים בפועל שונים מהקבצים המקוריים.
| אסטרטגיית מעבר | מתי מתאימה | מגבלות |
|---|---|---|
| עטיפה ללא העברה | שירותים יציבים ללא תיקונים תכופים | נשאר דריפט של קונפיגורציות, אין תבנית אחידה |
| העברה הדרגתית לפי שירותים | מוצר חי עם מהדורות סדירות | בתקופת המעבר שני מקורות אמת |
| העברה מלאה | סביבה קטנה או סטנד, השבתה מותרת | חלון השבתה, סיכון לאבד ניואנסים של מניפסטים |
העברה הדרגתית היא האפשרות הנפוצה ביותר עבור סביבת ייצור. מתארים את ה-chart כך ששמות האובייקטים, תוויות הסלקטורים וה-namespace יתאימו לקיימים: אז המערכת מקבלת משאבים קיימים לניהול, ולא מוחקת ויוצרת אותם מחדש.
המהדורה הראשונה נאספת מערכים שמשחזרים את הפרמטרים בפועל, ורק אחר כך הגדרות משותפות עוברות לתבניות ולתת-charts.
תאימות לאחור נבדקת לפני היישום: השוואה של מניפסטים מרונדרים למצב הנוכחי של האשכול והרצת ניסיון מראות מה בדיוק ישתנה. בנפרד מתעדים אילו שדות אי אפשר לעדכן באובייקט חי, — אותם מתקנים בחלון תחזוקה, ולא באופן עיוור במהלך המהדורה.
אסטרטגיית המעבר מעוגנת ב-chart עצמו ובסדר המהדורות: כל עוד לא הועברו כל השירותים, מניפסטים ידניים מסומנים כמוקפאים, והתיקונים עוברים רק דרך המאגר. זה מסיר את הדריפט של קונפיגורציות ומאפשר החזרה לאחור של כל שירות למהדורה הקודמת.
ספקות טכניים: שאלות על charts וסביבות
מהנדסים ממעטים להטיל ספק ב-Helm עצמו — השאלות בדרך כלל נוגעות לפרטים: כיצד סודות מגיעים לסביבות, מה קורה לפודים במהלך העדכון ומה יישאר במאגר לאחר המסירה. להלן תשובות קצרות לכל אחד מהנושאים הללו.
כיצד סודות ופרמטרים של סביבות מופצים בין הסביבות?
ערכי סודות אינם נשמרים ב-chart — הוא מפנה למקור חיצוני, והנתונים עצמם מגיעים ממערכת ניהול סודות. ההבדלים בין הסביבות מתוארים בסטים נפרדים של פרמטרים: סביבת הבדיקות דורסת תלויות ומשאבים, וסביבת הייצור — מספר עותקים, מגבלות וכתובות של שירותים חיצוניים. chart אחד משרת את כל הסביבות, ובמקביל אין לאף אחד גישה לאשכול הייצור ממחשבים מקומיים.
האם העדכון יעבור ללא השבתה וכיצד לחזור לאחור?
הפריסה מתבצעת באסטרטגיית עדכון הדרגתי: עותקים חדשים עוברים בדיקת מוכנות לפני שה�ישנים מוסרים, וחלון אי-הזמינות מוגבל ב-Pod Disruption Budget. מיגרציות סכמה הועברו ל-hooks ומבוצעות לפני או אחרי המהדורה, לכן מסד הנתונים לא נשבר באמצע. כל מהדורה נשמרת כמהדורה נפרדת — החזרה לאחור היא חזרה לגרסה הקודמת, ולא תיקון ידני של מניפסטים.
כיצד נבדקות התבניות ומה עם התמיכה לאחר המסירה?
רינדור תבניות ובדיקת סכמת ערכים מורצים באופן מקומי ובבנייה, והתוצאה מושווית למצב הנוכחי של האשכול — ניתן לראות מה בדיוק ישתנה לפני היישום. שגיאות צפות בענף, ולא בסביבת הייצור.
לאחר המסירה נשאר מאגר עם charts, סטים של ערכים לפי סביבות, בדיקות ותיאור תהליך המהדורה; לתקופה מוסכמת אנחנו מלווים, והלאה את השינויים מוציא הצוות שלכם.
נדון במשימה: נבנה סכמת פריסה לאשכול שלכם
ההכנה להתחלה מתחילה בספירת מלאי של שירותים, ולא בכתיבת charts: כל עוד לא רואים את הרכב האפליקציות והתלויות שלהן, כל הערכת היקף תהיה משוערת. כדי לדון במשימה באופן ענייני, נבקש מינימום נתוני קלט — בדרך כלל מספיקות שיחה אחת וגישה למאגרים.
- רשימת שירותים, התלויות שלהם ומה שכרגע נפרס באשכול ידנית;
- סביבות יעד: כמה הן, במה נבדלות, כיצד ערכים נדרסים ביניהן;
- דרישות לחזרה לאחור ולסדר העדכון — מה מותר להפעיל מחדש ומה אסור;
- סודות וקונפיגורציות: מאיפה מגיעים, מי הבעלים, כיצד נכנסים לאשכול;
- אסטרטגיית תיוג של image, כך שניתן יהיה לשחזר ולחזור לאחור כל גרסה;
- מגבלות האשכול: מכסות, מדיניות רשת, אחסון, תפקידים והרשאות גישה;
- נקודות בקרה — מי מאשר את המהדורה ולפי אילו סימנים מחשיב אותה כמוצלחת.
בתגובה נחזיר הערכת היקף, תוכנית עבודה לפי שלבים וסכמת פריסה: מבנה של Helm-charts, חלוקת ערכים לפי סביבות, סדר מיגרציות והחזרה לאחור. לאחר מכן נתקדם לפי התוכנית ונציג תוצאה כבר בסביבה הראשונה, עוד לפני סיום העבודה.
תארו את המשימה שלכם — נחזור עם הערכה ותוכנית.







