نمطا Sidecar وAmbassador
نمطا Sidecar وAmbassador
مع تنامي تعقيد الخدمات، تتراكم قائمة طويلة من الاهتمامات التشغيلية التي لا علاقة لها بمنطق الأعمال: مصادقة TLS المتبادلة، وتتبع الطلبات الموزعة، وتسجيل الوصول، وإعادة المحاولات، وتحديد معدل الطلبات، وفحوصات الصحة. تاريخيًا، كانت الفرق تدمج كل ذلك داخل كل خدمة على حدة، ما يعني أن كل فريق يُعيد تطبيق الشيفرة المكررة ذاتها بلغات مختلفة محتملة. يحلّ نمطا Sidecar وAmbassador هذه المشكلة بتغليف تلك الاهتمامات المشتركة في عملية منفصلة تعمل بجانب الخدمة الرئيسية، لا داخلها.
نمط Sidecar
Sidecar هو حاوية مساعدة تُضيف قدرات أو تمدّد إمكانيات الخدمة الرئيسية دون تعديل شيفرتها. تعمل في وحدة النشر ذاتها (Kubernetes Pod، أو ECS Task، أو مجموعة عمليات على جهاز ظاهري) وتتشارك شبكة localhost مع الحاوية الرئيسية.
تشمل المسؤوليات الشائعة لنمط Sidecar ما يلي:
- وكيل شفاف / شبكة الخدمات: يعترض Envoy أو Linkerd جميع حركة المرور الواردة والصادرة لفرض mTLS، وحقن رؤوس التتبع، وجمع المقاييس، وتطبيق منطق قاطع الدائرة — دون أي تغيير في شيفرة الخدمة.
- شحن السجلات: يراقب sidecar مثل Fluentd أو Filebeat ملفات السجل التي تكتبها التطبيقات ويُعيد توجيهها إلى Elasticsearch أو Splunk. يكتب التطبيق نصًا عاديًا؛ ويتولى الـ sidecar الإرسال المنظّم والتخزين المؤقت والتحكم في الضغط العكسي.
- تدوير الأسرار: يستطلع sidecar عميل Vault بانتظام HashiCorp Vault للحصول على بيانات اعتماد قصيرة العمر ويكتبها في وحدة تخزين مشتركة في الذاكرة. يقرأ التطبيق ملفًا؛ ويُجدّده الـ sidecar كل ساعة دون إعادة تشغيل.
- مزامنة الإعدادات: يراقب sidecar إعادة تحميل ConfigMap التغييرات ويُرسل
SIGHUPإلى العملية الرئيسية لتحفيز إعادة تحميل الإعداد دون نشر كامل.
مثال واقعي: شبكة خدمات Istio
تحقن Istio، أكثر شبكات الخدمات انتشارًا، وكيل Envoy كـ sidecar في كل pod تلقائيًا عبر خطاف القبول المتحوّل في Kubernetes. من تلك اللحظة فصاعدًا:
- تُعاد توجيه جميع حركة TCP بشفافية عبر Envoy باستخدام قواعد
iptables— دون أي تغيير في استدعاءات التطبيق مثلdial("localhost:3306"). - يفرض Envoy mTLS على كل اتصال، ما يُلغي الحاجة إلى أي شيفرة TLS في الخدمات.
- يحصل كل طلب على معرّف تتبع مُحقن في رؤوسه HTTP، مما يُتيح التتبع الموزع الشامل في Jaeger.
- تُضبط إعادة المحاولات والمهل وقاطع الدائرة في موارد Istio المخصصة، لا في شيفرة التطبيق.
على نطاق Airbnb، يُضيف تشغيل sidecar في كل pod من آلاف الـ Pods عبئًا حقيقيًا — نحو 50 MB من الذاكرة العشوائية و0.1 نواة معالج ظاهري لكل pod كنقطة بداية. هذا هو ثمن هذا المستوى من التجريد. في 1,000 Pod، يعني ذلك 50 GB من الذاكرة مخصصة للوكلاء فحسب. قِس قبل أن تلتزم.
نمط Ambassador
Ambassador هو sidecar متخصص مهمته العمل كـ وكيل خارجي ذكي — ممثل محلي يتعامل مع تعقيد التواصل مع الخدمات الخارجية. تُرسل الخدمة الرئيسية طلباتها إلى localhost:<port> كما لو كانت الخدمة المستهدفة محلية؛ وتتولى حاوية Ambassador فعليًا إدارة الاتصال: التجميع، والمصادقة، وإعادة المحاولات، واكتشاف الخدمات، وترجمة البروتوكول.
فكّر في Ambassador كمرافق شخصي للخدمة في مكالماتها الصادرة.
حالات استخدام Ambassador:
- جسر البروتوكولات القديمة: خدمة gRPC حديثة تحتاج إلى استدعاء نقطة نهاية SOAP قديمة. يُترجم Ambassador من gRPC إلى SOAP حتى لا تتعامل الخدمة الجديدة مع XML. وعند استبدال النظام القديم في نهاية المطاف، تتغير إعدادات Ambassador فحسب.
- توجيه قاعدة البيانات عبر سحابات متعددة: يتحدث التطبيق إلى
localhost:5432(PostgreSQL). يُوجّه Ambassador هذا إلى نموذج RDS الصحيح في المنطقة الصحيحة، مُضيفًا رؤوس مصادقة IAM التي كان التطبيق سيحتاج إلى إنتاجها بنفسه. - تجميع الاتصالات: يحافظ PgBouncer المنشور كـ ambassador على مجموعة صغيرة من الاتصالات الدائمة بقاعدة البيانات، مما يُتيح لمئات عمليات التطبيق مشاركة حفنة من اتصالات قاعدة البيانات الحقيقية — دون أن تمتلك كل عملية منطق تجميع خاصًا بها.
- اكتشاف الخدمات الديناميكي: يُضمّن التطبيق
localhost:9000. يُحلّ Ambassador العنوان الحالي للخدمة المستهدفة من Consul أو Kubernetes DNS ويوزّع الحمل على الحالات السليمة.
Sidecar مقابل Ambassador — متى تستخدم أيهما؟
يستخدم كلا النمطين عملية مساعدة مجاورة، لكنهما يحلّان اهتمامات اتجاهية مختلفة:
- Sidecar — يتعامل أساسًا مع حركة المرور الواردة والاهتمامات التشغيلية المشتركة (المراقبة، والأمان، والإعداد). يُغلّف الخدمة من منظور العالم الخارجي.
- Ambassador — يتعامل أساسًا مع الاستدعاءات الصادرة. يُدير التعقيد نيابةً عن الخدمة حين تحتاج إلى الوصول إلى تبعيات خارجية. يُغلّف العالم الخارجي من منظور الخدمة.
في الواقع العملي، يؤدي Envoy Sidecar الخاص بـ Istio كلا الدورين — يعترض حركة المرور الواردة والصادرة. لكن التمييز المفاهيمي يظل مهمًا عند تصميم حل موجّه: إذا كنت تحتاج فقط إلى إدارة اتصال صادر أذكى (تجميع، مصادقة)، فإن ambassador وحده (مثل PgBouncer، أو Twistlock) يكون أبسط وأقل تكلفة من شبكة خدمات كاملة.
اعتبارات دورة الحياة والنشر
في Kubernetes، تعمل كل من الحاوية الرئيسية وحاوية Sidecar في نفس الـ Pod، وبالتالي تُجدوَلان وتُكبَّران وتُنهَيان معًا. لهذا عواقب عملية:
- ترتيب بدء التشغيل: إذا كان يجب أن يكون الـ sidecar جاهزًا قبل أن تقبل الحاوية الرئيسية حركة المرور (مثلًا، يجب على Vault agent كتابة الأسرار أولًا)، استخدم init containers في Kubernetes للإعداد الأولي وـreadiness gate للصحة المستمرة.
- ترتيب الإغلاق: عند إنهاء Pod، تتلقى جميع الحاويات
SIGTERMفي وقت واحد بشكل افتراضي. إذا خرج الـ sidecar (مثل Envoy) قبل انتهاء التطبيق من تصريف الاتصالات، تضيع الطلبات الجارية. يتعامل Istio 1.12+ مع هذا بخطاف إغلاق مخصص؛ كانت الإصدارات الأقدم تتطلب إيقافpreStop. - محاسبة الموارد: تُحتسب وحدة المعالجة المركزية والذاكرة الخاصة بالـ sidecar ضمن إجمالي الـ Pod. اضبط دائمًا
requestsوlimitsعلى حاوية الـ sidecar حتى يتمكن المُجدوِل من وضع الـ Pod بشكل صحيح ولا يتمكن الـ sidecar من تجويع الحاوية الرئيسية.
restartPolicy: Always على init containers إلى حالة مستقرة في Kubernetes 1.29، مما يُوفر ميزة sidecar container أصيلة. تبدأ حاويات الـ sidecar الآن قبل الحاوية الرئيسية وتنتهي بعدها — مما يُلغي أخطاء الترتيب التي كانت تُعاني منها عمليات النشر القديمة.
ملخص المقايضات
- المزايا: لا تغييرات في الشيفرة للتبني؛ مستقل عن اللغة؛ تطبيق سياسات متسق عبر جميع الخدمات؛ فصل نظيف بين مخاوف البنية التحتية والأعمال.
- العيوب: كُمون إضافي لكل قفزة (نحو 0.2–1 ميلي ثانية)؛ تكلفة ذاكرة ومعالج لكل pod؛ تعقيد تشغيلي (حاويات أكثر للمراقبة والترقية)؛ تصحيح الأخطاء أصعب حين يكون الوكيل في المنتصف.
- غير مناسب حين: تشغّل خدمات قليلة جدًا (تفوق التكلفة الفائدة)؛ أو كانت خدماتك بالغة الحساسية للكُمون؛ أو لم تدعم بيئة النشر لديك العمليات المجاورة (مثل الدوال اللاسيرفرية).