ملاحظة perev. : تستمر هذه المقالة في سلسلة من المواد المتعلقة بالجهاز الأساسي للشبكات في Kubernetes ، والتي تم وصفها في شكل يمكن الوصول إليه وتوضيحات توضيحية (ومع ذلك ، لم تكن هناك أي رسوم توضيحية في هذا الجزء من الخرسانة حتى الآن). عند ترجمة الجزأين السابقين من هذه السلسلة ، قمنا بدمجها في منشور واحد ، تحدثنا عن نموذج شبكة K8s (التفاعل داخل العقد وبين العقد) وشبكات التراكب. قراءتها الأولية مرغوبة (موصى بها من قبل المؤلف نفسه). يكرس استمرار لخدمات Kubernetes ومعالجة حركة المرور الصادرة والواردة.
ملاحظة : من أجل راحة المؤلف ، يُستكمل نص المؤلف بروابط (بشكل أساسي إلى الوثائق الرسمية لـ K8s).
ديناميات الكتلة
نظرًا للتغير المستمر ، والطبيعة الديناميكية لـ Kubernetes والأنظمة الموزعة بشكل عام ، فإن القرون (ونتيجة لذلك ، عناوين IP الخاصة بهم) تتغير أيضًا باستمرار. تختلف أسباب ذلك من التحديثات الواردة للوصول إلى الحالة والأحداث المرغوبة والتي تؤدي إلى التوسع ، إلى الأعطال غير المتوقعة للعقدة أو العقدة. لذلك ، لا يمكن استخدام عناوين IP الخاصة بـ pod في الاتصال.
يتم تشغيل
الخدمة في Kubernetes - وهو عنوان IP افتراضي مع مجموعة من عناوين IP pod التي يتم استخدامها كنقاط نهاية ويتم تحديدها من خلال
محددات الملصقات . تعمل هذه الخدمة كموازن تحميل افتراضي ، حيث يظل عنوان IP ثابتًا ، وفي الوقت نفسه ، يمكن أن تتغير عناوين IP الخاصة بالقرنة التي تقدمها من خلاله باستمرار.
محدد التسمية في كائن خدمة في Kubernetesوراء التطبيق الكامل لهذا IP الظاهري ، توجد قواعد iptables (أحدث إصدارات Kubernetes لديها أيضًا
القدرة على استخدام IPVS ، ولكن هذا موضوع لمناقشة أخرى) ، والتي يتم التحكم فيها بواسطة مكون Kubernetes يسمى
kube-proxy . ومع ذلك ، فإن هذا الاسم مضلل في حقائق اليوم. تم استخدام Kube-proxy بالفعل كبديل في الأيام السابقة لإصدار Kubernetes v1.0 ، لكن هذا أدى إلى استهلاك كبير للموارد والموارد بسبب عمليات النسخ المستمرة بين مساحة kernel ومساحة المستخدم. الآن هو مجرد وحدة تحكم - مثل العديد من وحدات التحكم الأخرى في Kubernetes. يراقب خادم API عن التغييرات التي يتم إجراؤها على نقاط النهاية وتحديث قواعد iptables وفقًا لذلك.
وفقًا لقواعد iptables هذه ، إذا كانت الحزمة مخصصة لعنوان IP الخاص بالخدمة ، يتم إجراء ترجمة عنوان شبكة الوجهة (DNAT) لها: هذا يعني أن عنوان IP الخاص بها سيتغير من IP الخاص بالخدمة إلى إحدى نقاط النهاية ، أي أحد عناوين IP الخاصة بـ pod ، والتي تختار iptables بشكل عشوائي. هذا يضمن أن يتم توزيع الحمل بالتساوي بين القرون.
دنات في iptablesفي حالة مثل DNAT ، يتم تخزين المعلومات الضرورية في
conntrack - جدول محاسبة الاتصال في Linux (يقوم بتخزين ترجمات خمسة أزواج مصنوعة بواسطة iptables:
protocol
،
srcIP
،
srcPort
،
dstIP
،
dstPort
). يتم ترتيب كل شيء بطريقة يمكن عندها إرجاع استجابة ، قد تحدث عملية DNAT عكسية (إلغاء DNAT) ، أي استبدال مصدر IP من Pod IP إلى IP Service. بفضل هذا العميل ، ليست هناك حاجة مطلقًا إلى معرفة كيفية التعامل مع الحزم الموجودة خلف الكواليس.
إدخالات خمسة أزواج (5-tuple) في جدول conntrackلذلك ، باستخدام خدمات Kubernetes ، يمكننا العمل مع نفس المنافذ دون أي تعارض (لأن إعادة تعيين المنفذ إلى نقاط النهاية أمر ممكن). هذا يجعل اكتشاف الخدمة سهل للغاية. يكفي استخدام DNS الداخلي والرمز الثابت لمضيف الخدمات. يمكنك حتى استخدام متغيرات Kubernet التي تم تكوينها مسبقًا مع منفذ المضيف والخدمة.
تلميح : باختيار المسار الثاني ، يمكنك توفير الكثير من مكالمات DNS غير الضرورية!
حركة المرور الصادرة
تعمل خدمات Kubernetes الموضحة أعلاه ضمن مجموعة. في الممارسة العملية ، تحتاج التطبيقات عادةً إلى الوصول إلى بعض المواقع / API الخارجية.
بشكل عام ، يمكن أن يكون للمضيفين عناوين IP خاصة وعامة. للوصول إلى الإنترنت ، يتم توفير NAT واحد على واحد لعناوين IP الخاصة والعامة - وهذا ينطبق بشكل خاص على البيئات السحابية.
للتفاعل العادي من المضيف مع عنوان IP الخارجي ، يتغير عنوان IP المصدر من IP المضيف الخاص إلى IP العام للحزم الصادرة ، وللحزم الواردة - في الاتجاه المعاكس. ومع ذلك ، في الحالات التي يبدأ فيها الاتصال من عنوان IP الخارجي ، فإن عنوان IP المصدر هو عنوان IP IP ، الذي لا تعرفه آلية NAT الخاصة بالموفر السحابي. لذلك ، فإنه سيتم ببساطة إسقاط الحزم مع عناوين IP المصدر التي تختلف عن عناوين IP المضيف.
وهنا ، خمنت ، سنحتاج إلى iptables أكثر! هذه المرة ، يتم تنفيذ القواعد ، التي تتم إضافتها أيضًا بواسطة kube-proxy ، بواسطة SNAT (ترجمة عنوان الشبكة المصدر) ، ويعرف أيضًا باسم
IP MASQUERADE (التنكر). بدلاً من إخبار عنوان IP المصدر ، يُطلب من kernel استخدام واجهة IP التي تصل منها الحزمة. في conntrack ، يظهر سجل أيضًا لتنفيذ إضافي للعملية العكسية (un-SNAT) على الاستجابة.
حركة المرور الواردة
حتى الآن ، كان كل شيء على ما يرام. يمكن للقرون التواصل مع بعضهم البعض ومع الإنترنت. ومع ذلك ، لا نزال نفتقر إلى الشيء الرئيسي - خدمة حركة مرور المستخدم. يوجد حاليًا طريقتان لتنفيذه:
1. NodePort / Cloud Load Balancer (مستوى L4: IP والمنفذ)
NodePort
تعيين
NodePort
كنوع الخدمة إلى تعيين خدمة
NodePort
في
NodePort
إلى
NodePort
. هذا
nodePort
مفتوح على كل عقدة ، حتى في حالة عدم وجود pod قيد التشغيل على العقدة.
NodePort
إرسال حركة المرور الواردة على
NodePort
إلى أحد البرامج (التي قد تظهر حتى على عقدة أخرى!) ، مرة أخرى باستخدام iptables.
يقوم نوع الخدمة
LoadBalancer
في البيئات السحابية بإنشاء موازن تحميل سحابي (على سبيل المثال ، ELB) أمام جميع العقد ، مع زيادة العمل مع نفس
NodePort
.
2. الدخول (مستوى L7: HTTP / TCP)
تقوم العديد من التطبيقات الأخرى أيضًا بإجراء تعيين مسار / مضيف HTTP مع الواجهات الخلفية المقابلة - على سبيل المثال ، nginx ، traefik ، HAProxy ، إلخ. معهم ، يصبح كل من LoadBalancer و NodePort نقطة الدخول لحركة المرور ، ولكن هناك ميزة هنا أننا بحاجة إلى Ingress واحد فقط لخدمة حركة المرور الواردة لجميع الخدمات بدلاً من NodePort / LoadBalancers العديدة.
سياسات الشبكة
يمكن اعتبار
سياسات الشبكة بمثابة مجموعات أمان / قوائم ACL للأقراص. قواعد
NetworkPolicy
تسمح / ترفض حركة المرور بين القرون. يعتمد تنفيذها الدقيق على طبقة الشبكة / CNI ، ولكن معظمها يستخدم ببساطة iptables.
...
هذا كل شيء. في
الدفعات السابقة ، تعلمنا أساسيات التواصل في Kubernetes وكيف تعمل التراكبات. الآن نحن نعرف كيف يساعد تجريد الخدمة في مجموعة ديناميكية ويجعل من السهل اكتشاف الخدمات. درسنا أيضًا كيفية تدفق حركة المرور الصادرة / الواردة وسياسات الشبكة التي يمكن أن تكون مفيدة لتأمين كتلة.
PS من المترجم
اقرأ أيضًا في مدونتنا: