Ми вже розповідали про
Цікаво? Тоді прошу під кат, все розповімо та покажемо.
Почнемо з прикладу
Ми розглянемо лише частину функціональності нашої ролі. Повний опис всіх її можливостей та вхідних параметрів ви завжди можете знайти у
У Tarantool Cartridge є api
и storage
, які можуть бути призначені інстансам.
Сам Cartridge нічого не говорить про те, як запускати процеси, він лише надає можливість налаштувати вже запущені інстанси. Решта користувач повинен зробити сам: розкласти файли конфігурації, запустити сервіси і налаштувати топологію. Але ми не будемо цим займатися, за нас це зробить Ansible.
Від слів до справи
Отже, задеплоєм наш додаток на дві віртуалки і налаштуємо просту топологію:
- Реплікасет
app-1
реалізовуватиме рольapi
яка включає в себе рольvshard-router
. Тут буде лише одна інстанс. - Реплікасет
storage-1
реалізує рольstorage
(і одночасноvshard-storage
), сюди додамо дві інстанси з різних машин.
Для запуску прикладу нам знадобляться
Сама роль знаходиться в
Схиляємо репозиторій із прикладом:
$ 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: 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
Не будемо зупинятись на досягнутому та освоїмо управління топологією.
Управління топологією
Об'єднаємо наші нові інстанси у реплікасет 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
.
Давайте оцінимо результат наших старань. Знаходимо новий реплікасет на
Ура!
Поекспериментуйте зі зміною конфігурації інстансів та реплікасетів та подивіться, як змінюється топологія кластера. Ви можете випробувати різні експлуатаційні сценарії, наприклад, 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