ننشر اليوم ترجمة للجزء الثالث من دليل شبكات Kubernetes. كان الجزء
الأول يتعلق بالقرون ،
والثاني عن الخدمات ، واليوم سنتحدث عن موازنة التحميل وموارد Kubernetes من النوع Ingress.
التوجيه ليس موازنة التحميل
في المقالة
السابقة في هذه السلسلة ، نظرنا في تكوين يتكون من زوج من الموقد وخدمة تم تعيين عنوان IP لها باسم "نظام المجموعة IP". تم إرسال الاستعلامات الموجهة إلى الموقد إلى هذا العنوان. سنستمر هنا في العمل على نظامنا التدريبي ، بدءًا من حيث تخرجنا في المرة الأخيرة. تذكر أن عنوان IP الخاص
10.3.241.152
للخدمة ،
10.3.241.152
، ينتمي إلى مجموعة من عناوين IP التي تختلف عن تلك المستخدمة في شبكة الموقد وتلك المستخدمة في الشبكة التي توجد بها العقد. اتصلت بالشبكة المعرّفة من قِبل مساحة العنوان هذه باسم "شبكة الخدمة" ، على الرغم من أنها بالكاد تستحق اسمًا خاصًا ، حيث لا توجد أجهزة متصلة بهذه الشبكة ، ومساحة العنوان الخاصة بها ، في الواقع ، تتكون بالكامل من قواعد التوجيه. تم توضيح سابقًا كيف يتم تنفيذ هذه الشبكة على أساس مكون Kubernetes ، والذي يطلق عليه
kube-proxy ، ويتفاعل مع
netfilter الوحدة النمطية kernel Linux لاعتراض وإعادة توجيه حركة المرور المرسلة إلى كتلة IP للعمل تحت.
مخطط الشبكةحتى الآن ، تحدثنا عن "الاتصالات" و "الطلبات" وحتى استخدمنا مفهوم "المرور" الذي يصعب تفسيره ، ولكن من أجل فهم ميزات آلية Kubernetes Ingress ، نحتاج إلى استخدام مصطلحات أكثر دقة. لذلك ، تعمل الاتصالات والطلبات على المستوى الرابع من
نموذج OSI (tcp) أو على المستوى السابع (http ، rpc ، وما إلى ذلك). قواعد Netfilter هي قواعد توجيه ، وهي تعمل مع حزم IP في المستوى الثالث. تتخذ جميع أجهزة التوجيه ، بما في ذلك netfilter ، قرارات أكثر أو أقل استنادًا إلى المعلومات الموجودة في الحزمة فقط. بشكل عام ، يهتمون بأين تأتي الحزمة ومن أين تذهب. لذلك ، من أجل وصف هذا السلوك من حيث المستوى الثالث من نموذج OSI ، يجب القول أن كل حزمة مخصصة للخدمة الموجودة في
10.3.241.152:80
، والتي تصل إلى واجهة العقدة
eth0
، تتم معالجتها بواسطة netfilter ، وفقًا لـ تتم إعادة توجيه القواعد المحددة لخدمتنا إلى عنوان IP الخاص بالموقد العملي.
يبدو واضحًا تمامًا أن أي آلية نستخدمها للسماح للعملاء الخارجيين بالوصول إلى أجهزة الكمبيوتر المحمولة يجب أن تستخدم نفس بنية التوجيه الأساسية. نتيجةً لذلك ، سوف يصل هؤلاء العملاء الخارجيون إلى عنوان IP ومنفذ الكتلة ، لأنهم "نقطة الوصول" لجميع الآليات التي تحدثنا عنها حتى الآن. إنها تسمح لنا بعدم القلق بشأن المكان الذي يتم تنفيذه فيه بالضبط في وقت معين. ومع ذلك ، فليس من الواضح على الإطلاق كيف نجعل الأمر كله يعمل.
يمكن الوصول إلى خدمة IP الكتلة فقط مع واجهة Ethernet للعقدة. لا شيء خارج المجموعة يعرف ما يجب فعله بالعناوين من النطاق الذي ينتمي إليه هذا العنوان. كيف يمكنني إعادة توجيه حركة المرور من عنوان IP عام إلى عنوان لا يمكن الوصول إليه إلا إذا وصلت الحزمة بالفعل إلى المضيف؟
إذا حاولنا إيجاد حل لهذه المشكلة ، فسيتم دراسة قواعد netfilter باستخدام أداة
iptables أحد الأشياء التي يمكن القيام بها في عملية العثور على حل. إذا قمت بذلك ، يمكنك اكتشاف شيء قد يبدو ، للوهلة الأولى ، غير عادي: قواعد الخدمة لا تقتصر على شبكة مصدر محددة. هذا يعني أنه سيتم التعرف على أي رزم تم إنشاؤها في أي مكان تصل إلى واجهة Ethernet للعقدة ولديها عنوان وجهة
10.3.241.152:80
على أنها مطابقة للقاعدة وسيتم إعادة توجيهها إلى الباطن. هل يمكن أن نعطي العملاء مجموعة IP فقط ، ربما عن طريق ربطها باسم مجال مناسب ، ثم إعداد مسار يسمح لنا بتنظيم تسليم هذه الحزم إلى إحدى العقد؟
العميل الخارجي والكتلةإذا تم إعداد كل شيء بهذه الطريقة ، فسوف يتحول هذا التصميم إلى العمل. عملاء الوصول إلى كتلة IP ، تتبع الحزم الطريق المؤدي إلى المضيف ، ومن ثم يتم إعادة توجيههم إلى أسفل. في هذه اللحظة ، قد يبدو لك أن مثل هذا الحل يمكن أن يكون محدودًا ، لكنه يعاني من بعض المشكلات الخطيرة. الأول هو أن العقد ، في الواقع ، مفهوم سريع الزوال ، فهي لا تختلف بشكل خاص في هذا الصدد عن الموقد. إنها ، بالطبع ، أقرب إلى العالم المادي من القرون ، لكنها يمكن أن تنتقل إلى أجهزة افتراضية جديدة ، ويمكن للمجموعات أن تتوسع أو تنخفض ، وهكذا. تعمل أجهزة التوجيه على المستوى الثالث من طراز OSI ولا يمكن للتمييز بين الحزم العاملة عادة وبين الخدمات التي لا تعمل بشكل صحيح. إنهم يتوقعون أن يكون الانتقال التالي في المسار متاحًا ومستقرًا. إذا كانت العقدة غير قابلة للوصول ، فسيصبح المسار غير صالح وسيظل كذلك ، في معظم الحالات ، كثير من الوقت. حتى لو كان المسار مقاومًا للإخفاقات ، فإن مثل هذا المخطط سيؤدي إلى حقيقة أن كل حركة المرور الخارجية تمر عبر عقدة واحدة ، والتي ربما لا تكون مثالية.
بغض النظر عن الطريقة التي نجلب بها حركة مرور العميل إلى النظام ، نحتاج إلى القيام بذلك حتى لا يعتمد على حالة أي عقدة كتلة واحدة. وفي الواقع ، لا توجد طريقة موثوقة للقيام بذلك باستخدام التوجيه فقط ، دون وجود بعض الوسائل لإدارة الموجه بفعالية. في الواقع ، إنه بالضبط هذا الدور ، دور نظام التحكم ، الذي يلعبه kube-proxy فيما يتعلق بـ netfilter. ربما لم يكن توسيع نطاق مسؤولية Kubernetes لإدارة الموجه الخارجي أمرًا كبيرًا لمهندسي النظام ، خاصة وأن لدينا بالفعل أدوات مثبتة لتوزيع زيارات العملاء عبر خوادم متعددة. يطلق عليهم موازن التحميل ، وليس من المستغرب أن يكونوا الحل الموثوق به حقًا لـ Kubernetes Ingress. من أجل فهم كيفية حدوث ذلك بالضبط ، نحتاج إلى النهوض من المستوى الثالث من OSI والتحدث عن الاتصالات مرة أخرى.
من أجل استخدام موازن التحميل لتوزيع حركة مرور العميل بين عقد نظام المجموعة ، نحتاج إلى عنوان IP عام يمكن للعملاء الاتصال به ، ونحتاج أيضًا إلى عناوين العقد بأنفسهم التي يمكن لموازن التحميل إعادة توجيه الطلبات إليها. للأسباب المذكورة أعلاه ، لا يمكننا ببساطة إنشاء مسار ثابت ثابت بين جهاز توجيه البوابة والعقد باستخدام شبكة تعتمد على الخدمة (نظام IP).
من بين العناوين الأخرى التي يمكنك العمل بها ، يمكن فقط ملاحظة عناوين الشبكة التي تتصل بها واجهات Ethernet في العقد ، أي في هذا المثال ،
10.100.0.0/24
. يعرف جهاز التوجيه بالفعل كيفية إعادة توجيه الحزم إلى هذه الواجهات ، وستذهب الاتصالات المرسلة من موازن التحميل إلى جهاز التوجيه إلى حيث يجب أن تذهب. ولكن إذا أراد العميل الاتصال بخدمتنا على المنفذ 80 ، فلا يمكننا فقط إرسال الحزم إلى هذا المنفذ على واجهات شبكة العقد.
تحميل موازن ، محاولة فاشلة للوصول إلى المنفذ 80 من واجهة الشبكة المضيفةسبب عدم القيام بذلك واضح تمامًا. وهي نتحدث عن حقيقة أنه لا توجد عملية في انتظار الاتصالات في
10.100.0.3:80
(وإذا كان هناك ، فهذا بالتأكيد ليس هو نفس العملية) ، وقواعد netfilter ، والتي ، كما كنا نأمل ، سوف تعترض الطلب و سوف يرسلونه إليه ، ولن يعملوا في عنوان الوجهة هذا. أنها تستجيب فقط لشبكة IP الكتلة بناءً على الخدمات ، أي على العنوان
10.3.241.152:80
. ونتيجة لذلك ، لا يمكن تسليم هذه الحزم ، عند وصولها ، إلى عنوان الوجهة ، وستصدر النواة استجابة
ECONNREFUSED
. هذا يضعنا في موقف مربك: ليس من السهل العمل مع الشبكة لإعادة توجيه الحزمة التي تم تكوين netfilter عند إعادة توجيه البيانات من البوابة إلى العقد ، والشبكة التي يسهل التوجيه توجيهها ليست هي الشبكة التي يعيد netfilter توجيه الحزم إليها. لحل هذه المشكلة ، يمكنك إنشاء جسر بين هذه الشبكات. هذا هو بالضبط ما يفعله Kubernetes باستخدام خدمة مثل NodePort.
خدمات مثل NodePort
الخدمة التي أنشأناها ، على سبيل المثال ، في المقالة السابقة ، لم يتم تعيين نوع لها ، لذلك اعتمدت النوع الافتراضي -
ClusterIP
. هناك نوعان آخران من الخدمات التي تختلف في الميزات الإضافية ، والآخر الذي نهتم به الآن هو
NodePort
. فيما يلي مثال على وصف لخدمة من هذا النوع:
kind: Service apiVersion: v1 metadata: name: service-test spec: type: NodePort selector: app: service_test_pod ports: - port: 80 targetPort: http
خدمات النوع
NodePort
هي خدمات من النوع
ClusterIP
لها فرصة إضافية: يمكن الحصول على الوصول إليها من خلال عنوان IP المعين للمضيف والعنوان المعين إلى الكتلة في شبكة الخدمة. يتم تحقيق ذلك بطريقة بسيطة إلى حد ما: عندما تنشئ Kubernetes خدمة NodePort ، يخصص kube-proxy منفذًا في حدود 30000-32767 ويفتح هذا المنفذ على واجهة
eth0
لكل عقدة (ومن ثم اسم نوع الخدمة -
NodePort
). تتم إعادة توجيه الاتصالات التي تم إجراؤها على هذا المنفذ (سوف ندعو هذه المنافذ
NodePort
) إلى IP الكتلة للخدمة. إذا أنشأنا الخدمة المذكورة أعلاه
kubectl get svc service-test
بتشغيل الأمر
kubectl get svc service-test
، يمكننا أن نرى المنفذ المخصص لها.
$ kubectl get svc service-test NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE service-test 10.3.241.152 <none> 80:32213/TCP 1m
في هذه الحالة ، يتم تعيين الخدمة NodePort
32213
. هذا يعني أنه يمكننا الآن الاتصال بالخدمة من خلال أي عقدة في المجموعة التجريبية لدينا في
10.100.0.2:32213
أو في
10.100.0.3:32213
. في هذه الحالة ، سيتم إعادة توجيه حركة المرور إلى الخدمة.
بعد أن أخذ هذا الجزء من النظام مكانه ، أصبح لدينا جميع أجزاء خط الأنابيب لموازنة الحمل الذي تم إنشاؤه بواسطة طلبات العميل إلى جميع عقد المجموعة.
خدمة NodePortفي الشكل السابق ، يتصل العميل
10.100.0.3:32213
التحميل من خلال عنوان IP عام ، ويحدد موازن التحميل العقدة ويتصل بها في
10.100.0.3:32213
، يقبل kube-proxy هذا الاتصال ويعيد توجيهه إلى الخدمة التي يمكن الوصول إليها عبر نظام المجموعة IP
10.3.241.152:80
. هنا ، تتم معالجة الطلب بنجاح وفقًا للقواعد التي حددها netfilter ، ويتم إعادة توجيهها إلى جراب الخادم على العنوان
10.0.2.2:8080
. ربما يبدو كل هذا معقدًا إلى حد ما ، وإلى حد ما ، ولكن ليس من السهل التوصل إلى حل أبسط يدعم جميع الميزات الرائعة التي توفر لنا قرونًا وشبكات تعتمد على الخدمات.
هذه الآلية ، ومع ذلك ، لا تخلو من مشاكلها الخاصة. باستخدام خدمات مثل
NodePort
يتيح للعملاء الوصول إلى الخدمات باستخدام منفذ غير قياسي. غالبًا ما لا تمثل هذه مشكلة ، حيث يمكن
NodePort
التحميل تزويدهم بمنفذ عادي وإخفاء
NodePort
عن المستخدمين النهائيين. لكن في بعض السيناريوهات ، على سبيل المثال ، عند استخدام موازن تحميل منصة Google Cloud خارجي ، قد يكون من الضروري نشر
NodePort
للعملاء. تجدر الإشارة إلى أن هذه المنافذ ، بالإضافة إلى ذلك ، تمثل موارد محدودة ، على الرغم من أن 2768 منفذًا ربما تكون كافية حتى لأكبر المجموعات. في معظم الحالات ، يمكنك السماح لـ Kubernetes بتحديد أرقام المنافذ بشكل عشوائي ، ولكن يمكنك تعيينها بنفسك إذا لزم الأمر. مشكلة أخرى هي بعض القيود المتعلقة بتخزين عناوين IP المصدر في الطلبات. لمعرفة كيفية حل هذه المشكلات ، يمكنك الرجوع إلى
هذه المادة من وثائق Kubernetes.
Ports
NodePorts
هي الآلية الأساسية التي بواسطتها تدخل كل حركة المرور الخارجية في مجموعة Kubernetes. ومع ذلك ، فإنهم أنفسهم لا يقدمون لنا حلاً جاهزًا. للأسباب المذكورة أعلاه ، قبل الكتلة ، سواء كان العملاء كيانات داخلية أو خارجية موجودة في شبكة عامة ، فمن المطلوب دائمًا الحصول على نوع من موازن التحميل.
حقق مهندسو المنصة ، تحقيقًا لذلك ، طريقتين لتكوين موازن التحميل من النظام الأساسي Kubernetes نفسه. لنناقش هذا.
خدمات مثل LoadBalancer والموارد من نوع الدخول
تعتبر الخدمات مثل
LoadBalancer
والموارد من نوع
Ingress
من أكثر آليات Kubernetes تعقيدًا. ومع ذلك ، لن نقضي وقتًا كبيرًا عليها ، لأن استخدامها لا يؤدي إلى تغييرات جوهرية في كل ما تحدثنا عنه حتى الآن. كل حركة المرور الخارجية ، كما كان من قبل ، تدخل الكتلة من خلال
NodePort
.
يمكن للمهندسين المعماريين أن يتوقفوا هنا ، مما يسمح لأولئك الذين ينشئون مجموعات بالتركيز فقط على عناوين IP العامة وموازنات التحميل. في الواقع ، في بعض المواقف ، مثل بدء تشغيل نظام المجموعة على خوادم عادية أو في المنزل ، وهذا بالضبط ما يفعلونه. ولكن في البيئات التي تدعم تكوينات موارد الشبكة التي يتحكم فيها API ، يسمح لك Kubernetes بتكوين كل ما تحتاجه في مكان واحد.
الطريقة الأولى لحل هذه المشكلة ، أبسطها ، هي استخدام خدمات Kubernetes مثل
LoadBalancer
. تتمتع هذه الخدمات بجميع إمكانات الخدمات مثل
NodePort
، بالإضافة إلى ذلك ، لديها القدرة على إنشاء مسارات كاملة لحركة المرور الواردة ، بناءً على افتراض أن الكتلة تعمل في بيئات مثل GCP أو AWS التي تدعم تكوين موارد الشبكة عبر واجهة برمجة التطبيقات.
kind: Service apiVersion: v1 metadata: name: service-test spec: type: LoadBalancer selector: app: service_test_pod ports: - port: 80 targetPort: http
إذا قمنا بحذف وإعادة إنشاء الخدمة من مثالنا في Google Kubernetes Engine ، وبعد ذلك بفترة وجيزة ، باستخدام الأمر
kubectl get svc service-test
، يمكننا التحقق من تعيين عنوان IP الخارجي.
$ kubectl get svc service-test NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE openvpn 10.3.241.52 35.184.97.156 80:32213/TCP 5m
يقال أعلاه أننا سنكون قادرين على التحقق من حقيقة تعيين عنوان IP خارجي "قريبًا" ، على الرغم من أن تعيين عنوان IP خارجي قد يستغرق عدة دقائق ، وهو أمر غير مفاجئ نظرًا لحجم الموارد التي تحتاج إلى جلبها إلى حالة صحية. على النظام الأساسي لـ GCP ، على سبيل المثال ، يتطلب ذلك من النظام إنشاء عنوان IP خارجي وقواعد إعادة توجيه حركة المرور وخادم وكيل مستهدف وخدمة خلفية وربما نسخة من مجموعة. بعد تخصيص عنوان IP خارجي ، يمكنك الاتصال بالخدمة من خلال هذا العنوان ، وتعيين اسم مجال وإبلاغ العملاء. إلى أن يتم تدمير الخدمة وإعادة إنشائها (من أجل القيام بذلك ، نادراً ما يكون هناك سبب وجيه) ، لن يتغير عنوان IP.
خدمات مثل
LoadBalancer
لها بعض القيود. لا يمكن تكوين مثل هذه الخدمة لفك تشفير حركة مرور HTTPS. لا يمكنك إنشاء مضيفات ظاهرية أو تكوين توجيه قائم على المسار ، لذلك لا يمكنك ، باستخدام تكوينات عملية ، استخدام موازن تحميل واحد مع العديد من الخدمات. أدت هذه القيود إلى إدخال Kubernetes 1.1. مورد خاص لتكوين موازنات التحميل. هذا هو مورد من نوع الدخول. تهدف الخدمات مثل
LoadBalancer
إلى توسيع قدرات خدمة واحدة لدعم العملاء الخارجيين. في المقابل ، تعد موارد
Ingress
موارد خاصة تتيح لك تكوين موازنات التحميل بمرونة. تدعم واجهة برمجة تطبيقات Ingress فك تشفير حركة مرور TLS والمضيفات الافتراضية والتوجيه القائم على المسار. باستخدام واجهة برمجة التطبيقات هذه ، يمكن بسهولة تكوين موازن التحميل للعمل مع خدمات الواجهة الخلفية المتعددة.
واجهة برمجة تطبيقات المورد من نوع
Ingress
أكبر من أن تناقش ميزاتها هنا ؛ علاوة على ذلك ، لا تؤثر بشكل خاص على كيفية عمل موارد Ingress على مستوى الشبكة. يتبع تطبيق هذا المورد نمط Kubernetes المعتاد: يوجد نوع مورد ووحدة تحكم للتحكم في هذا النوع. المورد في هذه الحالة هو مورد الدخول ، الذي يصف طلبات موارد الشبكة. إليك ما يمكن أن يبدو عليه وصف مورد الدخول.
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress annotations: kubernetes.io/ingress.class: "gce" spec: tls: - secretName: my-ssl-secret rules: - host: testhost.com http: paths: - path: /* backend: serviceName: service-test servicePort: 80
وحدة التحكم في الدخول مسؤولة عن تنفيذ هذه الطلبات عن طريق إحضار موارد أخرى إلى الحالة المطلوبة. عند استخدام Ingress ، يتم إنشاء خدمات مثل
NodePort
، وبعد ذلك يُسمح
NodePort
التحكم في الدخول باتخاذ قرارات بشأن كيفية توجيه حركة المرور إلى العقد. هناك تطبيق لوحدة التحكم في Ingress لموازنات تحميل GCE ، لموازنات AWS ، للخوادم الوكيلة الشائعة مثل nginx و haproxy. لاحظ أن خلط موارد وخدمات Ingress مثل
LoadBalancer
يمكن أن يسبب مشاكل بسيطة في بعض البيئات. من السهل التعامل معها ، ولكن بشكل عام ، من الأفضل استخدام Ingress حتى للخدمات البسيطة.
HostPort و HostNetwork
ما نتحدث عنه الآن ، أي
HostPort
و
HostNetwork
، يمكن أن يعزى إلى فئة
HostNetwork
المثيرة للاهتمام ، وليس إلى الأدوات المفيدة. في الواقع ، أتعهد بأن أؤكد أنه في 99.99٪ من الحالات ، يمكن اعتبار استخدامها مضادًا للنمط ، ويجب أن يخضع أي نظام يتم استخدامه لفحص إلزامي لهيكله.
اعتقدت أنه لا يستحق الحديث عنها على الإطلاق ، لكنها تشبه الأدوات التي تستخدمها موارد Ingress لمعالجة حركة المرور الواردة ، لذلك قررت أنه يجدر ذكرها ، على الأقل لفترة وجيزة.
أولاً ،
HostPort
نتحدث عن
HostPort
. هذه خاصية حاوية (تم الإعلان عنها في بنية
ContainerPort
). عند كتابة رقم منفذ معين فيه ، يؤدي ذلك إلى فتح هذا المنفذ على العقدة وإلى إعادة توجيهه مباشرة إلى الحاوية. لا توجد آليات بروكسي ، ويتم فتح المنفذ فقط على العقد التي تعمل عليها الحاوية. في الأيام الأولى للنظام الأساسي ، قبل
ظهور آليات
DaemonSet و
StatefulSet فيه ، كان
HostPort
خدعة سمحت فقط بتشغيل حاوية واحدة من نوع معين على أي عقدة. على سبيل المثال ، استخدمت هذا مرة واحدة لإنشاء كتلة
HostPort
عن طريق تعيين
HostPort
إلى
9200
وتحديد العديد من النسخ المتماثلة كما كان هناك العقد. , Kubernetes, -
HostPort
.
NostNetwork
, , Kubernetes ,
HostPort
.
true
, -
network=host
docker run
. , .
eth0
. , . , , , Kubernetes, - .
النتائج
Kubernetes, , Ingress. , , , Kubernetes.
أعزائي القراء! Ingress?
