Дастурҳо: чӣ гуна бояд нақшҳои қобили мулоҳизаро санҷед ва дар бораи мушкилот пеш аз истеҳсол маълумот пайдо кунед

Салом хама!

Ман ҳамчун муҳандиси DevOps дар хидмати бронкунии меҳмонхонаҳо кор мекунам. Ostrovok.ru. Дар ин мақола, ман мехоҳам дар бораи таҷрибаи мо дар санҷиши нақшҳои қобили мулоҳиза сӯҳбат кунам.

Дар Ostrovok.ru мо ansible-ро ҳамчун мудири конфигуратсия истифода мебарем. Ба наздикӣ, мо ба зарурати санҷиши нақшҳо расидем, аммо тавре маълум шуд, барои ин асбобҳо он қадар зиёд нестанд - маъмултарин, шояд чаҳорчӯбаи Molecule аст, бинобар ин мо тасмим гирифтем, ки онро истифода барем. Аммо маълум шуд, ки ҳуҷҷатҳои ӯ дар бораи домҳои зиёде хомӯшанд. Мо ба забони русӣ дастури ба таври кофӣ муфассал пайдо карда натавонистем, бинобар ин мо тасмим гирифтем, ки ин мақоларо нависем.

Дастурҳо: чӣ гуна бояд нақшҳои қобили мулоҳизаро санҷед ва дар бораи мушкилот пеш аз истеҳсол маълумот пайдо кунед

Молекула

Молекула - чаҳорчӯба барои кӯмак дар санҷиши нақшҳои қобили қабул.

Тавсифи соддакардашуда: Молекула дар платформаи муайянкардаи шумо намуна эҷод мекунад (абр, мошини виртуалӣ, контейнер; барои тафсилоти бештар ба қисм нигаред. ронанда), нақши худро дар он иҷро мекунад, сипас санҷишҳоро иҷро мекунад ва мисолро нест мекунад. Дар сурати нокомӣ дар яке аз қадамҳо, Молекула ба шумо дар ин бора хабар медиҳад.

Акнун бештар.

Якчанд назария

Ду ҷузъи калидии Молекуларо баррасӣ кунед: Сенария ва Драйвер.

Сенатор

Дар скрипт тавсифи он аст, ки чӣ, дар куҷо, чӣ гуна ва бо кадом пайдарпай иҷро карда мешавад. Як нақш метавонад якчанд скрипт дошта бошад ва ҳар як директория дар қад-қади роҳ аст <role>/molecule/<scenario>, ки дорои тавсифи амалҳои барои санҷиш зарур аст. Скрипт бояд дохил карда шавад default, ки агар шумо нақшро бо истифода аз Molecule оғоз кунед, ба таври худкор эҷод карда мешавад. Номҳои скриптҳои зерин ба шумо вобастаанд.

Пайдарпайии амалҳои санҷишӣ дар скрипт номида мешавад Матраса, ва ба таври нобаёнӣ он аст:

(Қадамҳо нишон дода шудаанд ?, ба таври нобаёнӣ гузаред, агар корбар муайян накарда бошад)

  • lint - линтерҳои равон. Ба таври нобаёнӣ истифода мешаванд yamllint и flake8,
  • destroy - нест кардани мисолҳо аз оғози охирини Молекула (агар мавҷуд бошад),
  • dependency? - насби вобастагии воқеии нақши санҷидашуда,
  • syntax - тафтиши синтаксиси нақш бо истифода аз ansible-playbook --syntax-check,
  • create - эҷоди як мисол,
  • prepare? — тайёр намудани мисол; масалан, санҷед/насб кунед python2
  • converge — ифтитоҳи китоби бозӣ, ки дар озмоиш қарор дорад,
  • idempotence - аз нав оғоз кардани китоби бозӣ барои санҷиши импотенция,
  • side_effect? -амалҳое, ки бевосита ба нақш алоқаманд нестанд, вале барои санҷиш заруранд;
  • verify - гузаронидани санҷишҳои конфигуратсияи натиҷавӣ бо истифода аз testinfra(пешфарз) /goss/inspec,
  • cleanup? - (дар версияҳои нав) - тахминан, "тоза кардани" инфрасохтори беруна, ки аз Молекула зарар дидаанд,
  • destroy - Нест кардани мисол.

Ин пайдарпаӣ аксари ҳолатҳоро дар бар мегирад, аммо дар ҳолати зарурӣ метавонад тағир дода шавад.

Ҳар яке аз қадамҳои дар боло зикршуда метавонад алоҳида иҷро карда шавад molecule <command>. Аммо бояд дарк кард, ки барои ҳар як чунин фармон метавонад пайдарпайии амалии худро дошта бошад, ки шумо метавонед онҳоро тавассути иҷрои molecule matrix <command>. Масалан, ҳангоми иҷро кардани фармон converge (китоби бозиро дар зери санҷиш иҷро мекунад), амалҳои зерин иҷро карда мешаванд:

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

Пайдарҳамии ин амалҳоро таҳрир кардан мумкин аст. Агар чизе аз рӯйхат аллакай иҷро шуда бошад, он гузаронида мешавад. Ҳолати ҷорӣ, инчунин конфигуратсияи мисолҳо, Molecule дар феҳрист нигоҳ медорад $TMPDIR/molecule/<role>/<scenario>.

