نغلق الثقوب في مجموعة Kubernetes. تقرير ونسخة مع DevOpsConf

ألقى بافيل سيليفانوف ، مهندس حلول Southbridge ومعلم Slurm ، محاضرة في DevOpsConf 2019. هذه المحادثة جزء من أحد مواضيع دورة Slurm Mega المتقدمة Kubernetes.

Slurm Basic: مقدمة إلى Kubernetes يقام في موسكو في 18-20 نوفمبر.
Slurm Mega: نظرة خاطفة تحت غطاء Kubernetes - موسكو ، 22-24 نوفمبر.
Slurm Online: كلتا دورات Kubernetes دائما متاح.

تحت قص - نسخة من التقرير.

مساء الخير أيها الزملاء والمتعاطفون. اليوم سأتحدث عن الأمن.

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

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

حاولت شركتي السابقة بيع مثل هذه الخدمة. وقد طُلب مني أن أتحدث عن الموضوع - سواء كان هذا الحل مناسبًا أم لا.

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

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

سأخبرك بأمثلة كيف فعلت ذلك وكيف أدافع ضده.

لكن أولاً ، اسمحوا لي أن أقدم نفسي. اسمي بافيل سيليفانوف. أنا مهندس معماري في ساوثبريدج. أنا أفهم Kubernetes و DevOps وجميع أنواع الأشياء الفاخرة. أنا ومهندسو ساوثبريدج نبني كل شيء ، وأنا أستشير.

بالإضافة إلى أنشطتنا الرئيسية ، أطلقنا مؤخرًا مشاريع تسمى Slurms. نحاول أن نجلب قدرتنا على العمل مع Kubernetes إلى الجماهير قليلاً ، لتعليم الآخرين كيفية العمل مع K8s أيضًا.

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

سأتحدث عما يؤلمني أنا وزملائي من الأمن في مجموعة Kubernetes. نرى هذه المشكلات مع كل من مقدمي الخدمة الذين يقدمون مجموعات Kubernetes والعملاء الذين يأتون إلينا. وحتى للعملاء الذين يأتون إلينا من شركات إدارية استشارية أخرى. أي أن حجم المأساة كبير جدًا في الواقع.

حرفيًا ثلاث نقاط سأتحدث عنها اليوم:

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

شيء عام آخر سأذكره هو ما اختبرت كل شيء عليه ، والذي يمكنني القول بالتأكيد أنه يعمل بالكامل.

كأساس ، نتخذ تثبيت مجموعة Kubernetes باستخدام Kubespray. إذا كان شخص ما لا يعرف ، فهذه في الواقع مجموعة من الأدوار لـ Ansible. نحن نستخدمه طوال الوقت في العمل. الشيء الجيد هو أنه يمكنك التدحرج في أي مكان - ويمكنك التدحرج على قطع الحديد ، وفي مكان ما في السحابة. طريقة تثبيت واحدة مناسبة من حيث المبدأ لكل شيء.

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

نغلق الثقوب في مجموعة Kubernetes. تقرير ونسخة مع DevOpsConf

لقد وعدت بأن أول شيء سيكون لدينا هو الحصول على حقوق المسؤول في الكتلة. نحتاج إلى جراب مُعد خصيصًا من شأنه أن يكسر كتلة Kubernetes. كل ما علينا فعله هو تطبيقه على مجموعة Kubernetes.

kubectl apply -f pod.yaml

سيأتي هذا الكبسولة إلى أحد أساتذة مجموعة Kubernetes. وسيعيد الكتلة لحسن الحظ ملفًا يسمى admin.conf بعد ذلك. في كوبا ، يخزن هذا الملف جميع شهادات الإدارة ، وفي نفس الوقت يتم تكوين API للكتلة. هذا هو مدى سهولة الحصول على وصول المسؤول ، على ما أعتقد ، إلى 98٪ من مجموعات Kubernetes.

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

والآن عن موقد مُعد خصيصًا. نطلق على أي صورة. لنأخذ Debian: jessie كمثال.

لدينا شيء مثل هذا:

tolerations:
-   effect: NoSchedule 
    operator: Exists 
nodeSelector: 
    node-role.kubernetes.io/master: "" 

