REST 카탈로그 통합

REST 카탈로그 통합 (REST Catalog Integration)

Hive가 Iceberg REST 카탈로그를 사용하도록 설정하는 방법을 소개하는 문서예요. OAuth2 인증을 거친 Iceberg REST 서버로는 Gravitino(+Keycloak)와 Polaris 두 가지 구성을 다룹니다.

출처: 문서

본문

이 문서는 다음 두 구성을 다룹니다.

  • Hive + Gravitino + Keycloak
  • Hive + Polaris

Hive + Gravitino + Keycloak

이 설정의 코드는 Hive 저장소의 packaging/src/docker/thirdparties/gravitino 폴더에 있어요. Apache Hive, Gravitino Iceberg REST 서버, OAuth2 인증용 Keycloak을 통합한 docker-compose 기반 설정을 담고 있으며, Hive가 Keycloak으로 보호된 Iceberg REST 카탈로그를 사용할 수 있게 합니다.

아키텍처 개요 (Architecture Overview)

                                  oAuth2 (REST API)
         +-------------------------------------------------------------------+
         |                                                                   |
         |                                                                   v
+--------+----------+               +-------------------+            +-----------------+
|                   |  RESTCatalog  |                   |   oauth2   |                 |
|     Hive          |   (REST API)  |      Gravitino    | (REST API) |    Keycloak     |
|  (HiveServer2)    +-------------->|    Iceberg REST   +----------->|  OAuth2 Auth    |
|                   |               |       Server      |            |     Server      |
+--------+----------+               +---------+---------+            +-----------------+
         |                                    |                    
  data   |          metadata files            |                    
  files  +------------------------------------+                    
         |                                                 
         v                                                 
+-------------------+               +-------------------+     
|                   |  creates dir  |                   |     
|     /warehouse    |<--------------+       init        |     
|  (Docker volume)  |     sets      |     container     |     
|                   |  permissions  |                   |     
+-------------------+               +-------------------+
  • Hive: HiveServer2를 실행하고 Iceberg REST 카탈로그를 통해 Gravitino에 연결해요. Iceberg 데이터 파일을 공유 웨어하우스 볼륨에 씁니다.
  • Gravitino: Iceberg 카탈로그용 REST API를 노출해요. Iceberg 메타데이터 파일을 공유 웨어하우스 볼륨(.metadata.json)에 씁니다. OAuth2 제공자 역할을 하지 않으므로, 이 예시는 외부 OAuth2 제공자(Keycloak)를 사용합니다.
  • Keycloak: Hive/Gravitino용 인증과 토큰 발급을 제공하는 OAuth2 서버.
  • /warehouse: Iceberg 테이블 데이터와 메타데이터용 공유 Docker 볼륨.
  • Init container: 공유 /warehouse 폴더를 만들고 파일시스템 권한을 일회성 초기화 단계로 설정.

전제 조건 (Prerequisites)

  • Hive 버전 4.2.0+
  • Docker & Docker Compose
  • Java (로컬 Hive beeline 클라이언트용)
  • Beeline 연결용 $HIVE_HOME 환경 변수 (Hive 설치를 가리키는)

빠른 시작 (Quickstart)

STEP 1: Hive 버전 export

export HIVE_VERSION=4.2.0

STEP 2: 서비스 시작

docker-compose up -d

STEP 3: beeline에 연결

"${HIVE_HOME}/bin/beeline" -u "jdbc:hive2://localhost:10001/default" -n hive -p hive

STEP 4: 서비스 중지:

docker-compose down -v

구성 (Configuration)

Keycloak

  • Realm: hive
  • Client: iceberg-client
  • Secret: iceberg-client-secret
  • Protocol: OpenID Connect
  • Audience: hive-iceberg
  • Keycloak 컨테이너의 realm-export.json으로 import됨.
  • Port: 8080

Gravitino

  • HTTP port: 9001
  • Catalog backend: JDBC H2 (/tmp/gravitino_h2_db)
  • Warehouse: /warehouse (Hive와 공유)
  • Iceberg REST Catalog 백엔드 구성:
# Backend type for the catalog. Here we use JDBC (H2 database) as the metadata store.
gravitino.iceberg-rest.catalog-backend = jdbc

# JDBC connection URI for the H2 database storing catalog metadata.
gravitino.iceberg-rest.uri = jdbc:h2:file:/tmp/gravitino_h2_db;AUTO_SERVER=TRUE

# JDBC driver class used to connect to the metadata database.
gravitino.iceberg-rest.jdbc-driver = org.h2.Driver

# Database username for connecting to the metadata store.
gravitino.iceberg-rest.jdbc-user = sa

# Database password for connecting to the metadata store (empty here).
gravitino.iceberg-rest.jdbc-password = ""

# Whether to initialize the catalog schema on startup.
gravitino.iceberg-rest.jdbc-initialize = true

# --- Warehouse Location (shared folder) ---

# Path to the Iceberg warehouse directory shared with Hive.
gravitino.iceberg-rest.warehouse = file:///warehouse

Keycloak을 가리키는 OAuth2 구성:

# Enables OAuth2 as the authentication mechanism for Gravitino.
gravitino.authenticators = oauth

