Как стать автором
Обновить
35.44
АЭРОДИСК
Российский разработчик СХД и систем виртуализации

Автоматизированная настройка СХД АЭРОДИСК с помощью REST API

Уровень сложностиСредний
Время на прочтение8 мин
Количество просмотров897

Привет, Хабр.

В одном из наших недавних постов мы немного затронули тему автоматизации, которую мы активно продвигаем в наших продуктах. По различным каналам мы получили много положительных откликов и дополнительных вопросов о том, как можно использовать наши 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, попробуем что-нибудь сломать и, естественно, починить в СХД АЭРОДИСК без перерыва сервиса с помощью технологий метрокластера ?

Мероприятие бесплатное, регистрация обязательна!

Теги:
Хабы:
Всего голосов 1: ↑1 и ↓0+1
Комментарии2

Публикации

Информация

Сайт
aerodisk.ru
Дата регистрации
Дата основания
Численность
51–100 человек
Местоположение
Россия
Представитель
Вячеслав Володкович