مقدمة لسياسات شبكة Kubernetes لمتخصصي الأمن



تقريبا. perev. : مؤلف المقال - روفن هاريسون - لديه أكثر من 20 عامًا من الخبرة في مجال تطوير البرمجيات ، واليوم هو المدير التقني والمؤسس المشارك لشركة Tufin ، وهي الشركة التي تنشئ حلول إدارة السياسة الأمنية. نظرًا لسياسات شبكة Kubernetes كأداة قوية بما يكفي لتجزئة الشبكة في كتلة ما ، فإنه يعتقد أنه ليس من السهل تطبيقها في الممارسة العملية. تم تصميم هذه المواد (ضخمة جدًا) لتحسين معرفة المتخصصين في هذا الأمر ومساعدتهم في إنشاء التكوينات الضرورية.

اليوم ، العديد من الشركات تختار بشكل متزايد Kubernetes لتشغيل تطبيقاتها. الاهتمام بهذا البرنامج مرتفع لدرجة أن البعض يطلق عليه Kubernetes "نظام التشغيل الجديد لمركز البيانات". بالتدريج ، يبدأ النظر إلى Kubernetes (أو k8s) كجزء أساسي من العمل ، الأمر الذي يتطلب تنظيم عمليات الأعمال الناضجة ، بما في ذلك أمان الشبكة.

بالنسبة للمتخصصين في مجال الأمن الذين يشعرون بالحيرة من خلال العمل مع Kubernetes ، قد تكون السياسة الافتراضية لهذا النظام الأساسي اكتشافًا حقيقيًا: اسمح للجميع.

سيساعدك هذا الدليل على فهم البنية الداخلية لسياسات الشبكة ؛ فهم كيف تختلف عن قواعد جدران الحماية العادية. سيتم أيضًا وصف بعض المزالق وسيتم تقديم توصيات تساعد على حماية التطبيقات في Kubernetes.

سياسات شبكة Kubernetes


تتيح لك آلية سياسة شبكة Kubernetes التحكم في تفاعل التطبيقات المنشورة على النظام الأساسي على مستوى الشبكة (الثالث في نموذج OSI). تفتقر سياسات الشبكة إلى بعض الميزات المتقدمة للجدران النارية الحديثة ، مثل مراقبة OSI المستوى 7 واكتشاف التهديدات ، ولكنها توفر مستوى أساسيًا من أمان الشبكة ، والذي يعد نقطة انطلاق جيدة.

تتحكم سياسات الشبكة في الاتصالات بين القرون


يتم توزيع أحمال عمل Kubernetes عبر القرون التي تتكون من حاوية واحدة أو أكثر يتم نشرها معًا. Kubernetes يعين كل جراب عنوان IP يمكن الوصول إليها من القرون الأخرى. تحدد سياسات شبكة Kubernetes أذونات لمجموعات pod بنفس طريقة استخدام مجموعات الأمان في السحابة للتحكم في الوصول إلى مثيلات الجهاز الظاهري.

تحديد سياسات الشبكة


مثل موارد Kubernetes الأخرى ، يتم تعيين سياسات الشبكة في YAML. في المثال أدناه ، يتم منح balance حق الوصول إلى postgres :

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres namespace: default spec: podSelector: matchLabels: app: postgres ingress: - from: - podSelector: matchLabels: app: balance policyTypes: - Ingress 



( ملاحظة : لم يتم إنشاء لقطة الشاشة هذه ، مثل جميع اللقطات المشابهة اللاحقة ، باستخدام أدوات Kubernetes الأصلية ، ولكن باستخدام أداة Tufin Orca ، التي طورها مؤلف المقال الأصلي وذكرت في نهاية المقال.)

سيتطلب تحديد سياسة الشبكة الخاصة بك معرفة YAML الأساسية. تعتمد هذه اللغة على المسافة البادئة (التي تحددها المسافات وليس علامات التبويب). ينتمي عنصر المسافة البادئة إلى أقرب عنصر مسافة بادئة فوقه. يبدأ عنصر قائمة جديد بوصل ، وكل العناصر الأخرى ذات قيمة مفاتيح .

بعد وصف السياسة في YAML ، استخدم kubectl لإنشائها في الكتلة:

 kubectl create -f policy.yaml 

