Mga panudlo: kung giunsa pagsulay ang mga mahimo nga tahas ug mahibal-an ang bahin sa mga problema sa wala pa ang produksiyon

Hello sa tanan!

Nagtrabaho ko isip inhenyero sa DevOps sa usa ka serbisyo sa pag-book sa hotel. Ostrovok.ru. Niini nga artikulo, gusto nakong hisgutan ang among kasinatian sa pagsulay sa mga mahimo nga tahas.

Sa Ostrovok.ru, gigamit namo ang ansible isip usa ka configuration manager. Bag-ohay lang, nakaabut kami sa panginahanglan sa pagsulay sa mga tahas, apan ingon nga kini nahimo, wala’y daghang mga himan alang niini - ang labing inila, tingali, mao ang balangkas sa Molecule, mao nga nakahukom kami nga gamiton kini. Apan nahimo nga hilom ang iyang dokumentasyon bahin sa daghang mga lit-ag. Wala kami makakita og igo nga detalyado nga manwal sa Russian, mao nga nakahukom kami sa pagsulat niini nga artikulo.

Mga panudlo: kung giunsa pagsulay ang mga mahimo nga tahas ug mahibal-an ang bahin sa mga problema sa wala pa ang produksiyon

Molekyul

Molekul - usa ka balangkas aron matabangan ang pagsulay sa mga mahimo nga tahas.

Gipasimple nga paghulagway: Ang molekula nagmugna og usa ka pananglitan sa plataporma nga imong gitakda (panganod, virtual machine, sudlanan; alang sa dugang nga mga detalye, tan-awa ang seksyon Driver), nagpadagan sa imong papel niini, dayon nagpadagan sa mga pagsulay ug gitangtang ang pananglitan. Sa kaso sa pagkapakyas sa usa sa mga lakang, ang Molecule magpahibalo kanimo bahin niini.

Karon labaw pa.

Usa ka teoriya

Tagda ang duha ka importanteng entidad sa Molecule: Scenario ug Driver.

Scenario

Ang script naglangkob sa usa ka paghulagway sa unsa, asa, sa unsa nga paagi ug sa unsa nga sunod-sunod nga ipahigayon. Ang usa ka papel mahimong adunay daghang mga script, ug ang matag usa usa ka direktoryo sa agianan <role>/molecule/<scenario>, nga adunay mga paghulagway sa mga aksyon nga gikinahanglan alang sa pagsulay. Kinahanglang iapil ang script default, nga awtomatiko nga mabuhat kung imong sugdan ang tahas gamit ang Molecule. Ang mga ngalan sa mosunod nga mga script anaa kanimo.

Ang pagkasunod-sunod sa mga aksyon sa pagsulay sa usa ka script gitawag taguangkan sa, ug sa default kini mao ang:

(Mga lakang nga gimarkahan ?, gilaktawan pinaagi sa default kung wala gitino sa tiggamit)

  • lint - nagdagan nga mga linter. Pinaagi sa default gigamit yamllint и flake8,
  • destroy - pagtangtang sa mga higayon gikan sa katapusang paglansad sa Molecule (kung naa man),
  • dependency? - pag-instalar sa kasaligan nga pagsalig sa gisulayan nga papel,
  • syntax - pagsusi sa syntax sa papel nga gigamit ansible-playbook --syntax-check,
  • create - paghimo usa ka pananglitan,
  • prepare? - pag-andam sa pananglitan; pananglitan check/instalar python2
  • converge - paglansad sa playbook nga gisulayan,
  • idempotence - pagsugod pag-usab sa playbook para sa idempotency test,
  • side_effect? - mga aksyon nga dili direktang may kalabutan sa papel, apan gikinahanglan alang sa mga pagsulay,
  • verify - pagpadagan sa mga pagsulay sa resulta nga configuration gamit testinfra(default) /goss/inspec,
  • cleanup? - (sa bag-ong mga bersyon) - sa halos pagsulti, "paglimpyo" sa gawas nga imprastraktura nga naapektuhan sa Molecule,
  • destroy - Pagtangtang sa usa ka pananglitan.

Kini nga han-ay naglangkob sa kadaghanan sa mga kaso, apan mahimong usbon kung gikinahanglan.

