Databricks通过Service Principal写入Azure存储账户配置报错排查
问题根因
报错来自三个核心配置错误:
- 你配置的OAuth认证参数是ABFS(Azure Blob File System,Databricks官方推荐的新一代存储访问驱动)专属配置,但写入路径用的是老版WASB驱动的
wasbs://前缀,WASB驱动不会读取这组OAuth参数,直接回退到匿名访问,才会提示找不到有效凭据。 - 你写的Spark配置是全局无存储账户绑定的格式,部分Databricks运行时版本无法将全局配置匹配到对应存储账户的认证逻辑,直接判定为无有效凭据。
- 你给服务主体分配的「存储账户参与者」是Azure资源管理平面权限,仅支持修改存储账户配置、删除账户这类管理操作,不具备存储容器内数据的读写权限,就算认证通过也会触发权限拒绝。
正确配置方案
优先选方案1,ABFS驱动的性能、兼容性都优于老版WASB,是Databricks官方当前推荐的访问方式。
方案1:使用ABFS驱动(兼容ADLS Gen2、普通块Blob存储)
注意ABFS驱动对应的存储端点是dfs.core.windows.net,路径前缀用abfss://,所有配置项绑定到具体存储账户,避免匹配失败:
# 替换成实际的参数值 tenant_id = "你的Azure租户ID" client_id = "服务主体客户端ID" client_secret = "服务主体客户端密钥" storage_account_name = "MyStorageAccount" container_name = "MyContainer" # 所有配置绑定到目标存储账户 spark.conf.set(f"fs.azure.account.auth.type.{storage_account_name}.dfs.core.windows.net", "OAuth") spark.conf.set(f"fs.azure.account.oauth.provider.type.{storage_account_name}.dfs.core.windows.net", "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider") spark.conf.set(f"fs.azure.account.oauth2.client.id.{storage_account_name}.dfs.core.windows.net", client_id) spark.conf.set(f"fs.azure.account.oauth2.client.secret.{storage_account_name}.dfs.core.windows.net", client_secret) spark.conf.set(f"fs.azure.account.oauth2.client.endpoint.{storage_account_name}.dfs.core.windows.net", f"https://login.microsoftonline.com/{tenant_id}/oauth2/token") # 测试写入 df = spark.createDataFrame([(1, "foo")],["id", "label"]) df.write.format("delta").save(f"abfss://{container_name}@{storage_account_name}.dfs.core.windows.net/HERE")
方案2:兼容老逻辑使用WASB驱动
如果因为历史代码兼容必须用wasbs://前缀,需要将配置绑定到WASB对应的blob.core.windows.net端点,不要直接复用ABFS的全局配置:
# 替换成实际的参数值 tenant_id = "你的Azure租户ID" client_id = "服务主体客户端ID" client_secret = "服务主体客户端密钥" storage_account_name = "MyStorageAccount" container_name = "MyContainer" # 配置绑定到WASB对应的Blob端点 spark.conf.set(f"fs.azure.account.auth.type.{storage_account_name}.blob.core.windows.net", "OAuth") spark.conf.set(f"fs.azure.account.oauth.provider.type.{storage_account_name}.blob.core.windows.net", "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider") spark.conf.set(f"fs.azure.account.oauth2.client.id.{storage_account_name}.blob.core.windows.net", client_id) spark.conf.set(f"fs.azure.account.oauth2.client.secret.{storage_account_name}.blob.core.windows.net", client_secret) spark.conf.set(f"fs.azure.account.oauth2.client.endpoint.{storage_account_name}.blob.core.windows.net", f"https://login.microsoftonline.com/{tenant_id}/oauth2/token") # 测试写入,保留wasbs路径前缀 df = spark.createDataFrame([(1, "foo")],["id", "label"]) df.write.format("delta").save(f"wasbs://{container_name}@{storage_account_name}.blob.core.windows.net/HERE")
排查清单
改完配置仍报错的话按顺序排查:
- 提前在存储账户控制台手动创建好目标容器
MyContainer,默认配置下Spark不会自动创建不存在的容器,不要依赖自动创建逻辑。 - 给服务主体分配数据平面权限:进入存储账户的「访问控制(IAM)」页,添加角色分配,选择存储Blob数据参与者角色,绑定到对应的服务主体,权限生效需要5-10分钟,不要刚分配完就测试。
- 检查所有配置项的占位符有没有替换完全,尤其是OAuth端点里的
TENANT_ID要替换成实际的租户GUID,不要留占位符字符串。 - 如果用的是7.x以下的老版本Databricks运行时,升级到10.4 LTS及以上的长期支持版本,老版本存在ABFS OAuth认证的已知bug。
- 测试前重启集群,清除之前设置的存储账户访问密钥等旧认证配置,避免同个存储账户下多套认证配置出现优先级冲突。
内容的提问来源于stack exchange,提问作者Haha
相关产品推荐
相关产品推荐