مواصفات سياسة الشبكة


تتضمن مواصفات سياسة شبكة Kubernetes أربعة عناصر:

  1. podSelector : يحدد القرون المتأثرة بهذه السياسة (الأهداف) - إلزامي ؛
  2. policyTypes : يشير إلى أنواع السياسات المضمنة في هذا: الدخول و / أو الخروج - اختياري ، ومع ذلك ، أوصي بأن تقوم بتسجيلها بوضوح في جميع الحالات ؛
  3. ingress : يحدد حركة المرور الواردة المسموح بها إلى السنفات المستهدفة - اختياري ؛
  4. egress : يحدد حركة المرور الصادرة المسموح بها من السنفات المستهدفة - اختياري.

مثال مستعار من موقع Kubernetes (قمت باستبدال role app ) يوضح كيفية استخدام العناصر الأربعة:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default spec: podSelector: # <<< matchLabels: app: db policyTypes: # <<< - Ingress - Egress ingress: # <<< - from: - ipBlock: cidr: 172.17.0.0/16 except: - 172.17.1.0/24 - namespaceSelector: matchLabels: project: myproject - podSelector: matchLabels: role: frontend ports: - protocol: TCP port: 6379 egress: # <<< - to: - ipBlock: cidr: 10.0.0.0/24 ports: - protocol: TCP port: 5978 




يرجى ملاحظة أن جميع العناصر الأربعة اختيارية. podSelector فقط ، يمكن استخدام المعلمات الأخرى حسب الرغبة.

إذا حذفت policyTypes ، فسيتم تفسير السياسة على النحو التالي:

  • بشكل افتراضي ، من المفترض أنه يحدد جانب الدخول. إذا كانت السياسة لا تشير إلى ذلك صراحة ، فسيرى النظام أن كل حركة المرور محظورة.
  • سيتم تحديد السلوك على جانب الخروج من خلال وجود أو عدم وجود معلمة الخروج المقابلة.

لتجنب الأخطاء ، أوصي دائمًا بتحديد policyTypes بشكل صريح .

وفقًا للمنطق أعلاه ، إذا تم حذف egress ingress و / أو egress ، فستحظر السياسة كل حركة المرور (انظر "قاعدة التجريد" أدناه).

السياسة الافتراضية هي السماح


إذا لم يتم تحديد سياسات ، فإن Kubernetes بشكل افتراضي يسمح لكل حركة المرور. جميع القرون أحرار في تبادل المعلومات مع بعضها البعض. من وجهة نظر الأمان ، قد يبدو هذا غير بديهي ، ولكن تذكر أن Kubernetes تم إنشاؤه في الأصل من قبل المطورين لضمان التشغيل المتداخل للتطبيق. تم إضافة سياسات الشبكة لاحقًا.

مساحات الأسماء


مساحات الأسماء هي آلية تعاونية لـ Kubernetes. وهي مصممة لعزل البيئات المنطقية عن بعضها البعض ، بينما يُسمح بتبادل البيانات بين المسافات افتراضيًا.

مثل معظم مكونات Kubernetes ، توجد سياسات الشبكة في مساحة اسم محددة. في كتلة metadata الأولية ، يمكنك تحديد المساحة التي تنتمي إليها السياسة:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: my-namespace # <<< spec: ... 

إذا لم تتم كتابة مساحة الاسم بشكل واضح في البيانات الأولية ، فسيستخدم النظام مساحة الاسم المحددة في kubectl (حسب namespace=default ):

 kubectl apply -n my-namespace -f namespace.yaml 

أوصي بتحديد مساحة اسم صراحة ما لم تكن تكتب سياسة مخصصة لمساحات أسماء متعددة مرة واحدة.

podSelector عنصر podSelector الرئيسي في السياسة pods من مساحة الاسم التي تنتمي إليها السياسة (تم رفض الوصول إلى pods من مساحة اسم أخرى).

وبالمثل ، لا تستطيع podSelectors في كتل الدخول والخروج تحديد pods فقط من مساحة الاسم الخاصة بها ، إلا إذا قمت ، بالطبع ، بدمجها مع namespaceSelector (ستتم مناقشتها في القسم "تصفية حسب مساحة الاسم" و "pods") .

قواعد تسمية السياسة


