ھدايتون: جوابي ڪردار کي ڪيئن جانچيو وڃي ۽ پيداوار کان اڳ مسئلن بابت معلوم ڪريو

سلام هر!

مان هوٽل جي بکنگ سروس لاءِ DevOps انجنيئر طور ڪم ڪريان ٿو. Ostrovok.ru. هن آرٽيڪل ۾ آئون اسان جي تجربي جي باري ۾ ڳالهائڻ چاهيان ٿو جوابي ڪردار جي جانچ ڪرڻ ۾.

Ostrovok.ru تي اسان جوابي طور استعمال ڪريون ٿا ڪنفيگريشن مئنيجر. تازو اسان کي ڪردارن جي جانچ ڪرڻ جي ضرورت آهي، پر، جيئن اهو نڪتو، هن لاء ڪيترائي اوزار نه آهن - سڀ کان وڌيڪ مشهور، شايد، ماليڪيول فريم ورڪ آهي، تنهنڪري اسان ان کي استعمال ڪرڻ جو فيصلو ڪيو. پر اهو ظاهر ٿيو ته سندس دستاويز ڪيترن ئي نقصانن بابت خاموش آهي. اسان روسي ۾ ڪافي تفصيلي گائيڊ نه ڳولي سگهيا آهيون، تنهنڪري اسان اهو مضمون لکڻ جو فيصلو ڪيو.

ھدايتون: جوابي ڪردار کي ڪيئن جانچيو وڃي ۽ پيداوار کان اڳ مسئلن بابت معلوم ڪريو

آنو

مولائي - جوابي ڪردار کي جانچڻ ۾ مدد لاءِ هڪ فريم ورڪ.

آسان بيان: ماليڪيول توهان جي بيان ڪيل پليٽ فارم تي هڪ مثال ٺاهي ٿو (ڪلائوڊ، ورچوئل مشين، ڪنٽينر؛ وڌيڪ تفصيل لاءِ، سيڪشن ڏسو ڊرائيور)، ان تي توهان جو ڪردار هلندو آهي، پوء ٽيسٽ هلندو آهي ۽ مثال کي حذف ڪري ٿو. جيڪڏهن هڪ قدم ۾ ناڪامي آهي، ماليڪيول توهان کي ان بابت اطلاع ڏيندو.

هاڻي وڌيڪ.

نظريي جو ھڪڙو

اچو ته ماليڪيول جي ٻن اهم ادارن تي غور ڪريون: منظرنامو ۽ ڊرائيور.

مناظر

اسڪرپٽ ۾ وضاحت آهي ته ڇا، ڪٿي، ڪيئن ۽ ڪهڙي ترتيب ۾ ڪيو ويندو. ھڪڙي ڪردار ۾ ڪيترائي اسڪرپٽ ٿي سگھن ٿا، ۽ ھر ھڪڙي ھڪڙي ڊاريڪٽري آھي رستي ۾ <role>/molecule/<scenario>، جنهن ۾ ٽيسٽ لاءِ گهربل عملن جا تفصيل شامل آهن. اتي هڪ اسڪرپٽ هجڻ گهرجي default, جيڪو خودڪار طور تي ٺاھيو ويندو جيڪڏھن توھان ڪردار کي شروع ڪريو Molecule استعمال ڪندي. ھيٺ ڏنل لکتن جا نالا توھان جي صوابديد تي آھن.

اسڪرپٽ ۾ جانچ جي عملن جي تسلسل کي سڏيو ويندو آهي ميٽرڪس، ۽ ڊفالٽ طور اهو هن طرح آهي:

