نهج النظام للمتغيرات في أنسبل

ansible devops codestyle

يا! اسمي هو енис Калюжный أعمل كمهندس في قسم أتمتة عمليات التطوير. كل يوم ، يتم نشر تصميمات تطبيقات جديدة على مئات من خوادم الحملة. وفي هذه المقالة ، أشارك تجربتي في استخدام Ansible لهذه الأغراض.

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

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

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

نهج النظام للمتغيرات في أنسبل

المتغيرات في الأدوار

الدور هو كائن نظام نشر منفصل. مثل أي كائن في النظام ، يجب أن يكون له واجهة للتفاعل مع بقية النظام. متغيرات الدور هي مثل هذه الواجهة.

خذ على سبيل المثال الدور api، والذي يقوم بتثبيت تطبيق Java على الخادم. ما المتغيرات التي لديها؟

نهج النظام للمتغيرات في أنسبل

يمكن تقسيم متغيرات الدور إلى نوعين حسب النوع:

1. Свойства
    a) независимые от среды
    б) зависимые от среды
2. Связи
    a) слушатели 
    б) запросы внутри системы
    в) запросы в среду

خصائص متغيرة هي المتغيرات التي تحدد سلوك الدور.

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

المستمعين المتغير هي المتغيرات التي تستخدم قيمتها لتشكيل متغيرات الاستعلام.

من ناحية أخرى ، 1 أ ، 2 أ ، 2 ب هي متغيرات لا تعتمد على البيئة (الحديد ، والموارد الخارجية ، وما إلى ذلك) ويمكن ملؤها بالقيم الافتراضية في الدور الافتراضي. ومع ذلك ، لا يمكن ملء المتغيرات مثل 1.b و 2.c بقيم أخرى غير "المثال" ، حيث إنها ستتغير من موقف إلى آخر حسب البيئة.

أسلوب الكود

  • يجب أن يبدأ اسم المتغير باسم الدور. هذا سيجعل من السهل معرفة دور المتغير في المستقبل وما هو المسؤول عنه.
  • عند استخدام المتغيرات في الأدوار ، يجب أن تتأكد من اتباع مبدأ التغليف واستخدام المتغيرات المحددة إما في الدور نفسه أو في الأدوار التي يعتمد عليها الدور الحالي.
  • تجنب استخدام القواميس للمتغيرات. لا يسمح لك Ansible بتجاوز القيم الفردية في القاموس بسهولة.

    مثال على متغير سيء:

    myrole_user:
        login: admin
        password: admin

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

    myrole_user_login: admin
    myrole_user_password: admin

المتغيرات في نشر قواعد اللعبة

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

عند تجميع كتاب التشغيل ، للتلخيص ، من الممكن تجاوز القيم الافتراضية لمتغيرات الدور في مكانين: في متغيرات قواعد اللعبة ومتغيرات المخزون.

mydeploy                        # Каталог деплоя
├── deploy.yml                  # Плейбук деплоя
├── group_vars                  # Каталог переменных плейбука
│   ├── all.yml                 # Файл для переменных связи всей системы
│   └── myapi.yml               # Файл переменных свойств группы myapi
└── inventories                 #
    └── prod                    # Каталог окружения prod
        ├── prod.ini            # Инвентори файл
        └── group_vars          # Каталог для переменных инвентори
            └── myapi           #
                ├── vars.yml    # Средозависимые переменные группы myapi
                └── vault.yml   # Секреты (всегда средозависимы) *

* - المتغيرات والخزائن

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

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

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

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

متغيرات الخاصية للمجموعات

دعنا نوسع نموذجنا في الشكل 1 بإضافة مجموعتين من الخوادم بتطبيق Java مختلف ، ولكن بإعدادات مختلفة.

نهج النظام للمتغيرات في أنسبل

تخيل كيف سيبدو كتيب اللعبة في هذه الحالة:

- hosts: myapi
  roles:
    - api

- hosts: bbauth
  roles:
    - auth

- hosts: ghauth
  roles:
    - auth

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

نمط الرمز

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

متغيرات الارتباط

ومع ذلك ، هذا يتعلق بمتغيرات الخاصية ، ولكن ماذا عن متغيرات الارتباط؟
الفرق بينهما هو أنه يجب أن يكون لهما نفس القيمة في مجموعات مختلفة.

في البداية كان هناك فكرة استخدم البناء الوحشي للشكل:
hostvars[groups['bbauth'][0]]['auth_bind_port']، ولكن تم التخلي عنها على الفور
لأنها بها عيوب. أولاً ، الضخامة. ثانيًا ، الاعتماد على مضيف معين في المجموعة. ثالثًا ، من الضروري جمع الحقائق من جميع المضيفين قبل بدء النشر ، إذا كنا لا نريد الحصول على خطأ متغير غير محدد.

نتيجة لذلك ، تقرر استخدام متغيرات الارتباط.

متغيرات الارتباط هي المتغيرات التي تنتمي إلى قواعد اللعبة والمطلوبة لربط كائنات النظام.

يتم ملء متغيرات الارتباط في متغيرات النظام العامة group_vars/all/vars ويتم تشكيلها بإزالة جميع متغيرات المستمع من كل مجموعة ، وإضافة اسم المجموعة التي تم إزالة المستمع منها إلى بداية المتغير.

