Привет, Хабр.
В одном из наших недавних постов мы немного затронули тему автоматизации, которую мы активно продвигаем в наших продуктах. По различным каналам мы получили много положительных откликов и дополнительных вопросов о том, как можно использовать наши API для различных интеграций.
В рейтинге наиболее популярных «хотелок» – интеграция системы хранения данных с внешними отечественными или opensource продуктами: системы мониторинга, системы управления и планирования ёмкостей или сложные автоматизированные метрокластеры с классическим набором серверов приложений, СУБД и систем виртуализации. Решив, что краткого упоминания о REST API в системах хранения данных АЭРОДИСК явно недостаточно, в этой статье мы расскажем о том, как автоматизировать создание классических репликации, конфигурации метрокластера и управлять переключением сайтов с использованием REST API и Python. А послушать про это можно будет на вебинаре «ОколоИТ», который пройдёт 12 марта в 15:00 – регистрируйтесь по ссылке.
Немного матчасти
Прежде чем перейти к непосредственной разработке скриптов для автоматизированной настройки СХД через REST API, залезем под капот СХД АЭРОДИСК в части работы API.
При разработке API доступного конечному пользователю продукта, очень важно применять такие же принципы, как и при разработке качественного Front-End интерфейса, а именно учитывать пользовательский опыт и понимать, насколько удобно будет использовать тот или иной метод, рассчитывая на то, что использовать его будет скорее всего не команда разработки, а системный администратор заказчика. Немаловажным является качественное документирование API и возможных параметров при вызове методов. Для документирования REST API мы активно используем автодокументирование кода, написанного по спецификации OpenAPI с помощью известного пакета с открытым исходным кодом Swagger. Это позволяет одновременно получить качественный код, тест-кейсы под него и инструмент визуализации выполнения запросов (обычно в рамках обучения или отладки) с помощью Swagger UI. Естественно, это не отменяет необходимость написания технической документации для конечного пользователя с более подробным набором инструкций и примеров, но даже не имея под рукой никаких документов от вендора, можно довольно быстро разобраться с REST API, используя Swagger.
Приступим
Как знают администраторы СХД АЭРОДИСК, все управление нашим дисковым массивом выполняется через браузер: добавив в строке браузера “/api/docs/”, вы попадете как раз в управление СХД с помощью REST API и Swagger.

