【发布时间】:2018-08-15 05:00:12
【问题描述】:
我尝试从 Docker 容器(使用 EF Core 运行 .NET Core 应用)连接到主机的 SQL Server 实例(Windows 10 上的SQL 2017)。
SQL Server 配置为侦听默认端口 1433(不使用动态端口)并允许远程连接 (TCP/IP)。我还为防火墙和给定端口设置了入站规则(我也尝试关闭防火墙)。我可以连接到数据库并使用在 Docker 容器中运行的sqlcmd 命令行工具运行 SQL 查询。
这是我正在使用的连接字符串:
Server=tcp:host.docker.internal,1433;Database=AuthIdentity;Trusted_Connection=False;User Id=sa;Password=xxxx;MultipleActiveResultSets=True;
当我运行我的容器时,我收到以下错误:
发生网络相关或特定于实例的错误,同时 建立与 SQL Server 的连接。找不到服务器或 无法访问。验证实例名称是否正确,并且 SQL Server 配置为允许远程连接。 (提供者:TCP 提供者,错误:0 - 无法建立连接,因为目标 机器主动拒绝了。)
当我关闭防火墙时(即使 SQL 端口有防火墙规则),我最终会得到:
SqlException:发生与网络相关或特定于实例的错误 在建立与 SQL Server 的连接时。服务器没有 找到或无法访问。验证实例名称是否正确 并且 SQL Server 配置为允许远程连接。 (提供者:TCP 提供者,错误:0 - 连接尝试失败 因为连接方在一段时间后没有正确响应 时间,或建立连接失败,因为连接的主机有 没有回应。)
当我启动与 IIS 应用程序相同的程序(没有任何其他更改)时,它运行得非常好,并且按预期连接。
程序执行第一个 SQL 操作时发生错误(在这种情况下是数据库迁移 - 这是在程序启动内)
serviceScope.ServiceProvider.GetRequiredService<ApplicationDbContext>().Database.Migrate();
编辑:在另一个 API 项目中进行更简单的设置(两者都会引发与上述相同的错误):
[HttpGet("setup")]
[AllowAnonymous]
public IActionResult Setup()
{
try
{
this._context.Database.Migrate();
return Ok("success");
}
catch (Exception e)
{
return Json(e);
}
}
[HttpGet("get")]
[AllowAnonymous]
public List<ApplicationUser> Get()
{
return this._context.Users.ToList();
}
编辑 2:根据@Mohsin Mehmood 的建议,我使用NAT 地址(来自ipconfig /all)进行了测试,我可以成功连接到给定的IP(172.28.112.1)到SQL 服务器。我还检查了运行 docker run --rm -i microsoft/nanoserver:1709 ping host.docker.internal 时收到的内容,它得到了我的地址 62.138.239.45。
我更希望有一个解决方案,它不使用“硬编码”IP 地址,而是使用像 host.docker.internal 这样的 DNS。我也不确定为什么两个 IP 地址不同(172.28.112.1 与 62.138.239.45)以及为什么容器无法从 DNS 获取正确的地址。
我缺少什么?如何解决这个问题?我已经搜索了 Google 和 SO,但没有任何有效的答案。
【问题讨论】:
-
登录到正在运行的容器,看看是否可以解析命令提示符中提到的名称
-
我可以连接到数据库并使用在 Docker 容器中运行的
sqlcmd命令行工具运行 SQL 查询 -
使用与您的问题
tcp:host.docker.internal,1433相同的主机名? -
通过使用命令行语法
sqlcmd -S host.docker.internal -U sa -P xxxx。它是一个在 docker 容器中运行的独特 SQL 客户端。 -
我不确定
Service Migration是什么。我建议创建简单的 ASP.NET 页面,只检查到 DB 的连接性,以将应用程序问题与容器问题隔离开来
标签: docker sql-server-2017 docker-for-windows ef-core-2.1