Большинство современных систем хранения данных (СХД) предоставляют REST API для управления ими, включая настройку, конфигурирование, выполнение различных команд, получение логов, работу с пользователями и т.д. В зависимости от производителя СХД REST API могут отличаться друг от друга. Если вы используете несколько разных систем, их одновременная поддержка становится проблемой: нужно учитывать многообразие протоколов, интерфейсов, команд и способов взаимодействия с API.

Меня зовут Александр Пономарев, вместе с группой студентов СПбПУ Петра Великого на базе Лаборатории YADRO мы изучали способы сделать управление разными СХД менее трудоемким. Вариант, на котором мы остановились, — использовать системы, которые удовлетворяют спецификации Swordfish, в связке с Ansible. Рассказываю о проекте, который мы выполняли с инженерами компании  и преподавателями университета.

О Swordfish и преимуществах спецификации

Swordfish — это стандарт управления хранилищами данных, разработанный SNIA (Storage Networking Industry Association). Эта организация объединяет производителей и пользователей СХД с целью разработки и поддержки отраслевых стандартов и технологий хранения данных. Swordfish предоставляет богатый функционал для управления ресурсами хранилищ данных, конфигурации и мониторинга систем, поддерживает механизмы аутентификации и авторизации для обеспечения безопасности. Спецификация Swordfish призвана решить большое количество проблем с универсальностью управления СХД в современной инфраструктуре, а за развитием и улучшением стандарта стоит активное сообщество. 

У Swordfish есть ряд преимуществ:

  • Открытый стандарт. Swordfish доступен в open source и может быть использован различными поставщиками СХД и программного обеспечения для них. Это способствует формированию единых стандартов в индустрии хранения данных.

  • Простота взаимодействия. Спецификация предоставляет простой для понимания REST интерфейс, взаимодействовать с API можно с помощью всем привычного формата JSON и понятного Open Data Protocol (Odata).

  • Универсальность и совместимость. У Swordfish есть универсальные и стандартизированные интерфейсы для управления различными типами хранилищ данных. Это упрощает интеграцию и совместимость между различными поставщиками оборудования и программного обеспечения.

  • Поддержка современных технологий. Спецификацию разрабатывают с учетом современных требований и технологий в области хранения данных, таких как смешанные и распределенные среды хранения, облачные решения, технологии хранения данных на основе NVMe (Non-Volatile Memory Express) и другие.

  • Улучшенное управление данными. Swordfish предоставляет расширенные возможности для управления данными, включая более эффективное управление хранилищем, мониторинг состояния и автоматизацию определенных процессов.

  • Масштабируемость и гибкость. Спецификация Swordfish разрабатывается с учетом потребности в горизонтальном масштабировании СХД, что особенно важно в условиях растущих объемов данных. Стандарт предоставляет гибкие средства для управления хранилищем в различных масштабах (до нескольких тысяч серверов), включая крупные корпоративные среды и облачные решения.

Преимущества Ansible для решения задачи

Ansible — известный инструмент автоматизации, который позволяет управлять конфигурациями и автоматизировать на большом количестве систем. 

У него есть много преимуществ для использования с СХД. Одно из ключевых для нашей задачи — интегрируемость с другими инструментами, например, с системами мониторинга. Это обеспечивает согласованность и единый интерфейс для управления всей инфраструктурой, включая хранилища данных.

Другие преимущества Ansible
  • Использует декларативный язык конфигурации YAML. Это позволяет описывать конфигурацию СХД и вносить изменения без явного указания шагов по достижению этого состояния.

  • Прост для использования и в изучении. Даже новички могут быстро овладеть основами Ansible, что упрощает внедрение автоматизации в инфраструктуру хранения данных.

  • Автоматизирует повторяющиеся задачи. Ansible поможет автоматизировать настройку, масштабирование, обновление и мониторинг СХД. Это снизит вероятность ошибок и повысит эффективность администрирования.

  • Поддерживает множество устройств. Ansible — платформенно-независимое решение, что идеально подходит для единообразного управления различными типами СХД от разных производителей.

  • Масштабируемость. Решение позволяет управлять большим количеством узлов одновременно. Это особенно полезно при управлении распределенными хранилищами данных или когда необходимо провести операции на большом числе устройств.

  • Модульность. Ansible использует модули для выполнения различных задач, что обеспечивает гибкость и возможность настройки под конкретные потребности.

  • Легко проверить и отладить. Автоматизированные задачи, описанные в Ansible, легко протестировать и исправить. Это позволяет создавать надежные и стабильные сценарии управления СХД.

  • Интегрируется с другими инструментами. Например, с системами мониторинга. Это обеспечивает согласованность и единый интерфейс для управления всей инфраструктурой, включая хранилища данных.

В итоге комбинация спецификации Swordfish и Ansible может дать неплохое техническое решение для ввода в эксплуатацию и автоматического управления СХД в среде с большим количеством комплексов. К сожалению, готовой коллекции Ansible-модулей, поддерживающих Swordfish, для взаимодействия с СХД не было. Мы решили разработать эти модули совместно с инженерами YADRO.

