简体   繁体   中英

How to connect external MS SQL server database from container

I'm new in Docker and we are migrating our working ASP.NET CORE app to Docker in company

Problem is I did't find any releated topics about how to connect to external already existing MS SQL server [not in docker image] database from container. All topics are about connecting to official Image of MS SQL-Server [which I don't need].

I wrote Dockerfile and application running but there no connection to SQL Server

Please give me correct direction with topics or hints thank you!

Dockerfile

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS base
WORKDIR /app
EXPOSE 5000 //port to app
EXPOSE 1433 //SQL-Server port


FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /src
COPY UploadCore/UploadCore.csproj UploadCore/
RUN dotnet restore UploadCore/UploadCore.csproj
COPY . .
WORKDIR /src/UploadCore
RUN dotnet build UploadCore.csproj -c Release -o /app

FROM build AS publish
RUN dotnet publish UploadCore.csproj -c Release -o /app

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "UploadCore.dll"]

I'm running my app as below

docker run -it --rm -p 5000:5000 -p 1433:1433 --name UploadCore my-app_test:4.5

Error:

Microsoft.EntityFrameworkCore.Database.Connection[20004]
      An error occurred using the connection to database 'MIS_REPORTS' on server 'server02'.
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
Microsoft.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 25 - Connection string is not valid: Connection string is not valid)
   at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at Microsoft.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, Boolean encrypt, Boolean trustServerCert, Boolean integratedSecurity, Boolean withFailover, SqlAuthenticationMethod authType)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, DbConnectionPool pool)

Docker provides its own internal DNS service that can do things like resolve other container names as host names. It looks like you've configured your database location as a bare host name server02 . This hits the Docker DNS resolver first, and it tries to resolve it as a container name; when that fails, that's why you're getting the error you do.

In different environments you can tell this apart from different kinds of errors by error messages like "name resolution failed" or "no such host"; this is different from an error message like "connection refused" or "connection reset by peer".

You can resolve this by using a fully-qualified domain name (FQDN) as your database location; for example, server02.example.com instead of just server02 . Since that doesn't look like a container name, it will cause Docker to forward the DNS request to your normal name server.

The same issue bugged me for days and finally was able to solve it by following the steps below.

In my case the SQL server was hosted on Azure managed instance and exposed a private endpoint. The docker was able to resolve the DNS name of the Azure managed instance to a private IP address (as expected ). But this resolved IP was considered by the docker network/bridge as a locally running application because upon inspecting docker's bridge ( docker network inspect bridge )The subnet of the bridge was found to be a range of IP addresses where the resolved IP of the SQL server also falls. Hence, the docker assumed the SQL server to be hosted in the same local network and not outside (here enterprise network). In my case the Windows VM I was working was already on the private network of the enterprise.

Solution:

In the docker desktop -> settings -> Docker Engine json file, add a new key value pair "bip": "<local IP address range which is outside of the resolved sql server IP>" . Restart the docker desktop and the issue should be solved.

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