
Вече говорихме за , който позволява разработването на разпределени приложения и опаковането им. Остана само да се научим как да разгръщаме тези приложения и да ги управляваме. Не се притеснявайте, ние сме предвидили всичко! Събрахме всички най-добри практики за работа с Tarantool Cartridge и написахме , която ще разложи пакета на сървърите, ще стартира инстанциите, ще ги обедини в кластер, ще настрои авторизацията, ще подготви vshard, ще включи автоматичен failover и ще актуализира кластерната конфигурация.
Интересно ли ви е? Тогава заповядайте, ще разкажем и покажем всичко.
Започваме с пример
Ще разгледаме само част от функционалността на нашата роля. Пълното описание на всичките й възможности и входни параметри винаги можете да намерите в . Но по-добре е да опитате веднъж, отколкото сто пъти да гледате, така че да разгръщаме малко приложение.
Tarantool Cartridge има за създаване на малко Cartridge-приложение, което съхранява информация за клиентите на банката и техните сметки, а също така предоставя API за управление на данните чрез HTTP. За тази цел в приложението се описват две възможни роли: api и storage, които могат да бъдат зададени на инстанси.
Сами Cartridge не казва нищо за това как да се стартират процесите, той просто предоставя възможност за настройка на вече стартирани инстанси. Останалото потребителят трябва да направи сам: да разложи конфигурационните файлове, да стартира услугите и да настрои топологията. Но ние няма да правим всичко това, вместо нас ще се погрижи Ansible.
От думи на дело
И така, да разгръщаме нашето приложение на две виртуални машини и да настроим проста топология:
- Репликасет
app-1ще реализира ролятаapi, която включваvshard-router. Тук ще има само един инстанс. - Репликасет
storage-1реализира ролятаstorage(и едновременноvshard-storage), тук ще добавим два инстанса от различни машини.