ما هو التسامح؟ عادةً ما يتم تصنيف الماجستير في مجموعة Kubernetes بشيء يسمى taint. وجوهر هذه "العدوى" أنها تقول أنه لا يمكن تخصيص القرون للعقد الرئيسية. لكن لا أحد يكلف نفسه عناء الإشارة في أي جراب إلى أنه يتحمل "العدوى". يقول قسم التسامح فقط أنه إذا تم تثبيت NoSchedule على عقدة ما ، فإن جرابنا يتحمل مثل هذه العدوى - ولا توجد مشاكل.

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

مع هذين القسمين ، سيأتي بالتأكيد إلى السيد. وسيسمح له بالعيش هناك.

لكن مجرد المجيء إلى السيد لا يكفي بالنسبة لنا. لن يعطينا أي شيء. بعد ذلك ، لدينا هذين الأمرين:

hostNetwork: true 
hostPID: true 

نحدد أن الكبسولة التي نقوم بتشغيلها ستعيش في مساحة اسم kernel ومساحة اسم الشبكة ومساحة اسم PID. بمجرد تشغيل الكبسولة على الجهاز الرئيسي ، سيكون قادرًا على رؤية جميع الواجهات الحقيقية الحية لتلك العقدة ، والاستماع إلى كل حركة المرور ، ومشاهدة معرفات PID لجميع العمليات.

ثم الأمر متروك للأشياء الصغيرة. خذ وما إلى ذلك واقرأ ما تريد.

الشيء الأكثر إثارة للاهتمام هو ميزة Kubernetes هذه ، والتي توجد بشكل افتراضي.

volumeMounts:
- mountPath: /host 
  name: host 
volumes:
- hostPath: 
    path: / 
    type: Directory 
  name: host 

وجوهرها هو أنه يمكننا ، في الكبسولة التي نطلقها ، حتى بدون حقوق لهذه المجموعة ، أن نقول إننا نريد إنشاء وحدة تخزين من نوع مسار المضيف. لذا خذ المسار من المضيف الذي سنبدأ منه - واعتبره وحدة تخزين. ثم نسميها الاسم: المضيف. نقوم بتركيب كل هذا hostPath داخل الكبسولة. في هذا المثال ، إلى الدليل / host.

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

أنت تفهم أنه في دبيان لدينا bash run ، وهذا bash يعمل بالنسبة لنا كجذر. وهذا يعني أننا حصلنا للتو على الجذر في النظام الرئيسي ، بينما لا نملك أي حقوق في مجموعة Kubernetes.

بعد ذلك ، تكون المهمة بأكملها هي الانتقال إلى الدليل / المضيف / الخ / kubernetes / pki ، إذا لم أكن مخطئًا ، فاختر جميع الشهادات الرئيسية للكتلة هناك ، وبناءً عليه ، تصبح مشرف المجموعة.

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

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

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

حجم مسار المضيف - في رأيي ، أسرع طريقة للحصول على النتيجة المرجوة من مجموعة Kubernetes.

لكن ماذا تفعل بكل هذا؟

الأفكار التي يجب أن تأتي إلى أي مسؤول عادي يواجه Kubernetes: "نعم ، لقد أخبرتك ، Kubernetes لا يعمل. فيه ثقوب فيه. والمكعب كله هراء ". في الواقع ، هناك شيء مثل التوثيق ، وإذا نظرت هناك ، فهناك قسم نهج أمان جراب.

هذا كائن yaml - يمكننا إنشاؤه في مجموعة Kubernetes - التي تتحكم في جوانب الأمان في وصف البودات. وهذا يعني ، في الواقع ، أنه يتحكم في حقوق استخدام أي شبكة مضيفة ، أو hostPID ، وأنواع معينة من وحدات التخزين الموجودة في القرون عند بدء التشغيل. بمساعدة سياسة أمان Pod ، يمكن وصف كل هذا.

الشيء الأكثر إثارة للاهتمام حول Pod Security Policy هو أنه في مجموعة Kubernetes ، لا يتم وصف جميع أدوات تثبيت PSP بأي شكل من الأشكال ، بل يتم إيقاف تشغيلها افتراضيًا. يتم تمكين Pod Security Policy باستخدام المكون الإضافي للقبول.

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

ويبدو أننا بخير. ولا يمكن اختراق مجموعة Kubernetes الخاصة بنا في دقيقتين.

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

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

