はじめに
Azure DatabricksでADLS Gen2のファイルを加工・分析したいことは多いと思います
ググれば、DatabricksのクラスターにADLS Gen2をマウントする方法がたくさん出てきますが、
今回遭遇した403エラーはなかなか解決策を見つけられず苦労したのでメモとして残しておきます
マウントした後、Notebookで加工・分析する具体的な実装については触れていません
403エラーに遭遇するまで
公式チュートリアルを見ながら進める
こちらのチュートリアルを実施
ADLS Gen2は作成済のものを使いましたが、それ以外はチュートリアル通りに進めました
サービスプリンシパル等もろもろ準備ができたので、DatabricksにNotebookを作成して、いざマウント!!
configs = {"fs.azure.account.auth.type": "OAuth",
"fs.azure.account.oauth.provider.type": "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider",
"fs.azure.account.oauth2.client.id": "<application-id>",
"fs.azure.account.oauth2.client.secret": dbutils.secrets.get(scope="<scope-name>",key="<service-credential-key-name>"),
"fs.azure.account.oauth2.client.endpoint": "https://login.microsoftonline.com/<directory-id>/oauth2/token"}
# Optionally, you can add <directory-name> to the source URI of your mount point.
dbutils.fs.mount(
source = "abfss://<container-name>@<storage-account-name>.dfs.core.windows.net/",
mount_point = "/mnt/<mount-name>",
extra_configs = configs)
dbutils.fs.mount()
で403エラー
This request is not authorized to perform this operation
だそうです
ExecutionError: An error occurred while calling o267.mount.
: Operation failed: "This request is not authorized to perform this operation.", 403, HEAD, https://<account>.dfs.core.windows.net/<container>/?upn=false&action=getAccessControl&timeout=90
at shaded.databricks.azurebfs.org.apache.hadoop.fs.azurebfs.services.AbfsRestOperation.execute(AbfsRestOperation.java:200)
at shaded.databricks.azurebfs.org.apache.hadoop.fs.azurebfs.services.AbfsClient.getAclStatus(AbfsClient.java:750)
at shaded.databricks.azurebfs.org.apache.hadoop.fs.azurebfs.services.AbfsClient.getAclStatus(AbfsClient.java:732)
at shaded.databricks.azurebfs.org.apache.hadoop.fs.azurebfs.AzureBlobFileSystemStore.getIsNamespaceEnabled(AzureBlobFileSystemStore.java:299)
……省略
原因
結論:ADLS Gen2のFireWallでDatabricksからのアクセスがブロックされていた
- システム割り当てマネージドIDによるアクセス許可:Databricksをサポートしていない
-
信頼された Microsoft サービスによるこのストレージ アカウントに対するアクセスを許可します
をON:信頼されたMicrosoftサービスにDatabricksは含まれない
Databricksもアクセスできるのかと思っていたら違っていました、、、
チェックボックスの横にあるInformationアイコンから信頼されたサービスのリストを確認できるんだから、ちゃんと確認しとけば、、、
つまり、DatabricksからのアクセスはFWで許可されていない状態でした
FW設定は有効にしたまま、Databricksからアクセスしたい!
以下で実現できます
- 仮想NW内にDatabricksをデプロイ(VNetインジェクション)
- 仮想NWにADLS Gen2へのサービスエンドポイントを作成
- ADLS Gen2のFW設定で当該仮想NWのpublic subnetを許可
なお、Databricksを作成する時にしかVNetに関連付けることはできないので、既に作成している場合はDatabricksワークスペースから作り直しです
移行する方法も紹介されていますが、私はNotebookをDRC形式でExportして、ワークスペースやクラスターを手動で再作成した後でDRCをインポートする方法で移行しました
最終的な状態
イメージ
ADLS Gen2 FW設定
VNet サービスエンドポイント設定
その他
-
VNet内のDatabricksからKey Vaultへのアクセスについて
DatabricksでADLS Gen2をマウントする際に、サービスプリンシパル + OAuthで認証していますが、サービスプリンシパルのシークレットをKey Vaultに保存しています。Key VaultもStorageと同様に、①Key Vault側のFWでVNetを許可 & ②VNet側でKey Vaultへのサービスエンドポイントを設定が必要かと思ったのですが、設定しなくても問題ありませんでした。KeyVaultでは例外として許可されるサービスにDatabricksが含まれているからですね -
VNet内にpublic/private Subnetを作るのですが、DatabricksのリソースがどのSubnetにどう配置されるのか?
仮想NWの要件として以下のような記載がありましたが、クラスターはprivateに配置されるのか?といった所はイマイチ理解できていません- サブネット: VNet には、Azure Databricks ワークスペース専用の2つのサブネットが含まれている必要があります。コンテナーサブネット (プライベートサブネットと呼ばれることもあります) とホストサブネット (パブリックサブネットと呼ばれることもあります) です。
チェックするポイント
最終的にADLS Gen2のFW設定が原因でしたが、他にもチェックすべきポイントをまとめておきます
- ADLS Gen2
- 「許可するアクセス元」が「すべてのネットワーク」であれば問題なし
- 「選択されたネットワーク」にする必要がある場合、Databricksを仮想NW内にデプロイする
- サービスプリンシパル
- ストレージBlobデータ共同作成者など、適切なIAMロールを付与しているか
- アプリケーションID、テナントID、シークレット…などをあっちこっちにコピペする際に間違えていないか
- IAMロールのスコープ1
参考
-
stackoverflow
- VNetにDatabricksをデプロイするという解決策が記載されていました
- もう一つの解決策として紹介されていたのがAzureのDCのIPアドレスを全部ホワイトリストに入れちゃえよという案も提示されていましたが、やめておきました