متطلبات تطوير تطبيق في Kubernetes

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

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

اسمي بافيل سيليفانوف، حاليًا أنا مهندس DevOps الرائد في Mail.ru Cloud Solutions، نحن نصنع السحاب ونصنع kubernetes للإدارة وما إلى ذلك. تتضمن مهامي الآن المساعدة في التطوير، ونشر هذه السحابات، وطرح التطبيقات التي نكتبها، والتطوير المباشر للأدوات التي نقدمها لمستخدمينا.

متطلبات تطوير تطبيق في Kubernetes

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

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

إذا تحدثنا عن خطة ما سأتحدث عنه، فستبدو هكذا، بين قوسين مكتوب (TL؛DR) - "طويل جدًا؛ طويل جدًا؛ لا تقرأ". سيتكون عرضي اليوم من قوائم لا نهاية لها.

متطلبات تطوير تطبيق في Kubernetes

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

نظرًا لأن هذه المعلومات، بشكل عام، هي "ctrl+c, ctrl+v"، من بين أمور أخرى، من Wiki الخاص بنا في قسم DevOps، حيث كتبنا متطلبات للمطورين: "يا رفاق، حتى نطلق تطبيقكم في Kubernetes، ينبغي أن يكون الأمر هكذا."

ولهذا السبب تبين أن العرض التقديمي عبارة عن قائمة كبيرة. آسف. سأحاول أن أقول أكبر قدر ممكن حتى لا يكون الأمر مملاً إن أمكن.

ما سننظر إليه الآن:

  • هذه هي، أولا، السجلات (سجلات التطبيق؟)، ماذا تفعل بها في Kubernetes، ماذا تفعل بها، ما ينبغي أن تكون؛
  • ما يجب فعله بالتكوينات في Kubernetes، ما هي أفضل وأسوأ الطرق لتكوين تطبيق لـ Kubernetes؛
  • دعونا نتحدث عن ما هي عمليات التحقق من إمكانية الوصول بشكل عام، وكيف ينبغي أن تبدو؛
  • دعونا نتحدث عن ماهية الإغلاق الرشيق؛
  • دعونا نتحدث عن الموارد مرة أخرى؛
  • دعونا نتطرق إلى موضوع تخزين البيانات مرة أخرى؛
  • وفي النهاية سأخبرك ما هو مصطلح هذا التطبيق السحابي الأصلي الغامض. Cloudnativeness، كصفة لهذا المصطلح.

السجلات

أقترح البدء بالسجلات - حيث يجب دفع هذه السجلات إلى Kubernetes. لقد قمت الآن بتشغيل تطبيق في Kubernetes. وفقًا للكلاسيكيات، كانت التطبيقات السابقة تكتب دائمًا سجلات في مكان ما في الملف. قامت التطبيقات السيئة بكتابة سجلات إلى ملف في الدليل الرئيسي للمطور الذي قام بتشغيل التطبيق. كتبت التطبيقات الجيدة سجلات إلى ملف في مكان ما /var/log.

متطلبات تطوير تطبيق في Kubernetes

وفقًا لذلك، علاوة على ذلك، قام المسؤولون الجيدون بتكوين بعض الأشياء في بنيتهم ​​التحتية بحيث يمكن لهذه السجلات تدويرها - نفس سجل rsyslog، الذي ينظر إلى هذه السجلات وعندما يحدث شيء ما لها، يكون هناك الكثير منها، ويقوم بإنشاء نسخ احتياطية، ويضع السجلات هناك ، يحذف الملفات القديمة، أكثر من أسبوع وستة أشهر وبعضها أكثر. من الناحية النظرية، يجب أن يكون لدينا أحكام بحيث لا تنفد المساحة الموجودة على خوادم الإنتاج (خوادم القتال؟) لمجرد أن التطبيق يكتب السجلات. وعليه فإن الإنتاج بأكمله لم يتوقف بسبب جذوع الأشجار.

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

اتضح أنه إذا تحدثنا عن Kubernetes، فإن المكان المناسب لكتابة السجلات في مكان ما من حاوية عامل الإرساء هو ببساطة كتابتها من التطبيق إلى ما يسمى Stdout/Stderr، أي تدفقات الإخراج القياسية لنظام التشغيل، والخطأ القياسي الإخراج . هذه هي الطريقة الصحيحة والأبسط والأكثر منطقية لوضع السجلات من حيث المبدأ في Docker وتحديداً في Kubernetis. لأنه إذا كان تطبيقك يكتب سجلات إلى Stdout/Stderr، فإن الأمر متروك لـ Docker والوظيفة الإضافية Kubernetes لتحديد ما يجب فعله بهذه السجلات. سيقوم Docker افتراضيًا بإنشاء ملفاته الخاصة بتنسيق JSON.

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

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

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

الفكرة الأكثر أهمية، التي أريد تكرارها مرة أخرى، هي أنه داخل Docker، وخاصة داخل Kubernetes، يعد تخزين سجلاتك في ملف فكرة سيئة للغاية.

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

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

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

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

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

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

