عنوان IP لعميل VPN داخل Kubernetes: هل نحتفظ به أم نستخدم SNAT؟
اختر بين الحفاظ على عنوان عميل VPN الحقيقي وNAT المصدر داخل Kubernetes وفق ثلاثة شروط، ثم تحقق من مسار العودة وتغيّر الـ pods.
في مكان ما بين النفق والـ backend، إما أن ينجو عنوان العميل أو يُستبدل، وكلتا النتيجتين قابلتان للدفاع. القرار يخص مالك الخدمة المستقبلة، لا مالك من ثبّت الـ CNI. عندما تكون المصادقة لكل عميل أو الحصص أو سجلات التدقيق مهمة، يجب أن ينجو العنوان من كل قفزة. وعندما يكون الإسناد المشترك مقبولًا، يزيل NAT المصدر مشكلة توجيه كنت ستحافظ عليها إلى الأبد.
أين يختفي عنوان العميل فعليًا
تصل حزمة عميل بعيد إلى pod الـ VPN بمصدر داخلي ضمن نطاق النفق، لنقل 10.90.0.42. عندما يعيد الـ pod توجيه تلك الحزمة نحو ClusterIP أو IP الـ pod، يمكن لثلاث آليات مختلفة أن تعيد كتابة المصدر. قاعدة masquerade في الـ CNI على العقدة تغطي الحركة التي يرسلها الـ pod خارج CIDR العنقود. أما مدخل conntrack الخاص بـ kube-proxy على عقدة الوجهة فيغطي قفزة الـ Service نفسها. والوكيل الذي ينهي الاتصال لا يعيد توجيه الحزمة إطلاقًا، لذا فالمصدر الذي تراه في النهاية يخص الوكيل.
كل منها يعيش في طبقة مختلفة، ولهذا لا يصلح حقل Service واحد المسار كله تقريبًا.
يقرر externalTrafficPolicy على Service الـ VPN العام ما يحدث للاتصال الخارجي فقط: يُبقي Local العنوان البعيد على العقدة التي استقبلته، بينما يسمح Cluster لـ kube-proxy بتسليم الحزمة إلى عقدة أخرى وعمل masquerade لها هناك. ذلك الإعداد يحكم المستمع الذي يتصل به عملاؤك. ولا يقول شيئًا عن الحزمة المفككة التي يوجهها عملية الـ VPN بعد ذلك إلى العنقود.
ثلاثة شروط تحسم الجدل
أطرح الأسئلة الثلاثة نفسها بالترتيب نفسه في كل مرة تظهر فيها هذه المسألة، لأن الأول عادةً ينهي النقاش. أجب عنها لعبء العمل المحدد لا للعنقود ككل. يمكن لعنقودين داخل شركة واحدة أن يصلا إلى إجابتين مختلفتين وأن تكون كلتاهما صحيحة.
| Question | Preserve | SNAT |
|---|---|---|
| Does the backend enforce policy per client? | Yes, the address is the identity | Only if a trusted proxy supplies identity |
| Can the cluster route 10.90.0.0/24 back to a stable gateway? | Required | Not needed |
| Is the workload a forwarder or a proxy? | Forwarder | Proxy is fine |
إذا أجاب الـ backend بنعم على السؤال الأول ولا على الثاني، فلديك عمل شبكي تقوم به بدلًا من ملف manifest تعدّله. وإذا قال الصف الثالث إنه وكيل، فلن كان العنوان سينجو أصلًا، وادعاء العكس يكلف أسبوعًا من التقاط الحزم.
ما يتطلبه وضع preserve من الشبكة
الحفاظ على المصدر يعني أن على عقدة الوجهة إعادة الحركة إلى 10.90.0.42 عبر بوابة VPN نشطة. بركة الـ VPN ليست CIDR للعنقود، لذا لا يوجّهها أي CNI عنك افتراضيًا. تضيف المسار بنفسك، ثم تتأكد من أن نقطة نهاية البوابة التي يشير إليها تنجو من إعادة جدولة.
ip route add 10.90.0.0/24 via 10.244.3.17 dev eth0
sysctl -w net.ipv4.conf.eth0.rp_filter=2
تلك القفزة التالية عنوان pod، وعناوين الـ pods تتحرك. وجّه المسار إلى VIP لـ Service أو إلى عنوان عقدة يبقى في مكانه، أو اقبل أنك ستطارد البوابة بعد كل إخلاء. تصفية المسار العكسي هي الفخ الآخر: الوضع الصارم يُسقط الحزم التي لا يطابق مسار عودتها الواجهة التي وصلت عبرها، وهو بالضبط شكل تدفق VPN محفوظ.
التحقق المتساهل هو غالبًا الفرق بين مسار عودة عامل و ردود تختفي بعد مغادرة الـ backend. كما يجب أن تستثني قواعد masquerade على عقدة الـ VPN نطاق النفق، وإلا غادرت الحزمة المعاد توجيهها بعنوان الـ pod مهما كان المسار الذي بنيته. فضّل التعبير عن ذلك الاستثناء في إعداد الـ CNI نفسه بدل تحرير iptables يدويًا، لأن الوكيل يعيد كتابة سلاسله عند إعادة التشغيل وقاعدتك المكتوبة يدويًا تبقى بالضبط حتى الترقية التالية.
NetworkPolicy هو تحكم في الوصول وليس توجيهًا. لن يؤدي تشديد سياسة إلى استعادة عنوان استبدله masquerade بالفعل.
ماذا يكلف SNAT، وكيف تكتبه
NAT المصدر نحو العنقود هو التصميم الأرخص، وهو ليس خطأ. يرى الـ backend عنوان الـ pod أو العقدة، وتتفق السجلات مع بعضها، وليس من الضروري وجود مسار عودة. ما تخسره هو القدرة على التمييز بين عميلين على مستوى الشبكة، لذا يجب أن تأتي الحصص والحظرات وآثار التدقيق من مكان آخر.
عادةً يكون ذلك المكان الآخر هو التطبيق: رمز جلسة، أو ترويسة موقعة، أو سطر بروتوكول PROXY يكتبه وكيل تتحكم به. هذه تمنح المستقبِل هوية لا يثق بها إلا عندما يكون الوكيل في المسار ولا يمكن ضبط الترويسة من جهة العميل. كن صريحًا في الـ runbook بشأن أيها ينطبق، لأن المهندس التالي سيفترض أن العنوان في السجل هو العميل. وهو ليس كذلك، وحادثة واحدة تكفي لجعل ذلك الافتراض مكلفًا.
تبقى المقايضة صادقة ما دامت مكتوبة.
فحوص تفصل المسار العامل عن المسار المحظوظ
اختبر باتصال جديد لا باتصال مخزّن، واختبر في الاتجاهين. تبدو عدة أعطال متقطعة فقط لأن التدفقات الجديدة تسلك المسار المعاد كتابته.
التقط الـ tuple في ثلاث نقاط خلال طلب واحد مصرّح به: فورًا بعد فك التغليف، وعلى واجهة الخروج الخاصة بـ pod الـ VPN، وعلى الـ backend. إذا تغير المصدر بين الالتقاط الثاني والثالث، فالسبب أسفل من الـ pod. وإذا تغير قبل الثاني، فالـ pod نفسه هو من يترجم.
ثم احذف pod الـ VPN وأعد الاختبار أثناء إعادة جدولته. المسار المحفوظ الذي ينكسر عند الإخلاء غير مكتمل، وكذلك قاعدة NAT المثبتة على عنوان لم يعد موجودًا. وأخيرًا أرسل طلبًا واحدًا من مصدر تتوقع رفضه وتأكد من أن الرفض يأتي من السياسة لا من مسار مفقود.