Контейнерные приложения все чаще требуют постоянного хранилища, будь то базы данных, кэш или файловые серверы. Но Kubernetes по умолчанию не «умеет» работать напрямую с системами хранения данных, в этом ему помогает CSI (Container Storage Interface). А если хочется управлять хранилищем через единый стандарт и без привязки к конкретному вендору, на помощь приходит спецификация Swordfish.
В статье расскажем, как мы в лаборатории реализовали CSI-драйвер, поддерживающий спецификацию Swordfish и создали сервер-эмулятор, позволяющий тестировать и разворачивать такую систему без физического оборудования — и поделимся этим эмулятором, чтобы вы могли попробовать сами.
Kubernetes — наиболее популярная платформа оркестрации контейнеров, которую можно использовать для развертывания приложений, требующих постоянного хранилища данных (например, базы данных, файловые серверы, кэширование и т. д.). Однако Kubernetes изначально был ориентирован на управление контейнерами, а не на управление хранилищем. Поэтому для того, чтобы контейнеры могли подключаться к хранилищам, было разработано решение — CSI.
В предыдущих статьях мы написали Ansible-модули для управления разными системами хранения данных через Swordfish и объяснили проблемы mock-сервера Swordfish API Emulator.
Что такое Swordfish и для чего нужен
Swordfish — это спецификация, разработанная организацией SNIA (Storage Networking Industry Association), которая нацелена на создание стандартов для управления системами хранения данных (СХД) в дата-центрах и облачных инфраструктурах. Она расширяет возможности Redfish API, предоставляя единый интерфейс для управления разными типами хранилищ:
блочными (Block Storage),
файловыми (File Storage, например NFS),
объектными (Object Storag2e).
Swordfish нужен для автоматизации управления хранилищами, унификации API и упрощения работы с различными типами СХД.
Единый стандарт для СХД: почему мы выбрали Swordfish
Swordfish нам понадобился по нескольким причинам.
Необходимость унификации. В современных IT-инфраструктурах у заказчика часто используется множество СХД от разных производителей. Каждая из этих систем хранения данных имеет собственный API и интерфейс управления, что делает их администрирование сложным и неудобным. Задача Swordfish — создать единый стандарт для этого процесса, Swordfish предоставляет единых подход к управлению СХД различных вендоров.
Интеграция с облачными и гиперконвергентными системами. СХД интегрируются с облачными платформами и гиперконвергентными системами. Это программно-определяемые системы, которые объединяют вычислительные ресурсы (CPU, RAM), сетевые компоненты и хранилище в единую платформу. Swordfish предоставляет стандарты, которые упрощают работу с такими архитектурами.
Управление через API. Swordfish разрабатывался с акцентом на использование RESTful API для взаимодействия. Это облегчает автоматизацию процессов, таких как развертывание новых ресурсов, мониторинг состояния системы и оптимизация хранения.
Почему до сих пор нет CSI-драйвера, поддерживающего спецификацию Swordfish
В настоящее время не существует CSI-драйвера, поддерживающего спецификацию Swordfish, поскольку большинство существующих CSI-драйверов разработали вендоры СХД под свои решения. Разработка CSI-драйвера для Kubernetes — это непростая задача, особенно если один из пунктов — поддержка спецификации Swordfish. Интеграция с Kubernetes API, поддержка всех функций Swordfish, таких как управление различными типами хранилищ, — все это требует значительных усилий.
Наша команда решила взяться за это непростое задание и реализовать драйвер CSI, поддерживающий спецификацию Swordfish. Установить его можно по ссылке
Эмулятор вместо оборудования
Эмулятор Swordfish API нужен для тестирования и разработки решений, работающих с СХД, без необходимости подключения к реальному оборудованию. Это полезно, так как СХД дорогие и сложные в настройке. Помимо этого, благодаря эмулятору разработчики и тестировщики могут проверять работу API без риска повредить реальные данные. Более подробно про особенности и проблемы mock-сервера Swordfish API мы уже писали.
Swordfish API — это стандарт управления СХД, но разные вендоры реализуют его по-своему, а эмулятор помогает протестировать базовый функционал.
Требования к эмулятору:
Имитация API-запросов и ответов согласно спецификации Swordfish.
Поддержка основных операций с хранилищами: создание томов, управление атрибутами томов (размер, доступность, свободная память и т. д.) и удаление томов.
Возможность тестирования разных типов хранилищ (блоковое, файловое, объектное).
Use-case использования CSI-драйвера
CSI-драйвер, взаимодействующий со Swordfish API, позволяет Kubernetes-кластеру автоматически создавать, подключать и управлять томами на системах хранения. Это важно в enterprise-средах, где нужно обеспечивать стандартизированный доступ к различным типам СХД без привязки к конкретному вендору.

Когда приложение в кластере Kubernetes запрашивает постоянное хранилище (например, для хранения данных в общих папках), оркестратор отправляет запрос через PersistentVolumeClaim (PVC) с необходимыми характеристиками тома.
Что происходит, когда нужно создать том:
Kubernetes получает PVC с характеристиками тома (размер, тип хранилища и т. д.).
Находит соответствующий StorageClass, который указывает, что том должен создаваться через CSI-драйвер.
CSI-драйвер взаимодействует с эмулятором Swordfish API, который создает том с требуемыми параметрами.
Для файловых систем (например, NFS) Swordfish API конфигурирует подключение к серверу NFS и возвращает информацию о созданном томе обратно CSI-драйверу.
Когда том успешно создан, Kubernetes автоматически подключает его к нужному контейнеру или поду. Как это происходит:
Эмулятор Swordfish API извлекает путь из ресурса FileShare к директории и добавляет путь в конфигурацию сервера NFS в /etc/exports. Это позволяет клиентам подключаться к этой директории и использовать ее в качестве сетевого хранилища. Происходит на этапе создания ресурса.
Kubernetes связывает созданный том PersistentVolume (PV) с PVC, который был запрошен приложением. Контейнер или под, требующий доступ к данным, получает информацию о PV, который необходимо примонтировать.
Kubernetes вызывает метод NodePublishVolume в CSI-драйвере. Он отвечает за монтирование тома в файловую систему узла (worker node), на котором запущен под.
При ненадобности хранилища инициируем удаление PVC в Kubernetes. Он включает в себя два этапа: размонтирование тома с узла и полное удаление тома из системы хранения. Kubernetes вызывает NodeUnpublishVolume в CSI-драйвере, чтобы отмонтировать том с узла. CSI-драйвер отправляет команду в эмулятор Swordfish API. Эмулятор Swordfish API устраняет том и освобождает ресурсы: в случае использования файловой системы NFS удаляется запись из /etc/exports и сам каталог на сервере. После этого Kubernetes снимает объект PV, завершая процесс.
Из чего состоит архитектура CSI-драйвера
Архитектура CSI-драйвера состоит из следующих компонентов:
Config-модуль
Конфигурационный модуль отвечает за корректное чтение и обработку YAML-файла. Для работы необходим конфигурационный файл config.yaml. Чтение и обработка производятся с помощью библиотеки viper. Содержимое config.yaml:
server:
network_type — тип сетевого взаимодействия (unix или tcp), используемый gRPC-сервером.
socket — путь к Unix-сокету или адрес TCP-соединения для запуска CSI-драйвера.
swordfish:
base_url — базовый URL, по которому драйвер обращается к Swordfish API.
logging:
level — уровень логирования (debug, info, warn, error), определяет, какие сообщения будут выводиться.
format — формат логов (json или logfmt), влияет на читаемость и совместимость с системами мониторинга.
Identity-сервис
Identity выполняет роль идентификатора для драйвера — он сообщает Kubernetes и другим внешним системам базовую информацию о плагине, а также подтверждает, что он готов к работе:
GetPluginInfo:
Отвечает за передачу имени драйвера и его версии.
GetPluginCapabilities:
Возвращает список возможностей плагина (например, поддержка Controller Service, Volume Expansion и т. д.).
Probe:
Служит для проверки готовности драйвера. Kubernetes регулярно вызывает этот метод, чтобы убедиться, что компонент живой и исправно работает.
Node-сервис
Сервис отвечает за монтирование и демонтаж томов на уровне узлов Kubernetes.
Controller-сервис
Controller отвечает за управление жизненным циклом томов на уровне кластера.
Что умеет CSI-драйвер
Создание и удаление томов (Volume Provisioning)
Для достижения корректного Volume Provisioning CSI-драйвер обрабатывает запросы Kubernetes на создание и удаление хранилищ через Controller Service. Метод CreateVolume отправляет HTTP POST-запрос к эмулятору Swordfish:
POST /redfish/v1/Storage/<drive_id>/Volumes
с телом:
{
"Name": "volume_name",
"CapacityBytes": 1073741824
}
Метод DeleteVolume удаляет том через HTTP DELETE:
DELETE /redfish/v1/Storage/<drive_id>/Volumes/<volume_id>
Монтирование и размонтирование (Attach/Detach)
Монтирование и размонтирование томов производится так: на этапе запуска пода CSI-драйвер монтирует NFS-директорию в файловую систему узла. При завершении работы Pod-а размонтирует ресурс.
Эта функция реализована так. Метод NodePublishVolume получает из VolumeContext:
StorageService,
FileSystem,
Share.
NodePublishVolume обращается к API:
GET /redfish/v1/StorageServices/FileService/FileSystems/FS1/ExportedFileShares/Share
GET /redfish/v1/Systems/.../EthernetInterfaces/<id>
И получает ответ:
FileSharePath,
NFS-server IP.
Далее выполняется команда mount по этим данным:
mount -t nfs <IP>:<path> <target_path>
Для размонтирования NodeUnpublishVolume выполняет команду:
umount <target_path>
Как CSI-драйвер взаимодействует с эмулятором
Для взаимодействия с эмулятором SwordFish используется структура SwordfishClient, где происходит инкапсуляция всех HTTP-запросов к Swordfish Emulator. API вызывается через net/http, структура запроса строится вручную, а тело сериализуется через encoding/json.
Как это можно использовать:
url := fmt.Sprintf("%s/redfish/v1/Storage/%s/Volumes", baseURL, driveID)
В будущем вместо эмулятора будет использоваться настоящее оборудование СХД от вендора (например YADRO, Аквариус, DELL, EMC). Главное условие работы — поддержка Redfish/Swordfish API со стороны хранилища.
CSI-драйвер уже реализует стандартные HTTP-запросы. Благодаря этому можно использовать те же функции: CreateVolume, DeleteVolume,GetFileShare и прочие. Также для работы необходимо заменить base_url в config.yaml.
При переходе с эмулятора на реальное оборудование: не требуется изменений кода (при соблюдений стандарта API) и возможна проверка доступности и аутентификации через TLS или Token.
Реализация драйвера
Логирование и обработка ошибок
Для записи сбоев и отслеживания логов используется библиотека go-kit/log, которая:
подстраивается под формат (logfmt, json),
поддерживает уровни логов (debug, info, error),
выводит время и файл вызова через log.DefaultCaller.
Для обработки ошибок все внешние вызовы (http, exec) обернуты в проверки и сообщения. В случае возникновения ошибки CSI возвращает status.Errorf(...), лог сохраняется с полным сообщением и stack trace.
Автоматизированное тестирование с использованием csi-sanity
После запуска драйвера на unix socket можно выполнить команду csi-sanity:
csi-sanity -csi.endpoint=<путь к сокету>
csi-sanity проверяет обязательные методы: GetPluginInfo, NodePublishVolume, ControllerCreateVolume и т. д.
Тесты подтверждают корректность реализации CSI-спецификации, и их можно использовать в CI/CD-пайплайне для регресс-тестов.
Сборка CSI-драйвера
Для простоты развертывания и независимости от среды выполнения мы подготовили минимальный Docker-образ для CSI-драйвера. Используется alpine:3.18, который занимает мало места, но при этом предоставляет все необходимые утилиты.
Основные этапы:
добавление необходимых инструментов (например, ca-certificates для работы с HTTPS),
копирование готового бинарного файла драйвера (swordfish-csi),
добавление конфигурационного файла (config.yaml),
настройка прав на выполнение и установка рабочей директории,
определение точки входа, которая запускает драйвер с указанной конфигурацией.
Этот Docker-образ позволяет запускать swordfish-csi как отдельный контейнер в Kubernetes.
Чтобы упростить процесс сборки и развертывания драйвера в Kubernetes, мы подготовили автоматизированный скрипт.
Что делает этот скрирт:
собирает Docker-образ с CSI-драйвером,
запускает контейнер с драйвером.
применяет все необходимые манифесты для настройки Kubernetes-окружения,
выводит статусы компонентов.
Этот скрипт позволяет полностью развернуть CSI-драйвер и проверить его работоспособность в кластере.
Улучшение эмулятора: логика, логи и файловые шары
Для полноценного тестирования CSI-драйвера возможностей созданного сервера-эмулятора оказалось недостаточно. Поэтому мы решили расширить его функциональность и заодно переработать некоторые вещи — в первую очередь валидацию и систему логирования.
Валидация
В старой версии эмулятора не было никаких проверок на наличие ресурса, на который ссылается другой ресурс, — из-за этого ошибка 404 была не редкостью. Чтобы решить проблему, мы добавили проверку ресурсов перед их сохранением в базу. Во время проверки с помощью рефлексии определяется корректность типов данных полей ресурса и наличие всех связанных ресурсов.

Логи
Кроме того, мы переработали систему логирования: появилась возможность конфигурации вывода логов, включая источник (консоль и/или файл) и формат (JSON или текстовый). Также можно настроить ротацию логов, то есть указать максимальный размер файла с логом, их максимальное количество и период, после которого лог будет удален.
Ротация логов предотвращает переполнение диска, а поддержка формата JSON упрощает интеграцию с инструментами мониторинга, например с Grafana. Для реализации логирования использовались slog для вывода логов и lumberjack для ротации:
logger:
stdout: true
file: true
format: "json"
logger-rotation:
file-name: "./logs/log.log"
max-size: 10
max-backups: 5
max-age: 28
local-time: true
compress: true
Ресурсы
Чтобы реализовать создание файловой шары (shares) сервером-эмулятором, нужно было также добавить некоторые ресурсы и их обработчики в соответствии со спецификацией Swordfish:
StorageService — связывает физические ресурсы (диски, контроллеры) с логическими (тома, файловые системы), агрегирует все компоненты системы хранения (пулы, диски, файловые системы, LUN) в единую логическую единицу и предоставляет API для централизованного управления (например, создание томов, мониторинг).
FileShare — описывает общий доступ к файловому хранилищу (NFS, SMB/CIFS, S3-совместимые объектные хранилища), включает настройки доступа, квоты и политики безопасности.
FileSystem — ресурс, представляющий логическую файловую систему (например, NTFS, ext4, XFS), служит прослойкой между физическим хранилищем (дисками, пулами) и точками доступа (FileShare), обеспечивая стандартизированное управление файловыми данными.
EthernetInterface — ресурс, представляющий физические или виртуальные Ethernet-интерфейсы (NIC, vNIC) систем хранения. Обеспечивает управление сетевыми параметрами, например IP-адресацией (IPv4/IPv6, DHCP/статический), VLAN, MTU, скоростью соединения.
Для создания файловой шары мы остановились на протоколе NFS, для этого нам был нужен NFS-сервер. Чтобы не усложнять проект, использовали nfs-kernel-server и запускали его на одной машине с сервером-эмулятором.
Для работы с NFS-сервером необходимо предоставить клиенту информацию о его IP-адресе. В терминах Swordfish это можно сделать с помощью определенного ранее ресурса EthernetInterface, на который ссылается файловая шара.
Для удобства развертывания сервера-эмулятора мы добавили возможность автоматической инициализации сетевых интерфейсов во время запуска эмулятора. В ходе инициализации создаются экземпляры ресурса EthernetInterface. Это позволяет запускать сервер-эмулятор и сразу создавать экземпляры EthernetInterface, без необходимости что-либо настраивать, а это значительно облегчает развертывание.
После запуска сервера-эмулятора мы получили инициализированные ресурсы EthernetInterface, на которые мы будем ссылаться при создании файловой шары.
Запрос на создание файловой шары будет выглядеть так:
POST /redfish/v1/StorageServices/FileService/FileSystems/FS1/ExportedFileShares
{
"Description": "My File Share.",
"FileSharePath": "/srv5/nfs_share",
"FileSharingProtocols": [
"NFSv4_0"
],
"Name": "MyShare",
"EthernetInterfaces": {
"@odata.id": "/redfish/v1/Systems/FileServer/EthernetInterfaces/enp0s3"
}
}
Таким образом, мы указываем, что создаваемая шара будет доступна по указанному EthernetInterface. Эту информацию мы используем на стороне клиента при монтировании шары:
mount -t nfs <IP-адрес, полученный от ресурса EthernetInterface>:/data/nfs /mnt
Дополнительно мы реализовали автоматическое размонтирование директории от NFS-сервера при удалении файловой шары. Выполним следующий запрос на заранее созданную файловую шару MyFileShare12:
DELETE /redfish/v1/StorageServices/FileService/FileSystems/FS1/ExportedFileShares/MyFileShare12
Теперь директория удалена из конфигурационного файла /etc/exports и больше не экспортируется NFS-сервером, а ресурс FileShare не существует.
Гибкий доступ: динамическая ролевая модель для сервера Swordfish
Современные системы хранения данных требуют гибких механизмов управления доступом. Мы построили систему на основе RBAC (Role-Based Access Control) с использованием PostgreSQL и JWT — теперь роли и права можно гибко настраивать без перекомпиляции или перезапуска приложения.
Спецификация Swordfish определяет стандартные роли (Administrator, Operator, DevOps, StorageAdmin, CloudAdmin и ReadOnly), но существующие эмуляторы не поддерживают полноценную динамическую модель.

