بنية السايدكار والبنية المحيطية
بنية السايدكار والبنية المحيطية
قبل نشر شبكة الخدمات (Service Mesh)، يجب عليك أن تختار كيفية ربط الـ Proxy بأحمال عملك. هذا ليس مجرد إعداد بسيط، بل هو اختيار معماري جوهري يحدد تكلفة المعالج (CPU)، والذاكرة (RAM)، ونطاق الضرر عند الأعطال، وتعقيد عمليات الترقية، والوضع الأمني على نطاق واسع. يسود اليوم نموذجان رئيسيان: نموذج السايدكار (النهج الأصلي في Kubernetes، المستخدم في Istio قبل الإصدار 1.22، وفي Linkerd وConsul Connect) والنموذج المحيطي (Ambient) (Istio Ambient، الذي أصبح جاهزاً للإنتاج في Istio 1.22، مايو 2024). فهم الفوارق على المستوى الهندسي — لا على مستوى التسويق — هو ما يميز المهندسين القادرين على توصيل الأنظمة باستقرار.
نموذج السايدكار: كل Pod يحصل على Proxy خاص به
في نموذج السايدكار، يُحقن حاوية الـ Proxy — سواء كانت envoy في Istio أو linkerd-proxy في Linkerd — في كل Pod تلقائياً عند إنشائه عبر MutatingWebhookConfiguration. تشترك الحاوية المحقونة في نفس Network Namespace مع تطبيق الـ Pod، وتقوم حاوية initContainer (تعمل بصلاحية NET_ADMIN) بإعداد قواعد iptables لتحويل كل حركة TCP الواردة والصادرة عبر الـ Proxy على المنافذ 15001 (صادر) و15006 (وارد) في Istio. التطبيق نفسه لا يعلم شيئاً عن هذا الاعتراض.
كل اتصال TCP بين الخدمات يمر إذاً عبر أربع قفزات Proxy: Proxy الجانب المُرسِل ← الشبكة ← Proxy الجانب المستقبِل، مع تفعيل mTLS بين الـ Proxyين. التطبيق يكتب على مقبس عادي؛ الشبكة توصّل الاتصال مشفراً وموثّقاً وخاضعاً للسياسات.
في Google وLyft (المنشئ الأصلي لـ Envoy) وUber، تعمل أسطول تضم مئات الآلاف من الـ Sidecar Proxies بشكل اعتيادي. لكن التكلفة حقيقية: الـ Sidecar الأساسي في Istio يستهلك تقريباً 50–100 ميغابايت RAM و0.5–1 vCPU في وضع الخمول لكل Proxy، مع ارتفاع الـ CPU تحت الحمل. في مجموعة تضم 1,000 خدمة، كل منها تعمل على 5 نسخ، فهذا يعني 5,000 حاوية إضافية — تكلفة غير هيّنة. المقابل هو عزل كل حمل عمل بشكل مستقل: عطل أو خطأ في إعداد Proxy واحد لا يؤثر إلا على Pod واحد.
تداعيات الموارد ودورة حياة السايدكار
يجب أن يكون Webhook الحقن نشطاً حتى تدخل الـ Pods الجديدة في الشبكة. انقطاع istiod (أو linkerd-controller) أثناء عملية نشر متدحرجة يعني أن الـ Pods الجديدة تعمل بدون Proxy — إما يُرفض إنشاؤها (إذا كانت سياسة الـ Webhook تساوي failurePolicy: Fail) أو تنضم للمجموعة بدون تشفير أو مراقبة (إذا كانت Ignore). اختر Fail في بيئة الإنتاج؛ تقبّل خطر التوافرية أثناء أعطال المستوى التحكمي وخففها بتشغيل istiod على عدة نودات مع PodAntiAffinity وPodDisruptionBudgets.
ترقية الـ Proxy تستلزم إعادة تشغيل الـ Pod — لا يوجد تحديث في المكان. في مجموعة تضم 10,000 Pod، ترقية الشبكة تعني تدوير 10,000 Pod. استراتيجيات الترقية التدريجية (ترقية namespace واحد، التحقق من القياسات، ثم المتابعة) ضرورة وليست رفاهية.
النموذج المحيطي (Ambient): Proxy بدون Pod
نموذج Istio Ambient (جاهز للإنتاج منذ Istio 1.22، يونيو 2024) يُلغي الـ Sidecar في كل Pod كلياً ويستبدله ببنية ذات طبقتين:
- ztunnel — DaemonSet مكتوب بـ Rust، يعمل على مستوى النود ومسؤول عن الطبقة L4 فقط: mTLS، والنفق عبر بروتوكول HBONE (HTTP/2-based overlay)، وقياسات أساسية. خفيف للغاية: ~30 ميغابايت لكل نود بغض النظر عن عدد أحمال العمل عليه.
- waypoint proxy — نسخة Envoy (واحدة لكل Service Account أو Namespace) تتولى الطبقة L7: توجيه HTTP، وإعادة المحاولة، وقطع الدائرة، والتحقق من JWT، والقياسات المتقدمة. لا يُنشأ الـ Waypoint إلا عند الحاجة الفعلية لسياسة L7؛ خدمة داخلية تحتاج فقط mTLS لن تُنشئ Waypoint أبداً.
يعتمد تحويل حركة البيانات في النموذج المحيطي على برامج eBPF (على أنوية Linux 5.4+) يحملها DaemonSet الـ istio-cni عند إنشاء الـ Pod، أو يرجع إلى iptables-in-netns على الأنوية الأقدم. الفارق الجوهري عن نموذج السايدكار: إعادة التوجيه تعمل في Network Namespace للـ Pod، لكن عملية الـ Proxy تعيش على النود وليس داخل الـ Pod.
مقارنة مباشرة بين البنيتين
لا يوجد نموذج أفضل على إطلاقه. الاختيار الصحيح يعتمد على مزيج الأحمال في مجموعتك، ومتطلبات الأمان، والنضج التشغيلي.
- نطاق الضرر عند عطل الـ Proxy: السايدكار — تأثر Pod واحد؛ الاسترداد بإعادة تشغيله. النموذج المحيطي — عطل ztunnel على نود يوقف جميع أحمال العمل المسجلة في الشبكة على ذلك النود دفعة واحدة، مما يجعله مكوناً بنطاق ضرر على مستوى النود، مشابهاً لـ kubelet.
- استهلاك الذاكرة على نطاق واسع: السايدكار — خطي مع عدد الـ Pods، قد يصل إلى 50–100 ميغابايت × عدد الـ Pods. النموذج المحيطي — ثابت لكل نود للـ L4 (~30 ميغابايت × عدد النودات)؛ Waypoints فقط للخدمات التي تحتاجها. مجموعة تضم 1,000 Pod على 50 نوداً توفر تقريباً 48 غيغابايت من ذاكرة الحاويات في النموذج المحيطي لأحمال العمل التي تحتاج L4 فقط.
- دقة سياسة L7: السايدكار — كل Pod له Envoy خاص؛ يمكنك تطبيق AuthorizationPolicy لكل Pod. النموذج المحيطي — سياسات L7 تمر عبر Waypoint مشترك؛ نطاق الأمان هو Service Account للـ Waypoint.
- عملية الترقية: السايدكار — يستلزم تدوير جميع الـ Pods؛ النموذج المحيطي — ترقية DaemonSets لـ ztunnel والـ Waypoints بشكل مستقل دون إعادة تشغيل أي Pod.
- متطلبات النواة: النموذج المحيطي يحتاج نواة Linux 5.4+ لـ eBPF؛ النودات الأقدم تحتاج iptables كخيار احتياطي.
- النضج: السايدكار — مختبر منذ 2017 بسجل إنتاجي واسع. النموذج المحيطي جاهز للإنتاج منذ مايو 2024 — في طور النضج السريع لكن بخبرة تشغيلية أقل.
تفعيل النموذج المحيطي والتحقق منه
النموذج المحيطي يُفعَّل اختيارياً لكل Namespace عبر Label. يجب أن يكون DaemonSet الـ istio-cni oDaemonSet الـ ztunnel يعملان قبل تسجيل أي أحمال عمل.
Linkerd: سايدكار فقط، خفيف للغاية
يتخذ Linkerd (CNCF Graduated) مقايضة مختلفة: يبقى مع نموذج السايدكار فقط لكن يجعل الـ Proxy خفيفاً للغاية لدرجة تنهار معها حجة التكلفة. الـ linkerd-proxy هو Proxy مخصص مكتوب بـ Rust يستهلك ~10 ميغابايت RAM لكل Pod في وضع الخمول وكاد يكون معدوم الـ CPU — أخف بمقدار 5–10 أضعاف من Envoy لكل Sidecar. Linkerd يدفع ثمن ذلك بمجموعة ميزات أضيق: لا قابلية توسعة بـ Wasm، لا تكرار حركة معقد، دعم محدود لتحويل gRPC. للفرق التي تبحث أساساً عن mTLS شفاف + قياسات Golden Signal بدون الثقل التشغيلي لـ Istio، نموذج السايدكار في Linkerd غالباً هو الخيار الصحيح.
ISTIO_META_DNS_CAPTURE=true في Istio). الخدمات التي تعتمد على بروتوكولات UDP (NTP، syslog، بعض تطبيقات الألعاب) غير مرئية للشبكة ولا تحصل على أي من ضمانات الأمان أو الرصد. راجع أحمال عملك بحثاً عن حركة غير TCP قبل افتراض تغطية كاملة.