
لا يتكون منهج IaC (البنية التحتية ككود ) فقط من الكود الذي تم تخزينه في المستودع ، ولكن أيضًا من الأشخاص والعمليات التي تحيط بهذا الكود. هل من الممكن إعادة استخدام الأساليب من تطوير البرمجيات إلى إدارة ووصف البنية التحتية؟ لن يكون من غير الضروري وضع هذه الفكرة في الاعتبار أثناء قراءة المقال.
النسخة الروسية
هذا هو نسخة من أدائي في DevopsConf 2019-05-28 .
البنية التحتية كتاريخ باش

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

حتى في حالة غريبة مثل Infrastructure مثل bash history يمكن سحبها من قبل آذان Infrastructure كـ Code ، ولكن عندما نريد أن نفعل شيئًا أكثر تعقيدًا من خادم LAMP القديم الجيد ، سنتوصل إلى استنتاج مفاده أن هذا الرمز يحتاج إلى تعديل أو تعديل أو تعديل بطريقة أو بأخرى. . علاوة على ذلك ، نود أن نعتبر أوجه التشابه بين البنية التحتية بمثابة كود وتطوير البرمجيات.
DRY

في مشروع تطوير التخزين ، كانت هناك مهمة فرعية لتهيئة SDS بشكل دوري : نصدر إصدارًا جديدًا - يجب طرحه لإجراء مزيد من الاختبارات. المهمة بسيطة للغاية:
- تعال إلى هنا عن طريق ssh وتنفيذ الأمر.
- انسخ الملف هناك.
- هنا هو قرص إلى التكوين.
- ابدأ الخدمة هناك
- ...
- PROFIT!
يعد Bash أكثر من كافٍ للمنطق الموصوف ، خاصة في المراحل المبكرة من المشروع عندما يبدأ لتوه. ليس سيئًا أن تستخدم bash ، لكن مع مرور الوقت ، تتم مطالبتك بنشر شيء مشابه ، ولكنه مختلف قليلاً. أول ما يتبادر إلى الذهن: نسخ لصق. والآن لدينا نصان مشابهان للغاية يقومان بنفس الشيء تقريبًا. مع مرور الوقت ، زاد عدد البرامج النصية ، ونحن نواجه حقيقة أن هناك منطق عمل معين لنشر التثبيت ، والذي يجب أن تتم مزامنته بين البرامج النصية المختلفة ، إنه أمر صعب للغاية.

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

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

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

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

مبدأ الاستعاضة عن باربرا ليسكوف. يجب أن تكون الكائنات الموجودة في البرنامج قابلة للاستبدال مع مثيلات أنواعها الفرعية دون تغيير صحة البرنامج
إذا نظرت على نطاق أوسع ، فليس من ميزات أي مشروع معين أنه يمكنك تطبيق SOLID ، فهو يتعلق عمومًا بـ CFM ، على سبيل المثال ، في مشروع آخر تحتاج إلى نشر تطبيق Java محاصر أعلى Java ، وخوادم التطبيقات ، وقواعد البيانات ، ونظام التشغيل ، إلخ. في هذا المثال ، سأدرس مبادئ سوليد الإضافية.
في حالتنا ، كجزء من فريق البنية التحتية ، هناك اتفاق على أنه إذا قمنا بتثبيت دور imbjava أو oraclejava ، عندئذٍ لدينا java ثنائي قابل للتنفيذ. هذا ضروري ل تعتمد الأدوار العليا على هذا السلوك ؛ فهم يتوقعون وجود جافا. في الوقت نفسه ، يسمح لنا ذلك باستبدال تطبيق / إصدار واحد من java بآخر دون تغيير منطق نشر التطبيق.
تكمن المشكلة هنا في حقيقة أنه في Ansible يستحيل تنفيذ هذا ، ونتيجة لذلك ، تظهر بعض الاتفاقات داخل الفريق.
مبدأ فصل الواجهة

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

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

لا تتعلق البنية التحتية كرمز فقط بالشفرة ، ولكن أيضًا بالعلاقة بين الكود والشخص ، حول التفاعلات بين مطوري البنية التحتية.
عامل الحافلة

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

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

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

مع مرور الوقت ، بدأت المشاجرات تظهر أثناء المراجعة ، كما كان للمراجعين أسلوبهم الخاص وقابليتهم للتدوير للمراجعين الذين قاموا بتكديسهم بأنماط مختلفة: 2 مسافات أو 4 أو camelCase أو snake_case. تنفيذ هذا لم ينجح على الفور.
- كانت الفكرة الأولى التوصية باستخدام linter ، لأن جميع المهندسين نفسه ، كلهم أذكياء. لكن المحررين مختلفة ، OS ، ليست مريحة
- تطورت هذه إلى روبوت ، والتي تلتزم لكل التزام في إشكالية كتب في فترة الركود ، وتطبيق مخرجات linter. ولكن في معظم الحالات ، تم العثور على مزيد من الأمور الهامة وظلت الشفرة غير ثابتة.
سيد البناء الأخضر

يمر الوقت ، وتوصلنا إلى استنتاج مفاده أنه يجب ألا تسمح بالتعويضات التي لا تمرر اختبارات معينة إلى المعلم. فويلا! اخترعنا برنامج Green Build Master ، والذي تم ممارسته منذ فترة طويلة في تطوير البرمجيات:
- التنمية في فرع منفصل.
- الاختبارات تعمل على هذا الموضوع.
- في حالة فشل الاختبارات ، لن يتم إدخال الرمز في المعالج.
اتخاذ هذا القرار كان مؤلما للغاية ل تسبب الكثير من الجدل ، لكنه كان يستحق كل هذا العناء ، لأنه بدأت طلبات الدمج تأتي في المراجعة دون خلاف في الأسلوب وبمرور الوقت ، بدأ عدد المناطق التي تعاني من المشكلات في التناقص.
اختبار IAC

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

