Rados Gateway (RGW) - это компонент Ceph, который предоставляет S3- и Swift-совместимое API поверх кластера RADOS. Вы получаете объектное хранилище, способное масштабироваться до петабайт без единой точки отказа. Это руководство содержит проверенную последовательность действий: запуск RGW, интеграцию с Kubernetes через Rook, настройку multi-site репликации и управление жизненным циклом объектов. Каждый шаг сопровождается командами и пояснениями, которые помогут избежать типовых ошибок.
Материал ориентирован на DevOps-инженеров и системных администраторов, которые уже работают с кластером Ceph и хотят добавить объектный интерфейс к существующему хранилищу. Если кластер еще не развернут, начните с руководства по построению SDS-кластеров на Ceph и GlusterFS - там детально разобрана архитектура и запуск.
Архитектура Ceph RGW: как это работает
RGW работает как прослойка между клиентскими API и объектным хранилищем RADOS. Демон не хранит данные локально - он транслирует HTTP-запросы в операции с объектами через библиотеку librados. Это означает, что RGW stateless по своей природе: вы можете запустить несколько экземпляров за балансировщиком, и они будут обслуживать запросы параллельно.
Поддерживаются два основных API:
- S3 - совместимость с экосистемой AWS. Позволяет использовать awscli, s3cmd, SDK для Python/Java/Go.
- Swift - совместимость с OpenStack Swift. Востребован в облачных платформах на базе OpenStack.
Встроенные веб-серверы Civetweb и Beast обеспечивают HTTP-фронтенд. Beast - более производительный вариант на C++, который рекомендуется для production-нагрузок. Civetweb остается в кодовой базе для обратной совместимости и легковесных инсталляций.
Модель данных RGW включает три уровня: пользователь (user), бакет (bucket) и объект (object). Пользователь владеет бакетами. Бакет содержит объекты. Метаданные пользователей и бакетов хранятся в специальных пулах, а данные объектов - в пулах данных. Такое разделение критично для понимания производительности: индексные пулы могут стать узким местом при миллионах объектов в одном бакете.
Пошаговая установка и базовая настройка Rados Gateway
Перед запуском убедитесь, что кластер Ceph в состоянии HEALTH_OK. Версия Ceph должна быть не ниже Pacific (16.2.x). Более старые релизы содержат известные проблемы с производительностью индексов, которые исправлены только в Pacific и новее.
Создание пулов и развертывание демона
RGW требует несколько пулов для хранения метаданных, индексов и данных. Создайте их до запуска демона - это предотвратит автоматическое создание пулов с параметрами по умолчанию, которые часто неоптимальны.
ceph osd pool create .rgw.root 32 32
ceph osd pool create default.rgw.control 8 8
ceph osd pool create default.rgw.meta 16 16
ceph osd pool create default.rgw.log 8 8
ceph osd pool create default.rgw.buckets.index 32 32
ceph osd pool create default.rgw.buckets.data 256 256
Количество PG (первое число) зависит от числа OSD в кластере. Для 50 OSD значения выше - разумный старт. Для сотен OSD увеличьте PG в пулах данных до 1024 и выше. Второе число - pgp_num, оно должно совпадать с pg_num. Индексный пул требует особого внимания: при большом количестве бакетов с миллионами объектов именно здесь возникает деградация производительности. Начните с 32 PG и увеличивайте по мере роста.
Запуск демона через cephadm (рекомендуемый способ для Ceph Quincy и Reef):
ceph orch apply rgw myrgw --placement="3" --port=7480
Эта команда развернет три экземпляра RGW на случайных узлах кластера. Порт 7480 - стандартный для RGW. Если используется ceph-deploy (устаревший, но встречающийся), команда выглядит иначе:
ceph-deploy rgw create node1 node2 node3
Проверьте статус демона:
ceph status
# В выводе должна появиться строка rgw с количеством демонов
radosgw-admin bucket list
Пустой список бакетов подтверждает, что демон запущен и подключен к кластеру.
Настройка аутентификации и проверка
Создайте пользователя RGW - это учетная запись, от имени которой клиенты будут выполнять S3-операции:
radosgw-admin user create --uid=admin --display-name="Admin User" --system
Флаг --system дает пользователю права на административные операции, включая управление политиками жизненного цикла и multi-site конфигурацией. Вывод команды содержит access_key и secret_key - сохраните их в безопасном месте.
Проверьте подключение с помощью awscli:
aws configure set aws_access_key_id YOUR_ACCESS_KEY
aws configure set aws_secret_access_key YOUR_SECRET_KEY
aws --endpoint-url http://your-rgw-node:7480 s3 ls
Пустой вывод без ошибок означает, что аутентификация работает. Создайте тестовый бакет:
aws --endpoint-url http://your-rgw-node:7480 s3 mb s3://test-bucket
aws --endpoint-url http://your-rgw-node:7480 s3 ls
Бакет должен появиться в списке. Логи RGW находятся в /var/log/ceph/ceph-client.rgw.*.log - при любых сбоях начинайте диагностику с этого файла.
Интеграция Ceph RGW с Kubernetes через Rook
Rook автоматизирует развертывание и управление Ceph в Kubernetes. Оператор Rook создает поды для MON, OSD, MDS и RGW, отслеживает их состояние и восстанавливает после сбоев. Это устраняет ручные операции по масштабированию и обновлению компонентов хранилища. Если вы ранее настраивали постоянное хранение для stateful-приложений, принцип будет знаком - Rook использует стандартные механизмы Kubernetes, включая CRD и оператор.
Установка Rook и настройка CephCluster
Клонируйте репозиторий Rook и примените базовые манифесты:
git clone --single-branch --branch v1.13.0 https://github.com/rook/rook.git
cd rook/deploy/examples
kubectl create -f crds.yaml -f common.yaml -f operator.yaml
Дождитесь запуска оператора:
kubectl -n rook-ceph get pod
# rook-ceph-operator должен быть в статусе Running
Теперь создайте кластер Ceph с включенным RGW. Файл cluster.yaml требует доработки - добавьте секцию rgw:
apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
name: rook-ceph
namespace: rook-ceph
spec:
cephVersion:
image: quay.io/ceph/ceph:v18.2.0
dataDirHostPath: /var/lib/rook
mon:
count: 3
storage:
useAllNodes: true
useAllDevices: true
rgw:
instances: 2
resources:
limits:
cpu: "2"
memory: "4Gi"
requests:
cpu: "1"
memory: "2Gi"
Примените манифест:
kubectl apply -f cluster.yaml
Ожидание займет несколько минут - Rook последовательно запустит MON, OSD и RGW. Проверьте статус:
kubectl -n rook-ceph get pod -l app=rook-ceph-rgw
# Должны появиться pod'ы rook-ceph-rgw-my-store-a-... и rook-ceph-rgw-my-store-b-...
Создание StorageClass и динамическое предоставление бакетов
Rook поддерживает динамическое создание бакетов через механизм Object Bucket Claims (OBC). Разработчику не нужно знать детали Ceph - он запрашивает бакет через PVC-подобный интерфейс и получает готовые ключи доступа.
Создайте StorageClass:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: rook-ceph-bucket
provisioner: rook-ceph.ceph.rook.io/bucket
reclaimPolicy: Delete
parameters:
objectStoreName: my-store
objectStoreNamespace: rook-ceph
Затем создайте OBC:
apiVersion: objectbucket.io/v1alpha1
kind: ObjectBucketClaim
metadata:
name: my-bucket-claim
spec:
generateBucketName: my-bucket
storageClassName: rook-ceph-bucket
После применения манифеста Rook создаст бакет в Ceph и сгенерирует ConfigMap и Secret с параметрами подключения:
kubectl get secret my-bucket-claim -o yaml
# Содержит BUCKET_HOST, BUCKET_NAME, BUCKET_PORT, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
Подключите секрет к приложению как переменные окружения и используйте любой S3-совместимый клиент для работы с объектами. Это стандартный паттерн, который работает с любым языком и фреймворком. Для более глубокого понимания управления томами в Kubernetes изучите руководство по Infrastructure as Code для Kubernetes.
Настройка многозональной конфигурации для отказоустойчивости
Multi-site конфигурация RGW обеспечивает асинхронную репликацию данных между географически разнесенными кластерами Ceph. При выходе из строя одного дата-центра клиенты переключаются на другой, и данные остаются доступными. Архитектура включает три уровня: realm (область репликации), zonegroup (группа зон) и zone (отдельный кластер).
Создание realm и первичной зоны
На первичном кластере выполните последовательность команд. Realm определяет границы репликации - все зоны внутри одного realm синхронизируют метаданные и данные друг с другом.
radosgw-admin realm create --rgw-realm=myrealm --default
radosgw-admin zonegroup create --rgw-zonegroup=myzg --master --default --rgw-realm=myrealm
radosgw-admin zone create --rgw-zonegroup=myzg --rgw-zone=zone1 --master --default --endpoints=http://rgw1.example.com:7480
radosgw-admin period update --commit
Последняя команда фиксирует конфигурационный период - это снимок топологии, который рассылается всем зонам. Без коммита изменения не вступят в силу.
Перезапустите демон RGW, чтобы он подхватил новую конфигурацию:
systemctl restart ceph-radosgw@rgw.$(hostname)
Добавление вторичной зоны и настройка репликации
Экспортируйте конфигурацию с первичной зоны:
radosgw-admin realm pull --rgw-realm=myrealm --url=http://rgw1.example.com:7480 --access-key=... --secret=...
radosgw-admin period pull --url=http://rgw1.example.com:7480 --access-key=... --secret=...
На вторичном кластере импортируйте конфигурацию и создайте зону:
radosgw-admin realm import < realm.json
radosgw-admin zone create --rgw-zonegroup=myzg --rgw-zone=zone2 --endpoints=http://rgw2.example.com:7480
radosgw-admin period update --commit
Запустите демон синхронизации на вторичной зоне - он отвечает за получение изменений от первичной:
radosgw-admin sync init --rgw-zone=zone2
systemctl restart ceph-radosgw@rgw.$(hostname)
Проверьте статус репликации:
radosgw-admin sync status
# Вывод показывает количество ожидающих шардов и время последней синхронизации
Для тестирования загрузите объект в бакет через первичную зону и проверьте его доступность через вторичную. Задержка репликации обычно составляет секунды при нормальной сетевой связности.
В Kubernetes multi-site настраивается через параметры CephCluster в Rook. Добавьте секцию zones в манифест - оператор автоматически выполнит описанные выше шаги. Это снижает вероятность ошибок при ручном вводе команд.
Управление индексами бакетов и жизненным циклом объектов
Индекс бакета - это структура, которая сопоставляет имена объектов с их расположением в RADOS. Когда в одном бакете накапливаются десятки миллионов объектов, индексный пул становится узким местом: операции LIST занимают секунды, загрузка объектов замедляется. Проблема решается разделением индекса на шарды - логические сегменты, каждый из которых хранит часть записей.
Динамический и ручной resharding индексов
Начиная с Ceph Pacific, доступен автоматический resharding. Включите его в конфигурации:
ceph config set client.rgw rgw_dynamic_resharding true
ceph config set client.rgw rgw_max_objs_per_shard 100000
При превышении порога в 100 000 объектов на шард RGW автоматически разделит его. Это прозрачно для клиентов - операции чтения и записи не прерываются.
Диагностика состояния индексов:
radosgw-admin bucket stats --bucket=my-bucket
# Обратите внимание на num_shards и num_objects
Если автоматический resharding не справляется или отключен, выполните ручное разделение:
radosgw-admin bucket reshard --bucket=my-bucket --num-shards=16
Рекомендация по количеству шардов: для бакета с 10 миллионами объектов используйте 16-32 шарда. Для 100 миллионов - 64-128 шардов. Избыточное количество шардов создает накладные расходы на метаданные, поэтому не увеличивайте число без реальной необходимости.
Настройка политик жизненного цикла
Lifecycle policy автоматически удаляет или перемещает объекты по заданным правилам. Это снижает затраты на хранение и предотвращает бесконтрольный рост данных.
Пример политики в JSON для удаления объектов старше 90 дней:
{
"Rules": [
{
"ID": "expire-old-objects",
"Status": "Enabled",
"Filter": {
"Prefix": "logs/"
},
"Expiration": {
"Days": 90
}
}
]
}
Примените политику через awscli:
aws --endpoint-url http://rgw-node:7480 s3api put-bucket-lifecycle-configuration \
--bucket my-bucket \
--lifecycle-configuration file://lifecycle.json
Проверьте применение:
aws --endpoint-url http://rgw-node:7480 s3api get-bucket-lifecycle-configuration --bucket my-bucket
Политики выполняются асинхронно - объекты удаляются не мгновенно, а при следующем цикле обработки (обычно раз в сутки). Учитывайте это при тестировании.
Если вы управляете большим парком Linux-серверов, где хранилище - лишь часть инфраструктуры, обратитесь к практическому руководству по системному администрированию Linux - там собраны проверенные конфигурации для типовых задач.
Типичные ошибки и их решение
За годы эксплуатации RGW в production-средах накопился набор повторяющихся проблем. Ниже - симптомы, причины и способы исправления. Каждое решение проверено на кластерах от 50 до 500 OSD.
Ошибки аутентификации и доступа
Симптом: клиент получает 403 Forbidden при корректных ключах.
Причина: политика IAM пользователя запрещает операцию, или подпись запроса вычислена с неверным регионом.
Диагностика:
radosgw-admin user info --uid=username
# Проверьте раздел "op_mask" - это битовая маска разрешенных операций
radosgw-admin policy list --uid=username
# Выводит прикрепленные политики
Решение: сбросьте политики до полного доступа для тестирования:
radosgw-admin caps add --uid=username --caps="users=*;buckets=*;metadata=*;usage=*;zone=*"
Если ошибка исчезла, последовательно сужайте права до необходимого минимума.
Проблемы производительности и синхронизации
Симптом: загрузка CPU на узлах RGW достигает 100%, операции LIST выполняются десятки секунд.
Причина: индекс бакета переполнен и требует resharding. Диагностика:
radosgw-admin bucket stats --bucket=slow-bucket
# Если num_objects > 100000 * num_shards - индекс перегружен
Решение: выполните resharding, как описано в предыдущем разделе. После разделения индекса производительность восстанавливается в течение нескольких минут.
Симптом: отставание репликации в multi-site измеряется часами, команда radosgw-admin sync status показывает растущее количество ожидающих шардов.
Причина: сетевая задержка между зонами превышает 100 мс, или пропускная способность канала недостаточна для объема изменений.
Решение: увеличьте количество потоков синхронизации:
ceph config set client.rgw rgw_sync_concurrent_io 32
Проверьте логи синхронизации на наличие таймаутов:
grep "sync" /var/log/ceph/ceph-client.rgw.*.log | tail -50
При стабильно высоком отставании рассмотрите увеличение пропускной способности канала или перенос вторичной зоны ближе к первичной.
Симптом: таймауты при загрузке больших объектов (более 5 ГБ).
Причина: стандартный таймаут Civetweb/Beast (30 секунд) недостаточен для медленных клиентов.
Решение: увеличьте таймаут в конфигурации RGW:
ceph config set client.rgw rgw_http_client_timeout 300
Этот параметр задает максимальное время ожидания в секундах для HTTP-соединений. Значение 300 (5 минут) покрывает большинство сценариев с медленными каналами.
Для комплексной диагностики проблем в Kubernetes-окружении, включая ошибки CRD и зависшие поды, используйте системный алгоритм диагностики Custom Resources - методы отладки применимы и к ресурсам Rook/Ceph.