Ang matag usa sa mga lakang sa ibabaw mahimong ipadagan nga gilain sa molecule <command>. Apan kinahanglan nga sabton nga alang sa matag ingon nga cli-command mahimong adunay kaugalingon nga pagkasunod-sunod sa mga aksyon, nga mahimo nimong mahibal-an pinaagi sa pagpatuman. molecule matrix <command>. Pananglitan, kung nagpadagan sa mando converge (pagpadagan sa playbook ubos sa pagsulay), ang mosunod nga mga aksyon ipahigayon:

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

Ang han-ay niini nga mga aksyon mahimong i-edit. Kung ang usa ka butang gikan sa lista nahimo na, kini laktawan. Ang kasamtangan nga kahimtang, ingon man ang config sa mga higayon, ang Molecule nagtipig sa direktoryo $TMPDIR/molecule/<role>/<scenario>.

Idugang ang mga lakang sa ? mahimo nimong ihulagway ang gusto nga mga aksyon sa format nga ansible-playbook, ug himuon ang ngalan sa file sumala sa lakang: prepare.yml/side_effect.yml. Paabuta kini nga mga file Ang molekula naa sa folder sa script.

Driver

Ang usa ka drayber usa ka entidad diin gihimo ang mga pagsulay.
Ang lista sa standard nga mga drayber diin ang Molecule adunay mga templates nga andam mao ang mosunod: Azure, Docker, EC2, GCE, LXC, LXD, OpenStack, Vagrant, Delegated.

Sa kadaghanan nga mga kaso, ang mga template mga file create.yml и destroy.yml sa script folder nga naghulagway sa paghimo ug pagtangtang sa usa ka pananglitan, matag usa.
Ang mga eksepsiyon mao ang Docker ug Vagrant, tungod kay ang mga interaksyon sa ilang mga module mahimong mahitabo kung wala ang nahisgutan nga mga file.

Angayan nga ipasiugda ang Delegado nga drayber, tungod kay kung gigamit kini sa mga file alang sa paghimo ug pagtangtang sa usa ka pananglitan, ang pagtrabaho lamang sa pag-configure sa mga higayon nga gihulagway, ang nahabilin kinahanglan ihulagway sa engineer.

Ang default nga drayber mao ang Docker.

Karon magpadayon kita sa pagpraktis ug ikonsiderar ang dugang nga mga bahin didto.

Pagsugod

Ingon usa ka "hello world", atong sulayan ang usa ka yano nga papel sa pag-install sa nginx. Atong pilion ang docker isip drayber - sa akong hunahuna kadaghanan kaninyo naka-install niini (ug hinumdomi nga ang docker mao ang default driver).

Pag-andam virtualenv ug instalar niini molecule:

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

Ang sunod nga lakang mao ang pagsugod sa bag-ong papel.
Ang pagsugod sa usa ka bag-ong papel, ingon man usa ka bag-ong script, gihimo gamit ang mando 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

Kini nahimo nga usa ka tipikal nga ansible-role. Dugang pa, ang tanan nga mga interaksyon sa CLI Molecules gihimo gikan sa gamut sa papel.

Atong tan-awon kung unsa ang naa sa direktoryo sa papel:

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

1 directory, 6 files

Atong analisahon ang config molecule/default/molecule.yml (ilisan lang ang docker image):

---
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

pagsalig sa

Kini nga seksyon naghulagway sa tinubdan sa mga dependency.

Posible nga mga kapilian: Galaxy, gitabonan, kabhang.

Ang Shell usa lang ka command shell nga gigamit kung ang galaxy ug gilt dili makatabon sa imong mga panginahanglan.

Dili ako magpuyo dinhi sa dugay nga panahon, kini igo nga gihulagway sa dokumentasyon.

drayber

Ang ngalan sa drayber. Ang among pantalan.

labi ka labi

Ang linter kay yamllint.

Mapuslanon nga mga kapilian niini nga bahin sa config mao ang abilidad sa pagtino sa usa ka configuration file alang sa yamllint, forward environment variables, o pag-disable sa linter:

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

Plataporma