(قدم نشان لڳل ?, ڊفالٽ طور ڇڏيا ويا آهن جيڪڏهن صارف طرفان وضاحت نه ڪئي وئي آهي)

  • lint - هلندڙ ليٽر. ڊفالٽ طور yamllint и flake8,
  • destroy - ماليڪيول جي آخري لانچ کان مثالن کي ختم ڪرڻ (جيڪڏهن ڪو به رهي)،
  • dependency؟ - آزمائشي ڪردار جي قابل انحصار انحصار کي نصب ڪرڻ،
  • syntax - استعمال ڪندي ڪردار نحو چيڪ ڪرڻ ansible-playbook --syntax-check,
  • create - مثال ٺاهڻ،
  • prepare؟ - مثال تيار ڪرڻ؛ مثال طور چيڪ ڪرڻ / انسٽال ڪرڻ python2
  • converge - آزمائشي راند بڪ لانچ ڪرڻ،
  • idempotence - Idempotency ٽيسٽ لاءِ راند جو ڪتاب ٻيهر هلايو،
  • side_effect؟ - ڪارناما سڌو سنئون ڪردار سان لاڳاپيل نه آهن، پر ٽيسٽ لاء ضروري آهن،
  • verify - استعمال ڪندي نتيجن واري ترتيب جي هلندڙ ٽيسٽ testinfra(ڊفالٽ) /goss/inspec,
  • cleanup؟ - (نئين ورزن ۾) - تقريبن ڳالهائڻ، "صاف" خارجي انفراسٽرڪچر انو طرفان متاثر ٿيل،
  • destroy - مثال کي ختم ڪرڻ.

اهو سلسلو اڪثر ڪيسن تي پکڙيل آهي، پر جيڪڏهن ضروري هجي ته تبديل ڪري سگهجي ٿو.

مٿين قدمن مان هر هڪ الڳ الڳ استعمال ڪري سگهجي ٿو molecule <command>. پر توهان کي اهو سمجهڻ گهرجي ته هر اهڙي ڪلي ڪمانڊ لاءِ شايد عملن جو پنهنجو سلسلو هوندو، جنهن کي توهان ڊوڙڻ سان ڳولي سگهو ٿا. molecule matrix <command>. مثال طور، جڏهن حڪم هلائڻ converge (ٽيسٽ ٿيل پلے بڪ کي هلائڻ) ھيٺ ڏنل ڪارناما انجام ڏنا ويندا.

$ molecule matrix converge
...
└── default         # название сценария
    ├── dependency  # установка зависимостей
    ├── create      # создание инстанса
    ├── prepare     # преднастройка инстанса
    └── converge    # прогон плейбука

انهن عملن جي ترتيب کي تبديل ڪري سگهجي ٿو. جيڪڏهن فهرست مان ڪا شيءِ اڳ ۾ ئي مڪمل ٿي چڪي آهي، ته ان کي ڇڏيو ويندو. موجوده حالت، گڏوگڏ مثال جي ترتيب، انو ڊاريڪٽري ۾ ذخيرو ٿيل آهي $TMPDIR/molecule/<role>/<scenario>.

سان گڏ قدم شامل ڪريو ? توھان مطلوب ڪارناما بيان ڪري سگھوٿا جوابي پلے بڪ فارميٽ ۾، ۽ فائل جو نالو ٺاھيو قدم مطابق: prepare.yml/side_effect.yml. اميد رکو ته اهي ماليڪيول فائلون اسڪرپٽ فولڊر ۾ هجن.

ڊرائيور

ڊرائيور هڪ ادارو آهي جتي ٽيسٽ جا مثال ٺاهيا ويندا آهن.
معياري ڊرائيورن جي لسٽ جنهن لاءِ ماليڪيول وٽ تيار ڪيل ٽيمپليٽس آهن: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegated.

اڪثر ڪيسن ۾، ٽيمپليٽ فائلون آهن create.yml и destroy.yml اسڪرپٽ فولڊر ۾، جيڪو بيان ڪري ٿو مثال جي تخليق ۽ حذف ڪرڻ، ترتيب سان.
استثنا Docker ۽ Vagrant آهن، ڇاڪاڻ ته انهن جي ماڊلز سان ڳالهه ٻولهه مٿين فائلن جي بغير ٿي سگهي ٿي.