Названия разделов поделены согласно функциям дискового массива:
-
Authentication – авторизация пользователей, после авторизации будут доступны все остальные REST API запросы к СХД;
-
DDP – управление DDP группами, создание и удаление пулов, томов, снимков данных;
-
RDG – управление RDG группами, создание и удаление пулов, томов, снимков данных;
-
Disk – получение информации об установленных в СХД дисках;
-
Network – управление сетью, vlan, vip;
-
FC – управление Fibre Channel таргетами, группами, маппингами томов;
-
iSCSI – управление iSCSI таргетами, группами, маппингами томов;
-
Consistency group – управление группами консистентности;
-
Rrepl – управление удаленной репликацией и метрокластером, создание репликационных пар, управление переключением.
Авторизация
После авторизации пользователя становятся доступными все разделы по управлению СХД. При использовании Swagger UI возможно составить и отправить REST запрос, получить и проанализировать ответ СХД, а также использовать автоматически сгенерированный запрос curl, который уже можно использовать в своих скриптах.
Авторизация — обычно первая сложность, которую приходится побороть начинающему пользователю REST API. Для авторизации применяется endpoint http://IP_адрес/api/auth/token, куда c помощью POST запроса отправляются данные о пользователе и пароле. В ответе же в формате JSON приходит специальный токен, который можно использовать для авторизации при выполнении других команд. Токен действует в течение 1 часа, после этого времени необходимо его перегенерировать. Приведем пример получения токена авторизации с помощью curl:
curl -X 'POST' \ 'http://192.168.11.30/api/auth/token' \ -H 'accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=&username=admin&password=Bac12345&scope=&client_id=&client_secret='
Ответом на эту команду будет возвращен JSON c токеном (Response Body):
{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6NDkyMjczMzMzM30.Xe5poHQdIUJ_8yAlWfT_yHVVEgjhnmpLJa4NjmAN4pA", "token_type": "bearer" }
Далее можно использовать авторизационный токен, например, при получении информации о DDP пуле DDP1:
curl -X 'GET' \ 'http://192.168.11.30/api/ddp/pool?name=DDP1' \ -H 'accept: application/json' \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJhZG1pbiIsImV4cCI6NDkyMjczMzMzM30.Xe5poHQdIUJ_8yAlWfT_yHVVEgjhnmpLJa4NjmAN4pA'
Ответом на эту команду будет JSON c информацией о пуле DDP1:
[ { "name": "DDP1", "fullSize": 7681507065856, "sizeAvailable": 7670761259008, "dataDisksQty": 2, "cacheDisksQty": 0, "hotSpare": true, "blockSize": 4194304, "uuid": "wOCgyZ-oDio-HOLV-cR01-S7jj-TxZF-80G2ij", "state": "UP", "health": "ONLINE", "lunQty": 0, "alua": false, "missingDisks": 0, "disksInfo": [ { "wwn": "35000c500a189620b", "free": 3835380629504, "diskType": "data" }, { "wwn": "35000c500a189625b", "free": 3835380629504, "diskType": "data" } ], "thinStorage": false } ]
Метрокластер и репликация
Метрокластер – технология, позволяющая обеспечить доступность данных с помощью разнесения СХД на несколько площадок в пределах города или района и использовании репликации данных между ними. Основное отличие метрокластера от классической репликации – это автоматизация обработки отказов оборудования при обеспечении потребителей актуальными данными. Подробно о метрокластере и сценариях отказа мы рассказывали в одном из наших постов на Хабре и даже проводили демонстрацию на вебинаре «ОколоИТ». Здесь же поговорим о той подготовительной работе, которую необходимо провести при начальном развертывании метрокластера и как её можно автоматизировать с помощью REST API.
Подробные инструкции о настройке метрокластера приведены в руководстве администратора СХД, поэтому перечислим тут лишь основные необходимые шаги:
-
создание группы (RDG или DDP);
-
создание томов;
-
создание IP ресурсов для репликации и метрокластера;
-
создание репликационных связей;
-
создание маппингов томов;
-
управление переключением сайта (Primary/Secondary).
Естественно все шаги можно делать из GUI, но для двух массивов и, например, 20 томов это займет достаточно много времени даже у опытного системного администратора.
Приведем пример создания всей инфраструктуры метрокластера через REST API и Python. Ниже приведем шаги и листинги Python скриптов, при этом конфигурационные файлы и импортируемые модули приложим отдельными файлами.
Шаг 1 — создадим по два DDP пула на двух СХД (скрипт запускается два раза с разными настройками целевой СХД в конфигурационном файле config.conf):
import json from pages_methods.base_methods import * from pages_methods.DDP import * ddp_post_create_pool = { 'name_pool': "DDP1", 'qty_disks': 4 'is_alua': 0, 'block_size': 4194304, 'is_hotspare': 0, 'max_recovery_rate': 50000} name_pool = ddp_post_create_pool.get("name_pool") qty_disks = ddp_post_create_pool.get("qty_disks") is_alua = ddp_post_create_pool.get("is_alua") block_size = ddp_post_create_pool.get("block_size") is_hotspare = ddp_post_create_pool.get("is_hotspare") max_recovery_rate = ddp_post_create_pool.get("max_recovery_rate") disks = BaseApp.get_wwn_disks (4, "SSD") print (disks) Ddp_Methods.post_create_pool(name_pool, is_alua, block_size, is_hotspare, max_recovery_rate, qty_disks) ddp_post_create_pool = { 'name_pool': "DDP2", 'qty_disks': 4, 'is_alua': 0, 'block_size': 4194304, 'is_hotspare': 0, 'max_recovery_rate': 50000} name_pool = ddp_post_create_pool.get("name_pool") qty_disks = ddp_post_create_pool.get("qty_disks") is_alua = ddp_post_create_pool.get("is_alua") block_size = ddp_post_create_pool.get("block_size") is_hotspare = ddp_post_create_pool.get("is_hotspare") max_recovery_rate = ddp_post_create_pool.get("max_recovery_rate") disks = BaseApp.get_wwn_disks (4, "SSD") print (disks) Ddp_Methods.post_create_pool(name_pool, is_alua, block_size, is_hotspare, max_recovery_rate, qty_disks)
После выполнения скрипта можем видеть, что создались два пула на СХД1 и СХД2:

Шаг 2 — создадим по 22 тома на двух СХД:
for i in range (121,132): Ddp_Methods.post_create_lun("DDP2", "RAID-10", 300000000000, f'VOL{i}', "", 0, 0, 0) for i in range (101,112): Ddp_Methods.post_create_lun("DDP1", "RAID-10", 300000000000, f'VOL{i}', "", 0, 0, 0)

Шаг 3 — создадим репликационные IP ресурсы (адреса) на каждой СХД:
СХД 1:
for i in range (101,112): Network_Methods.post_create_vip("ens11f1", "ens11f1", f'192.168.100.{i}', "255.255.255.0", "DDP1", "repl", None) for i in range (121,132): Network_Methods.post_create_vip("ens11f1", "ens11f1", f'192.168.100.{i}', "255.255.255.0", "DDP2", "repl", None)

СХД2 – не забываем поменять адрес СХД в файле config:
for i in range (151,162): Network_Methods.post_create_vip("ens11f1", "ens11f1", f'192.168.100.{i}', "255.255.255.0", "DDP1", "repl", None) for i in range (171,182): Network_Methods.post_create_vip("ens11f1", "ens11f1", f'192.168.100.{i}', "255.255.255.0", "DDP2", "repl", None)

Шаг 4 — создадим репликационные связи между томами для каждого из томов:
for i in range (101,112): payload = { "name": f'rpl1ddp{i}', "protocol": "C", "local_node": { "pool_type": "DDP", "pool_name": "DDP1", "lun_name": f'VOL{i}', "vip": f'192.168.100.{i}' }, "remote_nodes": [ { "pool_type": "DDP", "pool_name": "DDP1", "lun_name": f'VOL{i}', "vip": f'192.168.100.{i+50}' } ]} print(payload) url = f'{URL}/rrepl/node' resp = requests.post(url, data=dumps(payload), headers=HEADERS) print (resp.text) for i in range (121,132): payload = { "name": f'rpl2ddp{i}', "protocol": "C", "local_node": { "pool_type": "DDP", "pool_name": "DDP2", "lun_name": f'VOL{i}', "vip": f'192.168.100.{i}' }, "remote_nodes": [ { "pool_type": "DDP", "pool_name": "DDP2", "lun_name": f'VOL{i}', "vip": f'192.168.100.{i+50}' } ]} print(payload) url = f'{URL}/rrepl/node' resp = requests.post(url, data=dumps(payload), headers=HEADERS) print (resp.text)

Шаг 5 — создадим VIP метрокластера (адреса для iSCSI порталов метрокластера).
Для большей наглядности сделаем это в графическом интерфейсе СХД. Естественно, можно сделать это через знакомый нам уже endpoint /api/network/vip.

Шаг 6 — сконфигурируем метрокластер и арбитр в интерфейсе.
Введем IP адреса арбитра и второй СХД:

Шаг 7 — подключим репликационные пары СХД1 к метрокластеру:
for i in range (101,112): payload = { "node_ip": f'192.168.100.{i}', "name": f'rpl1ddp{i}', "metro_ip": "192.168.11.23", "metro_mask": 24 } print(payload) url = f'{URL}/rrepl/node~connect_metro' resp = requests.post(url, data=dumps(payload), headers=HEADERS) print (resp.text) for i in range (121,132): payload = { "node_ip": f'192.168.100.{i}', "name": f'rpl2ddp{i}', "metro_ip": "192.168.11.24", "metro_mask": 24 } print(payload) url = f'{URL}/rrepl/node~connect_metro' resp = requests.post(url, data=dumps(payload), headers=HEADERS) print (resp.text)

Для подключения СХД2 к метрокластеру, необходимо отключить VIP метрокластера на СХД1, сконфигурировать арбитр и связь со вторым СХД и, аналогично предыдущему шагу, выполнить скрипт подключения к метрокластеру каждой репликационной пары.
Шаг 8 — подключим репликационные пары СХД2 к метрокластеру:
for i in range (101,112): payload = { "node_ip": f'192.168.100.{i+50}', "name": f'rpl1ddp{i}', "metro_ip": "192.168.9.23", "metro_mask": 24 } print(payload) url = f'{URL}/rrepl/node~connect_metro' resp = requests.post(url, data=dumps(payload), headers=HEADERS) print (resp.text) for i in range (121,132): payload = { "node_ip": f'192.168.100.{i+50}', "name": f'rpl2ddp{i}', "metro_ip": "192.168.9.24", "metro_mask": 24 } print(payload) url = f'{URL}/rrepl/node~connect_metro' resp = requests.post(url, data=dumps(payload), headers=HEADERS) print (resp.text)

Далее можно презентовать тома с каждого дискового массива для хостов и пользоваться отказоустойчивым сервисом по хранению данных.
При возникновении необходимости переключить направление репликации метрокластера можно воспользоваться графическим интерфейсом, либо также использовать REST API Post запрос /api/rrepl/node~set_primary.
Подводим итоги
Как видно из примеров выше, начать пользоваться REST API для автоматизации рутинных задач системного администратора достаточно просто. Естественно, можно прикрутить работу с API в любое приложение, интегрировать управление с мобильного устройства, встроить необходимые алгоритмы в портал самообслуживания для частного облака или даже создать свою графическую оболочку для управления СХД, максимально адаптированную под решаемую задачу.
Если вас заинтересовали возможности API АЭРОДИСК и вы хотите попробовать использовать REST для управления СХД, все примеры для работы и документация доступна на нашем портале docs.aerodisk.ru.
Чтобы узнать больше про REST API записывайтесь на наш вебинар «ОколоИТ» 12 марта. На нём мы покажем, как пользоваться REST API, попробуем что-нибудь сломать и, естественно, починить в СХД АЭРОДИСК без перерыва сервиса с помощью технологий метрокластера ?
Мероприятие бесплатное, регистрация обязательна!
ссылка на оригинал статьи https://habr.com/ru/articles/798475/
Добавить комментарий