生产环境配置

配置 Azure Blob 云存储

师成师成· 更新于 2026-09-29· 阅读 14 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

配置 Azure Blob 云存储

本页介绍如何将 Azure Blob Storage 和 Azure Data Lake Storage Gen2 (ADLS Gen2) 配置为 Polaris 目录的存储后端。Polaris 使用具有目标存储账户数据平面访问权限的服务主体(service principal)的凭据对 Azure 进行身份验证,并在每次表加载请求时向客户端签发短期 SAS 令牌。

服务主体与 Polaris 凭据

Polaris 使用 Azure SDK 的 DefaultAzureCredential 凭据链,默认情况下会从环境变量中读取服务主体凭据。请创建一个对存储账户具有数据访问权限的服务主体,并将其凭据传递给 Polaris 进程:

# Replace <subscription>, <resource-group>, <storage-account> with your values.
az ad sp create-for-rbac \
  --name polaris-storage \
  --role "Storage Blob Data Contributor" \
  --scopes "/subscriptions/<subscription>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>"

该命令会打印出 appId、password 和 tenant。请在 Polaris 服务端设置这些值:

export AZURE_TENANT_ID=<tenant>
export AZURE_CLIENT_ID=<appId>
export AZURE_CLIENT_SECRET=<password>

在 Kubernetes 部署中,不要以明文形式将 AZURE_CLIENT_SECRET 写入 Pod 规范。应将客户端密钥存放在 Kubernetes Secret(或由 Azure Key Vault 提供程序等 Operator 引用的外部密钥存储)中,并通过 envFrom/valueFrom: secretKeyRef 将其注入 Polaris 容器。POLARIS_BOOTSTRAP_CREDENTIALS 中的引导凭据也同理。

在存储帐户范围内授予 Storage Blob Data Contributor 角色后,Polaris 可以为该帐户下的任意容器签发 SAS 令牌;如果想将单个 Polaris 目录限制在一个容器内,应将该角色的作用域收窄(仅限单个容器)。

存储帐户要求

支撑目录的存储帐户应进行如下配置:

  • 分层命名空间(HNS) 并非 Polaris 或 Iceberg 执行表操作本身的硬性要求。它的主要作用在于决定 Polaris 能将签发的 SAS 令牌的作用域收窄到何种程度:启用 HNS 后,Polaris 可以将令牌的作用域收缩到支撑所请求命名空间或表的目录(文件夹);未启用 HNS 时,令牌只能限定在容器级别。需要按命名空间隔离的生产部署应启用 HNS。
  • storageConfigInfo 中的 hierarchical 字段必须与存储帐户的实际状态一致。若两者不匹配,签发的令牌会依据存储端并不存在的目录 ACL 进行作用域限定,从而导致运行时访问错误。
  • 一个用于存放目录中各命名空间和表的容器(例如 warehouse)。Polaris 不会自行创建该容器。
  • 防火墙规则需放行来自 Polaris 控制平面以及将要读取数据的引擎的流量。SAS 令牌无法绕过存储帐户防火墙。

目录存储配置

在服务器上准备好服务主体后,使用存储帐户的租户 ID 和 abfss:// 位置创建目录:

curl -X POST https://<polaris-host>/management/v1/catalogs \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "catalog": {
          "type": "INTERNAL",
          "name": "warehouse_azure",
          "properties": {
            "default-base-location": "abfss://warehouse@example.dfs.core.windows.net/prod/"
          },
          "storageConfigInfo": {
            "storageType": "AZURE",
            "tenantId": "00000000-0000-0000-0000-000000000000",
            "hierarchical": true,
            "allowedLocations": [
              "abfss://warehouse@example.dfs.core.windows.net/"
            ]
          }
        }
      }'

default-base-location 必须使用 abfss:// 协议,并配合 ADLS Gen2 端点(<account>.dfs.core.windows.net)使用。不支持 wasbs:// 协议。

AzureStorageConfigurationInfo 还接受 multiTenantAppName 和 consentUrl 两个字段。当前 Apache Polaris 代码在与 Azure API 通信时并不使用这些字段;它们仅作为参考信息,按照上文使用服务主体进行身份验证的自托管部署可以省略。

SAS 令牌的作用域与 HNS ACL

启用 HNS(hierarchical: true)时,Polaris 会将每个签发的 SAS 令牌的作用域缩小到支撑所请求命名空间或表的目录。该目录上的 ADLS Gen2 ACL 必须包含服务主体,以及任何需要通过签发凭据之外的方式读取数据的额外主体。

一种常见的故障模式是:令牌授予了对象级别的权限,却被目录级别的 ACL 拒绝。ADLS 返回的 403 错误中包含被拒绝的路径;将该精确前缀上的 ACL 调整一致即可恢复。

未启用 HNS 时,请设置 hierarchical: false。此时 Polaris 会签发作用域为存储容器级别(而非按目录)的 SAS 令牌;这种做法适用于小型部署,但无法限制跨命名空间访问。

客户端配置

各引擎通过 Iceberg REST API 调用 Polaris,并在加载表时接收 SAS 令牌属性;客户端无需配置静态 Azure 凭据。

以下为 Spark 示例,其属性名称与现有 MinIO / RustFS 指南中使用的保持一致:

bin/spark-sql \
    --packages org.apache.iceberg:iceberg-spark-runtime-3.5_2.12:1.10.1,org.apache.iceberg:iceberg-azure-bundle:1.10.1 \
    --conf spark.sql.extensions=org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions \
    --conf spark.sql.catalog.polaris=org.apache.iceberg.spark.SparkCatalog \
    --conf spark.sql.catalog.polaris.type=rest \
    --conf spark.sql.catalog.polaris.uri=https://<polaris-host>/api/catalog \
    --conf spark.sql.catalog.polaris.oauth2-server-uri=https://<polaris-host>/api/catalog/v1/oauth/tokens \
    --conf spark.sql.catalog.polaris.token-refresh-enabled=false \
    --conf spark.sql.catalog.polaris.warehouse=warehouse_azure \
    --conf spark.sql.catalog.polaris.scope=PRINCIPAL_ROLE:ALL \
    --conf spark.sql.catalog.polaris.credential=<client-id>:<client-secret> \
    --conf spark.sql.catalog.polaris.header.X-Iceberg-Access-Delegation=vended-credentials \
    --conf spark.sql.catalog.polaris.io-impl=org.apache.iceberg.azure.adlsv2.ADLSFileIO

推荐配置 oauth2-server-uri:若不配置,Iceberg REST 客户端会回退到硬编码的 /v1/oauth/tokens 路径,并记录一条弃用警告,因为这种自动回退行为计划在未来某个 Iceberg 版本中移除。

Spark 应用必须在 classpath 中包含 Iceberg Azure bundle(或 iceberg-azure 以及相应的 Hadoop / Azure jar);Polaris 不会将这些 jar 分发给计算引擎。

对于 Trino,请使用 Iceberg 连接器配合 REST catalog,其配置形式与同级页面上的 AWS S3 示例相同:

connector.name=iceberg
iceberg.catalog.type=rest
iceberg.rest-catalog.uri=https://<polaris-host>/api/catalog
iceberg.rest-catalog.warehouse=warehouse_azure
iceberg.rest-catalog.security=OAUTH2
iceberg.rest-catalog.oauth2.credential=<client-id>:<client-secret>
iceberg.rest-catalog.oauth2.scope=PRINCIPAL_ROLE:ALL
iceberg.rest-catalog.oauth2.server-uri=https://<polaris-host>/api/catalog/v1/oauth/tokens

对于 PyIceberg,使用 rest 目录类型,并将凭证分发请求头作为 REST 请求头转发:

from pyiceberg.catalog.rest import RestCatalog

cat = RestCatalog(
    name="polaris",
    **{
        "uri": "https://<polaris-host>/api/catalog",
        "warehouse": "warehouse_azure",
        "credential": "<client-id>:<client-secret>",
        "scope": "PRINCIPAL_ROLE:ALL",
        "oauth2-server-uri": "https://<polaris-host>/api/catalog/v1/oauth/tokens",
        "header.X-Iceberg-Access-Delegation": "vended-credentials",
    },
)

Polaris 会在加载表时向 FileIO 按账号发放 SAS 令牌。这些凭据以 adls.sas-token.<storage-account> 形式的键名返回(在需要限定作用域时,可附带 dfs.core.windows.net / blob.core.windows.net 后缀),具体定义见 StorageAccessProperty。PyIceberg 客户端可直接获取这些凭据,无需配置任何静态账户密钥或 SAS 令牌。

验证配置

CREATE NAMESPACE warehouse_azure.demo;
CREATE TABLE warehouse_azure.demo.t (id BIGINT, name STRING) USING iceberg;
INSERT INTO warehouse_azure.demo.t VALUES (1, 'hello');
SELECT * FROM warehouse_azure.demo.t;

如果任何操作失败:

  • 来自 Azure AD(AADSTS*)的错误通常表示 AZURE_CLIENT_ID / AZURE_CLIENT_SECRET / AZURE_TENANT_ID 中的服务主体凭据有误、密钥已过期,或该主体在存储账户上没有角色分配。
  • Failed to get subscoped credentials 伴随 Status code 403 和 AuthorizationPermissionMismatch 的 Azure 错误响应体,意味着服务主体在覆盖所访问路径的范围内没有数据平面角色(Storage Blob Data Contributor 或等效角色)。在存储账户(或特定容器)上授予该角色并等待 RBAC 生效即可解决。
  • 来自 dfs.core.windows.net 路径的 403 且没有 Azure 错误码,通常说明在启用 HNS 并且目录上设置了较严格 ACL 的情况下,基本位置上的 HNS ACL 不匹配。
  • 容器级别操作返回 404 表明容器尚不存在;Polaris 不会创建容器,只会创建其下的目录和 Blob。

评论

登录后参与评论

正在加载评论…