Основные проблемы статического подхода:
необходимость перезапуска сервера для изменения прав,
ограниченная масштабируемость (до 100 пользователей),
отсутствие API для управления пользователями и ролями,
жесткая привязка прав доступа к коду приложения.
Наш проект решает эти проблемы, предоставляя:
динамическое управление через REST API,
поддержку 1000+ пользователей,
соответствие спецификации Swordfish,
гибкую систему привилегий с поддержкой OEM-расширений.
Архитектура решения
Система построена по трехуровневой схеме:
Транспортный уровень — REST API на Go с использованием Gorilla Mux.
Бизнес-логика — сервисы аутентификации и авторизации.
Уровень данных — PostgreSQL для хранения информации о пользователях и правах.

Рассмотрим подробнее каждый из компонентов.
Модуль аутентификации
Реализован на основе JWT (JSON Web Tokens) и обеспечивает:
Безопасную идентификацию пользователей.
Ограничение времени жизни токенов (24 часа).
Защиту паролей с помощью bcrypt.
Автоматическую очистку устаревших сессий.
Как работает процесс аутентификации:
Пользователь отправляет POST /redfish/v1/SessionService/Sessions.
Сервер проверяет учетные данные.
Создается JWT-токен с claims (ID пользователя, роль, срок действия).