اهو نمايان ڪرڻ جي قابل آهي Delegated ڊرائيور، ڇاڪاڻ ته جيڪڏهن اهو استعمال ڪيو ويندو آهي، مثال جي ترتيب سان صرف ڪم مثال جي ٺاھڻ ۽ فائلن کي ختم ڪرڻ ۾ بيان ڪيو ويو آهي؛ باقي انجنيئر طرفان بيان ڪيو وڃي.

ڊفالٽ ڊرائيور آهي Docker.

هاڻي اچو ته مشق ڏانهن وڃو ۽ اتي وڌيڪ خاصيتن تي غور ڪريو.

شروع ڪرائڻ

هڪ "هيلو دنيا" جي طور تي اسان هڪ سادي نينڪس تنصيب ڪردار کي جانچ ڪنداسين. اچو ته ڊڪر کي ڊرائيور طور چونڊيو - مان سمجهان ٿو ته توهان مان اڪثر اهو انسٽال ڪيو آهي (۽ ياد رکو ته ڊڪر ڊفالٽ ڊرائيور آهي).

تيار ڪريو virtualenv ۽ ان ۾ انسٽال ڪريو molecule:

> pip install virtualenv
> virtualenv -p `which python2` venv
> source venv/bin/activate
> pip install molecule docker  # molecule установит ansible как зависимость; docker для драйвера

ايندڙ قدم هڪ نئين ڪردار کي شروع ڪرڻ آهي.
نئين ڪردار جي شروعات، گڏوگڏ هڪ نئين رسم الخط، ڪمانڊ استعمال ڪندي ڪيو ويندو آهي molecule init <params>:

> molecule init role -r nginx
--> Initializing new role nginx...
Initialized role in <path>/nginx successfully.
> cd nginx
> tree -L 1
.
├── README.md
├── defaults
├── handlers
├── meta
├── molecule
├── tasks
└── vars

6 directories, 1 file

نتيجو هڪ عام جوابي ڪردار آهي. ان کان علاوه، ماليڪيول CLI سان گڏ سڀئي تعامل رول روٽ مان ٺهيل آهن.

اچو ته ڏسو ته رول ڊاريڪٽري ۾ ڇا آهي:

> tree molecule/default/
molecule/default/
├── Dockerfile.j2  # Jinja-шаблон для Dockerfile
├── INSTALL.rst.   # Немного информации об установке зависимостей сценария
├── molecule.yml   # Файл конфигурации
├── playbook.yml   # Плейбук запуска роли
└── tests          # Директория с тестами стадии verify
    └── test_default.py

1 directory, 6 files

اچو ته config تي نظر molecule/default/molecule.yml (اسان صرف ڊاکر تصوير کي تبديل ڪنداسين):

---
dependency:
  name: galaxy
driver:
  name: docker
lint:
  name: yamllint
platforms:
  - name: instance
    image: centos:7
provisioner:
  name: ansible
  lint:
    name: ansible-lint
scenario:
  name: default
verifier:
  name: testinfra
  lint:
    name: flake8

انحصار

هي حصو بيان ڪري ٿو انحصار جو ذريعو.

ممڪن اختيارن: گائيڪس, لاڳو، خول.

شيل صرف هڪ ڪمانڊ شيل آهي استعمال ڪرڻ لاءِ جيڪڏهن گليڪس ۽ گلٽ توهان جي ضرورتن کي پورو نه ڪن.

مان هتي گهڻي وقت تائين نه رهندس، ان ۾ ڪافي بيان ڪيو ويو آهي دستاويز.

ڊرائيور

ڊرائيور جو نالو. اسان لاء هي ڊڪر آهي.

لکت

Yamllint هڪ linter طور استعمال ڪيو ويندو آهي.

