Aller au contenu

Apache Polaris

Aperçu

Apache Polaris 1.3.0 (incubating) sert de catalogue REST Iceberg pour AKKO. Il fournit une gestion centralisée des métadonnées pour toutes les tables Iceberg, avec authentification OAuth2, RBAC et une couche de persistance sauvegardée par PostgreSQL.

Architecture

  Trino ──────┐
              │  API REST + OAuth2
  Spark ──────┼──→  Polaris (:8181)  ──→  PostgreSQL
              │      (Quarkus)            (métadonnées)
  Notebooks ──┘          │
                     object storage (S3)
                    (données des tables)

Polaris est une application Java basée sur Quarkus qui implémente la spécification du catalogue REST Iceberg.

Ports

Port Fonction Exposé
8181 Toutes les API : catalogue Iceberg, gestion, point d'accès OAuth2 Oui (via Traefik)
8182 Vérifications de santé (/q/health) et métriques Prometheus uniquement Interne uniquement

Port API unique

Contrairement à certaines configurations qui séparent les ports catalogue et gestion, Polaris 1.3.0 sert toutes les API (catalogue, gestion, OAuth2) sur le port 8181. Le port 8182 est exclusivement pour la santé et les métriques.

Configuration

polaris/application.properties
# Persistance - backend PostgreSQL
polaris.persistence.type=relational-jdbc

# Valeurs par défaut des E/S fichiers S3/object storage
polaris.catalog.io.default-filesystem=s3

# Désactiver la distribution d'identifiants (object storage ne supporte pas STS AssumeRole)
polaris.features."SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION"=true
polaris.features."ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING"=false

Les détails de connexion PostgreSQL (hôte, port, base de données, identifiants) sont passés via des variables d'environnement dans les valeurs Helm, remplaçant les valeurs par défaut.

Authentification OAuth2

Polaris fournit son propre point d'accès OAuth2. Trino et Spark s'authentifient tous deux avec des identifiants client (le principal root de Polaris).

Point d'accès du jeton

POST http://akko-akko-polaris:8181/api/catalog/v1/oauth/tokens
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&client_id=root
&client_secret={POLARIS_ROOT_SECRET}
&scope=PRINCIPAL_ROLE:ALL

Configuration des clients

Client Identifiant Scope
Trino root:{POLARIS_ROOT_SECRET} PRINCIPAL_ROLE:ALL
Spark Connect root:{POLARIS_ROOT_SECRET} PRINCIPAL_ROLE:ALL

Le scope est obligatoire

Le scope PRINCIPAL_ROLE:ALL doit être spécifié explicitement. Sans cela, le scope par défaut est rejeté par Polaris avec une erreur invalid_scope.

API de gestion

L'API de gestion permet l'administration programmatique des catalogues, principaux et rôles.

Points d'accès principaux

Point d'accès Méthode Fonction
/api/management/v1/catalogs GET, POST Lister/créer des catalogues
/api/management/v1/catalogs/{name} GET, DELETE Obtenir/supprimer un catalogue
/api/management/v1/principals GET, POST Lister/créer des principaux
/api/management/v1/principal-roles GET, POST Lister/créer des rôles de principal
/api/management/v1/catalogs/{name}/catalog-roles GET, POST Lister/créer des rôles de catalogue

Modèle RBAC

Polaris implémente un modèle de rôle à deux niveaux :

  Principal (root)
  Rôle de principal (ALL)
  Rôle de catalogue (akko-warehouse-admin)
       │  Privilège CATALOG_MANAGE_CONTENT
  Catalogue (akko-warehouse)

Séquence de mise en place

Le sidecar polaris-init effectue cette configuration automatiquement à chaque déploiement (helm install/helm upgrade) :

  1. Créer le catalogue akko-warehouse avec la configuration de stockage S3
  2. Créer le rôle de principal ALL
  3. Assigner le rôle de principal ALL au principal root
  4. Créer le rôle de catalogue avec le privilège CATALOG_MANAGE_CONTENT
  5. Assigner le rôle de catalogue au rôle de principal ALL

