Лёгка і нязмушана дэплоім прыкладання на Tarantool Cartridge (частка 1)

Лёгка і нязмушана дэплоім прыкладання на Tarantool Cartridge (частка 1)

Мы ўжо расказвалі пра Tarantool Cartridge, які дазваляе распрацоўваць размеркаваныя прыкладанні і пакаваць іх. Засталося ўсяго нічога: навучыцца дэплоіць гэтыя прыкладанні і кіраваць імі. Не хвалюйцеся, мы ўсё прадугледзелі! Мы сабралі разам усе best practices па працы з Tarantool Cartridge і напісалі ansible-роля, якая раскладзе пакет на серверы, стартане інстансы, аб'яднае іх у кластар, наладзіць аўтарызацыю, забутстрапит vshard, уключыць аўтаматычны failover і выпатчыць кластарны канфіг.

Цікава? Тады прашу пад кат, усё раскажам і пакажам.

Пачнём з прыкладу

Мы разгледзім толькі частку функцыянальнасці нашай ролі. Поўнае апісанне ўсіх яе магчымасцяў і ўваходных параметраў вы заўсёды можаце знайсці ў дакументацыі. Але лепш адзін раз паспрабаваць, чым сто разоў убачыць, таму давайце задеплоим невялікае прыкладанне.

У Tarantool Cartridge ёсць тутарыял па стварэнні невялікага Cartridge-прыкладанні, якое захоўвае інфармацыю аб кліентах банка і іх рахунках, а таксама падае API для кіравання дадзенымі праз HTTP. Для гэтага ў дадатку апісваюцца дзве магчымыя ролі: api и storage, якія могуць прызначацца інстансам.

Сам Cartridge нічога не кажа пра тое, як запускаць працэсы, ён толькі дае магчымасць для наладкі ўжо запушчаных інстансаў. Астатняе карыстач павінен зрабіць сам: раскласці канфігурацыйныя файлы, запусціць сэрвісы і наладзіць тапалогію. Але мы ня будзем усім гэтым займацца, за нас гэта зробіць Ansible.

Ад слоў да справы

Такім чынам, задэплоім наша дадатак на дзве віртуалкі і настроім простую тапалогію:

  • Рэплікасэт app-1 будзе рэалізоўваць ролю api, якая ўключае ў сябе ролю vshard-router. Тут будзе толькі адзін інстанс.
  • Рэплікасэт storage-1 рэалізуе ролю storage (і адначасова vshard-storage), сюды дадамо два інстансы з розных машын.

Лёгка і нязмушана дэплоім прыкладання на Tarantool Cartridge (частка 1)

Для запуску прыкладу нам спатрэбяцца валацуга и анзибль (версіі 2.8 ці старэй).

Сама роля знаходзіцца ў Галактыка Ансібль. Гэта такое сховішча, якое дазваляе дзяліцца сваімі напрацоўкамі і выкарыстоўваць гатовыя ролі.

Склануем рэпазітар з прыкладам:

$ git clone https://github.com/dokshina/deploy-tarantool-cartridge-app.git
$ cd deploy-tarantool-cartridge-app && git checkout 1.0.0

Падымаем віртуалкі:

$ vagrant up

Усталёўваны ansible-роля Tarantool Cartridge:

$ ansible-galaxy install tarantool.cartridge,1.0.1

Запускаем устаноўленую ролю:

$ ansible-playbook -i hosts.yml playbook.yml

Чакаем канчаткі выканання плэйбука, пераходзім на http://localhost:8181/admin/cluster/dashboard і атрымліваем асалоду ад вынікам:

Лёгка і нязмушана дэплоім прыкладання на Tarantool Cartridge (частка 1)

Можна ліць дадзеныя. Стромка, праўда?

А зараз давайце разбяромся, як з гэтым працаваць, і заадно дадамо яшчэ адзін рэплікасэт у тапалогію.

Пачынаем разбірацца

Што ж адбылося?

Мы паднялі дзве віртуальныя машыны і запусцілі ansible-плэйбук, які наладзіў наш кластар. Давайце паглядзім на змесціва файла playbook.yml:

---
- name: Deploy my Tarantool Cartridge app
  hosts: all
  become: true
  become_user: root
  tasks:
  - name: Import Tarantool Cartridge role
    import_role:
      name: tarantool.cartridge

