Ansible لإدارة تكوين ويندوز. قصة نجاح

في أحد اجتماعات مجتمع St. Petersburg .Net لمطوري SpbDotNet Community ، قمنا بتجربة وقررنا التحدث عن كيفية تطبيق الأساليب التي أصبحت قياسية في عالم Linux لأتمتة البنية الأساسية لنظام Windows. ولكن حتى لا يتم إحضار كل شيء إلى الموجة التي لا أساس لها من علامة Ansible ، فقد تقرر إظهار ذلك بمثال نشر تطبيق ASP.Net.


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


أي شخص مهتم بنتيجة مثل هذه التجربة ، مرحبًا بك ، أسفل عملية فك التشفير.



مرحبًا) لقد أفسدوا قليلًا بالفعل وقالوا أنني أمامية ، لذا يمكنك أن تتباعد بالفعل =) اسمي أليكسي ، لقد كنت أقوم بكل أنواع الأشياء حول تطوير الويب لبعض الوقت. لقد بدأت مع Perl ، ثم كان هناك PHP ، RoR قليلاً ، قليلاً ، قليلاً من ذلك. ثم اقتحم جافا سكريبت في حياتي ، ومنذ ذلك الحين كنت أقوم بكل ذلك تقريبًا.


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


قبل التاريخ


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


لقد اعتدنا نحن ، أولئك الذين نطور نظام Linux ، على حقيقة أن كل شيء يجب أن يكون في Docker ، وهناك Kubernetes ، وكل شيء يتكشف بنقرة واحدة. وعندما انتهى بي المطاف في بيئة لا يوجد فيها كل هذا ، صدمت. وعندما بدأت في إجراء اختبارات السيارات ، أدركت أن هذا كان 20٪ فقط من النجاح ، وأن كل شيء آخر كان يعد البنية التحتية لهم.



مشاعري في البداية


الظروف الحالية


سوف أخبركم قليلاً عن كيفية ترتيب كل شيء معنا ، وما يتعين علينا القيام به تلقائيًا وما نفعله.


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


المشاكل


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


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


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



الخطوة الأولى نحو حل المشكلة هي قبولها.


اختيار الحل


عندما لا تعرف ماذا تفعل ، انظر إلى ما يفعله الآخرون.


وبالنسبة للمبتدئين ، وضعنا قائمة المتطلبات الخاصة بما نريد الحصول عليه في النهاية.


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

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


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


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



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


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

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


البنية التحتية كرمز


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


يطرح سؤال شرعي - لماذا؟


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


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

اختيار الأداة


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


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


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


بوويرشيل:


$url = "http://buildserver/build.msi" $output = "$PSSscriptRoot\build.msi" Invoke-WebRequest -Uri $url -OutFile $output 

Ansible:


 name: Download build hosts: all tasks: name: Download installer win_get_url: url: "http://buildserver/build.msi" dest: "build.msi" force: no 

هنا نرى أنه في المثال الأساسي ، سيكون ps-script أكثر إيجازًا من Ansible playbook. 3 أسطر من البرنامج النصي مقابل 7 أسطر من قواعد اللعبة من أجل تنزيل ملف.


ولكن ، Petka ، هناك فارق بسيط (ق). حالما نرغب في مراعاة مبدأ عدم الاستحالة ، وعلى سبيل المثال ، للتأكد من أن الملف الموجود على الخادم لم يتغير وأنه لا يحتاج إلى تنزيل ، سيتعين عليك تنفيذ طلب HEAD في البرنامج النصي ، والذي يضيف حوالي 200 سطر. وفي قواعد اللعبة - واحد. تحتوي وحدة Ansible win_get_url ، التي تقوم بجميع عمليات التحقق من أجلك ، على 257 سطرًا من التعليمات البرمجية التي ليس عليك إدراجه في كل برنامج نصي.


وهذا مجرد مثال واحد لمهمة بسيطة للغاية.



وإذا فكرت في الأمر ، فنحن بحاجة إلى الشغف في كل مكان:


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

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


من بين أمور أخرى مهمة بالنسبة لنا ، لا يستخدم Ansible وكلاء لإدارة الأجهزة المضيفة والأجهزة الخاصة بك. على نظام Linux ، بالطبع ، يتم تشغيله على ssh ، بينما بالنسبة لنظام Windows ، يتم استخدام WinRM. ومن هنا كانت النتيجة واضحة: Ansible هو عبر منصة. وهو يدعم عددًا رائعًا من المنصات ، حتى معدات الشبكة.


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


ولكن ليس كل شيء حلوًا ، فهناك مشاكل:


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

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


