לדלג לתוכן

תבנית Sidecar מוסברת

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

הבעיה - לוגיקת תשתית שמשוכפלת בכל שירות

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

הפתרון - container נפרד שרץ לצד השירות

Sidecar מוציא את הלוגיקה התשתיתית מקוד השירות אל container נפרד לגמרי, שרץ באותו pod (ביחידת ההרצה, למשל ב-Kubernetes) לצד ה-container הראשי. שני ה-containers חולקים את אותה רשת מקומית, כך שהם יכולים לתקשר ביניהם במהירות, אבל הם תהליכים נפרדים לגמרי - אפשר לעדכן, לפרוס, ואפילו להחליף את ה-Sidecar בלי לגעת בקוד השירות הראשי בכלל.

# תיאור פשוט - שני containers באותו pod
containers:
  - name: order-service       # קוד העסק בפועל
    image: order-service:v3
  - name: envoy-sidecar        # Sidecar - מטפל בתעבורת רשת, TLS, retry
    image: envoy:v1.28

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

Service Mesh - Sidecar בקנה מידה גדול

כשיש עשרות או מאות שירותים, וכל אחד מהם מקבל Sidecar משלו, נוצר מה שנקרא Service Mesh - רשת שלמה של Sidecars שכולם עובדים לפי אותה מדיניות מרכזית. כלי כמו Istio או Linkerd מנהלים את כל ה-Sidecars האלה ממקום אחד - הגדרת מדיניות "כל תעבורה בין שירותים חייבת TLS" מוגדרת פעם אחת במקום מרכזי, ונאכפת אוטומטית בכל Sidecar בכל שירות, בלי לגעת בקוד אף שירות בודד.

היתרון המרכזי - הפרדה בין שפות ובין צוותים

יתרון חשוב שלא תמיד בולט מיד הוא שSidecar עובד באותה צורה בדיוק לא משנה באיזו שפת תכנות השירות הראשי כתוב. שירות ב-Python, שירות ב-Java, ושירות ב-Go יכולים כולם לקבל את אותן יכולות תשתיתיות בדיוק דרך אותו Sidecar, בלי שכל שפה תצטרך ספרייה נפרדת שמיישמת retry ו-Circuit Breaker בעצמה. זה גם מפריד בין אחריות - צוות הפלטפורמה יכול לתחזק ולשדרג את ה-Sidecar בלי לתאם עם כל צוותי המוצר שכותבים את השירותים עצמם.

המחיר - עוד תהליך, עוד latency

Sidecar לא בא בלי עלות. כל תעבורת רשת עוברת עכשיו קפיצה נוספת דרך ה-Sidecar, מה שמוסיף latency קטן אך לא אפסי לכל קריאה. וכל pod עכשיו מריץ שני containers במקום אחד, מה שמעלה את צריכת המשאבים בקנה מידה - עוד זיכרון ו-CPU, מוכפלים במספר השירותים במערכת. בפרויקטים קטנים עם מעט שירותים, התועלת של עקביות מרכזית לרוב לא מצדיקה את התקורה הזאת.

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

עבדתם עם Service Mesh בפרויקט אמיתי? הצטרפו לקהילה בדיסקורד ותספרו איך זה השפיע על הארכיטקטורה שלכם.

לסיכום

תבנית Sidecar מוציאה לוגיקת תשתית - לוגים, מדדים, אבטחת רשת, retry - מקוד השירות אל container נפרד שרץ לצידו, כך שכל שירות מקבל את היכולות האלה בעקביות בלי לממש אותן בעצמו. בקנה מידה גדול, זה הופך ל-Service Mesh שלם שנאכף ממקום מרכזי אחד - יתרון משמעותי במיוחד כשיש שירותים בשפות שונות ובעלות על ידי צוותים שונים.