Лесно и неусетно деплойваме приложения на Tarantool Cartridge (част 1)

Лесно и неусетно деплойваме приложения на Tarantool Cartridge (част 1)

Вече говорихме за Tarantool Cartridge, който позволява разработването на разпределени приложения и опаковането им. Остана само да се научим как да разгръщаме тези приложения и да ги управляваме. Не се притеснявайте, ние сме предвидили всичко! Събрахме всички най-добри практики за работа с 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)

За стартиране на примера ще ни трябват 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 и се наслаждаваме на резултата:

Лесно и неусетно деплойваме приложения на Tarantool Cartridge (част 1)

Можем да започнем да вливаме данни. Яко, нали?

А сега нека да разберем как да работим с това и междувременно да добавим още един репликасет в топологията.

Започваме да разбираме

И така, какво се случи?

Създадохме две виртуални машини и стартирахме 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 http://localhost:8181/admin/cluster/dashboard и наблюдаваме новите си инстанси:

Лесно и неусетно деплойваме приложения на Tarantool Cartridge (част 1)

Няма да спрем дотук и ще овладеем управлението на топологията.

Управление на топологията

Нека обединим новите си инстанси в репликасет 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.

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

Ако нещо не работи, непременно ни уведомете за проблема. Ние ще го решим бързо!

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster