You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker部署的Azure Web App无法通过托管身份连接Azure SQL

Azure Web App Docker容器无法通过托管身份连接Azure SQL数据库

问题概述

将Python应用以Docker方式部署到Azure Web App后,应用无法连接仅允许托管身份认证的Azure SQL数据库。本地非Docker环境下执行az login可正常连接,但Docker部署后报错。应用及本人的托管身份均已加入my-group安全组,该组已配置为SQL Server外部管理员,并在数据库中创建了对应用户及角色权限。

报错详情

  • 初始报错:Login timeout expired
  • 添加AZURE_CLIENT_ID和AZURE_TENANT_ID环境变量后,报错变为:
azure.core.exceptions.ClientAuthenticationError: DefaultAzureCredential failed to retrieve a token from the included credentials.
Attempted credentials:
    EnvironmentCredential: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
    ManagedIdentityCredential: (None) No User Assigned or Delegated Managed Identity found for specified ClientId/ResourceId/PrincipalId.
Code: None
Message: No User Assigned or Delegated Managed Identity found for specified ClientId/ResourceId/PrincipalId.

注:环境变量值曾尝试使用应用的principalId、Application ID及安全组Object Id,均无效。

相关配置与代码

Python连接代码

from azure.identity import DefaultAzureCredential
import struct
import pyodbc

def create_token_struct(databaseToken):
    exptoken = b''
    for i in bytes(databaseToken[0], "UTF-8"):
        exptoken += bytes({i})
        exptoken += bytes(1)
    return struct.pack("=i", len(exptoken)) + exptoken

# 当前初始化方式
credential = DefaultAzureCredential()
pyodbc.connect(AZURE_SQL_CONNECTION_STRING, attrs_before = {1256: create_token_struct(credential.get_token('https://database.windows.net/'))})

连接字符串:

Driver={ODBC Driver 18 for SQL Server};Server=tcp:my-server-name.database.windows.net,1433;Database=my_database_name;Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30

SQL配置

CREATE USER [my-group] FROM EXTERNAL PROVIDER;

ALTER ROLE db_datareader ADD MEMBER [my-group];
ALTER ROLE db_datawriter ADD MEMBER [my-group];
ALTER ROLE db_ddladmin   ADD MEMBER [my-group];

SQL Server创建命令:az sql server create ... --external-admin-name my-group

Dockerfile

FROM python:3.10

COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

# 安装pyodbc依赖
RUN apt-get update && apt-get -y install unixodbc-dev

RUN sh -c "curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -" \
    && apt-get update \
    && sh -c "curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list > /etc/apt/sources.list.d/mssql-release.list" \
    && apt-get update \
    && ACCEPT_EULA=Y apt-get install -y msodbcsql18 \
    && ACCEPT_EULA=Y apt-get install -y mssql-tools18

# 安装Azure CLI
RUN sh -c "curl -sL https://aka.ms/InstallAzureCLIDeb | bash"

WORKDIR /app
COPY . /app
EXPOSE 8501

解决方案与问题分析

1. 移除冲突的环境变量

设置AZURE_CLIENT_ID和AZURE_TENANT_ID后,DefaultAzureCredential会优先尝试EnvironmentCredential,但仅设置这两个变量不足以完成环境认证(还需AZURE_CLIENT_SECRET或其他凭据),同时会干扰系统托管身份的自动检测。
操作:删除Web App中配置的AZURE_CLIENT_ID和AZURE_TENANT_ID环境变量。

2. 修正DefaultAzureCredential初始化

按照要求显式初始化凭据(默认exclude_environment_credential为False,明确配置可避免歧义):

credential = DefaultAzureCredential(exclude_environment_credential=False)

3. 验证系统托管身份的可用性

  • 确认Web App已启用系统分配托管身份:执行az webapp identity show,确保返回包含principalId和tenantId的有效结果。
  • 系统分配托管身份无需指定Client ID,ManagedIdentityCredential会自动从Azure实例元数据服务获取身份信息。

4. 确认SQL权限配置有效性

  • 验证my-group安全组确实包含应用的系统托管身份:在Azure AD中检查安全组成员。
  • 确认SQL Server的外部管理员配置正确:执行az sql server ad-admin list --resource-group <rg-name> --server-name <server-name>,确保返回my-group。

5. 容器网络与元数据端点访问

Azure Web App会自动将实例元数据服务端点(http://169.254.169.254)映射到Docker容器内,无需额外配置。若存在网络隔离,需确保容器可访问该端点(无需公网,为内部地址)。

内容的提问来源于stack exchange,提问作者limitIntegral314

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:46:25