Перейти к содержанию

Тенанты

Страница объясняет, как один кластер S3R обслуживает несколько независимых потребителей — тенантов: как разделены их данные, как запрос относится к тенанту и что настраивается для тенанта и его бакетов — дедупликация и сжатие. Она нужна администратору, который заводит тенантов и выдаёт им адреса и ключи доступа.

Коротко

  • Тенант — отдельное пространство имён со своими таблицами. Оборудование у тенантов общее.
  • Тенанта запроса определяют заголовок Host и ключ доступа. Если они указывают на разных тенантов, запрос отклоняется с ответом 403.
  • Дедупликация и сжатие по умолчанию выключены и действуют только на записи, выполненные после включения.

Как разделены данные тенантов

Один кластер обслуживает несколько тенантов, и каждый тенант представляет собой отдельное пространство имён.

Что хранится Где Как отделено
Объекты, директории, составные загрузки и служебные очереди тенанта Собственные таблицы тенанта: s3r_t<N>_object, s3r_t<N>_dir, s3r_t<N>_mpu и другие, где N — номер тенанта Запрос не может обратиться к объектам другого тенанта, потому что не может назвать его таблицу
Бакеты Глобальная таблица s3r_bucket Идентификатор тенанта входит в ключ строки бакета
Ключи доступа Глобальная таблица s3r_credential Идентификатор тенанта указан в строке ключа доступа

Тенант с номером 0 и именем default служит тенантом по умолчанию. Если в кластере не создано других тенантов, кластер целиком принадлежит ему и всё описанное в остальных разделах руководства относится к нему.

Определение тенанта запроса

Запрос может указывать тенанта двумя способами, и решение принимается по обоим:

  • заголовок Host с FQDN тенанта из s3r_tenant.fqdn указывает тенанта ещё до разбора запроса;
  • ключ доступа указывает тенанта через столбец s3r_credential.tenant_id.

Если запрос указывает тенанта обоими способами, они должны совпадать:

  • тенанты совпадают — запрос относится к этому тенанту;
  • тенанты разные — запрос отклоняется с ответом 403;
  • запрос без обоих признаков относится к тенанту 0.

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

Адресация тенанта

Тенант с заданным domain отвечает по своему FQDN в обеих формах адресации:

Формат пути: FQDN тенанта, бакет и ключ указаны в пути
https://acme.s3.example.net/documents/report.pdf

Виртуально-хостовая адресация: бакет указан меткой перед FQDN тенанта
https://documents.acme.s3.example.net/report.pdf

Точка входа по умолчанию — обращение по IP-адресу или имени узла без FQDN тенанта. Такой запрос обрабатывается как путь, а тенант определяется по ключу доступа; по умолчанию это тенант 0.

Хост, похожий на схему адресов тенантов, но не принадлежащий ни одному из них, отклоняется, а не обслуживается тенантом по умолчанию. Иначе запросы к несуществующему тенанту попадали бы к данным тенанта по умолчанию.

Смежные темы описаны на других страницах:

Дедупликация

При дедупликации объекты с одинаковым содержимым хранят одну общую копию. Совпадения находит индекс дедупликации по сумме SHA-256 содержимого.

По умолчанию дедупликация выключена. Её включают для тенанта или для бакета:

  • SQL-запросом:

    UPDATE s3r_bucket SET dedup = true WHERE tenant_id = 0 AND name = 'archive';
    UPDATE s3r_tenant SET dedup = true WHERE tenant_id = 0;
    
  • для бакета — в консоли, переключателем рядом с переключателем сжатия;

  • для бакета — в API управления: PUT /v2/buckets/{bucket}/deduplication с телом {"dedup": true}.

Пока дедупликация выключена, запись не оставляет никаких следов: ни записи в очереди, ни отпечатка содержимого в индексе дедупликации.

Включение действует только на новые записи

Дедуплицируются записи, начатые после включения. Ранее записанные объекты в индекс не попадают.

Причина в сумме SHA-256: при выключенной дедупликации запись вычисляет её, только если клиент её запросил (см. Контрольные суммы S3). Отсюда следует:

  • запись, которая началась до включения и не запрашивала SHA-256, не дедуплицируется, даже если завершилась после него;
  • то же относится к частям составной загрузки, переданным до включения;
  • копирование объекта в тот же ключ, например для замены метаданных, не переписывает содержимое и не добавляет объект в индекс.

Выключение не разделяет уже объединённое содержимое: записанное при включённом переключателе остаётся общим, но новые объекты к нему не добавляются.

Сжатие

По умолчанию сжатие выключено. Объект сжимается, если включён хотя бы один из трёх переключателей:

Переключатель Как задаётся
Бакета в консоли на странице настроек бакета; запросом API управления PUT /v2/buckets/{bucket}/compression с телом {"compress": true}; средствами SQL
Тенанта только средствами SQL
Яруса полем compress: true в записи яруса параметра s3r_storage.tiers (см. Классы хранения S3 и ярусы)

Переключатель яруса учитывается только при записи объекта операцией PutObject: части составной загрузки и копии объектов он не сжимает.

UPDATE s3r_bucket SET compress = true WHERE tenant_id = 0 AND name = 'archive';
UPDATE s3r_tenant SET compress = true, compress_level = 6 WHERE tenant_id = 0;

Включение действует только на новые записи

Переключатели действуют на записи, выполненные после их включения. Уже записанные объекты не перезаписываются.

Алгоритм и уровень

Применяется алгоритм zstd. Уровень сжатия задаётся для тенанта столбцом s3r_tenant.compress_level и действует для любого задействованного переключателя. Значение NULL означает уровень 3. Значение вне допустимого для zstd диапазона заменяется ближайшей границей диапазона.

