דפוס ה-Sidecar: הרחבת שירותי מיקרו ללא שינוי קוד
במערכות מודרניות מבוססות ענן, מיקרו-שירותים צפויים לעשות הרבה יותר מאשר להפעיל לוגיקה עסקית. עליהם לטפל ברישום, לנהל תעודות SSL/TLS, לאסוף מדדים, ליישם מנגנוני ניסיון חוזר ולתאם תקשורת מאובטחת עם שירותים אחרים.
אם נטמיע את כל הפונקציונליות הצולבת הזו ישירות בתוך בסיס הקוד של כל יישום, בסופו של דבר נגמור עם נפיחות קוד, צימוד הדוק ונעילה בשפה.
כאן נכנס לתמונה דפוס ה-Sidecar. במדריך זה, נפרק מהי תבנית ה-Sidecar, מדוע הוא חיוני לארכיטקטורות מיקרו-שירות מודרניות וכיצד הוא פועל באמצעות אנלוגיות פשוטות ודוגמאות תצורה של Kubernetes.
האנלוגיה העולמית האמיתית: רכב הצד לאופנוע
הדרך הקלה ביותר להבין את הדפוס הזה היא לחשוב על אופנוע עם קרון צד.
דמיינו שיש לכם אופנוע בעל ביצועים גבוהים. הוא נועד לעשות דבר אחד בצורה יוצאת דופן: להעביר רוכב אחד במהירות. כעת, נניח שאתה צריך לשאת מטען של נוסעים או להוסיף מושב נוסף.
אתה יכול לעצב מחדש לחלוטין את המסגרת, המנוע והגלגלים של האופנוע כדי להפוך אותו למכונית. עם זאת, זה דורש מאמץ מסיבי, הורס את הפשטות של האופניים ומקשה על תחזוקה.
במקום זאת, אתה מצרף קרונית צד.
הקרון הצידי הוא יחידה נפרדת, עצמאית המתחברת לאופנוע. הוא חולק את המסע של האופנוע, הולך לכל מקום שהאופניים הולכים ופועל בצמוד. עם זאת, מנוע הליבה של האופנוע נותר ללא פגע.
בארכיטקטורת תוכנה:
- האופנוע הוא מיכל היישומים העיקרי שלך (מפעיל את ההיגיון העסקי הליבה שלך, כמו קופה או אישור משתמש).
- The Sidecar הוא מיכל עוזר נפרד (הפעלת משימות שירות, כמו סיום SSL, ניטור או משלוח יומן).
- המסע הוא מחזור החיים של הפריסה (למשל, Pod Kubernetes).
הבעיה: דאגות חוצות ונפיחות קוד
לפני ה-sidecars, מפתחים היו צריכים לכלול ספריות עוזר ישירות בקוד האפליקציה שלהם. לדוגמה, אם רצית לשלוח יומנים לשרת מרכזי, ייבאת ספריית רישום. אם היית צריך מדדים, הוספת ערכת פיתוח של מדדים.
גישה מבוססת ספרייה זו יצרה מספר אתגרים משמעותיים:
- נעילת שפה: אם ספריית ניטור כתובה רק ב-Go, לא תוכל להשתמש בה בקלות במיקרו-שירות Python או Java. אתה צריך למצוא או לבנות ספרייה עבור כל שפה בערימה שלך.
- זיהום קוד: ההיגיון העסקי הופך עמוס בקוד ספציפי לתשתית עבור ניסיונות חוזרים, גילוי שירות, הצפנה ורישום.
- שדרוגים מורכבים: אם נמצאה פגיעות אבטחה בספריית התקשורת, כל מיקרו-שירות בודד חייב לעדכן את התלות שלו, לבצע קומפילציה מחדש ולפריסה מחדש.
- טענת משאבים: קוד העזר פועל באותו תהליך זמן ריצה כמו היישום הראשי, כלומר דליפת זיכרון ביוגר עלולה לקרוס את כל יישום הליבה שלך.
הפתרון: דפוס ה-Sidecar
דפוס ה-Sidecar פותר את הבעיות הללו על ידי הזזת משימות עוזר אל מחוץ לתהליך היישום הראשי והצבתן לתהליך נפרד ועצמאי הפועל ממש ליד היישום.
בסביבות מכולות כמו Kubernetes, מיכל היישומים והמיכל הצדדי פועלים בתוך אותו Pod. מכיוון שהם חולקים את אותו פוד:
- ** אותו מרחב שמות רשת**: הם חולקים את אותה כתובת IP ויציאות רשת. הם יכולים לדבר זה עם זה באופן מיידי מעל
localhostעם אחזור כמעט אפס. - נפחי אחסון משותפים: הם יכולים לגשת לאותו אחסון דיסק בדיוק, מה שמאפשר לגלגל הצד לקרוא קובצי יומן או לטעון קובצי תצורה שנכתבו על ידי היישום הראשי.
- מחזור חיים זהה: הקרון הצדדי נפרס, מופעל, נעצר ומוגדל לצד היישום הראשי.
מקרי שימוש עיקריים של דפוס ה-Sidecar
רכבי צד הם מגוונים להפליא. חלק מהיישומים הנפוצים ביותר כוללים:
1. שירות רשת פרוקסי (למשל, שליח, Linkerd)
במקום שהאפליקציה שלך תבצע שיחות HTTP ישירות לשירותים אחרים, היא שולחת בקשות ל-proxy הצד המקומי שלה. ה-sidecar proxy מטפל בניתוב, ניסיונות חוזרים, איזון עומסים, שבירת מעגלים והצפנת TLS הדדית (mTLS), ולאחר מכן מעביר את הבקשה. האפליקציה לא מודעת לחלוטין למורכבויות הרשת הללו.
2. איסוף והעברה של יומנים (למשל, Fluent Bit)
היישום שלך פשוט כותב את הצהרות היומן שלה לפלט סטנדרטי או לקובץ יומן מקומי. מיכל צדדי עוקב אחר הקובץ הזה, מנתח את היומנים ומעביר אותם למנוע ניתוח מרכזי כמו Elasticsearch או Datadog.
3. תצורה וטעינה מחדש סודית
רכב צד יכול לצפות בשרת מרוחק (כמו Consul או Vault) עבור עדכוני תצורה או סיבובי מפתח קריפטוגרפיים. כאשר מזוהה שינוי, הוא מוריד את הקבצים החדשים לנפח משותף ומאותת לאפליקציה הראשית לטעון אותם מחדש, ללא צורך בהפעלה מחדש.
דוגמה ליישום Kubernetes
הקמת קרונית צד היא פשוטה ב-Kubernetes. הנה תצורה פשוטה של YAML המציגה מיכל יישום שכותב יומנים לנפח משותף, ומיכל צד של Fluent Bit קורא ומשלוח את היומנים האלה:
apiVersion: v1
kind: Pod
metadata:
name: app-with-logging-sidecar
labels:
app: billing-service
spec:
containers:
# 1. Primary Application Container
- name: web-app
image: node:18-alpine
command: ["/bin/sh", "-c"]
args:
- >
while true; do
echo "$(date) [INFO] Transaction processed successfully" >> /var/log/app/output.log;
sleep 5;
done
volumeMounts:
- name: shared-logs
mountPath: /var/log/app
# 2. Sidecar Container (Log Shipper)
- name: log-shipper
image: fluent/fluent-bit:latest
volumeMounts:
- name: shared-logs
mountPath: /var/log/app
# In a real setup, Fluent Bit config would read /var/log/app/output.log
# and forward it to an external logging system.
# Shared disk storage accessible by both containers
volumes:
- name: shared-logs
emptyDir: {}
יתרונות וחסרונות של דפוס ה-Sidecar
כמו כל דפוס עיצובי, קרונות צד מגיעים עם פשרות:
| יתרון (פרו) | חסרון (קון) |
|---|---|
| שפה אגנוסטית: הקרון הצידי פועל בסביבה משלו. אתה יכול להשתמש באותו עוזר צד לצד אפליקציות Go, Java, Python או Ruby. | תקרת משאבים: הפעלת מיכלים מרובים לכל פוד מגדילה את צריכת המעבד והזיכרון. |
| מחזור חיים מנותק: צוותי תשתית יכולים לעדכן את תיקוני האבטחה של הרכב הצדדי מבלי לגעת בקוד האפליקציה. | מורכבות מוגברת: ניהול פי שניים של קונטיינרים מסבך תצורות פריסה, ניפוי באגים ותזמון. |
| בידוד כשל עצמאי: אם המכולה של הקרון הצידי קורס, Kubernetes יכולה להפעיל אותה מחדש באופן אוטומטי מבלי להוריד את האפליקציה הראשית. | השהיית רשת קלה: ניתוב תנועה דרך פרוקסי צדדי מקומי מוסיף קפיצה קטנה, אם כי היא בדרך כלל זניחה (< 1ms). |
מסקנה
דפוס Sidecar הוא אבן בניין בסיסית של ארכיטקטורות מודרניות של ענן. על ידי בידוד חששות רוחביים - כגון פרוקסי רשת, אבטחה, רישום וניהול תצורה - לתהליך נלווה נפרד, הוא מאפשר למפתחים להתמקד אך ורק בבניית ערך עסקי.
למרות שהיא מציגה תקורה נוספת של משאבים ודורשת פלטפורמות תזמור של מיכלים כמו Kubernetes לניהול יעיל, היתרונות של בסיסי קוד נקיים יותר, גמישות שפה ושינוי קנה מידה עצמאי הופכים אותו לדפוס הכרחי עבור שירותי מיקרו ארגוניים.