无法从 docker 容器连接到 SQL Server

Posted

技术标签:

【中文标题】无法从 docker 容器连接到 SQL Server【英文标题】:Unable to connect to SQL Server from a docker container 【发布时间】:2019-05-29 05:28:22 【问题描述】:

我们有一个 ASP.NET Core 2.2 应用程序,它与托管在单独服务器上的后端数据库完美配合。所有 CRUD 操作都完美无缺。我们将应用程序 docker 化,但我们开始收到以下错误消息:

与 SQL Server 建立连接时出现与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。 (提供者:SQL 网络接口,错误:26 - 错误定位服务器/指定的实例)

docker compose 文件如下代码:

version: '3.4'

services:
  services.webapi:
    image: $DOCKER_REGISTRY-serviceswebapi
    build:
      context: .
      dockerfile: Services.WebApi\Dockerfile
      network: host

此配置可能有什么问题阻碍了应用程序与 SQL Server 实例通信?

更新 1:SQL Server 未 dockerized。

UPDATE 2:应用程序从其 appsettings.json 文件中读取 SQL 连接字符串。这是重命名服务器名称和凭据后的连接字符串:

Server=WIN-MSSQL1\\MSSQLSERVER2017;Initial Catalog=ServiceDB;User ID=cruduser;Password=foo;Connect Timeout=60;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False

【问题讨论】:

是完整的compose文件还是更多的服务? SQL 也被 docker 化了? 是的,这就是完整的撰写文件。 SQL 服务器未 docker 化。 dockerized 应用程序如何知道如何访问 SQL 服务?我的意思是在配置文件中有 SQL 服务器的主机名?如果是,您可以尝试在 docker 的 hosts 文件中添加一个额外的主机,选项为:'extra_hosts: - "somehost:162.242.195.82"' 请参阅我发布连接字符串的问题中的更新 2。 只是为了确认:您是否能够在 docker 之外的控制台应用程序中使用完全相同的连接字符串并确认连接有效? 【参考方案1】:

在正常情况下,您可以通过 composer 文件在容器的 /etc/hosts 文件中添加 sql 主机名来修复,如下所示:

version: '3.4'

services:
  services.webapi:
    image: $DOCKER_REGISTRY-serviceswebapi
    build:
      context: .
      dockerfile: Services.WebApi\Dockerfile
      network: host
    extra_hosts:
      - "WIN_MSSQL1:192.168.0.1"

很遗憾,由于 issue 在 composer 文件中添加 extra_hosts 不起作用,我希望他们尽快解决问题。

所以让连接工作用 SQL 服务器的 IP 地址替换主机名:

从此:

Server=WIN-MSSQL1\\MSSQLSERVER2017;Initial Catalog=ServiceDB;User ID=cruduser;Password=foo;Connect Timeout=60;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False

到这里:

Server=192.168.0.1\\MSSQLSERVER2017;Initial Catalog=ServiceDB;User ID=cruduser;Password=foo;Connect Timeout=60;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False

【讨论】:

但是服务器名是WIN-MSSQL1吧? WIN-MSSQL1\\MSSQLSERVER2017 是别名。那么额外的主机不应该像下面的条目吗? extra_hosts: - "WIN_MSSQL1:192.168.0.1" 不幸的是,它没有用!我想知道这个配置还需要什么! 如果你进入容器内你能ping通SQL主机吗? "docker exec -it 'container_name' ping WIN_MSSQL1 好的,我知道了,我现在开车回家了,你有没有尝试使用 docker 桥代替 network:host(只需删除线路 network:host)并尝试再次 ping sql 服务器通过他的IP地址 好的,@Arash 我根据 cmets 修改了答案,请查看连接字符串。

以上是关于无法从 docker 容器连接到 SQL Server的主要内容,如果未能解决你的问题,请参考以下文章

无法连接到 docker 容器内的 SQL Server

无法使用桥接网络模式从 docker 容器连接到远程 SQL 服务器

无法从 docker windows 容器中的 asp.net 核心应用程序连接到主机数据库

无法从我的 Docker 容器内部连接到主机的 localhost

无法从另一个容器连接到 mongodb docker 容器

无法使用 Django 应用程序从容器连接到 MySQL docker 容器