Ne jamais recréer le catalogue manuellement

Utilisez toujours le job polaris-init pour créer ou recréer le catalogue (en Kubernetes : kubectl delete job akko-polaris-init -n akko && helm upgrade ...). Le script d'initialisation contient le format storageConfigInfo correct, le drapeau stsUnavailable et la configuration RBAC complète. Les commandes curl manuelles se trompent fréquemment sur le format.

Configuration du stockage

Polaris gère les métadonnées des tables Iceberg tandis que les fichiers de données réels résident dans object storage. La configuration de stockage du catalogue doit suivre un format spécifique :

Format correct de storageConfigInfo

{
  "storageType": "S3",
  "allowedLocations": ["s3://akko-warehouse/"],
  "stsUnavailable": true,
  "endpoint": "http://akko-minio:9000",
  "pathStyleAccess": true,
  "region": "us-east-1"
}

Pièges de format

  • Les champs doivent être au niveau supérieur de storageConfigInfo -- PAS imbriqués sous un objet s3.
  • N'utilisez pas de clés en notation pointée comme s3.endpoint -- elles sont silencieusement ignorées.
  • stsUnavailable: true est requis car object storage ne supporte pas AWS STS AssumeRole.
INCORRECT -- n'utilisez pas ces formats
// INCORRECT : objet s3 imbriqué
{ "s3": { "endpoint": "http://minio:9000" } }

// INCORRECT : notation pointée
{ "s3.endpoint": "http://minio:9000" }

Distribution d'identifiants

Polaris utilise normalement AWS STS pour distribuer des identifiants temporaires aux clients (Trino, Spark) pour un accès direct à S3. Comme object storage ne supporte pas STS AssumeRole, cette fonctionnalité est désactivée via deux paramètres :

Paramètre Valeur Fonction
SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION true Ignorer le sous-scopage des identifiants STS
ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING false Désactiver la distribution externe d'identifiants
stsUnavailable (catalogue) true Signaler que STS n'est pas disponible

Les clients (Trino, Spark) utilisent leurs propres identifiants S3 directs (clé d'accès et clé secrète object storage) au lieu de s'appuyer sur les identifiants distribués par Polaris.

Vérification de santé

Le point d'accès de santé est sur le port 8182 (pas 8181) :

GET http://akko-akko-polaris:8182/q/health

C'est un point d'accès de santé Quarkus qui renvoie UP lorsque le service est prêt.

Identifiants d'amorçage

Au premier démarrage avec une base de données vide, Polaris génère des identifiants d'amorçage contrôlés par la variable d'environnement POLARIS_BOOTSTRAP_CREDENTIALS. Ces identifiants sont l'ID client et le secret du principal root.

Premier démarrage uniquement

Les identifiants d'amorçage ne sont appliqués que lorsque la base de données est vide (premier helm install). Si la base de données est recréée, le sidecar d'initialisation doit s'exécuter à nouveau pour rétablir le catalogue et le RBAC.

Problèmes connus

Points d'attention importants

  • Les identifiants d'amorçage persistent : POLARIS_BOOTSTRAP_CREDENTIALS n'est lu qu'au premier démarrage. Le modifier dans .env n'a aucun effet sur une base de données existante.
  • Le catalogue peut disparaître : Après une recréation de base de données, polaris-init peut signaler « déjà existant » mais le catalogue est en réalité absent. Vérifiez toujours via l'API de gestion et recréez si nécessaire.
  • DROP TABLE interdit : Le RBAC de Polaris bloque DROP_TABLE_WITH_PURGE. Utilisez CALL iceberg.system.unregister_table('schema', 'table') depuis Trino à la place.
  • Port du healthcheck : Utilisez /q/health sur le port 8182, pas 8181. Le port 8181 sert uniquement l'API REST.
  • Redémarrer après modification de la config : Après modification de la configuration de Polaris, redéployez avec helm upgrade pour appliquer les changements.