За стартиране на примера ще ни трябват и (версия 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Очакваме завършване на изпълнението на плейбука, преминаваме на и се наслаждаваме на резултата:

Можем да започнем да вливаме данни. Яко, нали?
А сега нека да разберем как да работим с това и междувременно да добавим още един репликасет в топологията.
Започваме да разбираме
И така, какво се случи?
Създадохме две виртуални машини и стартирахме ansible-плейбук, който настрои нашия клъстер. Нека да погледнем съдържанието на файла playbook.yml:
---
- name: Разгръщане на моето приложение Tarantool Cartridge
hosts: all
become: true
become_user: root
tasks:
- name: Импорт на ролята Tarantool Cartridge
import_role:
name: tarantool.cartridgeТук не се случва нищо интересно, стартираме ansible-ролята, която се нарича tarantool.cartridge.
Всичкото важно (а именно, конфигурацията на клъстера) се намира в - файла hosts.yml:
---
all:
vars:
# общи променливи на клъстера
cartridge_app_name: getting-started-app
cartridge_package_path: .\/getting-started-app-1.0.0-0.rpm # път до пакета
cartridge_cluster_cookie: app-default-cookie # кластерно бисквитка
# общи ssh опции
ansible_ssh_private_key_file: ~\/vagrant.d\/insecure_private_key
ansible_ssh_common_args: '-o IdentitiesOnly=yes -o UserKnownHostsFile=\/dev\/null -o StrictHostKeyChecking=no'
# ИНСТАНЦИИ
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:
# ГРУПИРАНЕ НА ИНСТАНЦИИ ПО МАШИНИ
host1:
vars:
# опции за свързване на първата машина
ansible_host: 172.19.0.2
ansible_user: vagrant
hosts: # инстанции, които ще стартират на първата машина
storage-1:
host2:
vars:
# опции за свързване на втората машина
ansible_host: 172.19.0.3
ansible_user: vagrant
hosts: # инстанции, които ще стартират на втората машина
app-1:
storage-1-replica:
# ГРУПИРАНЕ НА ИНСТАНЦИИ ПО РЕПЛИКА СЕТА
replicaset_app_1:
vars: # конфигурация на реплика сет
replicaset_alias: app-1
failover_priority:
- app-1 # лидер
roles:
- 'api'
hosts: # инстанции на реплика сет
app-1:
replicaset_storage_1:
vars: # конфигурация на реплика сет
replicaset_alias: storage-1
weight: 3
failover_priority:
- storage-1 # лидер
- storage-1-replica
roles:
- 'storage'
hosts: # инстанции на реплика сет
storage-1:
storage-1-replica:Всичко, от което се нуждаем, е да се научим как да управляваме инстанциите и реплика сетовете, променяйки съдържанието на този файл. В бъдеще ще добавяме нови секции към него. За да не се объркате къде да ги добавите, можете да хвърлите поглед на финалната версия на този файл, hosts.updated.yml, която се намира в хранилището с примера.
Управление на инстанси
В термини на Ansible всеки инстанс е хост (не бъркайте с физически серевер), т.е. възел в инфраструктурата, който Ansible ще управлява. За всеки хост можем да зададем параметри за свързване (като ansible_host и ansible_user), както и конфигурация на инстанса. Описанието на инстансите се намира в секцията hosts.
Нека разгледаме конфигурацията на инстанса storage-1:
all:
vars:
...
# ИНСТАНСИ
hosts:
storage-1:
config:
advertise_uri: '172.19.0.2:3301'
http_port: 8181
...В променливата config посочихме параметрите на инстанса — advertise URI и HTTP порт.
По-долу са параметрите на инстансите app-1 и storage-1-replica.
Трябва да уведомим Ansible за параметрите за свързване за всеки инстанс. Изглежда логично да групираме инстансите по виртуални машини. За това, инстансите са обединени в групи host1 и host2, и в всяка група в секцията vars са зададени стойности ansible_host и ansible_user за една виртуалка. А в секцията hosts — хостовете (които също са инстанси), включени в тази група:
all:
vars:
...
hosts:
...
children:
# ГРУПИРАЙ ИНСТАНСИ ПО МАШИНИ
host1:
vars:
# опции за свързване на първата машина
ansible_host: 172.19.0.2
ansible_user: vagrant
hosts: # инстанси, които ще стартират на първата машина
storage-1:
host2:
vars:
# опции за свързване на втората машина
ansible_host: 172.19.0.3
ansible_user: vagrant
hosts: # инстанси, които ще стартират на втората машина
app-1:
storage-1-replica:Започваме да правим промени hosts.yml. Ще добавим още два инстанса, storage-2-replica на първата виртуалка и storage-2 на втората:
all:
vars:
...
# ИНСТАНСИ
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:
# ГРУПИРАЙ ИНСТАНСИ ПО МАШИНИ
host1:
vars:
...
hosts: # инстанси, които ще стартират на първата машина
storage-1:
storage-2-replica: # <==
host2:
vars:
...
hosts: # инстанси, които ще стартират на втората машина
app-1:
storage-1-replica:
storage-2: # <==
...Стартираме ansible-playbook:
$ ansible-playbook -i hosts.yml
--limit storage-2,storage-2-replica
playbook.ymlОбърнете внимание на опцията --limit. Понеже всеки инстанс на клъстера е хост в термини на Ansible, можем изрично да укажем кои инстанси трябва да бъдат конфигурирани при изпълнението на плейбука.
Отново влизаме в Web UI и наблюдаваме новите си инстанси:

Няма да спрем дотук и ще овладеем управлението на топологията.
Управление на топологията
Нека обединим новите си инстанси в репликасет storage-2. Ще добавим нова група replicaset_storage_2 и ще опишем параметрите на репликасета в неговите променливи по подобие на replicaset_storage_1. В секцията hosts ще посочим кои инстанции ще влизат в тази група (т.е. нашият репликасет):
---
all:
vars:
...
hosts:
...
children:
...
# ГРУПИРАНЕ НА ИНСТАНСИТЕ ПО РЕПЛИКАСЕТИ
...
replicaset_storage_2: # <==
vars: # конфигурация на репликасета
replicaset_alias: storage-2
weight: 2
failover_priority:
- storage-2
- storage-2-replica
roles:
- 'storage'
hosts: # инстанции на репликасета
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.
Нека оценим резултата от нашите усилия. Намираме новия репликасет на .

Ура!
Поекспериментирайте с промяна на конфигурацията на инстансите и репликасетите и вижте как се променя топологията на клъстера. Можете да опитате различни оперативни сценарии, например, или увеличаване на 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/myapp@.sevice за 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