Қадамҳоро бо ? шумо метавонед амалҳои дилхоҳро дар формати ansible-playbook тавсиф кунед ва номи файлро мувофиқи қадами зерин созед: prepare.yml/side_effect.yml. Ин файлҳоро интизор шавед Молекула дар папкаи скрипт хоҳад буд.

ронанда

Драйвер объектест, ки дар он намунаҳои санҷишӣ сохта мешаванд.
Рӯйхати драйверҳои стандартие, ки барои онҳо Molecule қолибҳои омода дорад, чунин аст: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegated.

Дар аксари ҳолатҳо, қолибҳо файлҳо мебошанд create.yml и destroy.yml дар папкаи скрипт, ки мутаносибан эҷод ва нест кардани мисолро тавсиф мекунад.
Истисноҳо Docker ва Vagrant мебошанд, зеро ҳамкорӣ бо модулҳои онҳо метавонанд бидуни файлҳои дар боло зикршуда сурат гиранд.

Бояд қайд кард, ки драйвери ваколатдорро қайд кунем, зеро агар он дар файлҳо барои эҷод ва нест кардани мисол истифода шавад, танҳо кор бо конфигуратсияи инстансияҳо тавсиф карда мешавад, боқимондаро бояд муҳандис тавсиф кунад.

Драйвери пешфарз Docker аст.

Акнун биёед ба амалия гузарем ва хусусиятҳои минбаъдаро дар он ҷо баррасӣ кунем.

саршавӣ

Ҳамчун "ҷаҳон салом", биёед нақши оддии насби nginx-ро санҷем. Мо докерро ҳамчун ронанда интихоб мекунем - Ман фикр мекунам, ки аксарияти шумо онро насб кардаед (ва дар хотир доред, ки докер драйвери пешфарз аст).

Тайёр кунед 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

Биёед конфигуратсияро таҳлил кунем 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

вобастагӣ дорад

Ин бахш манбаи вобастагиҳоро тавсиф мекунад.

Имкониятҳо: Галактика, заррин, снаряд.

Shell танҳо як қабати фармонест, ки дар сурати қонеъ кардани ниёзҳои шумо галактика ва гил истифода мешавад.

Ман дар ин ҷо муддати тӯлонӣ иқомат намекунам, дар он кофӣ тавсиф шудааст хуччатхо.

ронанда

Номи ронанда. Мо докер аст.

линт

Линтер ямлинт аст.

Вариантҳои муфид дар ин қисми конфигуратсия қобилияти муайян кардани файли конфигуратсия барои yamllint, тағирёбандаҳои муҳити атроф ё ғайрифаъол кардани linter мебошанд:

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

платформаҳо

Конфигуратсияи мисолҳоро тавсиф мекунад.
Дар мавриди докер ҳамчун драйвер, Молекула дар ин бахш такрор карда мешавад ва ҳар як унсури рӯйхат дар Dockerfile.j2 ҳамчун тағирёбанда item.

Дар сурати ронандае, ки талаб мекунад create.yml и destroy.yml, бахш дар онҳо ҳамчун дастрас аст molecule_yml.platforms, ва такрори он аллакай дар ин файлҳо тасвир шудааст.

Азбаски Molecule идоракунии мисолҳоро ба модулҳои Ansible таъмин мекунад, шумо бояд рӯйхати танзимоти имконпазирро дар он ҷо ҷустуҷӯ кунед. Барои докер, масалан, модул истифода мешавад docker_container_module. Кадом модулҳоро дар дигар драйверҳо истифода бурдан мумкин аст дар хуччатхо.

Инчунин мисолхои истифодаи ронандагони гуногунро ёфтан мумкин аст дар озмоишхои худи Молекула.

Биёед дар ин ҷо иваз кунем centos: 7 ба Ubuntu.

таъминкунанда

"Таъминкунанда" - субъекте, ки мисолҳоро идора мекунад. Дар мавриди Molecule, ин қобили қабул аст, дастгирии дигарон ба нақша гирифта нашудааст, бинобар ин ин бахшро метавон конфигуратсияи васеъшудаи ansible бо огоҳӣ номид.
Дар ин ҷо шумо метавонед бисёр чизҳоро муайян кунед, ман нуктаҳои асосиро таъкид мекунам, ба андешаи ман:

  • китобҳои бозӣ: шумо метавонед муайян кунед, ки кадом китобҳои бозӣ бояд дар марҳилаҳои муайян истифода шаванд.

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 ва ҳамчун арзиш барои он бо муайян кардани рӯйхати қадамҳои ба мо лозим аст.
Фарз мекунем, ки мо мехоҳем пайдарпайии амалҳоро ҳангоми иҷро кардани фармони иҷро кардани китоби playbook тағир диҳем: 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 --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 бефосила муттаҳид мешавад, ки ба шумо имкон медиҳад суръати рушдро тавассути кам кардани вақти санҷиши дастии китобҳои бозӣ зиёд кунед.

Ба диққататон ташаккур. Агар шумо таҷрибаи санҷиши нақшҳои қобили қабул дошта бошед ва он ба Молекула алоқаманд набошад, дар ин бора дар шарҳҳо ба мо бигӯед!

Манбаъ: will.com

Илова Эзоҳ