Тут нічога цікавага не адбываецца, запускаем ansible-роля, якая называецца tarantool.cartridge.

Усё самае важнае (а менавіта, канфігурацыя кластара) знаходзіцца ў інвентарызацыя-файле hosts.yml:

---
all:
  vars:
    # common cluster variables
    cartridge_app_name: getting-started-app
    cartridge_package_path: ./getting-started-app-1.0.0-0.rpm  # path to package

    cartridge_cluster_cookie: app-default-cookie  # cluster cookie

    # common ssh options
    ansible_ssh_private_key_file: ~/.vagrant.d/insecure_private_key
    ansible_ssh_common_args: '-o IdentitiesOnly=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no'

  # INSTANCES
  hosts:
    storage-1:
      config:
        advertise_uri: '172.19.0.2:3301'
        http_port: 8181

    app-1:
      config:
        advertise_uri: '172.19.0.3:3301'
        http_port: 8182

    storage-1-replica:
      config:
        advertise_uri: '172.19.0.3:3302'
        http_port: 8183

  children:
    # GROUP INSTANCES BY MACHINES
    host1:
      vars:
        # first machine connection options
        ansible_host: 172.19.0.2
        ansible_user: vagrant

      hosts:  # instances to be started on the first machine
        storage-1:

    host2:
      vars:
        # second machine connection options
        ansible_host: 172.19.0.3
        ansible_user: vagrant

      hosts:  # instances to be started on the second machine
        app-1:
        storage-1-replica:

    # GROUP INSTANCES BY REPLICA SETS
    replicaset_app_1:
      vars:  # replica set configuration
        replicaset_alias: app-1
        failover_priority:
          - app-1  # leader
        roles:
          - 'api'

      hosts:  # replica set instances
        app-1:

    replicaset_storage_1:
      vars:  # replica set configuration
        replicaset_alias: storage-1
        weight: 3
        failover_priority:
          - storage-1  # leader
          - storage-1-replica
        roles:
          - 'storage'

      hosts:   # replica set instances
        storage-1:
        storage-1-replica:

Усё, што нам трэба - гэта навучыцца кіраваць інстансамі і рэплікасэтамі, змяняючы змесціва гэтага файла. Далей мы будзем дабаўляць у яго новыя секцыі. Каб не заблытацца, куды іх дадаваць, можаце падглядаць у фінальную версію гэтага файла, hosts.updated.yml, які знаходзіцца ў рэпазітары з прыкладам.

Кіраванне інстансамі

У тэрмінах Ansible кожны інстанс - гэта хост (не блытаць з жалезным серверам), г.зн. вузел інфраструктуры, якім Ansible будзе кіраваць. Для кожнага хаста мы можам паказаць параметры злучэння (такія, як ansible_host и ansible_user), а таксама канфігурацыю інстансу. Апісанне інстансаў знаходзіцца ў секцыі hosts.

Разгледзім канфігурацыю інстансу storage-1:

all:
  vars:
    ...

  # INSTANCES
  hosts:
    storage-1:
      config:
        advertise_uri: '172.19.0.2:3301'
        http_port: 8181

  ...

У зменнай config мы паказалі параметры інстансу advertise URI и HTTP port.
Ніжэй знаходзяцца параметры інстансаў app-1 и storage-1-replica.

Нам трэба паведаміць Ansible параметры злучэння для кожнага інстанса. Здаецца лагічным аб'яднаць інстансы ў групы па віртуальных машынах. Для гэтага інстансы аб'яднаны ў групы. host1 и host2, і ў кожнай групе ў секцыі vars пазначаны значэння ansible_host и ansible_user для адной віртуалкі. А ў секцыі hosts - хасты (яны ж інстансы), якія ўваходзяць у гэтую групу:

all:
  vars:
    ...
  hosts:
    ...
  children:
    # GROUP INSTANCES BY MACHINES
    host1:
      vars:
        # first machine connection options
        ansible_host: 172.19.0.2
        ansible_user: vagrant
       hosts:  # instances to be started on the first machine
        storage-1:

     host2:
      vars:
        # second machine connection options
        ansible_host: 172.19.0.3
        ansible_user: vagrant
       hosts:  # instances to be started on the second machine
        app-1:
        storage-1-replica:

