【问题标题】:ASP.NET Core Web API Service cannot connect to Docker SQL Server on same networkASP.NET Core Web API 服务无法连接到同一网络上的 Docker SQL Server
【发布时间】:2020-04-15 02:50:32
【问题描述】:

我有一个 ASP.NET Core v3 Web API 服务。它可以正常运行并连接到普通的 Windows 托管 SQL Server 实例。但是当我尝试将它连接到 Docker Linux 托管的 SQL Server 实例时,它失败了。

这里有一些细节:

  • 两个容器都在我的 Windows 10 开发机器上运行
  • Web API 服务容器是基于 Linux 的,可以自己正常工作
  • Linux SQL Server 容器本身运行良好
    • 我可以毫无问题地通过 SSMS 连接和运行查询。
  • 两个容器都是同一个默认的 Bridge 网络。
    • 我运行了docker network inspect bridge -f "{{json .Containers }}",它列出了两个容器。

这是我的数据库连接字符串:

"Server=localhost;Database=MyDatabase;User Id=MySqlUser;Password=MyPassword"

我还尝试在我的hosts localsql 文件中设置一个条目,设置为 127.0.0.0。 localhost 和 localsql 都可以正常使用 SSMS 连接到 docker 数据库。

这是实际的错误信息:

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

当我尝试从我的主机文件中使用 localsql 时,它有一个内部异常,此消息 "Name or service not known"

【问题讨论】:

    标签: sql-server docker asp.net-core .net-core


    【解决方案1】:

    连接字符串指向本地主机。容器中的 localhost 是指容器本身,因此 ASP.NET Core 容器会尝试在同一容器上查找 SQL Server。

    在连接字符串中使用 SQL Server 容器的名称,而不是 localhost。为了使其工作,您需要创建一个用户定义的网桥,两个容器都连接到:

    docker network create sql-server-test
    

    运行容器时,需要指定容器连接的网络,如下所示:

    # Please note the --name and --network parameters
    docker run -e ACCEPT_EULA=Y -e 'SA_PASSWORD=<PWD>' -d --name sql-server --network sql-server-test mcr.microsoft.com/mssql/server:2019-latest
    # Please note the --network parameter
    docker run -d -p 8889:80 --name aspnet-core --network sql-server-test aspnet-core
    

    由于两个容器现在都连接到同一个网络,你可以在连接字符串中使用 Sql Server 容器的名称(在同一个 sql-server 中),并使用这个连接字符串连接到 Sql Server:

    "Data Source=sql-server;Initial Catalog=master;User ID=sa;Password=<PWD>"
    

    有关 Docker 网络的详细信息以及有关如何设置容器之间通信的其他选项,请参阅link

    【讨论】:

    • 这似乎可行。但我试过了,它仍然以同样的方式失败。我还尝试在启动容器并将值传递到连接字符串时添加-h 选项。那也不起作用....如果有任何变化,我将尝试对这个想法进行更多的排列并在此处更新。
    • 使用 Docker 创建的 IP 地址为它找到了服务器。不过,使用不容易改变的东西会很好。
    • @Vaccano 我想我误解了你的问题。现在我假设您没有为容器设置专用网络。我已经用必要的步骤更新了答案。使用此设置,我能够从 ASP.NET Core 容器访问 Sql Server。
    【解决方案2】:

    Markus 的回答非常好,但我想扩展他所写的内容或使其更全面。基本上是about default Bridging and User defined Bridging。 如果使用默认桥接,您也可以通过链接容器来实现这一点。更多信息见this文章

    您还可以使用创建用户定义的桥

    $ docker network create my-net
    

    然后当你像 Markus 的示例代码一样创建新容器时。你可以在你的 create 命令中给出这个桥的名字。

    $ docker create --name my-nginx \
      --network my-net \
      --publish 8080:80 \
      nginx:latest
    

    如果您已经创建了容器,您可以使用下面的命令将您创建的网桥连接到现有容器。对 sql server 和 api 执行此操作(sql1 是 sql server 的名称)。然后你不需要在你的连接字符串中定义 localhost 因为它们将在同一个网络中。

    $ docker network connect my-net sql1 
    

    实际上每次停止 docker 并重新部署(调试)容器时都非常烦人,您可能需要通过这些步骤来完成

    • 第一次断开连接:docker network disconnect my-net sql1
    • 删除网络:docker network rm my-net
    • 再次连接:docker network connect my-net sql1

    【讨论】:

      猜你喜欢
      • 2020-06-09
      • 2020-01-11
      • 2020-10-01
      • 2021-01-02
      • 2019-11-24
      • 1970-01-01
      • 2017-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多