ربما قرأ الجميع نفس المقالات عن حبري ، والمراقبة موجودة في مساحة أسماء المراقبة. يُطلق على مخطط Helm الاسم نفسه تقريبًا للجميع. أعتقد أنه إذا قمت بتثبيت مستقر / بروميثيوس ، فيجب أن ينتهي بك الأمر بنفس الأسماء تقريبًا. وحتى على الأرجح لن أضطر إلى تخمين اسم DNS في مجموعتك. لأنه قياسي.

نغلق الثقوب في مجموعة Kubernetes. تقرير ونسخة مع DevOpsConf

بعد ذلك ، لدينا dev ns معين ، حيث يمكنك تشغيل جراب معين. وبعد ذلك ، من السهل جدًا القيام بذلك من خلال هذا الكبسولة:

$ curl http://prometheus-kube-state-metrics.monitoring 

prometheus-kube-state-metrics هي واحدة من مصدري بروميثيوس الذين يجمعون المقاييس من Kubernetes API نفسها. هناك الكثير من البيانات ، ما الذي يتم تشغيله في مجموعتك ، وما هي المشاكل التي تواجهها معها.

كمثال بسيط:

kube_pod_container_info {namespace = "kube-system"، pod = "kube-apiserver-k8s-1"، container = "kube-apiserver"، image =

"gcr.io/google-containers/kube-apserver:v1.14.5"

,image_id=»docker-pullable://gcr.io/google-containers/kube- apiserver@sha256:e29561119a52adad9edc72bfe0e7fcab308501313b09bf99df4a96 38ee634989″,container_id=»docker://7cbe7b1fea33f811fdd8f7e0e079191110268f2 853397d7daf08e72c22d3cf8b»} 1

من خلال إجراء طلب تجعيد بسيط من حجرة غير متميزة ، يمكنك الحصول على معلومات مثل هذه. إذا كنت لا تعرف إصدار Kubernetes الذي تقوم بتشغيله ، فسيخبرك بسهولة.

والشيء الأكثر إثارة للاهتمام هو أنه بالإضافة إلى حقيقة أنك تصل إلى مقاييس kube-state-metrics ، يمكنك أيضًا الوصول إلى بروميثيوس نفسه مباشرةً. يمكنك جمع المقاييس من هناك. يمكنك حتى بناء مقاييس من هناك. حتى من الناحية النظرية ، يمكنك إنشاء مثل هذا الاستعلام من مجموعة في بروميثيوس ، والذي سيؤدي ببساطة إلى إيقاف تشغيله. وستتوقف مراقبتك عمومًا عن العمل من الكتلة.

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

تمامًا كما هو الحال مع PSP ، يبدو أن المشكلة تكمن في أن كل هذه التقنيات الرائعة - Kubernetes و Prometheus - لا تعمل ومليئة بالثغرات. ليس حقيقيًا.

هناك شيء من هذا القبيل - سياسة الشبكة.

إذا كنت مسؤولًا عاديًا ، فمن المرجح أنك تعرف عن سياسة الشبكة أن هذا هو yaml آخر ، يوجد منه بالفعل dofiga في المجموعة. وسياسات الشبكة ليست هناك حاجة بالتأكيد. وحتى إذا قرأت ما هي سياسة الشبكة ، وما هو جدار الحماية Kubernetes yaml ، فإنه يسمح لك بتقييد حقوق الوصول بين مساحات الأسماء ، وبين البودات ، ثم قررت بالتأكيد أن جدار الحماية yaml في Kubernetes يعتمد على التجريدات التالية ... لا لا. إنه بالتأكيد ليس ضروريًا.

حتى إذا لم يتم إخبار المتخصصين في الأمن لديك أنه بمساعدة Kubernetes ، يمكنك إنشاء جدار حماية سهل وبسيط للغاية ومحبب للغاية. إذا كانوا لا يعرفون هذا حتى الآن ولم يسحبوك: "حسنًا ، أعطه ، أعطه ..." ثم على أي حال ، تحتاج إلى سياسة الشبكة لمنع الوصول إلى بعض أماكن الخدمة التي يمكنك سحبها من مجموعتك بدون أي إذن.

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

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

ماذا تفعل؟

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

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

عندما ترفع كتلة جديدة ، أدخل في نفس الوقت كاليكو بدلاً من الفانيلا.

ماذا تفعل إذا كانت لديك شهادات صادرة منذ مائة عام ولن تعيد نشر الكتلة؟ هناك شيء من هذا القبيل Kube-RBAC-Proxy. هذا تطور رائع للغاية ، فهو يسمح لك بتضمين نفسه كحاوية جانبية لأي جراب في مجموعة Kubernetes. ويضيف في الواقع إذنًا من خلال RBAC الخاص بـ Kubernetes نفسه إلى هذه المجموعة.

هناك مشكلة واحدة. في السابق ، تم بناء حل Kube-RBAC-Proxy هذا في بروميثيوس المشغل. ولكن بعد ذلك رحل. تعتمد الإصدارات الحديثة الآن على حقيقة أن لديك سياسات شبكة وتغلقها بها. ولذا عليك إعادة كتابة الرسم البياني قليلاً. في الواقع ، إذا ذهبت إلى هذا المستودع، هناك أمثلة على كيفية استخدامها كعربات جانبية ، وسيتعين إعادة كتابة المخططات في الحد الأدنى.

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

لكن كما قلت ، إذا لم تتمكن من الوصول إلى الكتلة وجمع المعلومات ، فيمكنك على الأقل إلحاق الضرر.

لذلك سأريكم بسرعة طريقتين يمكن أن تمرض بهما مجموعة Kubernetes.

سوف تضحك عندما أخبرك ، هاتان حالتان حقيقيتان.

الطريقة الأولى. استنفاد الموارد.

نحن بصدد إطلاق جراب خاص آخر. سيحتوي هذا القسم.

resources: 
    requests: 
        cpu: 4 
        memory: 4Gi 

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

إذا قمت بتشغيل مثل هذا الكبسولة ، فأنا أصدر الأمر:

$ kubectl scale special-pod --replicas=...

بعد ذلك لن يتمكن أي شخص آخر من النشر إلى مجموعة Kubernetes. لأن جميع العقد سوف تنفد من الطلبات. ولذا سوف أوقف مجموعة Kubernetes الخاصة بك. إذا قمت بذلك في المساء ، فيمكن إيقاف عمليات النشر لفترة طويلة جدًا.

إذا نظرنا مرة أخرى إلى وثائق Kubernetes ، فسنرى شيئًا يسمى Limit Range. يحدد الموارد لكائنات الكتلة. يمكنك كتابة كائن Limit Range في yaml ، وتطبيقه على مساحات أسماء معينة - وفي مساحة الاسم هذه ، يمكنك القول إن لديك موارد للقرون الافتراضية والحد الأقصى والحد الأدنى.

بمساعدة مثل هذا الشيء ، يمكننا تقييد المستخدمين في مساحات أسماء منتجات فريق معينة من القدرة على الإشارة إلى جميع أنواع الأشياء السيئة في كبسولاتهم. لكن لسوء الحظ ، حتى إذا أخبرت المستخدم أنه لا يمكنك تشغيل البودات بطلبات لأكثر من وحدة معالجة مركزية واحدة ، فهناك أمر مقياس رائع ، حسنًا ، أو من خلال لوحة القيادة يمكنهم إجراء القياس.

وهنا يأتي دور العدد الثاني. قم بتشغيل 11 كبسولة. إنه أحد عشر مليارًا. هذا ليس لأنني توصلت إلى مثل هذا الرقم ، ولكن لأنني رأيته بنفسي.

قصة حقيقية. كنت على وشك مغادرة المكتب في وقت متأخر من المساء. أنا أنظر ، مجموعة من المطورين يجلسون في الزاوية ويفعلون شيئًا ما بشكل محموم مع أجهزة الكمبيوتر المحمولة. أتوجه إلى الرجال وأسألهم: "ماذا حدث لكم؟"

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

صحيح أن هذه القصة لم تحدث على Kubernetes ، في ذلك الوقت كانت Nomad. انتهى الأمر بحقيقة أنه بعد ساعة من محاولاتنا لمنع Nomad من محاولات التوسع العنيدة ، أجاب Nomad أنه لن يتوقف عن التوسع ولن يفعل أي شيء آخر. "أنا متعب ، سأرحل". واستدار.

حاولت بطبيعة الحال أن أفعل الشيء نفسه على Kubernetes. أحد عشر مليار كبسولة لم يرضها كوبيرنيتس ، قال: "لا أستطيع. يتجاوز الحدود القصوى الداخلية. لكن يمكن أن يصل عدد الكبسولات إلى 1،000،000،000.

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

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

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

إذا قمت بتشغيل مليار قرنة ، على سبيل المثال ، ثم استخدم برنامجًا نصيًا لإجبار Kubernetis على إنشاء خدمات جديدة:

for i in {1..1111111}; do
    kubectl expose deployment test --port 80  
        --overrides="{"apiVersion": "v1", 
           "metadata": {"name": "nginx$i"}}"; 