Что и как сжимается

  • Содержимое объекта сжимается участками по 1 МиБ до разбиения на полосы. Поэтому сжимаются объекты как с избыточным кодированием, так и с репликацией.
  • Участок, который после сжатия занимает больше 0,9 исходного размера, хранится без сжатия.
  • Чтение диапазона распаковывает только затронутые участки, но каждый из них целиком: запрос даже одного байта распаковывает до 1 МиБ.
  • Объекты со способом хранения inline не сжимаются.

Перенос между ярусами и дедупликация

Перенос объекта в другой ярус правилом жизненного цикла сохраняет его форму: несжатый объект не сжимается и в ярусе с включённым сжатием. Если перенос выполняется на том же инстансе, сжатый объект сжимается заново с уровнем 3, а не с уровнем тенанта.

Общее содержимое при дедупликации хранится в той форме, в которой была записана его первая копия.

Нагрузка и наблюдение

Сжатие и распаковку выполняют рабочие потоки плагина (среды выполнения Tokio), которые обслуживают запрос (см. Процессорные ядра).

  • Степень сжатия показывает метрика s3r_compression_bytes_total как отношение значения с меткой direction="stored" к значению с меткой direction="logical".
  • Ответ HeadObject на запрос всего объекта содержит заголовки x-s3r-codec с алгоритмом и x-s3r-stored-bytes с хранимым объёмом.
  • Квоты учитывают объём объекта до сжатия.

Ролевая модель тенантов

Миграции создают три роли. Субъект доступа S3 соответствует пользователю SQL Picodata, поэтому ролевая модель использует роли Picodata, а не отдельную таблицу плагина.

Роль Что даёт
s3r_superuser полные полномочия над плагином в кластере и доступ SQL ко всем таблицам плагина
s3r_observer только чтение состояния кластера
s3r_tenant_admin_<идентификатор> управление пользователями, ключами и бакетами одного тенанта

Роль выдаётся обычным оператором SQL. Оба имени берутся в кавычки, иначе они приводятся к нижнему регистру:

GRANT "s3r_superuser" TO "ivanov";

Роли не наследуют друг друга: если пользователю нужны полномочия двух видов, ему выдают две роли.

s3r_superuser

Полные полномочия над плагином в кластере:

  • ярусы и уровни избыточности;
  • режим обслуживания;
  • тенанты и их сертификаты;
  • доступ SQL ко всем таблицам плагина.

Это единственная роль с правом чтения s3r_tenant, поскольку она же записывает в таблицу сертификаты. Её обладатель создаёт тенантов и их сертификаты, а также получает список тенантов и сведения об их ёмкости с помощью SQL.

s3r_observer

Только чтение: ёмкость, состояние кластера и дисков, группы размещения, восстановление, проверка целостности. Роль предназначена тому, кто наблюдает за кластером и ничего в нём не меняет; без неё такому человеку пришлось бы выдать полномочия администратора.

Секреты наблюдателю недоступны: s3r_credential хранит секретные ключи, s3r_tenant хранит закрытые ключи TLS, и обе таблицы выданы только s3r_superuser.

s3r_tenant_admin_<идентификатор>

Управление пользователями, ключами и бакетами одного тенанта, идентификатор которого указан в имени роли. Такая роль создаётся для каждого тенанта.

Свойство Объяснение
Отдельная роль на тенанта полномочие нельзя выразить табличным разрешением: s3r_credential является глобальной таблицей, а разрешение SQL нельзя сузить до строк одного тенанта. Область действия задаёт выдача роли
В имени идентификатор, а не имя тенанта идентификатор не переиспользуется после удаления тенанта, поэтому выданная роль никогда не станет означать другого тенанта, и переименование тенанта её не ломает
Чужой тенант отвечает «не найдено», а не «запрещено» ответ «запрещено» подтвердил бы, что такой тенант существует
Пароль для входа по SQL администратор тенанта его не задаёт: это может только s3r_superuser, см. Пароль для входа по SQL
CREATE USER полномочие уровня кластера, которое нельзя сузить до тенанта. Поэтому администратор тенанта не получает его напрямую: пользователя Picodata создаёт плагин

Операции предоставляет API управления. Он принимает токен доступа OIDC и тенанта в самом запросе, поэтому именно выданная роль определяет, к какому тенанту обращение допустимо.

Запросы администратора тенанта

Запрос Действие
GET /v2/users?tenant_id=<id> перечислить пользователей тенанта и их ключи (без секретов)
POST /v2/users зарегистрировать пользователя
PUT /v2/users?tenant_id=<id> заблокировать или разблокировать пользователей (state)
DELETE /v2/users?tenant_id=<id> удалить пользователей
POST /v2/credentials?tenant_id=<id> выдать ключ доступа
PUT /v2/credentials/<ключ>?tenant_id=<id> заменить секрет, сохранив ключ
DELETE /v2/credentials/<ключ>?tenant_id=<id> удалить ключ
PUT /v2/buckets с именем бакета и именем нового владельца передать бакет другому владельцу; в консоли это действие «передать»

Правила:

  • Секретный ключ. Ответ на создание или замену ключа содержит секретный ключ доступа только один раз. Больше его не возвращает ни один запрос.
  • Блокировка действует на пользователя, а не на отдельный ключ: все ключи пользователя переходят в состояние «отключён» вместе. Операция обратима: ключи остаются, и разблокировка возвращает прежнее состояние.
  • Передача бакета. Новый владелец должен быть субъектом доступа того же тенанта. Прежний владелец не сохраняет никаких прав на бакет. В ответе назван тот, кто потерял владение; больше нигде прежний владелец не записан.

См. также