config جي ھن حصي ۾ ڪارآمد اختيارات آھن yamllint لاءِ ڪانفيگريشن فائل بيان ڪرڻ جي صلاحيت، ماحوليات کي اڳتي وڌائڻ، يا لينٽر کي غير فعال ڪرڻ:

lint:
  name: yamllint
  options:
    config-file: foo/bar
  env:
    FOO: bar
  enabled: False

پليٽ فارم

مثالن جي تشڪيل کي بيان ڪري ٿو.
ڊاڪر جي صورت ۾ ڊرائيور جي حيثيت ۾، ماليڪيول هن حصي تي ٻيهر ورجائي ٿو، ۽ فهرست جو هر عنصر موجود آهي Dockerfile.j2 هڪ variable طور item.

جنهن ۾ ڊرائيور جي صورت ۾ create.yml и destroy.yml، سيڪشن انهن ۾ موجود آهي جيئن molecule_yml.platforms، ۽ ان تي ورجائي اڳ ۾ ئي بيان ڪيل آهن انهن فائلن ۾.

جيئن ته ماليڪيول جوابي ماڊلز کي مثالي انتظام فراهم ڪري ٿو، توهان کي اتي ممڪن سيٽنگن جي فهرست ڳولڻ گهرجي. Docker لاء، مثال طور، ماڊل استعمال ڪيو ويندو آهي docker_container_module. ڪهڙا ماڊل استعمال ڪيا ويا آهن ٻين ڊرائيورن ۾ ڳولي سگهجن ٿا دستاويز.

توھان پڻ ڳولي سگھوٿا مختلف ڊرائيور استعمال ڪرڻ جا مثال پاڻ ماليڪيول جي ٽيسٽن ۾.

اچو ته هتي تبديل ڪريون سينٽ: 7 تي Ubuntu.

روزي ڏيندڙ

"فراهم ڪندڙ" اهو ادارو آهي جيڪو مثالن کي منظم ڪري ٿو. ماليڪيول جي صورت ۾، اهو قابل قبول آهي؛ ٻين لاءِ سپورٽ منصوبابندي نه ڪئي وئي آهي، تنهنڪري هن حصي کي، رزرويشن سان، هڪ وڌايل جوابي ترتيب سڏيو وڃي ٿو.
هتي تمام گهڻو آهي توهان هتي اشارو ڪري سگهو ٿا، پر مان مکيه نقطي کي اجاگر ڪندس، منهنجي راء ۾:

  • راند جا ڪتاب: توهان وضاحت ڪري سگھو ٿا ته ڪهڙن پلے بڪ کي خاص مرحلن تي استعمال ڪيو وڃي.

provisioner:
  name: ansible
  playbooks:
    create: create.yml
    destroy: ../default/destroy.yml
    converge: playbook.yml
    side_effect: side_effect.yml
    cleanup: cleanup.yml

provisioner:
  name: ansible
  config_options:
    defaults:
      fact_caching: jsonfile
    ssh_connection:
      scp_if_ssh: True

provisioner:
  name: ansible  
  connection_options:
    ansible_ssh_common_args: "-o 'UserKnownHostsFile=/dev/null' -o 'ForwardAgent=yes'"

  • اختيارن: جوابي پيٽرول ۽ ماحولياتي متغير

provisioner:
  name: ansible  
  options:
    vvv: true
    diff: true
  env:
    FOO: BAR

اهڙي منظرنامي

اسڪرپٽ جي تسلسل جو عنوان ۽ وضاحت.
توھان تبديل ڪري سگھو ٿا ڊفالٽ ايڪشن ميٽرڪس ڪمانڊ کي شامل ڪرڻ سان <command>_sequence ۽ ان جي قيمت جي طور تي، اسان کي گهربل قدمن جي فهرست جي وضاحت ڪندي.
اچو ته چئو ته اسان عملن جي ترتيب کي تبديل ڪرڻ چاهيون ٿا جڏهن پلے بڪ رن ڪمانڊ هلائي رهيا آهيو: molecule converge