done 

على جميع عقد الكتلة ، سيتم إنشاء المزيد والمزيد من قواعد iptables الجديدة في وقت واحد تقريبًا. علاوة على ذلك ، سيتم إنشاء مليار قاعدة iptables لكل خدمة.

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

وهذا أيضًا تم حله بمساعدة Kubernetes. هناك مثل حصة الموارد الكائن. يضبط عدد الموارد والكائنات المتاحة لمساحة الاسم في الكتلة. يمكننا إنشاء كائن yaml في كل مساحة اسم مجموعة Kubernetes. بمساعدة هذا الكائن ، يمكننا القول أن لدينا عددًا معينًا من الطلبات ، والحدود المخصصة لمساحة الاسم هذه ، علاوة على ذلك يمكننا القول أنه من الممكن إنشاء 10 خدمات و 10 وحدات تخزين في مساحة الاسم هذه. ويمكن لمطور واحد أن يسحق نفسه في المساء. سيخبره Kubernetes: "لا يمكنك توسيع نطاق البودات الخاصة بك إلى مثل هذا المبلغ ، لأنه يتجاوز حصة الموارد." هذا كل شيء ، تم حل المشكلة. التوثيق هنا.

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

حصة الموارد + نطاق الحد + RBAC
• إنشاء مساحة اسم
• إنشاء المدى الداخلي
• إنشاء الموارد الداخلية
• إنشاء حساب خدمة لـ CI
• إنشاء ربط الأدوار لـ CI والمستخدمين
• قم بتشغيل كبسولات الخدمة الضرورية اختياريًا

