如何在Docker的Python环境中通过Azure AD MFA连接SQL Server数据库
我正尝试搭建Python Docker容器,通过Azure AD MFA连接多个SQL Server数据库。Dockerfile构建成功并用于VSCode开发容器,但容器内无法连接数据库(Windows环境下相同配置可正常连接)。
当前Dockerfile内容:
# Docker image with Python3, poyodbc, MS ODBC 18 driver (SQL Server) # Use official Python image FROM python:3.10-bullseye # Set working directory WORKDIR /app # Send Python output streams to container log ENV PYTHONUNBUFFERED 1 # Update apt-get RUN apt-get update # Install ggc RUN apt-get install gcc # pyodbc dependencies RUN apt-get install -y tdsodbc unixodbc-dev RUN apt install unixodbc -y RUN apt-get clean -y ADD odbcinst.ini /etc/odbcinst.ini # ODBC driver dependencies RUN apt-get install apt-transport-https RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - RUN curl https://packages.microsoft.com/config/ubuntu/20.04/prod.list > /etc/apt/sources.list.d/mssql-release.list RUN apt-get update # Install ODBC driver RUN ACCEPT_EULA=Y apt-get install msodbcsql18 --assume-yes # Configure ENV for /bin/bash to use MSODBCSQL18 RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc # Upgrade pip RUN pip3 install --upgrade pip3 # Install Python libraries from requirements.txt COPY requirements.txt requirements.txt RUN pip3 install -r requirements.txt # Copy project code into image COPY . .
容器内Python连接代码:
import pandas as pd import pyodbc conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};' 'Server=<my-server-name>;' 'Database=<my-db-name>;' 'Trusted_Connection=yes;') cursor = conn.cursor()
运行后报错:
Error: ('HY000', '[HY000] [Microsoft][ODBC Driver 18 for SQL Server]SSPI Provider: No Kerberos credentials available (default cache: FILE:/tmp/krb5cc_0) (851968) (SQLDriverConnect)')
在Linux容器中,Trusted_Connection=yes依赖Kerberos实现Windows身份验证,Azure AD MFA需要通过Kerberos获取有效凭证,以下是具体配置步骤:
1. 容器内安装Kerberos工具
修改Dockerfile,添加Kerberos客户端安装指令:
# 安装Kerberos客户端 RUN apt-get install -y krb5-user
2. 配置krb5.conf文件
在项目根目录创建krb5.conf文件,内容如下(替换为你的Azure AD域名):
[libdefaults] default_realm = YOUR_AZURE_AD_DOMAIN.COM dns_lookup_realm = true dns_lookup_kdc = true ticket_lifetime = 24h renew_lifetime = 7d forwardable = true [realms] YOUR_AZURE_AD_DOMAIN.COM = { kdc = kerberos.YOUR_AZURE_AD_DOMAIN.COM admin_server = kerberos.YOUR_AZURE_AD_DOMAIN.COM } [domain_realm] .YOUR_AZURE_AD_DOMAIN.COM = YOUR_AZURE_AD_DOMAIN.COM YOUR_AZURE_AD_DOMAIN.COM = YOUR_AZURE_AD_DOMAIN.COM
将YOUR_AZURE_AD_DOMAIN.COM替换为实际的Azure AD域名(例如contoso.com)。
然后在Dockerfile中添加复制该文件的指令:
# 复制Kerberos配置文件 COPY krb5.conf /etc/krb5.conf
3. 获取Kerberos票据
容器启动后,执行以下命令获取Kerberos票据(替换为你的Azure AD账号):
kinit your-azure-ad-username@YOUR_AZURE_AD_DOMAIN.COM
执行后输入账号密码,生成票据缓存后,再运行Python连接脚本即可完成认证。
4. 可选:开发场景持久化票据缓存
如果使用VSCode开发容器,可将Kerberos票据缓存目录挂载到本地,避免每次重启容器重复获取票据:
在.devcontainer/devcontainer.json中添加挂载配置:
"mounts": [ "source=/tmp/krb5cc_0,target=/tmp/krb5cc_0,type=bind" ]
替代方案:直接使用Azure AD交互式认证
若Kerberos配置复杂,可改用Azure AD MFA专用连接参数,无需依赖Kerberos:
conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};' 'Server=<my-server-name>;' 'Database=<my-db-name>;' 'Authentication=ActiveDirectoryInteractive;')
该方式会弹出MFA验证窗口(需容器支持图形界面,或在VSCode中启用端口转发),适合开发场景快速验证。
内容的提问来源于stack exchange,提问作者Violet

