Cilium service mesh: מדוע ארכיטקטורת sidecar נתקלת בתקרת זכוכית
service mesh קלאסי בנוי על sidecar proxy: לצד כל קונטיינר של אפליקציה עולה proxy נפרד, שדרכו עובר כל התעבורה הנכנסת והיוצאת. באשכול עם מאות pods מדובר במאות תהליכים נוספים, כל אחד עם buffer משלו לחיבורים וטבלאות ניתוב משלו.
הדבר הראשון שמתחיל לכאוב הוא השיהוי ברשת: כל בקשה עוברת hop רשתי מיותר בתוך ה-pod, ובשרשראות של עשרה שירותים השיהויים מצטברים לכמות מורגשת.
צוואר הבקבוק השני הוא צריכת הזיכרון. ה-sidecar שומר על משאבים ללא קשר לכמות התעבורה שבאמת עוברת דרכו: לשירות עם בקשה אחת בדקה יש את אותן עלויות תקורה כמו לשירות עמוס. באשכולות גדולים זה מתבטא בעשרות גיגה-בייט שהולכים לא לאפליקציה, אלא לתחזוקת ה-mesh עצמו. בנוסף, כל proxy צריך לעדכן, להפעיל מחדש ולסנכרן בעת שינוי תצורה.
הבעיה השלישית היא דיבוג ועמידות לתקלות. כשבקשה לא מגיעה, הסיבה יכולה להיות באפליקציה, ב-sidecar שלה, ב-sidecar של המקבל או בשכבת הניהול. הלוגים מפוזרים בין ה-pods, ה-tracing נקטע בגבולות ה-proxy, ונפילה של רכיב ניהול משאירה את האשכול במצב לא מוגדר.
Cilium service mesh מסיר את מקור העלויות האלה עצמו: הניתוב והמדיניויות מבוצעים ברמת הקרנל דרך eBPF, ללא proxy מתווך בנתיב הנתונים. נבחן כיצד זה משנה את השיהויים, צריכת הזיכרון ועמידות לתקלות.
מה מספקת ארכיטקטורת eBPF ללא sidecar
service mesh קלאסי בנוי על sidecar-פרוקסי: לצד כל קונטיינר של אפליקציה מוקם קונטיינר-מתווך נפרד, שדרכו עובר כל התעבורה הנכנסת והיוצאת. באשכול של מאה פודים מדובר במאה תהליכים נוספים, כל אחד עם צריכת הזיכרון וזמן המעבד שלו, ושתי קפיצות רשת מיותרות לכל בקשה. ההשהיה גדלה, המשאבים מופנים לתחזוקת ה-mesh עצמו ולא לאפליקציה.
Cilium Cilium מעביר את אותה לוגיקה לתוך הליבה: מדיניות רשת, ניתוב, איזון עומסים והצפנה מבוצעים ברמת תוכניות eBPF המוצמדות לממשקי הרשת. אין צורך בפרוקסי-מתווך בפוד — התעבורה מעובדת במקום שבו היא ממילא עוברת, ללא החלפות הקשר נוספות בין מרחבי המשתמש והליבה. מכאן שלושה אפקטים מדידים.
השהיה. בקשה בין שירותים אינה עוברת עוד דרך שני תהליכי משתמש. בשרשראות מיקרושירותים טיפוסיות הדבר מסיר חלק ניכר מהוצאות התקורה לכל קריאה, וככל שהשרשרת ארוכה יותר, כך גדל הרווח המצטבר בזמן התגובה.
משאבים. מהפודים יוצא קונטיינר ה-sidecar: משתחרר הזיכרון שהוא החזיק וזמן המעבד שהוא הוציא על הפרוקסי. באשכול צפוף הדבר מפנה משאבים לעומסי העבודה עצמם, ולא לתשתית ה-mesh.
שקיפות. זרם האירועים ברמת הליבה רואה כל בקשה — מי דיבר עם מי, באיזה פרוטוקול, עם איזה קוד תגובה — ללא אינסטרומנטציה של קוד האפליקציה. הדבר מספק נראות כברירת מחדל: מפת התלויות וסיבות הכשל נראות מיד, ולא נאספות מיומנים ממקורות שונים.
השורה התחתונה המעשית: אותה קבוצת יכולות — אימות הדדי, הפרדת גישות, טלמטריה — עם מספר קטן יותר של חלקים נעים וביצועים צפויים תחת עומס.
מצבי פריסה: sidecar, sidecarless והיברידי
Cilium יכול לפעול בשלושה מצבים, והבחירה ביניהם היא בראש ובראשונה שאלה של תאימות עם מה שכבר רץ בקלאסטר. מצב sidecar הקלאסי מציב קונטיינר פרוקסי לצד כל פוד: האפליקציה לא משתנה, אבל צריכת המשאבים גדלה ומחזור החיים של הפוד נעשה מורכב יותר.
מצב sidecarless מעביר את עיבוד התעבורה לליבה דרך eBPF — אין פרוקסי בפוד, ההשהיות נמוכות יותר, אבל חלק מתרחישי L7 דורשים הפעלה מפורשת. המצב ההיברידי משאיר sidecar רק במקום שבו הוא באמת נחוץ, ואת השאר מוסר לליבה.
| וריאנט | מתי מתאים | מגבלות |
|---|---|---|
| Sidecar | נדרשים מסנני L7 לא סטנדרטיים, אפליקציות ללא תמיכה ביירוט eBPF, הגירה מדורגת | פרוקסי לכל פוד: צריכת זיכרון ומעבד גבוהה יותר, אתחול פוד איטי יותר |
| Sidecarless | קלאסטר הומוגני, עדיפות להשהיות ולצפיפות פודים, תעבורת L3/L4 עם L7 ממוקד | חלק מכללי L7 המתקדמים דורשים הגדרה מפורשת, לא כל ההרחבות של צד שלישי תואמות |
| היברידי | עומס מעורב: שירותים קריטיים עם sidecar, השאר בלעדיו | דיבאג ומדיניות אחידה מורכבים יותר, נדרשת משמעת בתיוג פודים |
מגבלה מעשית של sidecarless — לא כל האפליקציות מוכנות למסור תעבורה ליירוט ברמת הליבה, וחלק מתרחישי L7 (ניתוב מורכב לפי כותרות, מסננים מותאמים אישית) עדיין אמינים יותר לסגור עם פרוקסי.
המצב ההיברידי מסיר את הסתירה הזו, אבל דורש ציון מפורש אילו פודים עוברים דרך sidecar, אחרת ההתנהגות נעשית בלתי צפויה.
תאימות עם מדיניות רשת קיימת ו-mTLS נבדקת לפני המעבר: תחילה על מרחב שמות אחד, לאחר מכן הרחבה. נסיגה אפשרית בכל שלב — המצב נקבע באמצעות אנטציה על הפוד או הגדרה ברמת הקלאסטר, ללא בנייה מחדש של האפליקציות.
שלבי הטמעת Cilium service mesh באשכול
הטמעת Cilium service mesh אינה מתחילה בהתקנה, אלא במיפוי של מה שכבר פועל באשכול. בשלב זה חשוב להבין את טופולוגיית הרשת, תוספי ה-CNI הנוכחיים, מערך המדיניות הרשתית ואופן התקשורת בין האפליקציות.
טעויות בשלב זה הן היקרות ביותר: תעבורה שלא נלקחה בחשבון או התנגשות עם CNI קיים מובילות לפגיעה בקישוריות כבר לאחר הפריסה.
מכאן העבודה מתנהלת באופן איטרטיבי, עם בדיקה בכל שלב ואפשרות לחזרה לאחור. להלן תוכנית טיפוסית שאנו מתאימים לאשכול ספציפי.
- ביקורת האשכול והרשת. אוספים מפה של הצמתים, הגרסאות, ה-CNI הנוכחי, המדיניות הרשתית ונקודות הכניסה של התעבורה. מתעדים אילו שירותים קריטיים ואילו ניתן להעביר ראשונים.
- תכנון סכמת הרשת. קובעים את מצב הפעולה (overlay או native routing), טווחי הכתובות, מדיניות הניתוב בין פודים לצמתים. הסכמה מתואמת לפני תחילת השינויים.
- הכנת הסביבה. פורסים את Cilium במתאר בדיקה, בודקים תאימות עם הרכיבים הנוכחיים, מגדירים הצפנת תעבורה בין פודים ומדיניות בסיסית.
- הגדרת service mesh. מפעילים ניתוב ברמת L7, mTLS בין שירותים, כללי גישה ונראות דרך Hubble. המדיניות מתוארת באופן דקלרטיבי ומנוהלת בגרסאות יחד עם הקוד.
- בדיקה על שירותי פיילוט. מעבירים 2–3 שירותים לא קריטיים, בוחנים השהיות, שיעור חיבורים מוצלחים והתנהגות בעת כשל צומת. משווים למדדים המקוריים.
- פריסה הדרגתית. מרחיבים את המתאר לשאר השירותים בגלים, עם ניטור ותוכנית חזרה לאחור מוכנה בכל שלב.
- מסירת תיעוד. מוסרים את סכמת הרשת, הקונפיגורציות, תיאור המדיניות, נהלי העדכון והוראות לאבחון תקלות.
לאחר המסירה, צוות הלקוח מנהל באופן עצמאי את המדיניות ומטפל בתקלות לפי תרחישים מוכנים. אם ברצונכם לדון בהטמעה עבור האשכול שלכם — תארו את המשימה, ונחזור עם הערכה ותוכנית עבודה.
מדיניות גישה ותפקידי IAM ב-Cilium
מדיניות גישה ב-Cilium מתוארת באופן הצהרתי — כאובייקטים CiliumNetworkPolicy ו-CiliumClusterwideNetworkPolicy, ולא כמערכת כללים בממשק הענן. המשמעות היא שהלקוח מקבל לא "הגדרה", אלא חפץ מגורסא: ניתן להכניס אותו ל-git, להעביר אותו דרך סקירה ולהחזיר אותו לאחור יחד עם הגרסה. תפקידי IAM נשארים בצד הענן או האשכול ומקושרים למדיניות הרשת באמצעות מיפוי מפורש של חשבונות שירות.
להלן — מה בדיוק מועבר לידיים לאחר ההטמעה.
- תצורות מדיניות רשת: כללי L3/L4 לפי תוויות של פודים ומרחבי שמות, כללי L7 עבור HTTP/gRPC עם הגבלת מתודות ונתיבים, מערכת נפרדת עבור DNS ו-egress.
- תרשימי זרימת תעבורה: מפת "מי עם מי ובאיזה פורט", שנבנתה על בסיס נתוני תצפית בפועל, ולא על בסיס הנחות.
- מטריצת מיפוי של תפקידי IAM וחשבונות שירות: איזה תפקיד משויך לאיזה שירות ואילו מדיניויות מגבילות אותו.
- נוהל שינוי מדיניות: סדר הסקירה, בדיקות חובה לפני החלה, הליך החזרה לגרסה קודמת.
- מדיניות ברירת מחדל: מצב של חסימת כל התעבורה הנכנסת עם רשימה מפורשת של כיוונים מותרים — כדי שפוד חדש לא יקבל גישה "עם העלייה".
- הוראות אבחון: כיצד לקרוא את יומן החיבורים שנדחו ולהבחין בין חסימה על ידי מדיניות לבין תקלת רשת.
- רשימת תיוג לקבלה: רשימת תרחישים שנבדקים לאחר כל שינוי — זמינות שירותים, בידוד מרחבי שמות, פעילות אינטגרציות חיצוניות.
כל חפץ מלווה בתיאור קצר: לשם מה הוא נחוץ ומה יישבר אם לא לתחזק אותו. מערכת כזו מאפשרת לצוות הלקוח לשנות כללים באופן עצמאי, מבלי לחזור אלינו עבור כל תיקון.
קייס: מעבר ל-Cilium service mesh ללא השבתה
הלקוח — צוות מוצר עם עשרות שירותים בקלאסטר ודרישת זמינות מחמירה: ריליסים יוצאים מדי יום, חלון תחזוקה אינו קיים. בתחילה התעבורה בין השירותים עברה דרך sidecar-פרוקסי בכל פוד.
על הנייר התרשים עבד,但在 בפועל יצר שלוש בעיות מערכתיות: עלייה ניכרת בהשהיה בכל הופ, צריכת זיכרון מורגשת על הפרוקסי עצמם והיעדר מוחלט של תמונה ברורה של מי מדבר עם מי ואיך בתוך הקלאסטר.
המעבר נעשה ל-Cilium — שכבת רשת מבוססת eBPF, שמעבירה ניתוב, איזון עומסים והצפנה לרמת הקרנל, ללא קונטיינר פרוקסי לצד האפליקציה. הקריטי עבור הלקוח: זה לא "עוד רכיב מעל", אלא החלפה של שכבת הרשת הקיימת, ולכן ניתן לבצע את המיגרציה בהדרגה, ללא מיתוג חד-פעמי של כל הקלאסטר.
מה היה לפני ההטמעה
- השהיה בין השירותים בכל הופ — בגלל מעבר כפול דרך הפרוקסי.
- זיכרון וזמן מעבד הושקעו בקונטיינרי sidecar, ולא בעומס המועיל.
- אבחון תקלות — לפי לוגים של פרוקסי מפוזרים, ללא מפת קשרים אחודה.
- הצפנת תעבורה הוגדרה ידנית עבור כל שירות.
מה שינו
פרסו את Cilium במצב שבו מדיניות רשת וניתוב פועלים ברמת הקרנל, ו-mTLS בין השירותים מופעל בהגדרה, ולא בעריכה ידנית של כל מניפסט. Hubble חובר כמקור observability: הוא מציג זרימות בין השירותים ומאפשר לנתח תקלה לפי גרף קשרים, ולא לפי grep בלוגים. את המיגרציה הובילו לפי namespace — תחילה שירותים לא קריטיים, אחר כך השאר, עם בדיקת מטריקות בכל שלב.
מה נהיה אחרי
ההשהיה בין השירותים ירדה בכשליש בערך בשרשראות של כמה הופים. הזיכרון שתפסו קונטיינרי sidecar התפנה — צפיפות פריסת הפודים על הצמתים עלתה. הצפנת תעבורה הפכה להתנהגות ברירת מחדל, ולא למשימה נפרדת לכל שירות. ניתוח תקלה התקצר משעות לדקות: גרף הזרימות ב-Hubble מראה מיד היכן הקשר נשבר.
השבתה במהלך המעבר לא הייתה — המיגרציה התנהלה במקביל לעומס העבודה, וחזרה לשכבה הקודמת הייתה אפשרית בכל שלב.
במה שונה Cilium service mesh מ-Istio?
Cilium service mesh מבוסס על eBPF — התוכניות מורצות בליבת Linux בנקודות חיבור של חבילות רשת, ולכן ניתוב, איזון עומסים ומדיניות מיושמים ללא פרוקסי במרחב המשתמש. Istio עובד היסטורית דרך קונטיינרים מסוג sidecar: לצד כל pod עולה Envoy, אשר מיירט את התעבורה ומיישם כללים.
מכאן הפער הארכיטקטוני המרכזי — Cilium משתלב בליבה ומשתמש בנתיב הרשת הקיים, בעוד Istio מוסיף שכבת פרוקסי נפרדת לכל pod.
ההבדל המעשי מתבטא בתקורה ובמה שהמהנדס רואה. Sidecar לכל pod הוא קונטיינר נוסף שיש לעדכן, להקצות לו משאבים ולהתחשב בו בזמני השהיה: כל בקשה עוברת hop מיותר. Cilium מסיר את השכבה הזו עבור מדיניות L3/L4 ואיזון עומסים, וניתוח L7 מחבר באופן ממוקד, רק במקום שבו נדרשים כללים לפי HTTP.
יחד עם זאת, Istio מספק פונקציונליות L7 בוגרת וצפויה יותר באופן מובנה — ניתוב לפי כותרות, כללי retry ו-timeout מדויקים — וזה הצד החזק שלו.
גם בגישת mTLS הדרכים נפרדות. Istio מנפיק תעודות דרך מרכז משלו ושומר אותן ב-sidecar, ומצפין תעבורה בין pods ברמת הפרוקסי. Cilium יודע לבצע mutual TLS באמצעים של הליבה ודרך אינטגרציה עם מערכות חיצוניות להנפקת תעודות, מה שמפחית את מספר הרכיבים אך דורש הגדרה קפדנית של רוטציה.
צפיות: ב-Cilium זה Hubble עם מפת תלויות שירותים וזרימות ישירות מהליבה, וב-Istio — טלמטריה של Envoy עם תוויות עשירות, אך במחיר אותה שכבת פרוקסי.
תרחישי הבחירה הם כאלה. Cilium service mesh מנצח כאשר האשכול גדול וצפיפות חשובה: פחות קונטיינרים, זמני השהיה נמוכים יותר, מדיניות רשת ושירותים אחודה בשכבה אחת. את Istio בוחרים כאשר נדרש שליטה מלאה ככל האפשר ב-L7, ניתוב מורכב בין גרסאות ופרקטיקות תפעול מבוססות.
בפועל הגישות הללו אינן סותרות זו את זו — Cilium לעתים קרובות מכסה את הרשת והאבטחה, ומשימות L7 נפתרות באופן ממוקד. אנו מנתחים אשכול ספציפי ואומרים איזו אפשרות תיתן תוצאה צפויה ללא שכבות מיותרות.
ספקות טכניים נפוצים בעת הטמעה
Cilium מותקן מעל ממשק ה-CNI הסטנדרטי של Kubernetes, ולכן אין צורך לוותר על שכבת הרשת המוכרת — רק מי שמממש את הכללים משתנה. פודים, שירותים ו-NetworkPolicy ממשיכים לעבוד כבעבר, בעוד הניתוב ואיזון העומס עוברים לרמת הליבה. בפועל המשמעות היא שקובצי המניפסט הקיימים עוברים ללא כתיבה מחדש, ויכולות חדשות מופעלות לפי הצורך.
תאימות לאשכולות ולעננים הקיימים?
Cilium נפרס על אשכולות מנוהלים של ספקי ענן גדולים וגם על חומרה עצמאית. מגבלות מתעוררות במקומות שבהם הענן עצמו מנהל את שכבת הרשת — במקרים כאלה חלק מהיכולות מושבתות, והשאר פועל כשורה.
לפני ההטמעה אנו בודקים את גרסת הליבה על הצמתים ואת מצב הניתוב: מכך תלוי אילו יכולות זמינות מיד ואילו דורשות הגדרה.
כיצד מתבצעת חזרה לאחור אם משהו משתבש?
הפריסה מתבצעת בשלבים: תחילה קבוצת צמתים לבקרה, ולאחר מכן השאר. כללי הניתוב והמדיניות נשמרים באופן דקלרטיבי, ולכן החזרה למצב הקודם היא החלה של התצורה הקודמת, ולא עריכה ידנית. אם השכבה החדשה מפריעה, הצמתים חוזרים למצב הרשת המקורי אחד אחד, ללא עצירת שירותים.
מה עם אבטחה והצפנת תעבורה?
מדיניות הגישה מתוארת ברמת השירותים, ולא ברמת הכתובות, ונבדקת בכל צומת לפני שהחבילה מגיעה לאפליקציה. אימות הדדי בין שירותים מופעל ללא כתיבה מחדש של הקוד — האישורים מונפקים ומתחלפים אוטומטית. זה סוגר סוג תקיפות שבו התוקף כבר נמצא בתוך ההיקף ונע בין שירותים.
כיצד לנפות תקלות אם התעבורה לא עוברת?
כל החלטה לגבי חבילה נראית ביומן התצפית: איזה שירות פנה למי, האם החיבור אושר או נדחה ובאיזו מדיניות. במקום לבדוק השערות אחת לאחת, המהנדס מסתכל על האירוע הספציפי ומוצא את הסיבה תוך דקות. אותה תצפית מספקת גם תמונה של התלויות בין השירותים, שלרוב יש לאסוף ידנית.
אם נותרו שאלות לגבי הסביבה שלכם — תארו את המשימה, ונחזור עם הערכה ותוכנית הטמעה.
נדון במשימה שלכם ונחזור עם תוכנית
כדי שהשיחה תהיה עניינית ולא "ספרו לי על Cilium", התחילו משלוש נקודות פתיחה: מהו האשכול ואיזו עומס פועל בו, היכן כואב כרגע — רשת, אבטחה או נראות, ואיזו תוצאה תרצו לראות בעוד רבעון.
זה מספיק כדי להבין אם נדרש לכם service mesh מעל eBPF או שהמשימה נסגרת על ידי שכבת הרשת הסטנדרטית של Kubernetes.
מכאן עובדים בשלבים, ובכל שלב אתם רואים תוצר, ולא רק סטטוס בהתכתבות:
- מפרקים את המצב הנוכחי: כיצד בנויה הרשת בין השירותים, היכן מופעל mTLS, אילו מדיניות כבר פועלות, מה מציג Hubble.
- מקבעים את המטרה במונחים מדידים: שיעור התעבורה תחת אימות הדדי, זמן תגובה לאירוע, עומק היסטוריית הנראות.
- מציעים תרשים הטמעה: מצב החלפת שכבת הרשת, סדר הפעלת המדיניות, נקודות חזרה בכל שלב.
- מתאמים תוכנית לפי שלבים עם קריטריונים ברורים למוכנות — מה חייב לעבוד לפני המעבר לשלב הבא.
- פורסים על קו פיילוט: סביבה אחת, סט מוגבל של שירותים, שליטה מלאה במדדים לפני ואחרי.
- מעבירים לפרודקשן תוך שמירה על אפשרות לחזור לתצורה הקודמת ללא השבתה.
- מוסרים תיעוד ומגדירים ניטור, כדי שהצוות ימשיך להפעיל את המערכת בעצמו.
הערכה ותוכנית ההטמעה נשלחות לאחר ניתוח קצר — עם שלבים, לוחות זמנים ומה שיידרש מצדכם: גישות לאשכול, חלון לזמן שינויים, איש קשר של מהנדס לתיאום. תארו את המשימה בפורמט נוח — נחזור עם קונקרטיקה וצעדים הבאים.