Методика разработки модулей Ansible

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

Так выглядит процесс разработки Ansible-модулей.
Так выглядит процесс разработки Ansible-модулей.

Шаг 1: Изучение спецификации

Предположим, вы уже знакомы с инструментом Ansible и думаете, как подступиться к неизвестной ранее спецификации Swordfish. Очевидно, нужно изучить, что это за «зверь», то есть прочитать спецификацию. Документ довольно объемный и штудировать его от корки до корки бессмысленно. Лучше сконцентрироваться на следующих разделах:

  • термины, которые будут часто встречаться при дальнейшей работе,

  • схемы использования, которые наглядно показывают, в каком отношении находятся ресурсы, объявленные в спецификации,

  • основные ресурсы (свойства, какую функцию несут и так далее), на основе которых строится схема СХД,

  • способы применения, то есть конкретные сценарии взаимодействия с СХД посредством спецификации Swordfish.

Также для Swordfish есть open source-эмулятор, с которым можно «поиграть». Нам он понадобился при тестировании написанных модулей. Об этом эмуляторе мы напишем отдельную статью.

Шаг 2: Выбор ресурса

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

Когда мы уже знаем, с чем работаем, не составит труда выбрать какой-нибудь базовый ресурс. Мы остановились на StoragePool — логической группе хранилищ данных, объединяющей физические ресурсы, такие как диски, тома или даже другие пулы.  StoragePool предоставляет абстракцию, которая позволяет управлять ресурсами хранения данных на уровне одного хранилища.

Затем нужно посмотреть, какие связи есть у выбранного ресурса с другими. Некоторые из них не владеют StoragePool, а просто ссылаются на него. То есть из этих ресурсов мы можем «достучаться» до нужного. Будем просто иметь это в виду и не забудем в нужный момент. Но если ресурс относится к определенному, то мы должны подумать, есть ли у нас функционал, позволяющий создать/получить этот «родительский» ресурс. Если нет, стоит выбрать именно «родительский» ресурс.

Для выбранного нами StoragePool основным «родительским» ресурсом является StorageServices, но при разных сценариях StoragePool'ы также могут быть вложены друг в друга.

Шаг 3: Выбор сценария использования ресурса

После того как мы выбрали ресурс, определим вариант использования — например, создание, удаление, изменение ресурса или просто получение информации о нем. Заглянуть в User Guide и выбрать сценарий или набор сценариев, которые позволят достигнуть нужного нам результата. Самое сложное здесь — определить, что будет необходимо нашему будущему пользователю и что из этого разумно выделить в отдельный модуль, а что сделать составной частью другого.

Вариант использования StoragePool — его создание.

Шаг 4: Разработка модуля

На этом шаге мы также продумываем архитектуру модуля: как мы собираемся его писать, какие вспомогательные классы и утилиты нам нужны, как обеспечить расширяемость кода и так далее. Когда мы уже представляем, что будем писать, можно приступить непосредственно к кодингу, опираясь на базовую структуру Ansible-модуля.

→ Такой модуль мы разработали для создания ресурса StoragePool.

Шаг 5: Тестирование

Этот пункт можно рассматривать как опциональный, но для обеспечения правильного процесса разработки он необходим. Писать тесты или нет — ваш выбор. 

Теперь о том, как это делали мы. Здесь возможности ограничены функционалом эмулятора Swordfish (если у вас нет другого средства, эмулирующего СХД со Swordfish), но принцип довольно прост: пишем интеграционные Ansible-тесты, составляем end-to-end тестовые сценарии, запускаем эмулятор, запускаем тесты и радуемся тому, как у нас все работает (или нет).

На GitLab мы выложили тесты для нашей коллекции модулей, в том числе для создания ресурса StoragePool.

Шаг 6: Релиз

В основе Ansible лежат коллекции, содержащие в себе модули. Соответственно, нам необходимо создать собственную коллекцию согласно документации, добавить туда наши модули и опубликовать их в публичный Git-репозиторий. Теперь посмотрим, что у нас получилось. 

Коллекция Ansible-модулей и их применение

Рассмотрим несколько из написанных нами Ansible-модулей, готовых к использованию:

  • swordfish_ping.py — наверное, самый нужный модуль, поскольку он позволяет проверить работоспособность СХД.

  • swordfish_create_storage_pool.py — позволяет создать ресурс StoragePool.

  • swordfish_sp_pools_info.py — предоставляет описательную информацию о всех ресурсах типа StoragePool.

  • swordfish_namespace_capacity.py — модуль, который предоставляет информацию о количестве доступного и занятого места в определенном пространстве имен (namespace).

На момент публикации мы разработали и выложили 12 Ansible-модулей. Познакомиться с остальными можно по ссылке.

Как написать Ansible-playbook и протестировать его на эмуляторе Swordfish

В завершение коротко покажем, как можно протестировать написанный Ansible-модуль в эмуляторе Swordfish. Для начала нам необходимо:

  1. Установить Ansible.

  2. Скачать нашу коллекцию модулей с помощью команды:

ansible-galaxy collection install git+https://gitlab.com/IgorNikiforov/swordfish_ansible_pligin
  1. Скачать эмулятор Swordfish.

Для примера мы протестируем простой плейбук создания ресурса StoragePool и получение информации о нем.

Первым делом запускаем эмулятор Swordfish. Для этого переходим в директорию со скаченным эмулятором и устанавливаем его согласно инструкции на GitHub. После успешной установки в той же директории прописываем команду:

venv/bin/python emulator.py

Если вы не меняли настройки при установке, то эмулятор запустится по адресу https://127.0.0.1:5000.

При тестировании мы сталкивались с довольно странным поведением эмулятора. Приходилось углубляться в спецификацию, чтобы понять, действительно ли так задумано или это все же недоработка. Зачастую приходили к тому, что это баг и нужно его исправлять. Например, в спецификации указано: «The Id property of a resource uniquely identifies the resource within the resource collection that contains it» (В переводе: «Поле ID должно быть уникально для каждого ресурса коллекции»). Но эмулятор нарушал это правило.

Теперь напишем простой Ansible-playbook:

- name: Simple play
  hosts: localhost

Задаем имя нашего сценария и указываем, что будем запускать его на локальных хостах.

 vars:
    connection:
        base_url: "https://127.0.0.1:5000"
   	    username: "Administrator"
   	    password: "Password"

Зададим переменную connection, которая задаст параметры подключения к эмулятору и понадобится как аргумент для наших модулей.

tasks:
    - name: Create test storage pool
      spbstu.swordfish.swordfish_create_storage_pool:
        connection: "{{ connection }}"
   	    storage_id: "IPAttachedDrive1"
   	    name: "TestPool"
   	    provisioned_bytes: 10000
   	    description: "pool for test"

Указываем первый task, в котором создаем новый ресурс StoragePool с именем TestPool для хранилища, которое есть в базовой конфигурации эмулятора — IPAttachedDrive1.

- name: Get storage pools info
  spbstu.swordfish.swordfish_sp_pools_info:
    connection: "{{ connection }}"
  register: response

Следующим шагом мы используем модуль swordfish_sp_pools_info, чтобы посмотреть, действительно ли создался ресурс StoragePool, и записываем результат работы модуля в переменную response.

- name: See response
  debug:
    msg: “{{ response }}”

Чтобы увидеть результат в консоли, добавляем еще один task и с помощью debug отображаем переменную msg вместе с содержимым ответа (response).

В итоге наш файл (например, playbook.yml — можете назвать его как угодно) выглядит примерно так:

- name: Simple play
  hosts: localhost
  vars:
    connection:
      base_url: "https://127.0.0.1:5000"
      username: "Administrator"
      password: "Password"
  tasks:
    - name: Create test storage pool
      spbstu.swordfish.swordfish_create_storage_pool:
        connection: "{{ connection }}"
        storage_id: "IPAttachedDrive1"
        name: "TestPool"
        provisioned_bytes: 10000
        description: "pool for test"
    
    - name: Get storage pools info
      spbstu.swordfish.swordfish_sp_pools_info:
        connection: "{{ connection }}"
      register: response
    
    - name: See response
      debug:
        msg: "{{ response }}"

Чтобы запустить playbook из консоли, прописываем из директории с файлом:

ansible-playbook playbook.yml

И увидим в консоли информацию по каждому шагу и вывод ответа, содержащего следующее сообщение:

"storage": "/redfish/v1/Storage/IPAttachedDrive1",
"storage_pools": [
  {
    "@odata.id": "/redfish/v1/Storage/IPAttachedDrive1/StoragePools/TestPool",
    "description": "pool for test",
    "id": "TestPool",
    "name": "TestPool"
  }
]

То что мы и хотели получить.

Итоги

Одним из ключевых преимуществ разработанной коллекции является легкость интеграции с существующими Ansible-сценариями. Мы предоставляем прозрачные интерфейсы для основных операций, таких как создание, чтение, обновление и удаление ресурсов. Это делает автоматизацию управления хранилищем данных более доступной и понятной для пользователя.

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

А разработанная методика создания Ansible-модулей позволяет эффективно резрабатывать новые модули для спецификации Swordfish и помогает новым членам команды в короткие сроки «вливаться» в проект.

В будущем мы планируем расширять коллекцию модулей — на данный момент затронута лишь небольшая часть возможностей, описанных в спецификации. Последующие апдейты будут усовершенствовать архитектуру нашего проекта для более продуктивной и удобной разработки модулей.

Следите за проектом в следующих статьях. Во второй части расскажем, почему нам пришлось сделать fork официального репозитория Swordfish и что мы успели усовершенствовать. А завершим трилогию описанием вариантов реализации ролевой модели на примере эмулятора Swordfish.

Подписывайтесь на блог YADRO или на аккаунт лаборатории, чтобы не пропустить следующий части!

Комментарии (2)


  1. Tamerlan666
    10.01.2024 11:26
    +2

    У вас в части примеров yaml разметка жестко поплыла...


    1. yadro_team
      10.01.2024 11:26
      +3

      Да, поехало несколько отступов) Спасибо за внимательность! Поправили