اختبار IaC: تحليل ثابت
إذا قمت فورًا بنشر البنية التحتية بالكامل وتأكدت من أنها تعمل ، فقد يتضح أن الأمر يستغرق الكثير من الوقت ويتطلب الكثير من الوقت. لذلك ، يجب أن يكون الأساس يعمل بسرعة ، فهو كثير ، ويغطي العديد من الأماكن البدائية.
باش صعب
هنا مثال تافه. حدد جميع الملفات في الدليل الحالي وانسخ إلى موقع آخر. أول ما يتبادر إلى الذهن:
for i in * ; do cp $i /some/path/$i.bak done
ولكن ماذا لو كان هناك مساحة في اسم الملف؟ حسنًا ، حسنًا ، نحن أذكياء ، يمكننا استخدام علامات الاقتباس:
for i in * ; do cp "$i" "/some/path/$i.bak" ; done
أحسنت؟ لا! ماذا لو لم يكن هناك شيء في الدليل ، أي التذمر لن ينجح.
find . -type f -exec mv -v {} dst/{}.bak \;
الآن أحسنت؟ لا ... نسيت أن اسم الملف قد يكون \n
.
touch x mv x "$(printf "foo\nbar")" find . -type f -print0 | xargs -0 mv -t /path/to/target-dir
يمكن اكتشاف المشكلة من الخطوة السابقة عندما ننسى علامات الاقتباس ، فهناك في الطبيعة العديد من أدوات Shellcheck ، وهناك العديد منها ، وعلى الأرجح يمكنك العثور على الخطوط الملائمة لمجموعتك تحت IDE الخاص بك.
اختبار IAC: اختبارات الوحدة

كما رأينا من المثال السابق ، فإن linter ليس كلي القدرة ولا يمكنه الإشارة إلى جميع مناطق المشكلات. علاوة على ذلك ، عن طريق القياس مع الاختبار في تطوير البرمجيات ، يمكننا أن نتذكر اختبارات الوحدة. ثم شونيت ، junit ، rspec ، pytest تتبادر إلى الذهن على الفور. ولكن ماذا تفعل مع ansible ، طاه ، سالتستاك وغيرها مثلهم؟
في البداية ، تحدثنا عن SOLID وحقيقة أن البنية التحتية لدينا يجب أن تتكون من الطوب الصغيرة. لقد حان وقتهم.
- يتم سحق البنية التحتية إلى طوب صغيرة ، على سبيل المثال ، أدوار Ansible.
- نوع من البيئة تتكشف ، سواء كان ذلك عامل ميناء أو VM.
- نحن نطبق دورنا Ansible على بيئة الاختبار هذه.
- نتحقق من أن كل شيء يعمل كما نتوقع (إجراء الاختبارات).
- نقرر موافق أم لا.
السؤال هو ، ما هي اختبارات CFM؟ يمكنك تشغيل البرنامج النصي corny ، أو يمكنك استخدام حلول جاهزة لهذا:
مثال على testinfra ، نتحقق من وجود المستخدمين test1
و test2
وأنهم في مجموعة sshusers
:
def test_default_users(host): users = ['test1', 'test2' ] for login in users: assert host.user(login).exists assert 'sshusers' in host.user(login).groups
ماذا تختار؟ السؤال معقد وغامض ، وفيما يلي مثال على التغيير في المشاريع على جيثب للفترة 2018-2019:

أطر اختبار IaC
هناك كيفية وضع كل ذلك معا وتشغيلها؟ يمكنك أن تأخذ وتفعل كل شيء بنفسك إذا كان لديك عدد كاف من المهندسين. ويمكنك اتخاذ حلول جاهزة ، على الرغم من عدم وجود الكثير منها:
مثال على التغيير في المشاريع على جيثب للفترة 2018-2019:

جزيء مقابل Testkitchen

في البداية ، حاولنا استخدام testkitchen :
- إنشاء VMs بالتوازي.
- تطبيق أدوار Ansible.
- طرد بعيدا inspec.
لمدة 25-35 الأدوار ، وهذا عملت لمدة 40-70 دقيقة ، والتي كانت فترة طويلة.

كانت الخطوة التالية هي التبديل إلى جنينز / عامل ميناء / ansible / جزيء. من الناحية اللغوية ، كل شيء هو نفسه
- كتب اللعب الوبر.
- لتسرب الأدوار.
- تشغيل الحاوية
- تطبيق أدوار Ansible.
- طرد بعيدا testinfra.
- تحقق العاطفة.

بدأ الحاكم لمدة 40 الأدوار والاختبارات لعشرات يستغرق حوالي 15 دقيقة.

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

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

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

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

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

ذهبت فكرة البحث إلى أبعد من ذلك ، وفي الفتح كان هناك شيء APB (حزمة Ansible Playbook Bundle) يسمح لك بتعبئة المعرفة في الحاوية حول كيفية نشر البنية التحتية. أي هناك نقطة قابلة للتكرار وقابلة للاختبار لمعرفة كيفية نشر البنية التحتية.

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

البنية التحتية كما هو رمز
- الكود في المستودع.
- تفاعل الناس.
- اختبار البنية التحتية.