أسماء السياسة فريدة في مساحة اسم واحدة. لا يمكن أن يكون هناك سياستان بنفس الاسم في مسافة واحدة ، ولكن يمكن أن يكون هناك سياسات بنفس الاسم في مسافات مختلفة. يكون هذا مفيدًا عندما تريد إعادة تطبيق نفس السياسة عبر مسافات متعددة.

أنا لا سيما أحب طريقة واحدة للتسمية. يتكون من دمج اسم مساحة الاسم مع السنفات المستهدفة. على سبيل المثال:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres # <<< namespace: default spec: podSelector: matchLabels: app: postgres ingress: - from: - podSelector: matchLabels: app: admin policyTypes: - Ingress 



التسميات


يمكن إرفاق الملصقات المخصصة بكائنات Kubernetes ، مثل القرون ومساحات الأسماء. التسميات هي ما يعادل العلامات في السحابة. تستخدم سياسات شبكة Kubernetes التصنيفات لتحديد الأكواد التي تنطبق عليها:

 podSelector: matchLabels: role: db 

... أو مساحات الأسماء التي تنطبق عليها. في هذا المثال ، يتم تحديد جميع القرون في مساحات الأسماء مع الملصقات ذات الصلة:

 namespaceSelector: matchLabels: project: myproject 

تحذير واحد: عند استخدام namespaceSelector تأكد من أن namespaceSelector التي تحددها تحتوي على التسمية التي تريدها . ضع في اعتبارك أن مساحات الأسماء المدمجة مثل default ونظام kube-system لا تحتوي على تسميات بشكل افتراضي.

يمكنك إضافة تسمية إلى الفضاء كما يلي:

 kubectl label namespace default namespace=default 

في هذه الحالة ، يجب أن تشير مساحة الاسم في قسم metadata الأولية إلى الاسم الفعلي للمساحة ، وليس إلى التسمية:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default # <<< spec: ... 

المصدر والوجهة


تتكون سياسات جدران الحماية من قواعد مع مصادر ووجهات. يتم تحديد سياسات شبكة Kubernetes لهذا الغرض - مجموعة من الأكواد التي يتم تطبيقها عليها ، ثم تضع قواعد لحركة المرور الواردة (دخول) و / أو الصادرة (الخروج). في مثالنا ، سيكون الهدف من السياسة هو جميع البرامج في مساحة الاسم default مع تسمية لها مفتاح app وقيمة db :

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default spec: podSelector: matchLabels: app: db # <<< policyTypes: - Ingress - Egress ingress: - from: - ipBlock: cidr: 172.17.0.0/16 except: - 172.17.1.0/24 - namespaceSelector: matchLabels: project: myproject - podSelector: matchLabels: role: frontend ports: - protocol: TCP port: 6379 egress: - to: - ipBlock: cidr: 10.0.0.0/24 ports: - protocol: TCP port: 5978 




يفتح القسم الفرعي ingress في هذه السياسة حركة المرور الواردة إلى السنفات المستهدفة. وبعبارة أخرى ، الدخول هو المصدر ، والهدف هو المستلم المناسب. وبالمثل ، الخروج هو الهدف ، والهدف هو مصدره.



هذا يعادل قاعدتين لجدار الحماية: Ingress → Target؛ الهدف → الخروج.

الخروج و DNS (مهم!)


عند الحد من حركة المرور الصادرة ، انتبه بشكل خاص إلى DNS - يستخدم Kubernetes هذه الخدمة لتعيين خدمات لعناوين IP. على سبيل المثال ، لن تعمل السياسة التالية لأنك لم تسمح لتطبيق balance بالوصول إلى DNS:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.balance namespace: default spec: podSelector: matchLabels: app: balance egress: - to: - podSelector: matchLabels: app: postgres policyTypes: - Egress 



يمكنك إصلاحه عن طريق فتح الوصول إلى خدمة DNS:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.balance namespace: default spec: podSelector: matchLabels: app: balance egress: - to: - podSelector: matchLabels: app: postgres - to: # <<< ports: # <<< - protocol: UDP # <<< port: 53 # <<< policyTypes: - Egress 



آخر عنصر فارغ ، وبالتالي فإنه يختار بشكل غير مباشر جميع القرون في جميع مساحات الأسماء ، مما يسمح balance بإرسال استعلامات DNS إلى خدمة Kubernetes المقابلة (تعمل عادةً في مساحة kube-system ).

يعمل هذا النهج ، لكنه متساهل للغاية وغير آمن ، لأنه يسمح لك بتوجيه استعلامات DNS خارج المجموعة.

يمكنك تحسينه في ثلاث خطوات متتالية.

1. السماح باستعلامات DNS فقط داخل الكتلة عن طريق إضافة namespaceSelector :

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.balance namespace: default spec: podSelector: matchLabels: app: balance egress: - to: - podSelector: matchLabels: app: postgres - to: - namespaceSelector: {} # <<< ports: - protocol: UDP port: 53 policyTypes: - Egress 



2. السماح باستعلامات DNS فقط في مساحة اسم kube-system .

للقيام بذلك ، أضف تسمية إلى kubectl label namespace kube-system namespace=kube-system kube-system : kubectl label namespace kube-system namespace=kube-system - وقم بتسجيلها في السياسة باستخدام namespaceSelector :

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.balance namespace: default spec: podSelector: matchLabels: app: balance egress: - to: - podSelector: matchLabels: app: postgres - to: - namespaceSelector: # <<< matchLabels: # <<< namespace: kube-system # <<< ports: - protocol: UDP port: 53 policyTypes: - Egress 



3. يمكن للجنون العظمة أن تذهب أبعد من ذلك وتقتصر استعلامات DNS على خدمة DNS محددة في kube-system . في قسم "التصفية حسب مساحات الأسماء والقرون" ، سنشرح كيفية تحقيق ذلك.

خيار آخر هو حل DNS على مستوى مساحة الاسم. في هذه الحالة ، لن تحتاج إلى فتح لكل خدمة:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.dns namespace: default spec: podSelector: {} # <<< egress: - to: - namespaceSelector: {} ports: - protocol: UDP port: 53 policyTypes: - Egress 

تحديد podSelector فارغة كافة pods في مساحة الاسم.



المباراة الأولى وترتيب القاعدة


في جدران الحماية العادية ، يتم تحديد الإجراء ("السماح" أو "الرفض") لحزمة ما بموجب القاعدة الأولى التي ترضيها. في Kubernetes ، ترتيب السياسات غير ذي صلة.

افتراضيًا ، عندما لا يتم تعيين السياسات ، يُسمح بالاتصال بين السنفات ويمكنها تبادل المعلومات بحرية. بمجرد البدء في صياغة السياسات ، يصبح كل قرنة تتأثر بواحدة منها على الأقل معزولة وفقًا للفصل (المنطقي أو) لجميع السياسات التي اختارتها. القرون لا تتأثر بأي سياسة تبقى مفتوحة.

يمكنك تغيير هذا السلوك باستخدام قاعدة تجريد.

قاعدة تجريد (رفض)


تحظر سياسات جدار الحماية عمومًا أي حركة مرور غير مصرح بها صراحة.

ليس لدى Kubernetes إجراء رفض ، ومع ذلك ، يمكن تحقيق تأثير مماثل باستخدام سياسة (السماح) منتظمة من خلال تحديد مجموعة فارغة من السنفات المصدر (الدخول):

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all namespace: default spec: podSelector: {} policyTypes: - Ingress 



تحدد هذه السياسة جميع القرون في مساحة الاسم وتترك الدخول غير محدد ، مما يحظر كل حركة المرور الواردة.

وبالمثل ، يمكنك تقييد كل حركة المرور الصادرة من مساحة الاسم:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all-egress namespace: default spec: podSelector: {} policyTypes: - Egress 



لاحظ أن أي سياسات إضافية تسمح لحركة المرور بقرارات في مساحة الاسم ستكون لها الأسبقية على هذه القاعدة (على غرار إضافة قاعدة السماح على قاعدة الرفض في تكوين جدار الحماية).

السماح للجميع (أي - أي - أي - سماح)


لإنشاء سياسة السماح للكل ، يجب عليك إضافة سياسة الحظر أعلاه مع وجود عنصر فارغ:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all namespace: default spec: podSelector: {} ingress: # <<< - {} # <<< policyTypes: - Ingress 



