Всем привет. Меня зовут Виктор Панин, я Project Manager команды Deckhouse Storage в компании «Флант». В этой статье я поделюсь своим взглядом, возможно, отличным от мнения команды, на использование S3 в Kubernetes и расскажу, почему я считаю это крутым.
Когда речь заходит о хранении данных, объектные хранилища вроде S3 кажутся чем-то из параллельной вселенной по сравнению с традиционными файловыми системами. Они масштабируемы, долговечны и доступны через интернет, но при этом лишены привычных атрибутов. Например, в традиционных файловых системах права доступа управляются на уровне файлов, но в S3 доступ контролируется через IAM-политики и политики корзин, которые применяются на уровне бакетов и требуют дополнительной настройки. А символические ссылки отсутствуют — вместо них приходится дублировать объекты или использовать метаданные, что усложняет управление и организацию данных.

А теперь представьте: эти облачные гиганты проникают в мир контейнеров Kubernetes, становясь частью экосистемы, где всё крутится вокруг скорости, автоматизации и гибкости. При этом S3 обладают сравнительно высокой задержкой доступа, из-за чего они больше подходят для хранения статических данных и бэкапов, а не для часто изменяющихся файлов (в S3 нет нативной поддержки частичных обновлений, поэтому в большинстве реализаций для изменения объекта нужно его скачать, изменить и затем весь снова загрузить). Это не хорошо для задач, где требуются быстрая реакция и частые обновления.
Разберёмся, как S3 превращается в тома для контейнеров с помощью Deckhouse, почему это странно, но всё-таки может пригодиться, а также какие подводные камни ждут на пути.
Зачем нужна интеграция S3 с K8s
S3 (Simple Storage Service) появился в 2006 году как облачное хранилище для всего подряд: от резервных копий до статических сайтов. Его главная фишка — простота и надёжность. Вместо сложной структуры папок и файлов вы работаете с объектами, которые хранятся в бакетах и доступны по ключам.
Но что делать, если нужно использовать S3 не просто как удалённый склад, а как полноценное хранилище для приложений в Kubernetes? Например, для приложений с большим объёмом логов, когда локальные диски быстро заполняются и необходимо подключить облачное хранилище. При этом стандартные тома (Persistent Volumes) Kubernetes заточены под блочные или файловые системы, а не под объектные хранилища.
Для этого мы решили внедрить поддержку S3 в Kubernetes: интегрировали в наши Kubernetes-решения Deckhouse (DKP и DVP; далее — просто Deckhouse) файловую систему GeeseFS через CSI. Теперь мы можем примонтировать S3-бакет к контейнеру с помощью модуля csi-s3 в виде папки. Таким образом, S3-бакет превращается в полноценный том Kubernetes, который можно монтировать к контейнерам и использовать как обычную файловую систему. Посмотрим, что из этого вышло, но для начала немного о GeeseFS.
Почему мы выбрали именно GeeseFS
Во-первых, потому что у GeeseFS много интересного. Ниже в таблице приведено сравнение популярных файловых систем, которые позволяют монтировать объектные хранилища как обычные файловые системы, по их возможностям:
Возможности | GeeseFS | rclone | Goofys | S3FS | gcsfuse |
Read after write | + | + | – | + | + |
Partial writes | + | + | – | + | + |
Truncate | + | – | – | + | + |
fallocate | + | – | – | – | – |
chmod/chown | Y | – | – | + | – |
fsync | + | – | – | + | + |
Symlinks | Y | – | – | + | + |
Socket files | Y | – | – | + | – |
Device files | Y | – | – | – | – |
Custom mtime | Y | + | – | + | + |
xattr | + | – | + | + | – |
Directory renames | + | + | * | + | + |
readdir & changes | + | + | – | + | + |
* Переименование каталогов разрешено в Goofys для каталогов, содержащих не более 1000 записей, и это ограничение жёстко задано.
GeeseFS — самая функциональная из всех представленных систем. Она поддерживает практически все ключевые функции, включая работу с символьными и специальными файлами, расширенными атрибутами, частичными записями и корректной работой с метаданными. А некоторые возможности (например, работа с режимами файлов и спецфайлами), отмеченные в таблице как «Y», полностью реализованы только при использовании Yandex S3.
Остальные решения либо поддерживают только базовые операции, либо имеют ограничения, которые могут стать критичными для сложных приложений. Получается, GeeseFS — наиболее подходящий выбор.
Во-вторых, GeeseFS рвёт всех по перфомансу:
GeeseFS | rclone | Goofys | S3FS | gcsfuse | |
Parallel readahead | + | – | + | + | – |
Parallel multipart uploads | + | – | + | + | – |
No readahead on random read | + | – | + | – | + |
Server-side copy on append | + | – | – | * | + |
Server-side copy on update | + | – | – | * | – |
Partial object updates | +** | – | – | – | – |
xattrs without extra RTT | +*** | – | – | – | + |
Dir preload on file lookup | + | – | – | – | – |
Fast recursive listings | + | – | **** | – | + |
Asynchronous write | + | + | – | – | – |
Asynchronous delete | + | – | – | – | – |
Asynchronous rename | + | – | – | – | – |
Disk cache for reads | + | ***** | – | + | + |
Disk cache for writes | + | ***** | – | + | – |
* S3FS использует копирование на стороне сервера (server-side copy), но всё равно скачивает весь файл для его обновления. И тоже делает это с ошибками.
** Частичные обновления объектов (PATCH) работают только с Yandex S3.
*** Расширенные атрибуты (xattrs) без дополнительных задержек на передачу и приём данных (RTT) работают только с Yandex S3 (--list-type=ext-v1).
**** Оптимизация рекурсивного листинга в Goofys работает с ошибками и может пропускать файлы при определённых условиях.
**** У rclone mount есть VFS-кэш, но кэшируются только файлы целиком. Она также работает с ошибками — часто зависает при записи.
Как видим, GeeseFS и тут является наиболее продвинутым и производительным решением среди рассмотренных, специально оптимизированным для работы с S3-совместимыми хранилищами.
Все тесты проводил Yandex Cloud. По ссылке можно увидеть больше информации о GeeseFS.
К тому же коллеги из Yandex провели xfstests: GeeseFS достаточно стабилен, чтобы пройти большинство применимых тестов из набора xfstests, включая стресс-тесты dirstress и fsstress (generic/007, generic/011, generic/013).
Звучит как магия? Давайте разберём, как это работает.
Как S3 становится томом
GeeseFS — это своего рода переводчик между миром объектных хранилищ и файловыми операциями. Система берёт данные из S3 и представляет их так, будто это обычная папка на диске. Например, вы создаёте PersistentVolumeClaim
в Kubernetes, а Deckhouse автоматически подключает к нему S3-бакет. Хотите записать файл? GeeseFS отправляет его в S3 как объект. Нужно прочитать? Она вытягивает данные из облака и кладёт в кэш, чтобы всё работало быстрее.
Deckhouse упрощает этот процесс через модуль csi-s3. Всего-то нужно задать параметры: имя бакета, эндпойнт, ключи доступа и размер кэша, — а платформа сама регистрирует CSI-драйвер и запускает нужные сервисы. Пример конфигурации:
apiVersion: csi.s3.storage.k8s.io/v1
kind: S3StorageClass
metadata:
name: example-s3
spec:
bucketName: example-bucket
endpoint: https://s3.example.com
region: us-east-1
accessKey: <your-access-key>
secretKey: <your-secret-key>
maxCacheSize: 500 # Размер кэша монтировщика в мегабайтах.
insecure: false
В итоге мы получаем том, который выглядит как локальный диск, но на деле хранит данные где-то в облаке — будь то AWS, Яндекс S3 или любой другой совместимый сервис.
Подробнее о том, как в Deckhouse использовать объектное хранилище на базе S3 в Kubernetes, читайте в документации.
Что это даёт на практике
Представим приложение, которое генерирует тонны логов или обрабатывает большие датасеты. Локальные диски на узлах кластера быстро заполняются, а покупка дорогих блочных хранилищ вроде EBS бьёт по бюджету. С S3 можно просто подключить облачное хранилище, которое масштабируется почти бесконечно и стоит дешевле. Плюс ко всему данные остаются доступными даже при сбоях в кластере — они ведь «живут» в облаке.
Например, в стресс-тесте Deckhouse запустили 600 подов на семи узлах. Каждый под записывал 300 МБ данных в S3, читал их и завершал работу. Кэш GeeseFS был настроен на 500 МБ, и система справилась без сбоев.
В чём подвох
И вроде бы всё хорошо, но есть нюанс. Дело в том, что объектное хранилище не предназначено для работы в качестве файловой системы. Вот несколько «но», которые стоит учитывать:
Отсутствие привычных атрибутов. S3 не поддерживает привычные атрибуты вроде прав доступа, символических ссылок или пользовательских меток времени (
mtime
,ctime
). Время модификации файла всегда одинаково, а изменить его вручную нельзя. Для большинства приложений это не проблема, но если ваше ПО требует сложных операций с метаданными, могут возникнуть сложности.Нет блокировки файлов. Если два процесса одновременно пишут в один файл, S3 не спасёт от конфликтов. Это ограничение объектных хранилищ, и GeeseFS с ним ничего не сделает.
Размер имеет значение. По умолчанию GeeseFS делит большие файлы на части при передаче, и лимит на файл составляет 1,03 ТБ.
Кэш и производительность. GeeseFS использует локальный кэш для ускорения работы, но если он переполнится или узел упадёт, данные придётся снова тянуть из S3. Это может замедлить операции, особенно при плохой сети.
Странности с диагностикой. Например, если вы укажете неверные ключи доступа, поды в Kubernetes перейдут в состояние
Running
, а тома — вBound
. Но как только приложение попытается что-то записать, под перезапустится или подвиснет. Или вот ещё: командаdf -h
покажет, что у вас 1 ПБ свободного места, хотя реальный объём зависит от S3-бакета.Проигрыш в скорости. Несмотря на то, что GeeseFS — самая быстрая «черепаха» среди других решений, это всё-таки «черепаха»: из-за использования FUSE и HTTP-протокола задержки (latency) остаются высокими. В самом readme проекта разработчики пишут, что это хорошая производительность как для маленьких, так и для больших файлов.
В итоге не рекомендуем использовать csi-s3 для хранения регулярно и много изменяющихся файлов, например для файлов баз данных.
Почему это всё равно может быть нужно
Несмотря на ограничения, связка S3 и Kubernetes через Deckhouse вполне может быть полезна для stateful-приложений (например, legacy, которым не требуется активная запись на диск) и бэкапов, а также для интеграции с другими системами, которые используют объектные хранилища. Вы получаете простое и масштабируемое хранилище, которое не привязано к физическим дискам кластера.
Если хотите попробовать S3 в Kubernetes — не стоит попробуйте. Это не просто техническая интеграция, а пример того, как облачные технологии сливаются с контейнерами, создавая гибридные системы нового уровня. Ограничения есть, но это плата за масштабируемость и простоту.
P. S.
Читайте также в нашем блоге: