Русский
Русский
English
Статистика
Реклама

Как эксплуатировать приложения на Tarantool Cartridge



Привет! Я продолжаю разрабатывать распределённые системы на основе Tarantool. За последний год наша команда вывела в прод 17 новых систем. В прошлый раз я рассказал, как мы наладили автоматический деплой. В этой статье я покажу, как упростить обслуживание приложений на Tarantool Cartridge.

У одного крупного заказчика процесс выхода в прод сложный. Софт прогоняют через длинный чек-лист и, если система чему-то не соответствует, то никакого прода. Вместе с системой мы должны предоставить документацию по эксплуатации в штатном режиме и траблшутингу на случай аварий. Одной только документации мало, должно быть обучение! Взять хотя бы общий сценарий как восстановить упавшую реплику Tarantool мы должны показать команде эксплуатации последовательность шагов и ответить на вопросы.

Общетарантульные сценарии не меняются от приложения к приложению. А есть специфичные операции: перезагрузить данные кэша, сформировать отчёт по рекламной кампании и т. д. Каждая система будет иметь свой набор. Запуском этих сценариев тоже занимается команда эксплуатации, и тоже необходимо обучение. Однако у нас возникла проблема с доставкой таких операций до конечного исполнителя.

Мы испробовали разные способы:

  • Скрипт. Можно подложить в поставку с приложением. Плохая масштабируемость между разными приложениями и командами. Каждый разработчик захочет написать свой скрипт для вкручивания лампочки.
  • HTTP API. По сути удалённый способ вызова встроенной функции. Требует расширенной документации и способов использования. Сойдёт для первой реализации.
  • Вместе с инструментом автоматизации. Например, отдельные ansible-playbook для работы с теми же HTTP-вызовами. Это удобнее с точки зрения эксплуатации, но требует повышенной осторожности и документации. Кажется слишком громоздким решением.
  • Утилита для управления приложением. Единая точка входа для набора скриптов со встроенной документацией, возможными аргументами и сценариями использования. Можно реализовать --help для получения справки и всех доступных команд. Лучше переиспользуется, однако не защищает от копирования и создания по одной утилите на каждый проект.

Все методы вскрывали одни и те же проблемы. Каждый разработчик захочет написать свой велосипед, и каждый раз придётся выдумывать на чём ехать. Не забыть бы ещё про экплуатационную документацию, чтобы этим пользоваться. Затем провести обучение по взаимодействию с каждым из велосипедов. С таким подходом на внедрение одного скрипта уйдёт в лучшем случае месяц.

Тут появляется cartridge admin, который призван упростить для разработчика написание и поддержку эксплуатационных кейсов, повысить переиспользование операций, оптимизировать доставку до эксплуатации. Больше не нужно выдумывать, куда приложить кейс и как описать его в документации. cartidge admin становится единым местом описания всех процедур обслуживания. Эксплуатация становится частью кода, её можно обложить тестами и гарантировать работоспособность.

С точки зрения команды эксплуатации ситуация аналогична. Есть 17 проектов: каждый имеет свою специфику, документацию и скрипты. Нужно постоянно переключаться между контекстами: WebUI, tarantoolctl, cartridge, HTTP API и т.д. Чем больше разных вызовов, тем больше вероятность ошибки.

И здесь cartridge admin становится единой точкой взаимодействия. Утилита имеет простой консольный интерфейс и обратную связь. При обслуживании приложений на Tarantool Cartridge не придётся переключать контекст. Вызов справки позволяет ознакомиться со всеми операциями, доступными для конкретной системы. Риск человеческой ошибки минимизируется.

Далее опишу как работать с cartridge admin.

Необходимые компоненты



Установим cartridge-cli.

Для Centos:

$ curl -L https://tarantool.io/installer.sh | sudo bash -s -- --repo-only$ sudo yum install cartridge-cli

Для MacOS:

$ brew install cartridge-cli

Альтернативно, можно использовать наше энтерпрайз-решение Tarantool Enterprise SDK, который уже содержит нужные версии компонентов и сам Tarantool. Также в составе идет скрипт для настройки окружения env.sh.

Создаем приложение


Для простоты возьмём проект, созданный с помощью cartridge create (инструкция).

$ cartridge create --name tarantool-demo$ cd tarantool-demo$ cartridge build

Настраиваем сборку артефакта


  • В файле проекта tarantool-demo-scm-1.rockspec нужно добавить зависимость cartridge-cli-extensions.

    dependencies = {    ...    'cartridge-cli-extensions == 1.1.0-1',    ...}
    

  • В cartridge.pre-build добавить копирование бинаря cartridge, так как он не подкладывается в сборку автоматически. Например, если SDK был распакован в одноименную директорию:

    #!/usr/bin/env bashcp `which cartridge` .
    

    Теперь артефакт будет содержать все нужные модули.

    $ cartridge pack tgz --version 1
    

Пишем admin функцию


Вначале предлагаю ознакомиться с документацией README, которая находится в репозитории cartridge-cli-extension. Там пошагово описан процесс инициализации модуля и регистрации функций.

Из интересного:

  • В функции можно использовать команду print(). Сообщение сразу же будет напечатано в консоль. Удобно для промежуточных результатов выполнения команды, ошибок, прогресса.

      Cleanup: ready to proceed on 2 storages     Cleanup [1/2  tnt-storage_2]: deleted {products:100}     Cleanup [2/2  tnt-storage_1]: deleted {products:50}     Deleted total {products:150}-------------------     Cleanup: ready to proceed on 2 storages     Cleanup [1/2  tnt-storage_2]: error NetboxEvalError: Peer closed
    

  • Консольный вывод поддерживает смайлики (utf-8)

Пример