# URL of the Keycloak realm to request tokens from.
gravitino.authenticator.oauth.serverUri = http://keycloak:8080/realms/hive

# Path to the OAuth2 token endpoint on Keycloak.
gravitino.authenticator.oauth.tokenPath = /protocol/openid-connect/token

# OAuth2 scopes requested when obtaining a token. Includes "openid" and the custom "catalog" scope.
gravitino.authenticator.oauth.scope = openid catalog

# OAuth2 client ID registered in Keycloak.
gravitino.authenticator.oauth.clientId = iceberg-client

# OAuth2 client secret associated with the client ID.
gravitino.authenticator.oauth.clientSecret = iceberg-client-secret

# Java class used to validate incoming JWT tokens using the JWKS endpoint.
gravitino.authenticator.oauth.tokenValidatorClass = org.apache.gravitino.server.authentication.JwksTokenValidator

# URL to fetch JSON Web Key Set (JWKS) for verifying token signatures.
gravitino.authenticator.oauth.jwksUri = http://keycloak:8080/realms/hive/protocol/openid-connect/certs

# Identifier for the OAuth2 provider configuration in Gravitino.
gravitino.authenticator.oauth.provider = default

# JWT claim field(s) to extract as the principal/username (here, 'sub' claim).
gravitino.authenticator.oauth.principalFields = sub

# Acceptable clock skew (in seconds) when validating token expiration times.
gravitino.authenticator.oauth.allowSkewSecs = 60

# Expected audience claim in the token to ensure it is intended for this service.
gravitino.authenticator.oauth.serviceAudience = hive-iceberg

Hive

Iceberg REST 카탈로그(Gravitino) 연결에 HiveRESTCatalogClient를 사용해요. hive-site.xml의 카탈로그 구성:

<property>
  <name>metastore.catalog.default</name>
  <value>ice01</value>
  <description>Sets the default Iceberg catalog for Hive. Here, "ice01" is used.</description>
</property>

<property>
  <name>metastore.client.impl</name>
  <value>org.apache.iceberg.hive.client.HiveRESTCatalogClient</value>
  <description>Specifies the client implementation to use for accessing Iceberg via REST.</description>
</property>

<property>
  <name>iceberg.catalog.ice01.uri</name>
  <value>http://gravitino:9001/iceberg</value>
  <description>URI of the Iceberg REST server (Gravitino). Hive will send catalog requests here.</description>
</property>

<property>
  <name>iceberg.catalog.ice01.type</name>
  <value>rest</value>
  <description>Defines the catalog type as "rest", indicating it uses a REST API backend.</description>
</property>

<!-- Iceberg REST Catalog: OAuth2 authentication -->

<property>
  <name>iceberg.catalog.ice01.rest.auth.type</name>
  <value>oauth2</value>
  <description>Configures Hive to use OAuth2 for authenticating requests to the REST catalog.</description>
</property>

<property>
  <name>iceberg.catalog.ice01.oauth2-server-uri</name>
  <value>http://keycloak:8080/realms/hive/protocol/openid-connect/token</value>
  <description>URL of the Keycloak OAuth2 token endpoint used to request access tokens.</description>
</property>

<property>
  <name>iceberg.catalog.ice01.credential</name>
  <value>iceberg-client:iceberg-client-secret</value>
  <description>Client credentials (ID and secret) used to authenticate with Keycloak.</description>
</property>
  • HiveServer2 port: 10000 (Docker Compose에서 10001로 매핑)

네트워킹 메모 (Networking Notes)

  • 모든 컨테이너는 커스텀 브리지 네트워크 hive-net을 공유해요.
  • 서비스는 컨테이너 이름(hive, gravitino, keycloak)으로 통신합니다.
  • 호스트 접근용 매핑 포트: Keycloak → 8080, Gravitino → 9001, HiveServer2 → 10001

Hive + Polaris

이 설정의 코드는 Hive 저장소의 packaging/src/docker/thirdparties/polaris 폴더에 있어요. Apache Hive와 Polaris를 통합하는 docker-compose 기반 설정이며, Hive가 Polaris가 제공하는 oAuth2로 보호된 Iceberg REST 카탈로그를 사용할 수 있게 합니다.

아키텍처 개요 (Architecture Overview)

+-------------------+               +-------------------+
|                   |  RESTCatalog  |                   |
|     Hive          |   (REST API)  |      Polaris      |<-------+
|  (HiveServer2)    +-------------->|      Server       |        |
|                   |    oAuth2     |                   |        |  
+--------+----------+  (REST API)   +---------+---------+        | creates:
         |                                    |                  |     catalog,
  data   |           metadata files           |                  |     principal,
  files  +------------------------------------+                  |     roles,
         |                                                       |     grants (REST API)
         v                                                       |