وبالتالي ، يتم ضمان توحيد الأسماء وعدم تقاطعها.

دعنا نحاول ربط المتغيرات من المثال أعلاه:

نهج النظام للمتغيرات في أنسبل

تخيل أن لدينا متغيرات تعتمد على بعضها البعض:

# roles/api/defaults:
# Переменная запроса
api_auth1_address: "http://example.com:80"
api_auth2_address: "http://example2.com:80"

# roles/auth/defaults:
# Переменная слушатель
auth_bind_port: "20000"

دعونا نضعها في المتغيرات المشتركة group_vars/all/vars جميع المستمعين ، وأضف اسم المجموعة إلى الاسم:

# group_vars/all/vars
bbauth_auth_bind_port: "20000"
ghauth_auth_bind_port: "30000"

# group_vars/bbauth/vars
auth_bind_port: "{{ bbauth_auth_bind_port }}"

# group_vars/ghauth/vars
auth_bind_port: "{{ ghauth_auth_bind_port }}"

# group_vars/myapi/vars
api_auth1_address: "http://{{ bbauth_auth_service_name }}:{{ bbauth_auth_bind_port }}"
api_auth2_address: "http://{{ ghauth_auth_service_name }}:{{ ghauth_auth_bind_port }}"

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

نمط الرمز

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

ملفات البيئة

يمكن أن تستخدم الأدوار ملفات تختلف من بيئة إلى أخرى.

شهادات SSL هي مثال على هذه الملفات. قم بتخزينها كنص
في متغير ليست مريحة للغاية. لكن من الملائم تخزين المسار لهم داخل متغير.

على سبيل المثال ، نستخدم المتغير api_ssl_key_file: "/path/to/file".

نظرًا لأنه من الواضح أن شهادة المفتاح ستتغير من بيئة إلى أخرى ، فهذا متغير يعتمد على البيئة ، مما يعني أنه يجب أن يكون موجودًا في الملف
group_vars/myapi/vars جرد المتغيرات ، ويحتوي على القيمة "على سبيل المثال".

الطريقة الأكثر ملاءمة في هذه الحالة هي وضع ملف المفتاح في مستودع Playbook على طول المسار
files/prod/certs/myapi.key، فإن قيمة المتغير ستكون:
api_ssl_key_file: "prod/certs/myapi.key". تكمن الراحة في حقيقة أن الأشخاص المسؤولين عن نشر النظام على منصة معينة لديهم أيضًا مكان مخصص لهم في المستودع لتخزين ملفاتهم. في الوقت نفسه ، يظل من الممكن تحديد المسار المطلق للشهادة على الخادم ، في حالة توفير الشهادات من قبل نظام آخر.

تقف متعددة في بيئة واحدة

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

سيعيد استخدام مخزون group_vars وسيكون أيضًا قادرًا على إعادة تعريف بعض المتغيرات مباشرةً لنفسه.

هيكل الدليل النهائي لمشروع النشر:

mydeploy                        # Каталог деплоя
├── deploy.yml                  # Плейбук деплоя
├── files                       # Каталог для файлов деплоя
│   ├── prod                    # Католог для средозависимых файлов стенда prod
│   │   └── certs               # 
│   │       └── myapi.key       #
│   └── test1                   # Каталог для средозависимых файлов стенда test1
├── group_vars                  # Каталог переменных плейбука
│   ├── all.yml                 # Файл для переменных связи всей системы
│   ├── myapi.yml               # Файл переменных свойств группы myapi
│   ├── bbauth.yml              # 
│   └── ghauth.yml              #
└── inventories                 #
    ├── prod                    # Каталог окружения prod
    │   ├── group_vars          # Каталог для переменных инвентори
    │   │   ├── myapi           #
    │   │   │   ├── vars.yml    # Средозависимые переменные группы myapi
    │   │   │   └── vault.yml   # Секреты (всегда средозависимы)
    │   │   ├── bbauth          # 
    │   │   │   ├── vars.yml    #
    │   │   │   └── vault.yml   #
    │   │   └── ghauth          #
    │   │       ├── vars.yml    #
    │   │       └── vault.yml   #
    │   └── prod.ini            # Инвентори стенда prod
    └── test                    # Каталог окружения test
        ├── group_vars          #
        │   ├── myapi           #
        │   │   ├── vars.yml    #
        │   │   └── vault.yml   #
        │   ├── bbauth          #
        │   │   ├── vars.yml    #
        │   │   └── vault.yml   #
        │   └── ghauth          #
        │       ├── vars.yml    #
        │       └── vault.yml   #
        ├── test1.ini           # Инвентори стенда test1 в среде test
        └── test2.ini           # Инвентори стенда test2 в среде test

تلخيص لما سبق

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

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

لم يعد مسؤولو النظام بحاجة إلى فهم كود النشر. كل ما هو مطلوب منهم للنشر الناجح هو ملء ملفات متغيرات البيئة.

أدب

  1. توثيق

مؤلف

كاليوجني دينيس الكسندروفيتش

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

إضافة تعليق