Ролевая модель (RBAC)
Полностью соответствует спецификациям Swordfish и Redfish, поддерживая:
Стандартные роли (Administrator, Operator, StorageAdmin, CloudAdmin, DevOps, ReadOnly).
OEM-привилегии производителей.
Динамическое управление правами через REST API.
Переопределения прав для отдельных свойств ресурсов.
База данных
Мы разработали схему БД PostgreSQL, включающую следующие ключевые таблицы:
role — хранит информацию о ролях,
privilege — определяет привилегии,
role_privilege — связывает роли с привилегиями,
operation_privilege — определяет привилегии для операций,
user_account — содержит данные пользователей,
session — хранит активные сессии.

Проверка прав
Процесс проверки прав состоит из следующих шагов:
Middleware извлекает JWT и проверяет подпись.
Определяет требуемые привилегии для запрашиваемого ресурса.
Проверяет права пользователя через БД.

Для обеспечения высокой производительности мы реализовали кэширование решений о доступе. Для потокобезопасного хранения используется sync.Map, где ключом служит комбинация ID пользователя и списка привилегий. При изменении прав кэш автоматически очищается.
Реализованная динамическая ролевая модель расширяет возможности сервера-эмулятора Swordfish, делая его более удобным инструментом для тестирования Ansible-модулей и других клиентов СХД.

