HAProxy Ingress Controller ב-Kubernetes: איזון עומסים, TCP, ניטור

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

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

שאלות נפוצות

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

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

HAProxy Ingress Controller: צווארי בקבוק באיזון עומסים בקלאסטר

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

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

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

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

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

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

מה נותנת שכבת כניסה ייעודית: אפקט מדיד

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

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

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

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

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

מצבי עבודה של Ingress: השוואת גישות

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

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

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

סדר היישום: מהאודיט ועד למסירה לתפעול

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

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

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

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

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

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

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

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

קונפיגורציות, סכימות ומדיניות גישה

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

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

מקרה בוחן: העברת עומס העבודה לשכבת כניסה ייעודית

לפני: שכבת הכניסה חלקה צמתים עם האפליקציות

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

סעיף נפרד — פניות לתמיכה: 10–15 בחודש, חלקן עם אותה נוסחה בדיוק «בזמן העדכון הכול נפל». המהנדסים עסקו בחקירת תקלות במקום במשימות פיתוח.

מה שינו

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

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

אחרי: המספרים

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

פניות לתמיכה בנושא שכבת הכניסה הצטמצמו מ-10–15 ל-1–2 בחודש, וגם אלה עוסקות בהרשאות ובתעודות. יישום קונפיגורציה וחזרה לגרסה הקודמת אורכים שניות במקום דקות.

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

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

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

את שיעור התעבורה מעבירים במשקלים במאזן העומסים החיצוני או דרך DNS עם TTL קצר: 5, 10, 25, 50, 100 אחוזים. ניהול לפי משקל ולא לפי מיתוג מאפשר מעבר ללא השבתה: בכל רגע רואים כמה בקשות הולכות לסכימה החדשה וכיצד היא עונה להן, ובמקביל הנתיב תמיד קיים לפחות מצד אחד.

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

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

ספקות טכניים לפני תחילת העבודה

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

מאיפה נובעת השהיה בשכבת הכניסה?

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

האם חיבורים ארוכים נקטעים — צ'אטים, הורדות, סטרימינג?

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

כיצד שכבת הכניסה יודעת שצומת אינו זמין?

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

האם הכתובת האמיתית של הלקוח תגיע לאפליקציה?

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

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

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

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

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

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

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

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

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