Лесно и удобно разгръщаме приложения на Tarantool Cartridge (част 1)

Лесно и удобно разгръщаме приложения на Tarantool Cartridge (част 1)

Вече разказахме за Tarantool Cartridge, който позволява разработването на разпределени приложения и опаковането им. Остана само още малко: да се научим как да разгръщаме тези приложения и да ги управляваме. Не се тревожете, предвидили сме всичко! Събрахме всички добри практики за работа с Tarantool Cartridge и написахме ansible-роля, която ще разпространи пакета на сървърите, ще стартира инстанциите, ще ги обедини в кластер, ще настрои автентикацията, ще добави vshard, ще активира автоматичен failover и ще патчи кластерната конфигурация.

Интересно? Тогава моля, продължете, всичко ще разкажем и покажем.

Да започнем с пример

Ще разгледаме само част от функционалността на нашата роля. Пълно описание на всичките й възможности и входни параметри можете да намерите в документацията. Но е по-добре да опитате веднъж, отколкото сто пъти да гледате, затова да разгръщаме малко приложение.

Tarantool Cartridge има урок за създаване на малко Cartridge-приложение, което съхранява информация за клиентите на банката и техните сметки, а също така предоставя API за управление на данните чрез HTTP. За целта в приложението се описват две възможни роли: api и хранилище, които могат да бъдат назначавани на инстанции.

Самият Cartridge не казва нищо за това как да стартира процеси, той само предоставя възможност за настройка на вече стартираните инстанции. Останалото потребителят трябва да направи сам: да разпространи конфигурационните файлове, да стартира услугите и да настрои топологията. Но ние няма да се занимаваме с всичко това, Ansible ще го направи за нас.

От думи на дело

И така, ще разгръщаме нашето приложение на две виртуалки и ще настроим проста топология:

  • Репликасет app-1 ще внедри ролята api, която включва ролята vshard-router. Тук ще има само един инстанс.
  • Репликасет storage-1 внедрява ролята хранилище (и в същото време 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: 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.

Всичко най-важно (а именно, конфигурацията на клъстера) се намира в inventory- файла 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 плейбук:

$ 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:

Отново стартираме плейбукa:

$ 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. След като разберете, че сте готови да продължите, изучете най-добрите практики за написване на плейбукове. Може би ще ви е по-удобно да управлявате топологията с помощта на group_vars и host_vars.

Скоро ще ви разкажем как да премахнете безвъзвратно инстанции от топологията, да бутстрапнете vshard, да управлявате режима на автоматичен failover, да настроите авторизация и да патчнете кластерния конфиг. А дотогава можете сами да изследвате документацията и да експериментирате с параметрите на кластера.

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

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

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