متطلبات تطوير تطبيق في Kubernetes

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

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

ترتيب

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

Docker، في رأيي، يتعلق بالمعايير. وهناك معايير لكل شيء تقريبًا: معايير لبناء تطبيقك، ومعايير لتثبيت تطبيقك.

متطلبات تطوير تطبيق في Kubernetes

وهذا الشيء - استخدمناه من قبل، وقد أصبح شائعًا بشكل خاص مع ظهور الحاويات - هذا الشيء يسمى متغيرات ENV (البيئة)، أي متغيرات البيئة الموجودة في نظام التشغيل الخاص بك. تعد هذه بشكل عام طريقة مثالية لتكوين التطبيق الخاص بك، لأنه إذا كان لديك تطبيقات في JAVA وPython وGo وPerl، لا قدر الله، ويمكنهم جميعًا قراءة مضيف قاعدة البيانات، ومستخدم قاعدة البيانات، ومتغيرات كلمة مرور قاعدة البيانات، فهي مثالية. لديك تطبيقات بأربع لغات مختلفة تم تكوينها في خطة قاعدة البيانات بنفس الطريقة. لا يوجد المزيد من التكوينات المختلفة.

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

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

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

السؤال الوحيد هو أن التكوينات ليست كما تعتقد. Config.pi ليس تكوينًا مناسبًا للاستخدام. أو بعض التكوينات بتنسيقك الخاص، أو موهوبًا بدلاً من ذلك - وهذا أيضًا ليس التكوين الذي أقصده.

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

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

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

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

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

فحص طبي

النقطة التالية هي هذا الشيء الذي يسمى الفحص الصحي. بشكل عام، الفحص الصحي هو ببساطة التحقق من عمل التطبيق الخاص بك. في الوقت نفسه، نتحدث غالبًا عن بعض تطبيقات الويب، والتي، وفقًا لذلك، من وجهة نظر الفحص الصحي (من الأفضل عدم الترجمة هنا وأكثر) سيكون هذا عنوان URL خاصًا، والذي تتم معالجته كـ معيار، يفعلون عادة /health.

عند الوصول إلى عنوان URL هذا، يقول تطبيقنا إما "نعم، حسنًا، كل شيء على ما يرام معي، 200" أو "لا، كل شيء ليس على ما يرام معي، حوالي 500". وفقًا لذلك، إذا لم يكن تطبيقنا http، وليس تطبيق ويب، فنحن نتحدث الآن عن نوع ما من البرنامج الخفي، يمكننا معرفة كيفية إجراء عمليات التحقق من الصحة. أي أنه ليس من الضروري، إذا لم يكن التطبيق http، فكل شيء يعمل بدون فحص صحي ولا يمكن القيام بذلك بأي شكل من الأشكال. يمكنك تحديث بعض المعلومات في الملف بشكل دوري، ويمكنك التوصل إلى بعض الأوامر الخاصة للبرنامج الخفي، مثل، daemon status، والذي سيقول "نعم، كل شيء على ما يرام، البرنامج الخفي يعمل، وهو حي."

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

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

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

متطلبات تطوير تطبيق في Kubernetes

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

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

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

لذلك، في هذا الصدد، أعود مرة أخرى إلى اختبارات الاستعداد/الحياة - لماذا تحتاج على الأرجح إلى اختبار الاستعداد، ولكن اختبار الاستعداد موضع تساؤل. لأنه إذا قمت بوصف عمليات التحقق من الصحة تمامًا كما قلت للتو، فسوف يتبين أنها غير متوفرة في جزء المثيلв или со всех instanceفي قاعدة البيانات، على سبيل المثال. عندما أعلنت عن اختبار الاستعداد، بدأت عمليات التحقق من الصحة لدينا بالفشل، وبالتالي فإن جميع التطبيقات التي لا يمكن الوصول إلى قاعدة البيانات منها، يتم ببساطة إيقاف تشغيلها من التوازن وفي الواقع "تعلق" فقط في حالة مهملة وتنتظر قواعد البيانات الخاصة بها عمل.

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

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

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

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

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

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

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

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

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

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

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

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

بعد ذلك، لدينا أيضًا إحدى المشكلات المؤلمة عند تشغيل التطبيقات.

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

رشيقة الاغلاق

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

متطلبات تطوير تطبيق في Kubernetes

هناك خيار سيئ بنفس القدر تقريبًا وهو عندما يتلقى تطبيقك SIGTERM ويكون مثل "لقد قالوا segterm، وهذا يعني أننا ننتهي، لم أر، لا أعرف أي طلبات من المستخدمين، لا أعرف أي نوع من الطلبات" الطلبات التي أعمل عليها الآن، قالوا SIGTERM، وهذا يعني أننا ننتهي " وهذا أيضًا خيار سيء.

الخيار الذي هو جيد؟ النقطة الأولى هي أن تأخذ في الاعتبار الانتهاء من العمليات. الخيار الجيد هو أن يظل خادمك يأخذ في الاعتبار ما يفعله إذا تلقى SIGTERM.

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

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

