[英]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.我有一个应用程序应该使用命名实例连接到在远程服务器上运行的 SQL Server。
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.使用 IISExpress,我可以连接到 SQL Server,但是从 Docker(Linux 容器)它失败了 - 在访问上下文时它只是挂起 - 没有抛出异常或错误消息。 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.使用 node.js 我什至可以从 docker 连接到 SQL Server 没有问题。
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.当我使用例如 [ipaddress 或 host.docker.internal],1433 时,我可以从 Docker 中的 ASP.NET Core 连接到与 Docker 在同一台机器上运行的 SQL Server Developer 版本 - 不幸的是,在远程 SQL Server 上,我无法配置固定端口。
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();
它将挂在conn.Open();
线上conn.Open();
. .
Any idea what I could do?知道我能做什么吗?
Update:更新:
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.我可以 ping 远程 IP 地址以及远程服务器名称。
Unfortunately installing mssql-cli on the ubuntu image fails because of missing dependencies.不幸的是,由于缺少依赖项,在 ubuntu 映像上安装 mssql-cli 失败。
The Data Source
is wrong. Data Source
错误。 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.仅当字符串存储在需要这种转义的介质中时才需要转义反斜杠,例如在 C# 字符串或 JSON 字符串中。 For C#, JSON, Javascript and C++-related languages, the escape character is the backslash itself eg :对于 C#、JSON、Javascript 和 C++ 相关的语言,转义字符是反斜杠本身,例如:
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.文字 C# 字符串、XML 或 INI 文件不需要转义。 The following C# line doesn't need escaping.以下 C# 行不需要转义。
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.当 DNS 尝试将无法识别的字符串解析为有效 IP 时,错误的地址很容易传递给应用程序。
Another problem is that docker containers have no network connectivity by default.另一个问题是 docker 容器默认没有网络连接。 You have to specify what they can connect to and how internal IPs and ports are mapped to external IPs and ports.您必须指定它们可以连接到什么以及如何将内部 IP 和端口映射到外部 IP 和端口。
You can use the the SQL Server CLI tool, mssql-cli to test connectivity to a server without running your own application with :您可以使用 SQL Server CLI 工具mssql-cli来测试与服务器的连接,而无需运行您自己的应用程序:
mssql-cli -S InternallyMappedIP\WEBDB -d TestDB -U testuser
I'm Using Docker containerized application.我正在使用 Docker 容器化应用程序。 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 是运行在 docker 上的 sql 镜像,
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. SqlClient 存储库中的问题#222解释了该问题。
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
将基础mcr.microsoft.com/dotnet/core/aspnet:3.1.0-buster-slim
映像文件从mcr.microsoft.com/dotnet/core/aspnet:3.1.0-buster-slim
为mcr.microsoft.com/dotnet/core/aspnet:3.1.0-bionic
Adding some steps to my docker file:在我的 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 . . .
I know you resolved the issue.我知道你解决了这个问题。 I just add more for others people.我只是为其他人添加更多。 Type类型
ipconfig配置文件
We can see the IP of network我们可以看到网络的IP
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.如果我们在 IIS 上运行应用程序,我们可以使用上面的 IP。 However, the application can't connect to database if we run on docker.但是,如果我们在 docker 上运行,应用程序将无法连接到数据库。
Server=172.17.0.2;Database=VoiconCrochet;User Id=sa;Password=P@ssw0rd123;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.