يسمح بالوصول من جميع البرامج في جميع مساحات الأسماء (وجميع عناوين IP) إلى أي ملفات في مساحة الاسم default . يتم تمكين هذا السلوك افتراضيًا ، لذلك عادة لا يحتاج إلى تعريف إضافي. ومع ذلك ، في بعض الأحيان قد يكون من الضروري تعطيل بعض الأذونات المحددة مؤقتًا لتشخيص المشكلة.

يمكن تضييق القاعدة والسماح بالوصول فقط إلى مجموعة معينة من القرون ( app:balance ) في مساحة الاسم default :

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all-to-balance namespace: default spec: podSelector: matchLabels: app: balance ingress: - {} policyTypes: - Ingress 



تسمح السياسة التالية لكل حركة مرور الدخول والخروج ، بما في ذلك الوصول إلى أي IP خارج الكتلة:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-all spec: podSelector: {} ingress: - {} egress: - {} policyTypes: - Ingress - Egress 




الجمع بين سياسات متعددة


يتم الجمع بين السياسات باستخدام OR المنطقي على ثلاثة مستويات ؛ يتم تعيين أذونات كل جراب وفقًا لفصل جميع السياسات التي تؤثر عليه:

1. في الحقول from وإلى الحقل ، يمكنك تحديد ثلاثة أنواع من العناصر (يتم دمج كل منها باستخدام OR):

  • namespaceSelector - تحديد مساحة الاسم بالكامل ؛
  • podSelector - يختار القرون.
  • ipBlock - يختار شبكة فرعية.

في الوقت نفسه ، لا يقتصر عدد العناصر (حتى نفسها) في القسم الفرعي from / to . سيتم دمج كل منهم بواسطة OR المنطقية.

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres namespace: default spec: ingress: - from: - podSelector: matchLabels: app: indexer - podSelector: matchLabels: app: admin podSelector: matchLabels: app: postgres policyTypes: - Ingress 



2. داخل السياسة ، يمكن أن يحتوي قسم ingress على العديد from العناصر (مدمجة بواسطة OR المنطقي). وبالمثل ، يمكن أن يشتمل قسم egress على العديد من العناصر (يرتبط أيضًا بفقرة):

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres namespace: default spec: ingress: - from: - podSelector: matchLabels: app: indexer - from: - podSelector: matchLabels: app: admin podSelector: matchLabels: app: postgres policyTypes: - Ingress 



3. يتم الجمع بين السياسات المختلفة أيضًا عن طريق المنطق المنطقي

ولكن عند الجمع بينهما ، هناك قيود واحدة أشار إليها كريس كوني : Kubernetes لا يمكنها إلا الجمع بين السياسات مع أنواع السياسات المختلفة ( Ingress أو policyTypes ). السياسات التي تحدد الدخول (أو الخروج) ستحل محل بعضها البعض.

العلاقة بين مساحات الأسماء


افتراضيًا ، يُسمح بتبادل المعلومات بين مساحات الأسماء. يمكن تغيير هذا باستخدام سياسة محظورة تقيد حركة المرور الصادرة و / أو الواردة إلى مساحة الاسم (انظر "قاعدة تجريد" أعلاه).

بمنع الوصول إلى مساحة الاسم (انظر "قاعدة التعرية" أعلاه) ، يمكنك إجراء استثناءات للسياسة التقييدية من خلال السماح بالاتصالات من مساحة اسم معينة باستخدام namespaceSelector :

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: database.postgres namespace: database spec: podSelector: matchLabels: app: postgres ingress: - from: - namespaceSelector: # <<< matchLabels: namespace: default policyTypes: - Ingress 



نتيجةً لذلك ، سيكون لجميع القرون في مساحة الاسم default حق الوصول إلى قرون postgres في مساحة اسم database . ولكن ماذا لو كنت تريد فتح الوصول إلى postgres فقط postgres معينة في مساحة الاسم default ؟

تصفية حسب مساحات الأسماء والقرون


يسمح لك الإصدار 1.11 من Kubernetes والإصدارات الأحدث بتجميع namespaceSelector ومُشغلي podSelector باستخدام المنطقي الأول. يبدو كما يلي:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: database.postgres namespace: database spec: podSelector: matchLabels: app: postgres ingress: - from: - namespaceSelector: matchLabels: namespace: default podSelector: # <<< matchLabels: app: admin policyTypes: - Ingress 