Gihulagway ang configuration sa mga higayon.
Sa kaso sa docker isip usa ka drayber, ang Molecule gisubli niini nga seksyon, ug ang matag elemento sa listahan anaa sa Dockerfile.j2 isip usa ka variable item.

Sa kaso sa usa ka drayber nga nagkinahanglan create.yml и destroy.yml, ang seksyon anaa kanila ingon nga molecule_yml.platforms, ug ang mga pag-uli sa ibabaw niini gihulagway na niini nga mga file.

Tungod kay ang Molecule naghatag og kontrol sa mga instance sa ansible modules, ang lista sa posible nga mga setting kinahanglan usab nga pangitaon didto. Alang sa docker, pananglitan, ang module gigamit docker_container_module. Hain nga mga module ang gigamit sa ubang mga drayber makita sa dokumentasyon.

Ingon man usab ang mga pananglitan sa paggamit sa lainlaing mga drayber makita sa mga pagsulay sa Molecule mismo.

Ilisan dinhi centos:7 sa Ubuntu.

tighatag

"Supplier" - usa ka entidad nga nagdumala sa mga higayon. Sa kaso sa Molecule, kini ansible, ang suporta alang sa uban wala giplano, mao nga kini nga seksyon matawag nga ansible extended configuration nga adunay caveat.
Dinhi mahimo nimong ipiho ang daghang mga butang, akong ipasiugda ang mga nag-unang punto, sa akong opinyon:

  • playbooks: mahimo nimong ipiho kung unsang mga playbook ang kinahanglan gamiton sa pila ka yugto.

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'"

  • mga kapilian: Mahimong kapilian ug mga variable sa palibot

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

nga situwasyon

Ngalan ug paghulagway sa mga han-ay sa script.
Mahimo nimong usbon ang default action matrix sa bisan unsang command pinaagi sa pagdugang sa yawe <command>_sequence ug isip usa ka bili niini pinaagi sa pagpasabot sa listahan sa mga lakang nga atong gikinahanglan.
Ingnon ta nga gusto namong usbon ang han-ay sa mga aksyon sa dihang nagdagan ang playbook run command: molecule converge

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

check

Paghimo og usa ka balangkas alang sa mga pagsulay ug usa ka linter niini. Ang default nga linter mao ang testinfra и flake8. Ang posible nga mga kapilian parehas sa ibabaw:

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

Balik ta sa atong papel. I-edit nato ang file tasks/main.yml sa niini nga matang:

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

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

Ug idugang ang mga pagsulay sa 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")

Nahuman na, kini nagpabilin lamang sa pagdagan (gikan sa gamut sa papel, pahinumdoman ko ikaw):

> molecule test

Taas nga tambutso ubos sa spoiler:

--> 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

Ang among yano nga tahas gisulayan nga walay problema.
Angayan nga hinumdoman nga kung adunay mga problema sa panahon sa trabaho molecule test, unya kung wala nimo usba ang default sequence, ang Molecule magtangtang sa instance.

Ang mosunod nga mga sugo mapuslanon sa pag-debug:

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

Naglungtad nga Papel

Ang pagdugang og bag-ong script sa kasamtangan nga papel mao ang gikan sa direktoryo sa papel uban sa mosunod nga mga sugo:

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

Kung kini ang una nga senaryo sa papel, unya ang parameter -s mahimong laktawan tungod kay maghimo kini og script default.

konklusyon

Sama sa imong nakita, ang Molecule dili kaayo komplikado, ug pinaagi sa paggamit sa imong kaugalingon nga mga templates, ang pag-deploy sa usa ka bag-ong script mahimong mapakunhod sa pag-edit sa mga variable sa pananglitan sa paghimo ug pagtangtang sa mga playbook. Ang molekula naghiusa nga hapsay sa mga sistema sa CI, nga nagtugot kanimo nga madugangan ang katulin sa pag-uswag pinaagi sa pagkunhod sa oras alang sa manual nga pagsulay sa mga playbook.

Salamat sa imong pagtagad. Kung adunay ka kasinatian sa pagsulay sa mga mahimo nga tahas, ug wala kini kalabutan sa Molecule, isulti kanamo ang bahin niini sa mga komento!

Source: www.habr.com

Idugang sa usa ka comment