Мы уже рассказывали про
Интересно? Тогда прошу под кат, всё расскажем и покажем.
Начнем с примера
Мы рассмотрим только часть функциональности нашей роли. Полное описание всех ее возможностей и входных параметров вы всегда можете найти в
У Tarantool Cartridge есть api
и storage
, которые могут назначаться инстансам.
Сам Cartridge ничего не говорит о том, как запускать процессы, он лишь предоставляет возможность для настройки уже запущенных инстансов. Остальное пользователь должен сделать сам: разложить конфигурационные файлы, запустить сервисы и настроить топологию. Но мы не будем всем этим заниматься, за нас это сделает Ansible.
От слов к делу
Итак, задеплоим наше приложение на две виртуалки и настроим простую топологию:
- Pепликасет
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
, который находится в репозитории с примером.
Puleaina o faataitaiga
В терминах 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
...
E fesuia'i 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
Не будем останавливаться на достигнутом и освоим управление топологией.
Pulea Topology
Объединим наши новые инстансы в репликасет storage-2
. Добавим новую группу replicaset_storage_2
и опишем в ее переменных параметры репликасета по аналогии с replicaset_storage_1
. I le vaega 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
.
Давайте оценим результат наших стараний. Находим новый репликасет на
Hoa!
Поэкспериментируйте с изменением конфигурации инстансов и репликасетов и посмотрите, как меняется топология кластера. Вы можете опробовать различные эксплуатационные сценарии, например, memtx_memory
. Роль попытается сделать это без рестарта инстанса, чтобы сократить возможный даунтайм вашего приложения.
Не забудьте запустить vagrant halt
, чтобы остановить виртуалки, когда закончите с ними работать.
Ma o le a le mea o loʻo i lalo o le pulou?
Здесь я расскажу подробнее о том, что происходило под капотом ansible-роли во время наших экспериментов.
Рассмотрим по шагам деплой Cartridge-приложения.
Установка пакета и старт инстансов
Сначала нужно доставить пакет на сервер и установить его. Сейчас роль умеет работать с RPM- и DEB-пакетами.
Дальше запускаем инстансы. Тут всё очень просто: каждый инстанс — это отдельный systemd
-сервис. Рассказываю на примере:
$ systemctl start myapp@storage-1
Эта команда запустит инстанс storage-1
apps myapp
. Запущенный инстанс будет искать свою /etc/tarantool/conf.d/
. Логи инстанса можно будет посмотреть при помощи journald
.
Unit-файл /etc/systemd/system/[email protected]
для systemd-сервиса будет доставлен вместе с пакетом.
В Ansible имеются встроенные модули для установки пакетов и управления systemd-сервисами, тут мы ничего нового не изобрели.
Настройка топологии кластера
А вот здесь начинается самое интересное. Согласитесь, было бы странно заморачиваться со специальной ansible-ролью для установки пакетов и запуска systemd
-au'aunaga.
Настроить кластер можно вручную:
- Первый вариант: открываем Web UI и нажимаем на кнопочки. Для разового старта нескольких инстансов вполне подойдет.
- Второй вариант: можно воспользоваться GraphQl API. Тут уже можно что-нибудь автоматизировать, например, написать скрипт на Python.
- Третий вариант (для сильных духом): заходим на сервер, коннектимся к одному из инстансов при помощи
tarantoolctl connect
и производим все необходимые манипуляции с Lua-модулемcartridge
.
Основная задача нашего изобретения — сделать за вас именно эту, самую сложную часть работы.
Ansible позволяет написать свой модуль и использовать его в роли. Наша роль использует такие модули для управления различными компонентами кластера.
Как это работает? Вы описываете желаемое состояние кластера в декларативном конфиге, а роль подает на вход каждому модулю его секцию конфигурации. Модуль получает текущее состояние кластера и сравнивает его с тем, что пришло на вход. Далее через сокет одного из инстансов запускается код, который приводит кластер к нужному состоянию.
O taunuʻuga
Сегодня мы рассказали и показали, как задеплоить ваше приложение на Tarantool Cartridge и настроить простую топологию. Для этого мы использовали Ansible — мощный инструмент, который отличается простотой в использовании и позволяет одновременно настраивать множество узлов инфраструктуры (в нашем случае это инстансы кластера).
Выше мы разобрались с одним из множества способов описания конфигурации кластера средствами Ansible. Как только вы поймете, что готовы идти дальше, изучите group_vars
и host_vars
.
Очень скоро мы расскажем, как безвозвратно удалять (expel) инстансы из топологии, бутстрапить vshard, управлять режимом автоматического failover-а, настраивать авторизацию и патчить кластерный конфиг. А пока вы можете самостоятельно изучать
Если что-то не работает, обязательно
puna: www.habr.com