على هذا الجهاز سنحتاج:


  • بيثون و python package package pip. هناك توزيعات كثيرة خارج الصندوق ، لذلك لا مفاجآت هنا.
  • تثبيت Ansible عبر نقطة ، باعتبارها الطريقة الأكثر عالمية: pip تثبيت ansible
  • أضف وحدة winrm للانتقال إلى أجهزة Windows: pip install pywinrm [credssp]
  • وعلى الأجهزة التي نريد التحكم فيها ، نحتاج إلى تمكين winrm ، لأن انها مغلقة افتراضيا. هناك العديد من الطرق للقيام بذلك ، ويتم شرحها جميعًا في وثائق Ansible. ولكن أبسطها هو أخذ البرنامج النصي النهائي من مستودع Ansible وتشغيله باستخدام خيار التفويض المطلوب: ConfigureRemotingForAnsible.ps1 -EnableCredSSP

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


 all: children: webservers: hosts: spbdotnet-test-host.dev.local: dbservers: hosts: spbdotnet-test-host.dev.local: vars: ansible_connection: winrm ansible_winrm_transport: credssp ansible_winrm_server_cert_validation: ignore ansible_user: administrator ansible_password: 123qweASD 

كل شيء بسيط هنا: مجموعة الجذر هي جميعها ومجموعتان فرعيتان ، خدمات الويب وخوادم dbservers. كل شيء آخر بديهي ، لكنني سألفت انتباهك إلى حقيقة أن Ansible بشكل افتراضي يعتقد أن Linux موجود في كل مكان ، لذا يجب على Windows بالنسبة لك تحديد winrm ونوع الترخيص.


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


وحدات


كل ما يفعله Ansible ، يفعل بمساعدة الوحدات النمطية. الوحدات النمطية لنظام التشغيل Linux مكتوبة بلغة python و Windows في PowerShell. وتوقير للغبطة: تأتي نتيجة الوحدة دائمًا في شكل ملف json ، مما يشير إلى ما إذا كانت هناك تغييرات على المضيف أم لا.


في الحالة العامة ، سنقوم بتشغيل إنشاء قائمة الوحدات النمطية ملف جرد مجموعة المضيف ansible:



Pleybuki


قواعد اللعبة عبارة عن وصف لكيفية ومكان تنفيذ وحدات Ansible.


 - name: Install AWS CLI hosts: all vars: aws_cli_download_dir: c:\downloads aws_cli_msi_url: https://s3.amazonaws.com/aws-cli/AWSCLI32PY3.msi tasks: - name: Ensure target directory exists win_file: path: "{{ aws_cli_download_dir }}" state: directory - name: Download installer win_get_url: url: "{{ aws_cli_msi_url }}" dest: "{{ aws_cli_download_dir }}\\awscli.msi" force: no - name: Install AWS CLI win_package: path: "{{ aws_cli_download_dir }}\\awscli.msi" state: present 

في هذا المثال ، لدينا ثلاث مهام. كل مهمة هي مكالمة وحدة. في كتاب اللعب هذا ، نقوم أولاً بإنشاء دليل (تأكد من وجوده) ، ثم قم بتنزيل AWS CLI هناك وتثبيته باستخدام وحدة win_packge.


من خلال تشغيل كتاب اللعب هذا ، نحصل على هذه النتيجة.



يوضح التقرير أن أربع مهام قد تم إكمالها بنجاح وأن ثلاثًا من الأربع قد أجرت بعض التغييرات على المضيف.


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



هذا هو الشغف الذي لم نتمكن من تحقيقه مع PowerShell.


ممارسة


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


 - name: Setup App hosts: webservers tasks: - name: Install IIS win_feature: name: - Web-Server - Web-Common-Http include_sub_features: True include_management_tools: True state: present register: win_feature - name: reboot if installing Web-Server feature requires it win_reboot: when: win_feature.reboot_required 

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


المهمة الأولى التي نحلها هي وحدة win_feature ، التي تشارك في إدارة ميزات Windows. وهنا لأول مرة لدينا متغيرات البيئة Ansible ، في عنصر السجل. تذكر ، قلت أن المهام دائما إرجاع كائن json؟ الآن ، بعد إكمال مهمة تثبيت IIS ، تحتوي الوحدة النمطية win_feature على إخراج الوحدة النمطية win_feature (آسف للتعلم).


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


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


 - name: SQL Server hosts: dbservers tasks: - name: Install MS SQL Server 2014 win_chocolatey: name: mssqlserver2014express state: present 

لذلك ، قمنا بإعداد المضيف لبدء التطبيق ، دعونا نشره!


 - name: Deploy binaries hosts: webservers vars: myapp_artifacts: files/MyAppService.zip myapp_workdir: C:\myapp tasks: - name: Remove Service if exists win_service: name: MyAppService state: absent path: "{{ myapp_workdir }}\\MyAppService.exe" 

فقط في حالة ، أول شيء نقوم به هو حذف الخدمة الحالية.


 - name: Delete old files win_file: path: "{{ myapp_workdir }}\\" state: absent - name: Copy artifacts to remote machine win_copy: src: "{{ myapp_artifacts }}" dest: "{{ myapp_workdir }}\\" - name: Unzip build artifacts win_unzip: src: "{{ myapp_workdir }}\\MyAppService.zip" dest: "{{ myapp_workdir }}" 

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


  - name: Register and start the service win_service: name: ReporterService start_mode: auto state: started path: "{{ myapp_workdir }}\\MyAppService.exe" 