Я хочу организовать чистку хранилища, а именно таблицы некоторых продуктов. Ниже описана admin функция, которая вызывает box.space.products:truncate() на подмножестве серверов (в данном случае стораджей-мастеров) и возвращает количество удаленных записей.

Для этого добавим в конец файла init.lua следующий код. В коде есть пояснения к каждой секции.

local admin_tasks = {}local json = require('json')local pool = require('cartridge.pool')admin_tasks.cleanup = {    -- описываем новую функцию    usage = 'Clean old products from cache',    -- конкретно cleanup не будет принимать аргументов.    -- с форматом аргументов можно ознакомиться в примере на GitHub    -- https://github.com/tarantool/cartridge-cli-extensions/blob/master/doc/admin.md#example    args = nil,     call = function(opts)        opts = opts or {}        local servers = {}        local total = { products = 0 }        -- функция для проверки имеет ли репликасет определённую роль        local function replicaset_has_role(replicaset, role)            for _, name in ipairs(replicaset.roles) do                if name == role then                    return true                end            end            return false        end        -- обходим все сервера в кластере и выбираем только те, которые:        -- 1) имеют роль vshard-storage        -- 2) являются мастером в своем репликасете    for _, rs in pairs(cartridge.admin_get_replicasets()) do            if replicaset_has_role(rs, 'vshard-storage') then                local server = rs.active_master                if server ~= nil and server ~= "expelled" then                    if server.status == 'unreachable' then                        return nil, ("Server %s status is %s"):format(server.alias, server.status)                    else                        servers[server.alias] = server.uri                    end                end            end        end        -- выполняем очистку данных по очереди на каждом из стораджей        for alias, uri in pairs(servers) do            -- префикс можно задать любой, например добавить порядковый номер сервера            local prefix = alias            local conn, err = pool.connect(uri)            if err ~= nil then                print(("Cleanup [%s]: error %s"):format(prefix, err))            else                -- собственно вызов функции                -- здесь есть небольшой хак, создадим таблицы прямо из admin функции                -- на реальном примере таблица должна существовать изначально                local res = conn:eval([[                    box.schema.create_space('products', { if_not_exists = true })                    box.space.products:create_index('primary', { if_not_exists = true })                    local len = box.space.products:len()                    box.space.products:truncate()                    return { products = len }                ]])                -- выводим промежуточный результат в консоль                print(("Cleanup [%s]: deleted %s"):format(prefix, json.encode(res)))                total.products = total.products + res.products            end        end        return ("Deleted total %s"):format(json.encode(total))    end}

Я рекомендую добавлять обход по всем инстансам, как это сделано в примере. Тогда admin операции можно запускать с любой машины, потому что все инстансы кластера могут выполнять одни и те же функции.

Теперь зарегистрируем эту функции в кластере.

-- инициализация модуля adminlocal cli_admin = require('cartridge-cli-extensions.admin')cli_admin.init()-- регистрируем все функции таблицы admin_tasks из примера вышеfor name, task in pairs(admin_tasks) do    local ok, err = cli_admin.register(name, task.usage, task.args, task.call)    if ok ~= true then        error(err)    endend

В коде есть создание таблицы прямо в admin-функции. Конечно на реальном примере так делать не нужно. Если запустить функцию без этих строк

box.schema.create_space('products', { if_not_exists = true })box.space.products:create_index('primary', { if_not_exists = true })

то получим ошибку, так как таблицы products не существует.

 Failed to call "cleanup": eval:1: attempt to index field 'products' (a nil value)

Запускаем приложение


$ cartridge start -d$ cartridge replicasets setup

Запускаем admin функцию


Все вызовы необходимо производить из директории с бинарем cartridge-cli.

Начиная с cartridge-cli v2.6 есть два способа подключиться к инстансу Tarantool.

  • Через socket-файл

    ./cartridge admin \  --name tarantool-demo \  --run-dir ./tmp/run \  --instance router \  --list
    
  • С помощью логин-пароля по сети

    ./cartridge admin \  --conn admin:<cluster-cookie>@localhost:3301  --list
    

Далее буду рассматривать работу с socket-файлами. Оба способа идентичны в плане запуска команд.

Сначала проверим, какие функции определены в кластере. Используем директиву --list:

./cartridge admin \  --name tarantool-demo \  --run-dir ./tmp/run \  --instance router \  --list

  • Обязательно задать имя приложения через --name.
  • Директория для поиска socket-файлов --run-dir.
  • Имя инстанса в кластере задается с помощью --instance.
  • При указанных параметрах cartridge-cli будет работать с кластером через сокет tarantool-demo.router.control. Его наличие в run-dir обязательно. Для Tarantool Cartridge путь к сокету можно задать, например, через переменную среды TARANTOOL_CONSOLE_SOCK.

    Получаем в ответ:

     Available admin functions:cleanup  Clean old products from cache
    

    Теперь запустим желаемую операцию. Используя упомянутый выше пример, запущу чистку продуктов:

    ./cartridge admin \  --name tarantool-demo \  --run-dir ./tmp/run \  --instance router \  cleanup
    
  • Название команды (cleanup) и любые параметры, которые были определены для этой команды, указываются в конце.

И всё, по завершению операции кластер будет чист!

Итоги


cartridge admin оказался неплохой заменой разрозненной кучке скриптов в нашем окружении. Мы перевели часть операций на его рельсы и не собираемся останавливаться.

Появилась единая точка сбора всех функций по управлению системой. Упростились как технические, так и административные процессы. Меньше затрат на разработку и поддержку эксплуатационных сценариев. С помощью cartridge admin обслуживание приложения на Tarantool Cartridge стало удобнее и понятнее.
Источник: habr.com
К списку статей
Опубликовано: 23.03.2021 14:22:27
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании mail.ru group

It-инфраструктура

Devops

Tarantool

Cartridge

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru