无法从同一主机上的网络应用docker访问docker托管的SQL服务器

时间:2019-02-25 10:27:59

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

在同一台病毒检测机(远程,ubuntu)上,我有

  • 在Docker中运行的SQL Server
  • 在docker中运行的.NET Core 2.2 (IdentityServer)应用程序
  • jwilder.nginx-proxy 的实例用作计算机上每个Web应用程序的反向代理
  • 众多其他.NET Core应用

我能够使用计算机IP +端口和域名连接到我的所有网站,这意味着反向代理可以正常工作,并且docker配置正确

我能够从本地计算机上使用SSMS 连接到SQL Server,这意味着SQL Server泊坞程序可以正确转发端口1433上的TCP连接

IdentityServer .NET Core 2 Web应用程序在本地计算机上运行时能够连接到SQL Server 。

远程Docker IdentityServer应用程序无法访问SQL Server实例,并出现以下错误(为简明起见,已删除堆栈跟踪)

  

System.Data.SqlClient.SqlException (0x80131904)

     

建立与SQL Server的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称正确,并且已将SQL Server配置为允许远程连接。

     

(提供者:TCP Provider, error: 40-无法打开与SQL Server的连接),位于[...]

我知道SQL服务器正在运行并且可以从Internet访问,并且我知道应用程序的代码没有错误,因为我对这两者进行了测试。

因此,我推断必须是阻止连接的IdentityServer泊坞窗。所以我尝试了:

  • 在IdentityServer泊坞窗上使用--expose 20命令
  • 打开将容器内的端口20映射到-p 45264:20外部的某个端口上,除了已经暴露的端口80之外
  • 我最初是在映射的两边使用端口1433,但是由于它没有用,所以我尝试在外部使用另一个端口(20)。没有任何改变

这是IdentityServer使用的连接字符串(隐藏了敏感数据):

Data Source=***.***.***.***,20;Initial Catalog=Identity;Persist Security Info=True;User ID=**;Password=******************

为什么在完全可以访问SQL Server时,我的IdentityServer泊坞窗无法到达SQL Server泊坞窗?如何使该设置正常工作?

4 个答案:

答案 0 :(得分:1)

将SQL Server包装到Docker中时,首先要想到的是连接方式。 SQL Server更喜欢命名管道,您必须将模式显式设置为tcp

如果连接是在本地完成的,请不要使用localhost,将其更改为127.0.0.1。同样,编写明确的tcp:前缀也可能会有所帮助,例如:Server=tcp:x.y.z.q,1433

答案 1 :(得分:1)

据我了解,您在单独的Docker容器中运行Sql Server和IdentityServer(存在连接问题)。

如果是这样,则引用本地主机(即127.0.0.1)是不正确的。因为在这种情况下,IdentityServer尝试连接到自身。如果IdentityServer已在主机上运行,​​这将起作用,因为您将SQL Server端口转发到了主机。但是,在这种情况下,您应该改为连接到SQL Server容器IP。 考虑到以上所有因素,我为您提供了三种解决方案:

  1. 您可以通过运行docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <sql_container_name_or_id>
  2. 获得SQL Server容器的IP地址。
  3. 通过docker run --ip <static_ip_value> <sql_container_name_or_id>使用静态IP运行SQL容器,然后使用在连接字符串中指定的静态ip。
  4. 通过docker run --hostname <sql_host_name> <sql_container_name_or_id>用指定的主机名运行SQL容器,然后在连接字符串中使用指定的主机名。

由您决定走哪条路。

答案 2 :(得分:0)

使用tcp,127.0.0.1和主机端口进行连接。在身份服务器docker设置中提到它取决于sql数据库服务器容器。像这样

identityservice:
   ...
   depends_on:
      - sqldataservice

这样,数据库容器将首先可用。

"ConnectionString": "Server=tcp:127.0.0.1,8433;Database=dbname;User Id=sa;Password=abc@1234;"

答案 3 :(得分:0)

我最终放弃了使用单个主机来运行它,所以我只是决定让SQL Server在单独的计算机上运行。