هناك يمكننا أن نقول على وجه التحديد المدة التي نحتاجها للانتظار بين الوقت الذي نرسل فيه SIGTERM إلى التطبيق وعندما نفهم أن التطبيق يبدو مجنونًا بشيء ما أو أنه "عالق" ولن ينتهي - ونحن بحاجة إلى أرسلها SIGKILL، أي أنه من الصعب إكمال عملها. وهذا هو، وفقا لذلك، لدينا نوع من البرنامج الخفي قيد التشغيل، وهو يعالج العمليات. نحن ندرك أن عملياتنا التي يعمل عليها البرنامج الخفي لا تدوم في المتوسط ​​أكثر من 30 ثانية في المرة الواحدة. وفقًا لذلك، عندما يصل SIGTERM، ندرك أن البرنامج الخفي الخاص بنا يمكنه، على الأكثر، الانتهاء بعد 30 ثانية من SIGTERM. نكتبها، على سبيل المثال، 45 ثانية فقط في حالة ونقول أن SIGTERM. بعد ذلك ننتظر 45 ثانية. من الناحية النظرية، خلال هذا الوقت كان من المفترض أن يكون الشيطان قد أكمل عمله وأنهى نفسه. ولكن إذا لم يحدث ذلك فجأة، فهذا يعني أنه على الأرجح عالق، ولم يعد يعالج طلباتنا بشكل طبيعي. وفي 45 ثانية يمكنك بأمان القضاء عليه.

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

عند إنهاء التطبيق الخاص بك، يجب عليك تقديم بعض رموز الخروج المناسبة. أي أنه إذا طُلب من تطبيقك الإغلاق والإيقاف وكان قادرًا على إيقاف نفسه بشكل طبيعي، فلن تحتاج إلى إرجاع نوع من رمز الخروج 1,5,255،0،0 وما إلى ذلك. أي شيء لا يحتوي على كود صفري، على الأقل في أنظمة Linux، أنا متأكد من ذلك، يعتبر غير ناجح. أي أنه يعتبر أن طلبك في هذه الحالة انتهى بخطأ. وفقًا لذلك، وبطريقة ودية، إذا اكتمل طلبك بدون خطأ، فستقول XNUMX على الإخراج. إذا فشل تطبيقك لسبب ما، فستقول غير XNUMX في الإخراج. ويمكنك العمل مع هذه المعلومات.

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

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

موارد

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

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

لماذا هناك حاجة إلى الموارد على الإطلاق؟ هناك نوعان من الموارد في Kubernetes. بعضها يسمى طلبات، والبعض الآخر يسمى حدود. من خلال الموارد سوف نفهم أن هناك دائمًا قيدين أساسيين فقط. وهذا يعني الحدود الزمنية لوحدة المعالجة المركزية وحدود ذاكرة الوصول العشوائي (RAM) للحاوية التي تعمل في Kubernetes.

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

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

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

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

تخزين البيانات

نقطتنا التالية تتعلق بتخزين البيانات. ماذا تفعل معهم وبشكل عام، ماذا تفعل مع المثابرة في Kubernetes؟

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

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

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

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

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

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

سيكون لدينا دورة تدريبية على Ceph، يمكنك ذلك تعرف على البرنامج وقم بتقديم الطلب.

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

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

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

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

ما هي المشاكل التي يعاني منها مينيو؟ المشكلة الرئيسية في Minio هي أنه لكي يعمل هذا الشيء، يجب تشغيله في مكان ما، ويجب أن يكون هناك نوع من نظام الملفات، أي التخزين. وهنا نواجه نفس المشاكل التي يواجهها Ceph. أي أنه يجب على Minio تخزين ملفاته في مكان ما. إنها ببساطة واجهة HTTP لملفاتك. علاوة على ذلك، من الواضح أن الأداء الوظيفي أضعف من أداء Amazon S3. في السابق، لم يكن قادرًا على تفويض المستخدم بشكل صحيح. الآن، على حد علمي، يمكنه بالفعل إنشاء مجموعات بتفويضات مختلفة، ولكن مرة أخرى، يبدو لي أن المشكلة الرئيسية، إذا جاز التعبير، هي نظام التخزين الأساسي على الأقل.

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

Cloudnativeness

والموضوع الفرعي الأخير هو ما هو Cloudnative. لماذا هو مطلوب؟ Cloudnativeness وما إلى ذلك.

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

متطلبات تطوير تطبيق في Kubernetes

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

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

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

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

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

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

وهناك نقطة أخيرة أود أيضًا أن ألفت انتباهكم إليها. لكي يصبح تطبيقك وبنيتك التحتية Cloudnative، فمن المنطقي أن تبدأ أخيرًا في تكييف النهج المسمى Infrastructure as a Code، أي أن هذا يعني أن تطبيقك، أو بالأحرى البنية التحتية الخاصة بك، يحتاج تمامًا إلى نفس التعليمات البرمجية. التطبيق، منطق عملك في شكل رمز. والعمل معه كرمز، أي اختباره، وطرحه، وتخزينه في git، وتطبيق CICD عليه.

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

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

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

إضافة تعليق