لذلك ، وأغتنم هذه الفرصة ، أود أن أشارككم التطورات. هناك شيء يسمى مشغل SDK. هذه هي الطريقة في مجموعة Kubernetes لكتابة تعليمات لها. يمكنك كتابة البيانات باستخدام Ansible.

في البداية ، كتبنا في Ansible ، ثم نظرت إلى ماهية مشغل SDK وأعدت كتابة دور Ansible إلى عامل. تسمح لك هذه العبارة بإنشاء كائن في مجموعة Kubernetes يسمى الأمر. داخل الأمر ، يسمح لك بوصف البيئة لهذا الأمر في yaml. وداخل بيئة الفريق ، يسمح لنا بوصف أننا نخصص الكثير من الموارد.

صغيرتي الميسر لهذه العملية المعقدة.

وفي الختام. ماذا تفعل بكل هذا؟
أولاً. سياسة أمان Pod جيدة. وعلى الرغم من حقيقة أن أيا من مُثبِّتي Kubernetes لا يستخدمها حتى يومنا هذا ، فلا يزال يتعين عليك استخدامها في مجموعاتك.

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

LimitRange / ResourceQuota - حان وقت الاستخدام. لقد بدأنا استخدامه منذ فترة طويلة ، ولفترة طويلة كنت متأكدًا من أن الجميع بدون استثناء يستخدمه. اتضح أن هذا نادر.

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

بعض الأشياء حزينة ومؤلمة للغاية. على سبيل المثال ، في ظل ظروف معينة ، يمكن للمكعبات في مجموعة Kubernetes إعطاء محتويات دليل warlocks ولمستخدم غير مصرح له.

هنا هناك تعليمات حول كيفية إعادة إنتاج كل ما قلته. هناك ملفات مع أمثلة الإنتاج ، كيف تبدو ResourceQuota ، Pod Security Policy. ويمكن لمس كل هذا.

شكرا للجميع.

المصدر: www.habr.com

إضافة تعليق