# изначально:
# - dependency
# - create
# - prepare
# - converge
scenario:
  name: default
  converge_sequence:
    - create
    - converge

چيڪ

ٽيسٽ لاءِ فريم ورڪ قائم ڪرڻ ۽ ان لاءِ لينٽر. ڊفالٽ طور، لينٽر استعمال ڪيو ويندو آهي testinfra и flake8. ممڪن اختيارن مٿي ڏنل آهن:

verifier:
  name: testinfra
  additional_files_or_dirs:
    - ../path/to/test_1.py
    - ../path/to/test_2.py
    - ../path/to/directory/*
  options:
    n: 1
  enabled: False
  env:
    FOO: bar
  lint:
    name: flake8
    options:
      benchmark: True
    enabled: False
    env:
      FOO: bar

اچو ته اسان جي ڪردار ڏانهن واپس وڃو. اچو ته فائل کي ايڊٽ ڪريون tasks/main.yml هن نظر ڏانهن:

---
- name: Install nginx
  apt:
    name: nginx
    state: present

- name: Start nginx
  service:
    name: nginx
    state: started

۽ ٽيسٽ شامل ڪريو molecule/default/tests/test_default.py

def test_nginx_is_installed(host):
    nginx = host.package("nginx")
    assert nginx.is_installed

def test_nginx_running_and_enabled(host):
    nginx = host.service("nginx")
    assert nginx.is_running
    assert nginx.is_enabled

def test_nginx_config(host):
    host.run("nginx -t")

ٿي ويو، باقي اهو سڀ ڪجهه هلڻو آهي (ڪردار جي روٽ کان، مون کي توهان کي ياد ڏيارڻ ڏيو):

> molecule test

اسپائلر جي هيٺان ڊگھي نڪرڻ:

--> Validating schema <path>/nginx/molecule/default/molecule.yml.
Validation completed successfully.
--> Test matrix

└── default
    ├── lint
    ├── destroy
    ├── dependency
    ├── syntax
    ├── create
    ├── prepare
    ├── converge
    ├── idempotence
    ├── side_effect
    ├── verify
    └── destroy

--> Scenario: 'default'
--> Action: 'lint'
--> Executing Yamllint on files found in <path>/nginx/...
Lint completed successfully.
--> Executing Flake8 on files found in <path>/nginx/molecule/default/tests/...
Lint completed successfully.
--> Executing Ansible Lint on <path>/nginx/molecule/default/playbook.yml...
Lint completed successfully.
--> Scenario: 'default'
--> Action: 'destroy'

    PLAY [Destroy] *****************************************************************

    TASK [Destroy molecule instance(s)] ********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) deletion to complete] *******************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Delete docker network(s)] ************************************************

    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=1    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'dependency'
Skipping, missing the requirements file.
--> Scenario: 'default'
--> Action: 'syntax'

    playbook: <path>/nginx/molecule/default/playbook.yml

--> Scenario: 'default'
--> Action: 'create'

    PLAY [Create] ******************************************************************

    TASK [Log into a Docker registry] **********************************************
    skipping: [localhost] => (item=None)

    TASK [Create Dockerfiles from image names] *************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Discover local Docker images] ********************************************
    ok: [localhost] => (item=None)
    ok: [localhost]

    TASK [Build an Ansible compatible image] ***************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Create docker network(s)] ************************************************

    TASK [Create molecule instance(s)] *********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) creation to complete] *******************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    PLAY RECAP *********************************************************************
    localhost                  : ok=5    changed=4    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'prepare'
Skipping, prepare playbook not configured.
--> Scenario: 'default'
--> Action: 'converge'

    PLAY [Converge] ****************************************************************

    TASK [Gathering Facts] *********************************************************
    ok: [instance]

    TASK [nginx : Install nginx] ***************************************************
    changed: [instance]

    TASK [nginx : Start nginx] *****************************************************
    changed: [instance]

    PLAY RECAP *********************************************************************
    instance                   : ok=3    changed=2    unreachable=0    failed=0

--> Scenario: 'default'
--> Action: 'idempotence'
Idempotence completed successfully.
--> Scenario: 'default'
--> Action: 'side_effect'
Skipping, side effect playbook not configured.
--> Scenario: 'default'
--> Action: 'verify'
--> Executing Testinfra tests found in <path>/nginx/molecule/default/tests/...
    ============================= test session starts ==============================
    platform darwin -- Python 2.7.15, pytest-4.3.0, py-1.8.0, pluggy-0.9.0
    rootdir: <path>/nginx/molecule/default, inifile:
    plugins: testinfra-1.16.0
collected 4 items

    tests/test_default.py ....                                               [100%]

    ========================== 4 passed in 27.23 seconds ===========================
Verifier completed successfully.
--> Scenario: 'default'
--> Action: 'destroy'

    PLAY [Destroy] *****************************************************************

    TASK [Destroy molecule instance(s)] ********************************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Wait for instance(s) deletion to complete] *******************************
    changed: [localhost] => (item=None)
    changed: [localhost]

    TASK [Delete docker network(s)] ************************************************

    PLAY RECAP *********************************************************************
    localhost                  : ok=2    changed=2    unreachable=0    failed=0

اسان جو سادو ڪردار بغير مسئلن جي آزمائشي.
اهو ياد رکڻ جي قابل آهي ته جيڪڏهن آپريشن دوران مسئلا پيدا ٿئي ٿي molecule test، پوء جيڪڏھن توھان معياري ترتيب کي تبديل نه ڪيو، Molecule مثال کي ختم ڪري ڇڏيندو.

هيٺيون حڪم ڊيبگنگ لاءِ ڪارآمد آهن:

> molecule --debug <command> # debug info. При обычном запуске Молекула скрывает логи.
> molecule converge          # Оставляет инстанс после прогона тестируемой роли.
> molecule login             # Зайти в созданный инстанс.
> molecule --help            # Полный список команд.

موجوده ڪردار

موجوده ڪردار ۾ نئين اسڪرپٽ شامل ڪرڻ ٿئي ٿي رول ڊاريڪٽري مان ھيٺ ڏنل حڪمن سان:

# полный список доступных параметров
> molecule init scenarion --help
# создание нового сценария
> molecule init scenario -r <role_name> -s <scenario_name>

جيڪڏهن اهو ڪردار ۾ پهريون اسڪرپٽ آهي، پوء پيٽرولر -s ختم ڪري سگھجي ٿو ڇاڪاڻ ته هڪ اسڪرپٽ ٺاهي ويندي default.

ٿڪل

جئين توهان ڏسي سگهو ٿا، ماليڪيول تمام پيچيده نه آهي، ۽ جڏهن توهان جي پنهنجي ٽيمپليٽس کي استعمال ڪندي، توهان مثالن ٺاهڻ ۽ حذف ڪرڻ لاءِ پلے بڪ ۾ متغيرن کي ايڊٽ ڪرڻ لاءِ نئين اسڪرپٽ جي ترتيب کي گهٽائي سگهو ٿا. انو بيشمار طور تي CI سسٽم سان ضم ٿي ٿو، جيڪو توهان کي ترقي جي رفتار کي وڌائڻ جي اجازت ڏئي ٿو پلے بڪ جي دستيابي جاچ لاءِ وقت گھٽائي.

توهان جي توجه لاء مهرباني. جيڪڏهن توهان کي جوابي ڪردار جي جانچ ڪرڻ جو تجربو آهي، ۽ اهو ماليڪيول سان لاڳاپيل ناهي، اسان کي تبصرن ۾ ان بابت ٻڌايو!

جو ذريعو: www.habr.com

تبصرو شامل ڪريو