لماذا يتم تفسيره كـ AND بدلاً من OR المعتاد؟

لاحظ أن podSelector لا يبدأ podSelector . في YAML ، هذا يعني أن podSelector namespaceSelector أمامه تشير إلى عنصر القائمة نفسه. لذلك ، يتم دمجها بواسطة المنطقية الأولى.

podSelector إضافة واصلة أمام podSelector إلى عنصر قائمة جديد سيتم دمجه مع namespaceSelector السابقة المحددة باستخدام OR منطقي.

لتحديد حافظات مع تسمية محددة في جميع مساحات الأسماء ، أدخل namespaceSelector :

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: database.postgres namespace: database spec: podSelector: matchLabels: app: postgres ingress: - from: - namespaceSelector: {} podSelector: matchLabels: app: admin policyTypes: - Ingress 



تتحد الملصقات المتعددة مع AND


يتم دمج قواعد جدار الحماية مع العديد من الكائنات (المضيفين والشبكات والمجموعات) باستخدام OR المنطقي. ستعمل القاعدة التالية إذا كان مصدر الحزمة يطابق Host_1 أو Host_2 :

 | Source | Destination | Service | Action | | ----------------------------------------| | Host_1 | Subnet_A | HTTPS | Allow | | Host_2 | | | | | ----------------------------------------| 

على العكس من ذلك ، في Kubernetes ، يتم الجمع بين التسميات المختلفة في podSelector أو namespaceSelector بواسطة المنطق المنطقي I. على سبيل المثال ، ستحدد القاعدة التالية podSelector التي تحتوي على كلتا التسميات ، role=db AND version=v2 :

 podSelector: matchLabels: role: db version: v2 

ينطبق نفس المنطق على جميع أنواع العوامل: محددات أهداف السياسة ، محددات الحافظة ، محددات مساحة الاسم.

الشبكات الفرعية وعناوين IP (IPBlocks)


تستخدم جدران الحماية شبكات محلية ظاهرية وعناوين IP وشبكات فرعية لتقسيم الشبكة.

في Kubernetes ، يتم تعيين عناوين IP للقرون تلقائيًا ويمكن أن تتغير بشكل متكرر ، لذلك يتم استخدام الملصقات لتحديد الحافظات ومساحات الأسماء في سياسات الشبكة.

ipBlocks ( ipBlocks ) للتحكم في الاتصالات الخارجية (الداخلية) أو الخارجية (الخارجية) (الشمالية-الجنوبية). على سبيل المثال ، توفر هذه السياسة لجميع القرون من الوصول default لمساحة الاسم إلى خدمة Google DNS:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: egress-dns namespace: default spec: podSelector: {} policyTypes: - Egress egress: - to: - ipBlock: cidr: 8.8.8.8/32 ports: - protocol: UDP port: 53 



يعني محدد الجراب الفارغ في هذا المثال "تحديد جميع الحافظات في مساحة الاسم."

توفر هذه السياسة الوصول إلى 8.8.8.8 فقط ؛ تم رفض الوصول إلى أي IP آخر. وبالتالي ، في الأساس ، قمت بحظر الوصول إلى خدمة DNS الداخلية Kubernetes. إذا كنت لا تزال ترغب في فتحه ، فحدده بوضوح.

عادةً ما تكون ipBlocks و podSelectors حصرية بشكل متبادل ، نظرًا لعدم استخدام عناوين IP الداخلية ipBlocks في ipBlocks . من خلال تحديد حافظات IP الداخلية ، ستسمح فعليًا بالاتصالات من / إلى الحافظات التي تحتوي على هذه العناوين. في الممارسة العملية ، لن تعرف عنوان IP المراد استخدامه ، وهذا هو السبب في أنه لا ينبغي استخدامها لتحديد السنفات.

كمثال مضاد ، تشتمل السياسة التالية على جميع عناوين IP ، وبالتالي ، تتيح الوصول إلى جميع البرامج الأخرى:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: egress-any namespace: default spec: podSelector: {} policyTypes: - Egress egress: - to: - ipBlock: cidr: 0.0.0.0/0 



