Перейти к содержимому
Последнее обновление

Интеграция с 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 и использует два основных способа доступа к хранилищу данных:

    1. Временные AK/SK, выдаваемые Polaris (механизм Credential Vending)
    2. Прямой доступ 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. Такой подход соответствует рекомендациям по безопасности: принципу минимальных привилегий и разделению обязанностей.

  1. Создайте файл политики доверия

    Создайте файл 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.

  2. Создайте роль 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"
  3. Прикрепите политику разрешений на доступ к S3

    aws iam attach-role-policy \
    --role-name polaris-doris-demo \
    --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
  4. Проверьте результаты создания

    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 вместо использования ключей доступа. Это позволяет избежать жёсткого задания учётных данных в коде и повышает безопасность.

  1. Создайте политику доверия для роли экземпляра EC2

    Сначала создайте файл политики доверия, разрешающей сервису EC2 принимать эту роль:

    cat > ec2-trust-policy.json << 'EOF'
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "Service": "ec2.amazonaws.com"
    },
    "Action": "sts:AssumeRole"
    }
    ]
    }
    EOF
  2. Создайте роль экземпляра 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"
  3. Прикрепите политику разрешений на доступ к S3

    # Attach AmazonS3FullAccess managed policy
    aws iam attach-role-policy \
    --role-name polaris-ec2-role \
    --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
  4. Создайте профиль экземпляра

    # 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
  5. Привяжите профиль экземпляра к экземпляру 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​

  1. Клонируйте репозиторий 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
  2. Задайте учётные данные 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
  3. Соберите и запустите Polaris

    Убедитесь, что установлены Java 21+ и Docker 27+.

    ./gradlew run -Dpolaris.bootstrap.credentials=POLARIS,root,secret
  • POLARIS задаёт realm
  • root задаёт CLIENT_ID
  • secret задаёт CLIENT_SECRET
  • Если учётные данные не заданы, будут использованы предустановленные учётные данные POLARIS,root,s3cr3t

Эта команда запустит сервис Polaris, который по умолчанию прослушивает порт 8181.

2.2 Создание Catalog и Namespace в Polaris​

  1. Экспортируйте учётные данные ROOT

    export CLIENT_ID=root
    export CLIENT_SECRET=secret
  2. Создайте 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.
  3. Создайте Namespace

    ./polaris namespaces create --catalog doris_catalog doris_demo

В результате в Catalog будет создана база данных (Namespace) с именем doris_demo; имя Catalog: doris_catalog.

2.3 Настройка ролей безопасности и разрешений Polaris​

Чтобы Doris мог обращаться к Polaris от имени пользователя, отличного от root, необходимо создать нового пользователя и роль, а также предоставить соответствующие разрешения.

  1. Создайте 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
  2. Предоставьте разрешения роли 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
  3. Свяжите 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
  4. Создайте нового 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