Пачынаем змяняць hosts.yml. Дадамо яшчэ два інстансы, storage-2-replica на першай віртуалцы і storage-2 на другі:

all:
  vars:
    ...

  # INSTANCES
  hosts:
    ...
    storage-2:  # <==
      config:
        advertise_uri: '172.19.0.3:3303'
        http_port: 8184

    storage-2-replica:  # <==
      config:
        advertise_uri: '172.19.0.2:3302'
        http_port: 8185

  children:
    # GROUP INSTANCES BY MACHINES
    host1:
      vars:
        ...
      hosts:  # instances to be started on the first machine
        storage-1:
        storage-2-replica:  # <==

    host2:
      vars:
        ...
      hosts:  # instances to be started on the second machine
        app-1:
        storage-1-replica:
        storage-2:  # <==
  ...

Запускаем ansible-плэйбук:

$ ansible-playbook -i hosts.yml 
                   --limit storage-2,storage-2-replica 
                   playbook.yml

Звярніце ўвагу на опцыю --limit. Паколькі кожны інстанс кластара з'яўляецца хастом у тэрмінах Ansible, мы можам відавочна паказваць, якія інстансы павінны быць наладжаны пры выкананні плэйбука.

Зноў заходзім у Web UI http://localhost:8181/admin/cluster/dashboard і назіраем нашы новыя інстансы:

Лёгка і нязмушана дэплоім прыкладання на Tarantool Cartridge (частка 1)

Не будзем спыняцца на дасягнутым і асвоім кіраванне тапалогіяй.

Кіраванне тапалогіяй

Аб'яднаем нашы новыя інстансы ў рэплікасэт storage-2. Дададзім новы гурт replicaset_storage_2 і апішам у яе зменных параметры рэплікасета па аналогіі з replicaset_storage_1. У секцыі hosts пакажам, якія інстансы будуць уваходзіць у гэтую групу (гэта значыць наш рэплікасэт):

---
all:
  vars:
    ...
  hosts:
    ...
  children:
    ...
    # GROUP INSTANCES BY REPLICA SETS
    ...
    replicaset_storage_2:  # <==
      vars:  # replicaset configuration
        replicaset_alias: storage-2
        weight: 2
        failover_priority:
          - storage-2
          - storage-2-replica
        roles:
          - 'storage'

      hosts:   # replicaset instances
        storage-2:
        storage-2-replica:

Зноў запускаем плэйбук:

$ ansible-playbook -i hosts.yml 
                   --limit replicaset_storage_2 
                   --tags cartridge-replicasets 
                   playbook.yml

У параметр --limit мы на гэты раз перадалі імя гурта, які адпавядае нашаму рэплікасэту.

Разгледзім опцыю tags.

Наша роля паслядоўна выконвае розныя задачы, якія пазначаныя наступнымі тэгамі:

  • cartridge-instances: кіраванне інстансамі (налада, падлучэнне да membership);
  • cartridge-replicasets: кіраванне тапалогіяй (кіраванне рэплікасэтамі і беззваротнае выдаленне (expel) інстансаў з кластара);
  • cartridge-config: кіраванне астатнімі параметрамі кластара (vshard bootstrapping, рэжым аўтаматычнага failover-а, параметры аўтарызацыі і канфігурацыя прыкладання).

Мы можам відавочна паказаць, якую частку працы жадаем зрабіць, тады роля прапусціць выкананне астатніх задач. У нашым выпадку мы хочам працаваць толькі з тапалогіяй, таму паказалі cartridge-replicasets.

Давайце ацэнім вынік нашых намаганняў. Знаходзім новы рэплікасэт на http://localhost:8181/admin/cluster/dashboard.

Лёгка і нязмушана дэплоім прыкладання на Tarantool Cartridge (частка 1)

Ура!

Паэксперыментуйце са зменай канфігурацыі інстансаў і рэплікасэтаў і паглядзіце, як змяняецца тапалогія кластара. Вы можаце апрабаваць розныя эксплуатацыйныя сцэнары, напрыклад, rolling update або павелічэнне memtx_memory. Роля паспрабуе зрабіць гэта без рэстарту інстанса, каб скараціць магчымы даунтайм вашага прыкладання.

Не забудзьцеся запусціць vagrant halt, Каб спыніць віртуалкі, калі скончыце з імі працаваць.

А што пад капотам?

Тут я распавяду падрабязней аб тым, што адбывалася пад капотам ansible-ролі падчас нашых эксперыментаў.

Разгледзім па кроках дэплой Cartridge-прыкладанні.

Усталяванне пакета і старт інстансаў

Спачатку трэба даставіць пакет на сервер і ўсталяваць яго. Цяпер роля ўмее працаваць з RPM-і DEB-пакетамі.

Далей запускаем інстансы. Тут усё вельмі проста: кожны інстанс - гэта асобны systemd-сэрвіс. Расказваю на прыкладзе:

$ systemctl start myapp@storage-1

Гэтая каманда запусціць інстанс storage-1 прыкладання myapp. Запушчаны інстанс будзе шукаць сваю канфігурацыю в /etc/tarantool/conf.d/. Логі інстанса можна будзе паглядзець пры дапамозе journald.

Unit-файл /etc/systemd/system/[email protected] для systemd-сэрвісу будзе дастаўлены разам з пакетам.

У Ansible маюцца ўбудаваныя модулі для ўсталёўкі пакетаў і кіраванні systemd-сэрвісамі, тут мы нічога новага не вынайшлі.

Настройка тапалогіі кластара

А вось тут пачынаецца самае цікавае. Пагадзіцеся, было б дзіўна затлумляцца са спецыяльнай ansible-роллю для ўстаноўкі пакетаў і запуску systemd-сэрвісаў.

Наладзіць кластар можна ўручную:

  • Першы варыянт: адчыняны Web UI і націсканы на кнопачкі. Для разавага старту некалькіх інстансаў цалкам падыдзе.
  • Другі варыянт: можна карыстацца GraphQl API. Тут ужо можна нешта аўтаматызаваць, напрыклад, напісаць скрыпт на Python.
  • Трэці варыянт (для моцных духам): заходзім на сервер, канэктуемся да аднаго з інстансаў пры дапамозе tarantoolctl connect і вырабляем усе неабходныя маніпуляцыі з Lua-модулем cartridge.

Асноўная задача нашага вынаходкі - зрабіць за вас менавіта гэтую, самую складаную частку працы.

Ansible дазваляе напісаць свой модуль і выкарыстоўваць яго ў ролі. Наша роля выкарыстоўвае такія модулі для кіравання рознымі кампанентамі кластара.

Як гэта працуе? Вы апісваеце жаданае стан кластара ў дэкларатыўным канфігу, а роля падае на ўваход кожнаму модулю яго секцыю канфігурацыі. Модуль атрымлівае бягучы стан кластара і параўноўвае яго з тым, што прыйшло на ўваход. Далей праз сокет аднаго з інстансаў запускаецца код, які прыводзіць кластар да патрэбнага стану.

Вынікі

Сёння мы распавялі і паказалі, як задэплоіць ваша дадатак на Tarantool Cartridge і наладзіць простую тапалогію. Для гэтага мы выкарыстоўвалі Ansible - магутны інструмент, які адрозніваецца прастатой у выкарыстанні і дазваляе адначасова наладжваць мноства вузлоў інфраструктуры (у нашым выпадку гэта інстансы кластара).

Вышэй мы разабраліся з адным са мноства спосабаў апісання канфігурацыі кластара сродкамі Ansible. Як толькі вы зразумееце, што гатовы ісці далей, вывучыце перадавога вопыту па напісанні плэйбукаў. Магчыма, вам будзе зручней кіраваць тапалогіяй пры дапамозе group_vars и host_vars.

Вельмі хутка мы раскажам, як беззваротна выдаляць (expel) інстансы з тапалогіі, бутстрапіць vshard, кіраваць рэжымам аўтаматычнага failover-а, наладжваць аўтарызацыю і патчыць кластарны канфіг. А пакуль вы можаце самастойна вывучаць дакументацыю і эксперыментаваць са зменай параметраў кластара.

Калі нешта не працуе, абавязкова паведаміце нам аб праблеме. Мы аператыўна ўсё разрулім!

Крыніца: habr.com

Дадаць каментар