无法从在Docker(Linux)中运行的ASP.NET Core连接到SQL Server命名实例

时间:2019-06-06 08:29:40

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

我有一个应用程序,该应用程序应使用命名实例连接到在远程服务器上运行的SQL Server。

使用IISExpress,我可以连接到SQL Server,但是从Docker(Linux容器)中,它失败-访问上下文时,它只是挂起了-没有抛出异常或错误消息。例如

var context = serviceScope.ServiceProvider.GetService<AppContext>();
context.Users.ToList();

在调试器中,它永远不会到达异常处理程序。

相反,我看到很多这样的输出:

The thread 125 has exited with code 0 (0x0).
The thread 164 has exited with code 0 (0x0).
The thread 0xa4 has exited with code 0 (0x0).

使用node.js,我甚至可以从docker连接到SQL Server,而不会出现问题。

当我使用时,我可以从Docker中的ASP.NET Core连接到与Docker在同一台机器上运行的SQL Server Developer版本。 [ipaddress或host.docker.internal] 1433-不幸的是,在远程SQL Server上,我无法配置固定端口。

  • 使用IISExpress进行工作(因此可在Windows上运行)
  • 使用固定端口而不是命名实例连接到在开发计算机上运行的SQL Server时可以工作(但我不能更改生产服务器)
  • 在使用node.js时有效!从docker也使用命名实例(都是:使用主机名或IP地址-这样我就可以解析远程名称,防火墙不是问题)
  • 使用Microsoft容器作为基础尝试了ASP.NET Core 2.2和3.0preview5,例如从mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS基础

连接字符串:

"Data Source=remoteIP\\WEBDB;Initial Catalog=TestDB;User ID=testuser;Password=******;"

还尝试了“集成安全性= False;”。在连接字符串中

服务器身份验证设置为混合

我也可以在没有实体框架的情况下重现它:

var conString = "Data Source=remoteIP\\WEBDB;Initial Catalog=TestDB;Integrated Security=False;User ID=testuser;Password=********";

using (SqlConnection conn = new SqlConnection(conString))
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn))
{
   conn.Open();
   var rows = cmd.ExecuteNonQuery();
   Console.WriteLine($"rows: {rows}");
}

它将挂在conn.Open();行上。

知道我能做什么吗?

更新:

  • 输入错误的连接字符串。
  • 使用完整示例更新代码

修改

这有效:

var conString = "Data Source=10.0.75.1,1433;Initial Catalog=TestDB;Integrated Security=False;User ID=testuser;Password=********";

这不起作用:

var conString = "Data Source=10.0.75.1\\Developer;Initial Catalog=TestDB;Integrated Security=False;User ID=testuser;Password=********";

我可以ping通远程IP地址以及远程服务器名称。

不幸的是,由于缺少相关性,因此在ubuntu映像上安装mssql-cli失败。

5 个答案:

答案 0 :(得分:0)

Data Source是错误的。命名实例仅使用单个反斜杠。正确的来源是:

remoteIP\WEBDB

仅当字符串存储在需要这种转义的媒体中(例如,在C#字符串或JSON字符串中)时,反斜杠needs to be escaped。对于C#,JSON,Javascript和与C ++相关的语言,转义字符是反斜杠本身,例如:

var connectionString="Data Source=remoteIP\\WEBDB;Initial Catalog=TestDB;User ID=testuser;Password=******;"

{
    "ConnectionStrings": {
        "BloggingDatabase": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;"
    },
}

文字C#字符串,XML或INI文件不需要转义。下面的C#行不需要转义。

var connectionString=@"Data Source=remoteIP\WEBDB;Initial Catalog=TestDB;User ID=testuser;Password=******;"

修改

固定名称只是可能出错的一件事。 DNS尝试将无法识别的字符串解析为有效IP时,错误的地址很容易将应用程序移交给应用程序。

另一个问题是,默认情况下,Docker容器具有 no 网络连接。您必须指定它们可以连接的内容以及内部IP和端口如何映射到外部IP和端口。

您可以使用SQL Server CLI工具mssql-cli来测试与服务器的连接性,而无需使用以下命令运行您自己的应用程序:

mssql-cli -S InternallyMappedIP\WEBDB -d TestDB -U testuser

答案 1 :(得分:0)

我正在使用Docker容器化应用程序。我添加了如下的连接字符串,

services.AddDbContext<OrderContext>(options =>
            {
                options.UseSqlServer(Configuration["ConnectionString"]);
            });

我的连接字符串如下:

Server=sqlserver ; Database=CustomerDb; User Id=sa;Password=8jkGh47hnDw89Haq8LN2

sqlserver是在docker上运行的sql映像,

sqlserver:
    image: microsoft/mssql-server-linux:latest
    container_name: sqlserver
    ports:
      - "7100"
    environment:
      - ACCEPT_EULA=Y 
      - MSSQL_PID=Developer
      - SA_PASSWORD=8jkGh47hnDw89Haq8LN2

答案 2 :(得分:0)

尝试在连接字符串中添加“连接超时= 60”。

答案 3 :(得分:0)

Issue #222 in SqlClient repository解释了问题。

我已经验证了这两个选项都对我有用:

  • 将基本docker映像文件从mcr.microsoft.com/dotnet/core/aspnet:3.1.0-buster-slim更改为mcr.microsoft.com/dotnet/core/aspnet:3.1.0-bionic

  • 向我的docker文件添加一些步骤:

    FROM mcr.microsoft.com/dotnet/core/aspnet:3.1.0-buster-slim AS final
    RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /etc/ssl/openssl.cnf
    RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /etc/ssl/openssl.cnf
    RUN sed -i 's/DEFAULT@SECLEVEL=2/DEFAULT@SECLEVEL=1/g' /usr/lib/ssl/openssl.cnf
    RUN sed -i 's/MinProtocol = TLSv1.2/MinProtocol = TLSv1/g' /usr/lib/ssl/openssl.cnf
    . . .
    

答案 4 :(得分:0)

我知道您已经解决了该问题。 我只是为别人添加更多。 输入

ipconfig

我们可以看到网络的IP

Ethernet adapter vEthernet (DockerNAT):

   Connection-specific DNS Suffix  . :
   IPv4 Address. . . . . . . . . . . : 10.0.75.1
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . :

如果我们在IIS上运行该应用程序,则可以使用上述IP。 但是,如果我们在docker上运行,则应用程序无法连接到数据库。 enter image description here enter image description here

Server=172.17.0.2;Database=VoiconCrochet;User Id=sa;Password=P@ssw0rd123;