פריסת קנארי ב-Kubernetes: פריסה בטוחה עם Argo Rollouts

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

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

שאלות נפוצות

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

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

Canary deployment: היכן נשברת הפריסה לפרודקשן

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

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

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

אנחנו מפרקים איך זה נסגר. פריסה קנרית (canary deployment) באמצעות Argo Rollouts מעבירה לגרסה החדשה תחילה חלק קטן מהתעבורה, משווה את שיעור השגיאות וזמן התגובה לקו הבסיס, ומחזירה לאחור אוטומטית — בלי להמתין לתורנות ובלי לבנות מחדש.

מה נותנת פריסה הדרגתית על חלק מהתעבורה

פריסה הדרגתית היא העברת הסיכון מהריליס לחלק קטן מהתעבורה. הגרסה החדשה מקבלת משקל לא באופן מלא: 5%, אחר כך 10, 25, 50 — עם השהיה בכל שלב. כל עוד הבקר Argo Rollouts רואה שהמטריקות של הסביבה הקנרית והסביבה היציבה דומות, המשקל עולה; בסטייה התעבורה חוזרת לגרסה הקודמת.

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

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

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

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

Canary deployment מול blue-green ופריסה מלאה

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

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

אפשרות מתי מתאימה מגבלות
פריסה מלאה שירותים פנימיים וריליסים נדירים, שבהם החזרה לאחור היא שחרור חוזר של הבילד הקודם השגיאה נראית לכל הקהל, והזמן בין השחרור לחזרה לאחור אינו מוגבל
פריסת blue-green נדרשת חזרה לאחור מיידית לגרסה הקודמת ויש מלאי קיבולת המשאבים מוכפלים בזמן השחרור, התעבורה האמיתית לא בודקת את הגרסה בחלקים, ומיגרציות סכימה דורשות תאימות של שתי הגרסאות
Canary עם מיתוג לפי משקלים (Argo Rollouts) ריליסים תכופים, תעבורה יציבה ומטריקות שגיאות והשהיה מוגדרות נדרשת ניתוב לפי משקלים וניתוח אוטומטי של מדדים, והסשנים והמטמון נעשים מורכבים יותר

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

שלבי הטמעת פריסה הדרגתית בריליסים

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

  1. ביקורת תהליך הריליס. בודקים איך נבנים האימג'ים, במה נבדלות הסביבות, האם יש מטריקות וטרייסינג לשירות. בלי קו בסיס לשגיאות ולזמן תגובה, לפריסה קנרית (canary deployment) אין עם מה להשוות.
  2. הכנת מניפסטים ותיוג. האפליקציה מקבלת סט פודים יציב וסט פודים קנרי, התעבורה מתחלקת לפי משקלים דרך אובייקט מנוהל כמו Argo Rollouts, והגרסה נראית בתוויות ובלוגים — אחרת אי אפשר להבדיל בין אירוע לריליס קודם.
  3. בדיקה בסביבת קדם-פרודקשן. מריצים את אותו מסלול על עותק של הפרודקשן: שלבי משקלים, השהיות, ניתוח. כאן גם בודקים את החזרה לאחור — היא צריכה להחזיר תעבורה ופודים, ולא להשאיר מצב חלקי.
  4. הגדרת מטריקות וספים. מתארים מה נחשב לדעיכה: שיעור תגובות עם שגיאה, השהיה באחוזון 95, חוסר במשאבים. את הספים גוזרים מההתנהגות הנצפית, אחרת החזרה לאחור האוטומטית מופעלת על רעש.
  5. הרצה על ריליס אמיתי. את הפריסה הראשונה מובילים עם אישור ידני של שלבים, ומהנדס לצד בוחן את המטריקות. כך רואים את מהירות החימום האמיתית ואילו התראות מרעישות לשווא.
  6. מסירת הנוהל. מוסרים לצוות מסמך: שלבים והשהיות, תנאי החזרה לאחור אוטומטית, פעולות איש התורנות, סדר החזרה הידנית. שלב ה-canary הופך לסעיף חובה בצ'ק-ליסט של הריליס.

תצורות, סכימות תעבורה ונוהלי מסירה

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

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

מקרה בוחן: שיעור המשתמשים שנפגעו מתקלה ירד פי 20

מה היה לפני ההטמעה

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

מה שינו

העברנו את הפריסה לתרחיש הדרגתי ב-Argo Rollouts: הגרסה החדשה קיבלה תחילה 5% מהתעבורה, אחר כך 20% ו-50%, ורק לאחר מכן 100%. בכל שלב המערכת השוותה את תדירות השגיאות ואת השהיית התגובה לקו הבסיס, ועצרה את הריליס אם המדד חצה את הסף.

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

מה נהיה

שיעור המשתמשים שנפגעו מהתקלה ירד פי 20: את הגרסה הבעייתית הספיקו לראות לא יותר מ-5% מהקהל. זמן ההתאוששות ירד מ-40 דקות ל-2–3 — החזרה לאחור הופעלה אוטומטית לפי מטריקה, בלי מעורבות מהנדס תורנות. במשך רבעון אף שחרור פגום לא הגיע לתעבורה מלאה, והצוות הפסיק לפחד מריליסים בסוף השבוע.

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

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

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

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

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

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

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

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

כל עוד הגרסה הקנרית מחזיקה 5–10% מהתעבורה, חריגה מהסף עוצרת אוטומטית את הפריסה ומחזירה את התעבורה לגרסה היציבה.

להלן ספקות שצצים לרוב בשלב התיאום.

איך הגרסה החדשה משפיעה על העומס על מסד הנתונים?

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

מי מקבל החלטה לעצור את הפריסה?

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

מהן המגבלות של הגישה?

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

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

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

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

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

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