يمكنك فتح الوصول إلى عناوين IP الخارجية فقط عن طريق استبعاد عناوين IP الداخلية للقرون. على سبيل المثال ، إذا كانت الشبكة الفرعية الخاصة بـ pod هي 10.16.0.0/14:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: egress-any namespace: default spec: podSelector: {} policyTypes: - Egress egress: - to: - ipBlock: cidr: 0.0.0.0/0 except: - 10.16.0.0/14 



الموانئ والبروتوكولات


القرون عادة الاستماع على منفذ واحد. هذا يعني أنه يمكنك ببساطة حذف أرقام المنافذ في السياسات وترك كل شيء افتراضيًا. ومع ذلك ، يوصى بوضع سياسات تقييدية قدر الإمكان ، لذلك في بعض الحالات لا يزال بإمكانك تحديد المنافذ:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres namespace: default spec: ingress: - from: - podSelector: matchLabels: app: indexer - podSelector: matchLabels: app: admin ports: # <<< - port: 443 # <<< protocol: TCP # <<< - port: 80 # <<< protocol: TCP # <<< podSelector: matchLabels: app: postgres policyTypes: - Ingress 



لاحظ أن محدد ports ينطبق على جميع العناصر الموجودة في الكتلة التي يحتوي عليها أو منه. لتحديد منافذ مختلفة لمجموعات مختلفة من العناصر ، قم بتقسيم ingress أو egress إلى عدة أقسام فرعية مع أو from ingress egress في كل منها:

 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default.postgres namespace: default spec: ingress: - from: - podSelector: matchLabels: app: indexer ports: # <<< - port: 443 # <<< protocol: TCP # <<< - from: - podSelector: matchLabels: app: admin ports: # <<< - port: 80 # <<< protocol: TCP # <<< podSelector: matchLabels: app: postgres policyTypes: - Ingress 



المنافذ الافتراضية تعمل:

  • إذا حذفت تعريف المنافذ تمامًا ، فهذا يعني جميع البروتوكولات وجميع المنافذ ؛
  • إذا حذفت تعريف البروتوكول ، فهذا يعني TCP ؛
  • إذا حذفت تعريف المنفذ ، فهذا يعني جميع المنافذ.

أفضل ممارسة: لا تعتمد على القيم الافتراضية ، حدد ما تريده صراحة.

يرجى ملاحظة أنه من الضروري استخدام منافذ pod ، وليس الخدمات (المزيد حول هذا الموضوع في الفقرة التالية).

هل تم تعريف السياسات الخاصة بالقرون أو الخدمات؟


عادةً ما تتصل القرون في Kubernetes ببعضها البعض من خلال خدمة - موازن تحميل افتراضي يعيد توجيه حركة المرور إلى قرون تنفذ الخدمة. قد تعتقد أن سياسات الشبكة تتحكم في الوصول إلى الخدمات ، ولكن هذا ليس كذلك. تعمل سياسات شبكة Kubernetes مع منافذ pod ، وليس الخدمات.

, 80- , 8080 pod', 8080.

: ( pod') .

Service Mesh (, . Istio — . .) .

Ingress, Egress?


— , pod pod' , ( egress-), pod ( , , ingress-).

, .

pod- egress -, . pod'- . pod - , (egress) .

pod'- , ingress -, . pod'-. pod - , (ingress) .

. «Stateful Stateless» .


Kubernetes . , , .


Kubernetes (DNS) egress. , IP- ( aws.com).


. Kubernetes . kubectl Kubernetes , , . Kubernetes . :

 kubernetes get networkpolicy <policy-name> -o yaml 

, Kubernetes .


Kubernetes , API-, , Container Networking Interface (CNI). Kubernetes CNI . CNI , Kubernetes, ( — . .) , , CNI .

, Kubernetes , CNI.

Stateful Stateless?


CNI Kubernetes, , (, Calico Linux conntrack). pod' TCP- . Kubernetes, (statefulness).


Kubernetes:

  1. Service Mesh sidecar- . Istio .
  2. CNI , Kubernetes.
  3. Tufin Orca Kubernetes.

Tufin Orca Kubernetes ( , ).



الخاتمة


Kubernetes , . , - . .

, , .

PS من المترجم


اقرأ أيضًا في مدونتنا:

Source: https://habr.com/ru/post/ar443190/


All Articles