Легко і невимушено деплоим програми на Tarantool Cartridge (частина 1)

Alex Alex 04 грудня 2019

Легко і невимушено деплоим програми на 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), сюди додамо два инстанса з різних машин.


Для запуску прикладу нам знадобляться Vagrant і Ansible (версії 2.8 або старше).


Сама роль знаходиться в Ansible Galaxy. Це таке сховище, яке дозволяє ділитися своїми напрацюваннями та використовувати готові ролі.


Склонируем репозиторій з прикладом:


$ 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 і насолоджуємося результатом:



Можна лити дані. Круто, правда?


А тепер давайте розберемося, як з цим працювати, і заодно додамо ще один репликасет в топологію.


Починаємо розбиратися


Отже, що ж сталося?


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


---
- name: Deploy my Tarantool Cartridge app
hosts: all
become: true
become_user: root
завдання:
- name: Import Tarantool Cartridge role
import_role:
name: tarantool.cartridge

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


Все найважливіше (а саме, конфігурація кластера) знаходиться в inventory-файлі 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 options 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'

# 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 і спостерігаємо наші нові инстансы:



Не будемо зупинятися на досягнутому і освоїмо управління топологією.


Управління топологією


Об'єднаємо наші нові инстансы в репликасет 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.



Ура!


Поекспериментуйте зі зміною конфігурації инстансов і репликасетов і подивіться, як змінюється топології кластера. Ви можете випробувати різні експлуатаційні сценарії, наприклад, rolling update або збільшення memtx_memory. Роль спробує зробити це без рестарту инстанса, щоб скоротити можливий даунтайм вашого додатка.


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


А що під капотом?


Тут я розповім докладніше про те, що відбувалося під капотом ansible ролі під час наших експериментів.


Розглянемо покроково деплой Cartridge-програми.


Установка пакета і старт инстансов


Спочатку потрібно доставити пакет на сервер і встановити його. Зараз роль вміє працювати з RPM і DEB-пакетів.


Далі запускаємо инстансы. Тут все дуже просто: кожен інстанси — це окремий systemd-сервіс. Розповідаю на прикладі:


$ systemctl start [email protected]

Ця команда запустить інстанси 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. Як тільки ви зрозумієте, що готові йти далі, вивчіть best practices з написання плейбуков. Можливо, вам буде зручніше керувати топологією за допомогою group_vars та host_vars.


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


Якщо щось не працює, обов'язково повідомте нам про проблему. Ми оперативно все розрулив!

Source: habr.com

Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.