Интеграция с Apache Polaris
По мере развития технологий озёр данных эффективное и безопасное управление огромными объёмами данных в объектном хранилище (например, AWS S3) с предоставлением единой точки доступа для аналитических движков (например, Apache Doris) стало одной из ключевых задач современной архитектуры данных. Apache Polaris, открытый стандартизированный сервис REST Catalog для Iceberg, предлагает решение этой задачи. Он не только обеспечивает централизованное управление метаданными, но и существенно повышает безопасность и управляемость озёр данных благодаря детальному контролю доступа и гибким механизмам управления учётными данными.
В этой статье подробно описано, как интегрировать Apache Doris с Polaris для эффективного выполнения запросов к данным Iceberg в S3 и управления ими. Мы пошагово рассмотрим весь процесс: от подготовки среды до выполнения запросов.
Из этого документа вы узнаете:
-
Подготовка среды AWS: как создать и настроить бакеты S3 в AWS, а также подготовить необходимые роли и политики IAM для Polaris и Doris, чтобы Polaris мог самостоятельно обращаться к S3 и выдавать Doris учётные данные для доступа.
-
Развёртывание и настройка Polaris: как скачать и запустить сервис Polaris на сервере, а также создать в Polaris Iceberg Catalog, Namespace и соответствующие Principal/Role и разрешения, чтобы предоставить Doris защищённые конечные точки доступа к метаданным.
-
Подключение Doris к Polaris: как Doris получает от Polaris токены доступа к метаданным через OAuth2 и использует два основных способа доступа к хранилищу данных:
- Временные AK/SK, выдаваемые Polaris (механизм Credential Vending)
- Прямой доступ Doris к S3 со статическими AK/SK
Требуется Doris версии 3.1+
1. Подготовка среды AWS
Перед началом работы необходимо подготовить бакеты S3 и соответствующие роли IAM в AWS. Они обеспечат основу для управления данными через Polaris и доступа к ним из Doris.
1.1 Создание бакета S3
Сначала создадим бакет S3 с именем polaris-doris-demo для хранения данных таблиц Iceberg, которые будут созданы позже.
# Create S3 storage bucket
aws s3 mb s3://polaris-doris-demo --region us-west-2
# Verify bucket creation success
aws s3 ls | grep polaris-doris-demo
1.2 Создание роли IAM для доступа к объектному хранилищу
Для безопасного управления учётными данными необходимо создать роль IAM, которую Polaris будет использовать через механизм STS AssumeRole. Такой подход соответствует рекомендациям по безопасности: принципу минимальных привилегий и разделению обязанностей.
-
Создайте файл политики доверия
Создайте файл
polaris-trust-policy.json:cat > polaris-trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::YOUR_ACCOUNT_ID:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "polaris-doris-demo"
}
}
}
]
}
EOFПримечание: замените YOUR_ACCOUNT_ID фактическим идентификатором вашего аккаунта AWS. Его можно получить командой
aws sts get-caller-identity --query Account --output text. -
Создайте роль IAM
aws iam create-role \
--role-name polaris-doris-demo \
--assume-role-policy-document file:///path/to/polaris-trust-policy.json \
--description "IAM Role for Polaris to access S3 storage" -
Прикрепите политику разрешений на доступ к S3
aws iam attach-role-policy \
--role-name polaris-doris-demo \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess -
Проверьте результаты создания
aws iam get-role --role-name polaris-doris-demo
aws iam list-attached-role-policies --role-name polaris-doris-demo
1.3 Привязка роли IAM к экземпляру EC2 (необязательно)
Если вы пропустите этот шаг, перед запуском Polaris необходимо задать AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY
Если сервис Polaris будет работать на экземпляре EC2, рекомендуется привязать роль IAM к этому экземпляру EC2 вместо использования ключей доступа. Это позволяет избежать жёсткого задания учётных данных в коде и повышает безопасность.
-
Создайте политику доверия для роли экземпляра EC2
Сначала создайте файл политики доверия, разрешающей сервису EC2 принимать эту роль:
cat > ec2-trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF -
Создайте роль экземпляра EC2
aws iam create-role \
--role-name polaris-ec2-role \
--assume-role-policy-document file:///path/to/ec2-trust-policy.json \
--description "IAM Role for EC2 instance running Polaris service" -
Прикрепите политику разрешений на доступ к S3
# Attach AmazonS3FullAccess managed policy
aws iam attach-role-policy \
--role-name polaris-ec2-role \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess -
Создайте профиль экземпляра
# Create instance profile
aws iam create-instance-profile \
--instance-profile-name polaris-ec2-instance-profile
# Add role to instance profile
aws iam add-role-to-instance-profile \
--instance-profile-name polaris-ec2-instance-profile \
--role-name polaris-ec2-role -
Привяжите профиль экземпляра к экземпляру EC2
# If it's a newly created EC2 instance, specify during launch
aws ec2 run-instances \
--image-id ami-xxxxxxxxx \
--instance-type t3.medium \
--iam-instance-profile Name=polaris-ec2-instance-profile \
--other-parameters...
# If it's an existing EC2 instance, associate instance profile
aws ec2 associate-iam-instance-profile \
--instance-id i-xxxxxxxxx \
--iam-instance-profile Name=polaris-ec2-instance-profile
2. Развёртывание Polaris и создание Catalog
После подготовки среды перейдём к развёртыванию сервиса Polaris и настройке Catalog.
В этом документе используется способ быстрого запуска из исходного кода. Другие варианты развёртывания описаны здесь: https://polaris.apache.org/releases/1.0.1/getting-started/deploying-polaris/
2.1 Клонирование исходного кода и запуск Polaris
-
Клонируйте репозиторий Polaris и переключитесь на нужную версию
git clone https://github.com/apache/polaris.git
cd polaris
# Recommend using a released stable version
git checkout apache-polaris-1.0.1-incubating -
Задайте учётные данные AWS (необязательно)
Если Polaris работает вне EC2 или к экземпляру EC2 не привязана подходящая роль IAM, необходимо через переменные среды предоставить Polaris пару AK/SK с разрешением на принятие роли
polaris-doris-demo.export AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_ACCESS_KEY -
Соберите и запустите Polaris
Убедитесь, что установлены Java 21+ и Docker 27+.
./gradlew run -Dpolaris.bootstrap.credentials=POLARIS,root,secret
POLARISзадаёт realmrootзадаётCLIENT_IDsecretзадаётCLIENT_SECRET- Если учётные данные не заданы, будут использованы предустановленные учётные данные
POLARIS,root,s3cr3t
Эта команда запустит сервис Polaris, который по умолчанию прослушивает порт 8181.
2.2 Создание Catalog и Namespace в Polaris
-
Экспортируйте учётные данные ROOT
export CLIENT_ID=root
export CLIENT_SECRET=secret -
Создайте Catalog, указывающий на хранилище S3
./polaris catalogs create \
--storage-type s3 \
--default-base-location s3://polaris-doris-test/polaris1 \
--role-arn arn:aws:iam::<account_id>:role/polaris-doris-test \
--external-id polaris-doris-test \
doris_catalog--storage-type s3: указывает S3 в качестве хранилища данных.--default-base-location: корневой путь по умолчанию для данных таблиц Iceberg.--role-arn: роль IAM, которую сервис Polaris принимает для доступа к S3.--external-id: внешний идентификатор, используемый при принятии роли; он должен соответствовать настройке в политике доверия роли IAM.
-
Создайте Namespace
./polaris namespaces create --catalog doris_catalog doris_demo
В результате в Catalog будет создана база данных (Namespace) с именем doris_demo; имя Catalog: doris_catalog.
2.3 Настройка ролей безопасности и разрешений Polaris
Чтобы Doris мог обращаться к Polaris от имени пользователя, отличного от root, необходимо создать нового пользователя и роль, а также предоставить соответствующие разрешения.
-
Создайте Principal Role и Catalog Role
# Create a Principal Role for aggregating permissions
./polaris principal-roles create doris_pr_role
# Create a Catalog Role under doris_catalog
./polaris catalog-roles create --catalog doris_catalog doris_catalog_role -
Предоставьте разрешения роли Catalog Role
# Grant doris_catalog_role permission to manage content within this Catalog
./polaris privileges catalog grant \
--catalog doris_catalog \
--catalog-role doris_catalog_role \
CATALOG_MANAGE_CONTENT -
Свяжите Principal Role и Catalog Role
# Assign doris_catalog_role to doris_pr_role
./polaris catalog-roles grant \
--catalog doris_catalog \
--principal-role doris_pr_role \
doris_catalog_role -
Создайте нового Principal (пользователя) и привяжите роль
# Create a new user (Principal) named doris_user
./polaris principals create doris_user
# Example output: {"clientId": "6e155b128dc06c13", "clientSecret": "ce9fbb4cc91c43ff2955f2c6545239d7"}
# Please note down this new client_id and client_secret pair, as Doris will use it for connection.
# Bind doris_user to doris_pr_role
./polaris principal-roles grant \
doris_pr_role \
--principal doris_user
На этом настройка Polaris завершена. Мы создали пользователя doris_user, который получает разрешение на управление doris_catalog через doris_pr_role.
3. Подключение Doris к Polaris
Теперь создадим в Doris Iceberg Catalog, подключённый к только что настроенному сервису Polaris. Doris поддерживает различные сочетания способов аутентификации.
Примечание: в этом примере для подключения к REST-сервису Polaris используются учётные данные OAuth2. Кроме того, Doris поддерживает параметр
iceberg.rest.oauth2.token, позволяющий напрямую передать заранее полученный Bearer Token.
Способ 1: OAuth2 + временные учётные данные хранилища (Credential Vending)
Это наиболее рекомендуемый подход. Doris использует учётные данные OAuth2 для аутентификации в Polaris и получения метаданных. Когда требуется прочитать или записать файлы данных в S3, Doris запрашивает у Polaris временные учётные данные для доступа к S3 с минимальными привилегиями.
Используйте clientId и clientSecret, созданные для doris_user.
CREATE CATALOG polaris_vended PROPERTIES (
'type' = 'iceberg',
-- Catalog name in Polaris
'warehouse' = 'doris_catalog',
'iceberg.catalog.type' = 'rest',
-- Polaris service address
'iceberg.rest.uri' = 'http://YOUR_POLARIS_HOST:8181/api/catalog',
-- Metadata authentication method
'iceberg.rest.security.type' = 'oauth2',
-- Replace with doris_user's client_id:client_secret
'iceberg.rest.oauth2.credential' = 'client_id:client_secret',
'iceberg.rest.oauth2.server-uri' = 'http://YOUR_POLARIS_HOST:8181/api/catalog/v1/oauth/tokens',
'iceberg.rest.oauth2.scope' = 'PRINCIPAL_ROLE:doris_pr_role',
-- Enable credential vending
'iceberg.rest.vended-credentials-enabled' = 'true'
);
Способ 2: OAuth2 + статические учётные данные хранилища (AK/SK)
При таком подходе Doris по-прежнему использует OAuth2 для доступа к метаданным Polaris, но для доступа к данным S3 применяет статические AK/SK, явно заданные в конфигурации Catalog в Doris. Этот способ прост в настройке и подходит для быстрого тестирования, но обеспечивает меньшую безопасность.
CREATE CATALOG polaris_aksk PROPERTIES (
'type' = 'iceberg',
'iceberg.catalog.type' = 'rest',
'iceberg.rest.uri' = 'http://YOUR_POLARIS_HOST:8181/api/catalog',
'iceberg.rest.warehouse' = 'doris_catalog',
'iceberg.rest.security.type' = 'oauth2',
'iceberg.rest.oauth2.credential' = '6e155b128dc06c13:ce9fbb4cc91c43ff2955f2c6545239d7',
'iceberg.rest.oauth2.server-uri' = 'http://YOUR_POLARIS_HOST:8181/api/catalog/v1/oauth/tokens',
'iceberg.rest.oauth2.scope' = 'PRINCIPAL_ROLE:doris_pr_role',
-- Directly provide S3 access keys
's3.access_key' = 'YOUR_S3_ACCESS_KEY',
's3.secret_key' = 'YOUR_S3_SECRET_KEY',
's3.endpoint' = 'https://s3.us-west-2.amazonaws.com',
's3.region' = 'us-west-2'
);
4. Проверка подключения в Doris
Независимо от выбранного способа создания Catalog вы можете проверить работоспособность всей цепочки подключения с помощью следующего SQL.
-- Switch to the Catalog you created and the Namespace configured in Polaris
USE polaris_vended.doris_demo;
-- Create an Iceberg table
CREATE TABLE my_iceberg_table (
id INT,
name STRING
)
PROPERTIES (
'write-format'='parquet'
);
-- Insert data
INSERT INTO my_iceberg_table VALUES (1, 'Doris'), (2, 'Polaris');
-- Query data
SELECT * FROM my_iceberg_table;
-- Expected result:
-- +------+---------+
-- | id | name |
-- +------+---------+
-- | 1 | Doris |
-- | 2 | Polaris |
-- +------+---------+
Если все перечисленные операции выполнены успешно, поздравляем! Вы настроили полную цепочку работы с озером данных: Doris -> Polaris -> S3.
Подробнее об управлении таблицами Iceberg с помощью Doris:
https://doris.apache.org/docs/lakehouse/catalogs/iceberg-catalog