هل انتهيت؟


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


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


ما الذي يمكن عمله؟ بدلاً من ذلك ، يمكنك التحقق من المجموع الاختباري لأعمالنا الفنية ومقارنتها مع تلك الموجودة على الخادم.


  - name: Get arifacts checksum stat: path: "{{ myapp_artifacts }}" delegate_to: localhost register: myapp_artifacts_stat - name: Get remote artifacts checksum win_stat: path: "{{ myapp_workdir }}\\MyAppService.zip" register: myapp_remote_artifacts_stat 

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


  - name: Stop play if checksums match meta: end_play when: - myapp_artifacts_stat.stat.checksum is defined - myapp_remote_artifacts_stat.stat.checksum is defined - myapp_artifacts_stat.stat.checksum == myapp_remote_artifacts_stat.stat.checksum 

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


  - name: Ensure that the WebApp application exists win_iis_webapplication: name: WebApp physical_path: c:\webapp site: Default Web Site state: present 

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


إعادة استخدام الرمز


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


لهذا ، Ansible له أدوار. هذا هو في الأساس اتفاقية. نقوم بإنشاء مجلد / أدوار / على الخادم ونضع أدوارنا فيه. كل دور هو مجموعة من ملفات التكوين: وصف لأجهزتنا ، المتغيرات ، ملفات الخدمة ، إلخ. عادة ما يقوم بعض الكيان المعزول بدور. يُعد تثبيت IIS مثالًا رائعًا إذا كنا لا نحتاج فقط إلى تثبيته ، ولكن أيضًا تكوينه بطريقة أو أخرى أو التحقق من ذلك بمهام إضافية. نحن نقوم بدور منفصل ، وبالتالي نعزل جميع قواعد اللعبة ذات الصلة بـ IIS في مجلد الأدوار. في المستقبل ، ندعو هذا الدور ببساطة بتوجيه include_role٪ role_name٪.


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


 - name: Run App hosts: webservers tasks: - name: "Install IIS" include_role: name: IIS - name: Run My App include_role: name: MyAppService vars: myapp_artifacts: ./buld.zip 

في هذا المثال ، فإن دور Run My App لديه القدرة على نقل بعض المسارات إلى الأعمال الفنية.


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


مزيد من المرونة


ولكن ماذا لو لم يكن هناك وحدة مدمجة أو دور مناسب في Galaxy؟ هناك خياران: إما أن نفعل شيئًا خاطئًا ، أو لدينا بالفعل مهمة فريدة.


في حالة الخيار الثاني ، يمكننا دائمًا كتابة وحدتنا. كما أوضحت لك في البداية ، فإن Ansible يجعل من الممكن كتابة أبسط وحدة نمطية في 10 دقائق حرفيًا ، وعندما تتعمق ، تأتي الوثائق المفصلة تمامًا لمساعدتك ، وتغطي الكثير من الأسئلة.


CI
في قسمنا ، نحب حقًا TeamCity ، ولكن يمكن أن يكون هناك أي خادم CI آخر من اختيارك. لماذا نحتاج إلى مشاركتها؟


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


أيضًا على خادم CI ، يتم تشغيل الوبر المذهل. هذا هو محلل ثابت من التكوينات ansible ، والذي يعطي قائمة من التوصيات.



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


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


والسبب الرئيسي الثاني لاستخدام خادم CI هو إطلاق قواعد اللعبة. هذا هو نفس الزر السحري "افعل جيدًا" ، والذي يعطينا TeamCity. نقوم فقط بإنشاء بعض التكوينات البسيطة لمنتجات مختلفة ، حيث نقول: ansible-playbook reporter_vm.yml -i inventory.yml -vvvv والحصول على زر Deploy.


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


في المجموع


  • مخطوطات PowerShell مشوشة ومتباينة استبدلناها بتكوينات YAML.
  • لقد استبدلنا تطبيقات مختلفة لنفس المشكلات بأدوار مشتركة يمكن إعادة استخدامها. تم إنشاء مستودع حيث تكمن الأدوار. إذا كان الدور مناسبًا لك ، فيمكنك استخدامه فقط. إذا لم يناسبك ذلك ، فأنت فقط ترسل طلب البلياردو ، وتناسبك =)
  • يمكنك الآن التحقق من نجاح النشر في مكان واحد.
  • يعلم الجميع أن ننظر فيها للسجلات.
  • تم حل مشكلات الاتصال أيضًا من خلال مستودع مشترك و TeamCity. يعرف جميع المهتمين أين توجد قواعد اللعب وكيف تعمل.

ملاحظة: يمكن أخذ جميع الأمثلة من المقال على جيثب .

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


All Articles