简体   繁体   中英

Can't connect to SQL Server named instance from ASP.NET Core running in Docker (Linux)

I have an application that should connect to a SQL Server running on a remote server using a named instance.

Using IISExpress, I can connect to the SQL Server, but from Docker (Linux container) it fails - when accessing the context it just hangs - no exception or error message is thrown. Eg

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

In the debugger it never reaches the exception handler.

Instead I see a lot of output like this:

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).

Using node.js I can connect to the SQL Server even from docker without problem.

I can connect to a SQL Server Developer edition running on the same machine as Docker from ASP.NET Core in Docker when I use eg [ipaddress or host.docker.internal],1433 - unfortunately on the remote SQL Server, I cannot configure a fixed port.

  • works using IISExpress (so runs on Windows)
  • works when connecting to a SQL Server running on the dev machine when using a fixed port instead of named instance (but I can't change our production server)
  • works when using node.js! from docker also with named instance (both: with hostname or ip address - so I can resolve remote names, firewall is not an issue)
  • tried ASP.NET Core 2.2 and 3.0preview5 using Microsoft container as a base eg FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS base

Connecting string:

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

Also tried with "Integrated Security=False;" in the connection string

Server Authentication is set to mixed

I can reproduce this is also without Entity Framework:

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}");
}

It will hang on the line conn.Open(); .

Any idea what I could do?

Update:

  • entered connection string incorrectly.
  • updated code with complete example

Edit

This works:

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

This doesn't work:

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

I can ping the remote IP address and also the remote server name.

Unfortunately installing mssql-cli on the ubuntu image fails because of missing dependencies.

The Data Source is wrong. Named instances use only a single backslash. The correct source is:

remoteIP\WEBDB

The backslash needs to be escaped only if the string is stored in a medium that requires such escaping, eg in a C# string or a JSON string. For C#, JSON, Javascript and C++-related languages, the escape character is the backslash itself eg :

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

or

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

Literal C# strings, XML or INI files don't require escaping. The following C# line doesn't need escaping.

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

Edit

Fixing the name is only one thing that could be wrong. A wrong address can easily hand the application while DNS tries to resolve the unrecognized string to a valid IP.

Another problem is that docker containers have no network connectivity by default. You have to specify what they can connect to and how internal IPs and ports are mapped to external IPs and ports.

You can use the the SQL Server CLI tool, mssql-cli to test connectivity to a server without running your own application with :

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

I'm Using Docker containerized application. I added the connectionstring like following,

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

And My connection string is following:

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

sqlserver is sql image running on the docker,

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

尝试将“Connect Timeout=60”添加到您的连接字符串中。

Issue #222 in SqlClient repository explains the problem.

I have verified that these both options work for me:

  • Changing the base docker image file from mcr.microsoft.com/dotnet/core/aspnet:3.1.0-buster-slim to mcr.microsoft.com/dotnet/core/aspnet:3.1.0-bionic

  • Adding some steps to my docker file:

     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 . . .

I know you resolved the issue. I just add more for others people. Type

ipconfig

We can see the IP of network

Ethernet adapter vEthernet (DockerNAT):

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

If we run the application on IIS, we can use above IP. However, the application can't connect to database if we run on docker. 在此处输入图片说明 在此处输入图片说明

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM