Прототип Vitastor S3 на базе Zenko CloudServer

11.08.2024

Завёлся прототип S3 Vitastor-бэкенда для Zenko CloudServer 😊

Это конечно ещё далеко не релиз, нужно ещё как минимум реализовать дефрагментацию. Но попробовать запустить и что-то записать-прочитать в S3 уже можно. Даже GeeseFS поверх уже работает. 😊

Итак, инструкция!

1. Устанавливаем сам сервер Zenko и зависимости

  • Клонируем https://git.yourcmc.ru/vitalif/zenko-cloudserver-vitastor.
  • Делаем npm install, можно npm install --omit dev для установки зависимостей - zenko-специфичные зависимости я либо поотрезал, либо перенёс к себе в git, ну и в целом чуть прибрался в версиях зависимостей.
  • Клонируем сам Vitastor: git clone https://git.yourcmc.ru/vitalif/vitastor
  • Заходим в папочку node-binding, делаем тоже npm install, чтобы собрать биндинг. Тут понадобятся установленные заголовки vitastor-библиотеки (vitastor-client-dev) свежей версии, чтобы это сработало, а также сам сборщик нативных модулей node.js (node-gyp).
  • Делаем ссылку на собранный модуль к zenko: ln -s /path/to/vitastor/node-binding /path/to/zenko/node_modules/vitastor

2. Устанавливаем и настраиваем MongoDB

Думаю, справитесь сами. :-)

Можно следовать руководству MongoDB: https://www.mongodb.com/docs/manual/installation/

3. Настраиваем Vitastor-бэкенд

  • Создаём у себя в Vitastor отдельный пул для данных S3.
  • Создаём (в другом пуле) образ для хранения метаданных (“s3-volume-meta” должно соответствовать значению в locationConfig.json):
    vitastor-cli create -s 10G s3-volume-meta
  • Копируем config.json.vitastor в config.json, правим адрес доступа, если нужно.
  • Копируем authdata.json.example в authdata.json - там указываются access & secret key для доступа - правим их, если нужно. У Scality за это отвечает отдельный сервис, а здесь пока что доступна только файловая заглушка.
  • Копируем locationConfig.json.vitastor в locationConfig.json - там указываются данные для подключения собственно к Vitastor. Прописываем туда правильные pool_id и metadata_image.

4. Запускаем

Командой node index.js.

И в принципе всё. Получаем работающий S3-сервер на порту 8000.

Бонус - утаптывание node_modules

В node.js приложениях типичная ситуация - это “девки в озере купались, ноде_модулес нашли” ©.

При установке Zenko CloudServer, например, вам в node_modules приезжает 23885 файлов общим весом 475 МБ. Чувство прекрасного страдает - что же делать?

Ответ на этот вопрос - webpack. Да, его можно применять не только для клиентского браузерного кода, а и на сервере!

Как это работает? Вам нужен webpack.config.js - в репозитории zenko-vitastor он уже есть. Так что заходите в свою директорию с установленным zenko cloudserver и запускайте:

npm exec webpack --mode=development

На выходе вы получите один файл dist/zenko-vitastor.js размером 25 МБ (или даже 15 МБ, если запустить с --mode=production), который больше не зависит ни от чего, кроме модулей с нативным кодом. Найти такие модули можно командой find node_modules -name '*.node' - бинарные модули node.js имеют расширение .node.

В случае zenko таких модулей 7 - их нужно скопировать из исходного node_modules:

  • Собственно, vitastor
  • bufferutil
  • diskusage
  • fcntl
  • ioctl
  • leveldown
  • utf-8-validate

Бонус номер два - зависимости Zenko

Кроме “нормальных” зависимостей из npm у Zenko есть некоторое количество собственных.

Первая порция - на самом деле необязательные библиотеки, которые были исключены методом выпиливания из зависимостей и убирания require() под if:

  • vaultclient - клиент для закрытого (с закрытыми исходниками) сервиса хранения паролей/ключей «Scality Vault» (не Hashicorp Vault, а другой). Нюанс: в самом клаудсервере-то он необязательный, но на него завязана другая библиотека utapi, и вот в ней он вполне себе обязательный.
  • bucketclient - клиент для закрытого сервиса хранения метаданных S3-объектов, представленного в виде отдельного закрытого сервиса «Scality bucketd».
  • hdclient - клиент для закрытого сервиса хранения данных S3-объектов «Scality Hyperdrive».
  • sproxydclient - клиент для, видимо, ещё одного закрытого сервиса хранения данных S3-объектов «Scality sproxyd».

Вторая порция - изолированные библиотеки, которые я просто не стал тащить к себе:

  • backbeat и breakbeat — сервис Lifecycle, открытый, но на первый взгляд работающий несколько через ж… (через переливку mongo oplog в kafka и чтение его оттуда), и потому на первый взгляд для нас непригодный.
  • s3utils - на 99% состоит из связанных с репликацией и закрытыми сервисами Scality (теми же sproxyd и т. п.) штук.

Третья порция - нужные или условно-нужные библиотеки:

  • arsenal - криво вынесенная в библиотеку часть, собственно, zenko cloudserver-а.
  • eslint-config-scality - просто конфиг eslint.
  • node-fcntl - на самом деле это никакой не fcntl, а posix_fadvise для node.js.
  • httpagent - их обёртка над стандартным HTTP-клиентом.
  • scubaclient - клиент для сервиса квот/счётчиков по бакету «АКВАЛАНГ» (SCUBA, Scality Consumption Utilization and Billing API). Можно оставить, так как через него запускаются тесты об заглушку этого сервиса, и так как, возможно, в будущем у нас тоже будет сервис счётчиков по бакетам - некая логика в этом есть.
  • utapi - utilization API, библиотека для выставления/сбора метрик — фиг знает, зачем так сложно сделано, можно было сделать просто prometheus exporter, но они решили обернуть.
  • werelogs - их библиотека/обёртка для логгирования.

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

Ещё пока что за пределами рассмотрения остался Orbit — это их Web-интерфейс для Zenko.