В планах развития внедрение двухфакторной аутентификации, добавление OEM-привилегий для специфических СХД и интеграция с внешними системами аутентификации (LDAP, OAuth2).
Где и как использовать это решение
Чтобы воспользоваться Swordfish‑CSI, необходимо собрать проект, подготовить окружение с Kubernetes (Minikube), Docker и NFS‑сервером, а затем задеплоить эмулятор и CSI‑драйвер.
Требования:
kubectl: Client Version v1.28.2.
Minikube: v1.35.0.
Docker: Version 28.0.4 (API version 1.48).
NFS‑сервер (для хранения PV/PVC).
Git (для клонирования репозиториев).
Проверка инструментов
Необходимо выполнить команды kubectl version --client, minikube version, docker version.
Настройка NFS
Скрипт setup_nfs.sh:
Настройка статического IP на интерфейсе хоста.
Установка и запуск NFS‑сервера.
Настройка экспорта папки /srv/nfs_share для указанной подсети.
Конфигурация фаервола (UFW) для доступа по NFS.
Сценарий сборки и запуска
Клонировать репозитории:
git clone git@gitlab.com:IgorNikiforov/swordfish-emulator-go.git
git clone https://gitlab.com/swordfish-csi-dev-team/swordfish-csi.git
Эмулятор Swordfish: swordfish-emulator-go.
CSI‑драйвер Swordfish: swordfish-csi.
Перейти в директорию swordfish-csi и запустить скрипт сборки и развертывания:
cd swordfish-csi
chmod +x deploy/deploy_csi_driver_from_rep.sh
./deploy/deploy_csi_driver_from_rep.sh
Убедиться, что создан config.yaml в корне или скопировать его из образца:
server:
network_type: "unix"
socket: "/var/lib/kubelet/plugins/swordfish-csi/csi.sock"
swordfish:
base_url: "http://localhost:8080"
logging:
level: "info"
format: "json"
Настроить и запустить NFS-сервер (если требуется вручную):
chmod +x setup_nfs.sh
sudo ./setup_nfs.sh
Запустить эмулятора Swordfish:
cd swordfish-emulator-go
make start
Проверить статус ресурсов:
kubectl get pods -n kube-system
kubectl get pv
kubectl get pvc
При необходимости задеплоить тестовый под:
kubectl apply -f examples/pod.yaml
Тестовый под должен создать тестовое окружение, в котором можно будет провести сценарий работы драйвера и эмулятора как СХД. На хостовой машине в файловой шаре должны будут добавляться файлы, которые мы прокидываем в поде.
Описание YAML‑манифестов
rbac.yaml
Настраивает сервисный аккаунт, ClusterRole с правами управления PV, PVC, nodes, secrets и ресурсами storage.k8s.io, а также ClusterRoleBinding.swordfish.yaml
Деплой CSI‑драйвера в namespace kube-system:— контейнер swordfish-csi (основной), csi-provisioner, csi-attacher, csi-resizer, liveness-probe,
— монтирование каталога плагина и конфигурации через ConfigMap.
pv.yaml и pvc.yaml
Создают PersistentVolume объемом 1 Gi и PersistentVolumeClaim, запрашивающий этот объем из storageClass: swordfish-csi.pod.yaml
Тестовый под с контейнером Nginx, монтирующий PVC в /usr/share/nginx/html.storage_class.yaml
Определяет StorageClass swordfish-csi с provisioner swordfish-csi, политикой Retain и Immediate binding.
Скрипты
setup_nfs.sh
Скрипт для настройки статического IP, установки и конфигурации NFS‑сервера и фаервола.deploy_csi_driver_from_rep.sh
Автоматизация:
Клонирование CSI‑репозитория и чек-аут нужной ветки.
Сборка и запуск Docker‑образа драйвера.
Применение YAML‑манифестов (rbac, deployment, PV/PVC).
Создание ConfigMap из config.yaml.
Проверка статуса Pod, PV и PVC.
Dockerfile и конфигурация
Dockerfile
Двухэтапная сборка: компиляция Go‑бинаря и финальный Alpine‑образ с конфигом.config.yaml
Параметры:тип сети и путь к CSI‑сокету,
URL эмулятора Swordfish,
уровень и формат логирования.
Эмулятор
nfs_setup.sh
Скрипт проверяет root‑привилегии, устанавливает nfs-kernel-server, задает права на экспорт и добавляет пользователя в группу sudo.
После выполнения всех шагов окружение будет готово: развернут NFS‑сервер, запущен эмулятор и CSI‑драйвер Swordfish, а также созданы PV, PVC и тестовый под с монтированным хранилищем.
Собираем в контейнер emulator и driver, загружаем в Minicube.
minikube image load swordfish-emulator:latest
minikube image load swordfish-csi:latest
bash ./deploy_csi_driver.sh
Далее для ручного тестирования драйвера заходим в него:
kubectl exec -it swordfish-csi-6bcd8867b5-7lbqj -n kube-system -- sh
/etc/swordfish # apk add curl
/etc/swordfish # curl -sSL "https://github.com/fullstorydev/grpcurl/releases/download/v1.8.9/grpcurl_1.8.9_linux_x86_64.tar.gz" | tar -xz -C /usr/local/bin
Вызов CreateVolume:
grpcurl -d '{"name":"demo-vol","capacityRange":{"requiredBytes":1073741824},"parameters":{"drive_id":"IPAttachedDrive1"},"volumeCapabilities":[{"accessMode":{"mode":"SINGLE_NODE_WRITER"},"mount":{"fsType":"ext4"}}]}' -plaintext -unix /var/lib/kubelet/plugins/swordfish-csi/csi.sock csi.v1.Controller/CreateVolume
Вызов ControllerPublishVolume:
/etc/swordfish # grpcurl -plaintext -unix -d '{"volume_id":"hFBQva", "node_id":"hFBQva"}' /var/lib/kubelet/plugins/swordfish-csi/csi.sock csi.v1.Controller/ControllerPublishVolume
# {}
Вызов ControllerUnpublishVolume:
/etc/swordfish # grpcurl -plaintext -unix -d '{"volume_id":"hFBQva", "node_id":"hFBQva"}' /var/lib/kubelet/plugins/swordfish-csi/csi.sock csi.v1.Controller/ControllerUnpublishVolume
# {}
Вместо заключения
Итак, мы разработали полноценную связку:
CSI-драйвер для Kubernetes, поддерживающий спецификацию Swordfish API.
Сервер-эмулятор Swordfish, позволяющий тестировать работу с СХД без реального оборудования.
CSI-драйвер поддерживает все базовые операции с томами, включая их создание, удаление, монтирование и размонтирование. Благодаря интеграции со Swordfish API управление хранилищем осуществляется через единый стандартизированный интерфейс. Поддержка NFS позволяет удобно подключать сетевое хранилище к Kubernetes-приложениям. Кроме того, мы реализовали систему логирования и обработки ошибок, что значительно повышает стабильность работы и облегчает отладку.
Для проверки работоспособности решения мы проведены тесты с использованием утилиты csi-sanity, которые подтвердили соответствие CSI-драйвера официальной спецификации. Также развернули полноценное Kubernetes-окружение для демонстрации и отладки, что позволило на практике оценить интеграцию с эмулятором Swordfish. Кроме того, подготовили Docker-образы и скрипты, обеспечивающие быстрое развертывание и запуск системы в тестовой среде.
В планах — еще больше возможностей: добавить динамическое управление доступом (RBAC) для авторизации в СХД, реализовать эту модель прямо в эмуляторе — с полноценной валидацией прав и расширить поддержку новых типов хранилищ в рамках спецификации Swordfish. Кроме того, мы адаптируем CSI-драйвер под разные протоколы подключения и проверим совместимость с реальными СХД от разных вендоров.
С исходным кодом проектов можно ознакомиться по ссылкам: Swordfish Emulator Go и Swordfish CSI.