+-------------------+               +-------------------+        |
|                   |  creates dir  |                   |        |
|     /warehouse    |<--------------+    Polaris-init   +--------+
|  (Docker volume)  |     syncs     |      container    |
|                   |  permissions  |                   |
+-------------------+               +-------------------+
  • Hive: HiveServer2를 실행하고 Iceberg REST 카탈로그를 통해 Polaris에 연결해요. Iceberg 데이터 파일을 공유 웨어하우스 볼륨에 씁니다.
  • Polaris: Iceberg 카탈로그용 REST API를 노출하고 인증용 oauth2를 제공해요. OAuth2 제공자 역할도 하므로 이 예시는 외부 OAuth2 컴포넌트가 필요 없습니다. Iceberg 메타데이터 파일을 공유 웨어하우스 볼륨(.metadata.json)에 씁니다.
  • /warehouse: Iceberg 테이블 데이터와 메타데이터용 공유 Docker 볼륨.
  • Polaris-init: Hive-Iceberg용 Polaris를 부트스트랩해요. REST API로 Polaris 리소스를 만들고 구성하며, 공유 /warehouse/* 폴더의 파일시스템 권한을 지속적으로 동기화합니다. Polaris와 Hive가 각각의 컨테이너에서 다른 사용자로 실행되기 때문에 필요해요.

전제 조건 (Prerequisites)

  • Hive 버전 4.2.0+
  • Docker & Docker Compose
  • Java (로컬 Hive beeline 클라이언트용)
  • $HIVE_HOME 환경 변수

빠른 시작 (Quickstart)

STEP 1: Hive 버전 export

export HIVE_VERSION=4.2.0

STEP 2: 서비스 시작

docker-compose up -d

STEP 3: beeline에 연결

"${HIVE_HOME}/bin/beeline" -u "jdbc:hive2://localhost:10001/default" -n hive -p hive

STEP 4: 서비스 중지:

docker-compose down -v

구성 (Configuration)

Polaris

  • HTTP port: 8181
  • Warehouse: /warehouse (Hive와 공유)
  • 핵심 Polaris 구성(docker-compose.yml의 env 변수로 정의):
 # A realm provides logical isolation for different Polaris environments.
 polaris.realm-context.realms: POLARIS

 # Initial bootstrap credentials for the Polaris server.
 # The format is: <realm-name>,<client-id>,<client-secret>
 POLARIS_BOOTSTRAP_CREDENTIALS: POLARIS,iceberg-client,iceberg-client-secret

Hive

Iceberg REST 카탈로그(Polaris) 연결에 HiveRESTCatalogClient를 사용해요. hive-site.xml의 카탈로그 구성:

<property>
  <name>metastore.catalog.default</name>
  <value>ice01</value>
  <description>Sets the default Iceberg catalog for Hive. Here, "ice01" is used.</description>
</property>

<property>
  <name>metastore.client.impl</name>
  <value>org.apache.iceberg.hive.client.HiveRESTCatalogClient</value>
  <description>Specifies the client implementation to use for accessing Iceberg via REST.</description>
</property>

<property>
  <name>iceberg.catalog.ice01.uri</name>
  <value>http://polaris:8181/api/catalog</value>
  <description>URI of the Iceberg REST server (Polaris). Hive will send catalog requests here.</description>
</property>

<property>
  <name>iceberg.catalog.ice01.type</name>
  <value>rest</value>
  <description>Defines the catalog type as "rest", indicating it uses a REST API backend.</description>
</property>

<property>
  <name>hive.metastore.warehouse.dir</name>
  <value>file:///warehouse</value>
  <description>Defines the warehouse location, required for Polaris</description>
</property>

<!-- Iceberg REST Catalog: OAuth2 authentication -->

<property>
  <name>iceberg.catalog.ice01.rest.auth.type</name>
  <value>oauth2</value>
  <description>Configures Hive to use OAuth2 for authenticating requests to the REST catalog.</description>
</property>

<property>
  <name>iceberg.catalog.ice01.oauth2-server-uri</name>
  <value>http://polaris:8181/api/catalog/v1/oauth/tokens</value>
  <description>URL of the Polaris OAuth2 token endpoint used to request access tokens.</description>
</property>

<property>
  <name>iceberg.catalog.ice01.credential</name>
  <value>iceberg-client:iceberg-client-secret</value>
  <description>Client credentials (ID and secret) used to authenticate with Keycloak.</description>
</property>

<property>
  <name>iceberg.catalog.ice01.scope</name>
  <value>PRINCIPAL_ROLE:ALL</value>
  <description>oAuth2 scope tied to the principal role defined in Polaris</description>
</property>
  • HiveServer2 port: 10000 (Docker Compose에서 10001로 매핑)

네트워킹 메모 (Networking Notes)

  • 모든 컨테이너는 커스텀 브리지 네트워크 hive-net을 공유해요.
  • 서비스는 컨테이너 이름(hive, polaris)으로 통신합니다.
  • 호스트 접근용 매핑 포트: Polaris → 8181, HiveServer2 → 10001

더 알아보기 (Learn more)

REST 카탈로그는 Hive가 Iceberg 같은 오픈 테이블 포맷의 메타데이터를 원격 서버로부터 가져오는 방식이에요. 구성요소를 컨테이너 이름으로 연결하는 docker-compose 구조를 이해하면, 운영 환경에서도 같은 원리로 OAuth2 보호 REST 카탈로그를 붙일 수 있습니다.