如何从另一个容器连接到SQL Server Docker容器?

23
我已经使用以下命令拉取并运行了SQL Server 2017容器镜像:

(我)

docker pull microsoft/mssql-server-linux
docker run --name mssql -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=!Abcd123' -p 1433:1433 -d microsoft/mssql-server-linux

我还使用以下命令将ASP.NET Core Web API应用程序部署到Docker容器中:

dotnet publish -c Release -o Output
docker build -t apitest .
docker run -p 3000:80 --name apitest_1 apitest

Dockerfile的内容:

FROM microsoft/dotnet
COPY Output /app
WORKDIR /app
EXPOSE 80/tcp
ENTRYPOINT ["dotnet", "DockerSQLTest.dll"]

在我的Web API应用程序中,我创建了一个Entity Framework Core迁移,它将创建数据库并填充一些数据。在Startup类的Configure方法中,我添加了以下代码来将待处理的迁移应用于数据库:
public async void Configure(IApplicationBuilder app,
                            IHostingEnvironment env, 
                            StudentDbContext dbContext)
{
    await dbContext.Database.MigrateAsync();
    ...
}

数据库连接字符串从appsettings.json中检索,其中包含以下部分:

"ConnectionStrings": {
    "DefaultConnection": "Server=localhost,1433;Database=student;User Id=sa;Password=!Abcd123;"
}

但是该应用程序无法正确运行,异常信息为:
fail: WebApplication6.Startup[0]
  System.Threading.Tasks.TaskCanceledException: A task was canceled.
     at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
     at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
     at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.<>c__DisplayClass20_0.<<ExistsAsync>b__0>d.MoveNext()
  --- End of stack trace from previous location where exception was thrown ---
     at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
     at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.ExistsAsync(CancellationToken cancellationToken)
     at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateAsync(String targetMigration, CancellationToken cancellationToken)

有什么问题吗?


1
在你的 docker run 命令中添加 -h mssql。这将允许你通过该名称 (Server=mssql) 连接到 SQL 容器。 - Dan Guzman
4个回答

22

Docker内置了一个DNS服务器,容器之间通过容器名称相互连接。在您的情况下,您将SQL Server容器命名为mssql,因此这是您需要将其放入.NET应用程序连接字符串中的服务器名称:Server=mssql;Database=student;User Id=sa;Password=!Abcd123;

请查看GitHub上的.NET Core相册查看器示例,该示例使用Docker Compose定义多容器应用程序。


这在 Visual Studio 的默认 Docker 设置中完美运行。通过容器编排支持。 - WiseGuy

18
我通过首先检查容器网络,然后找到网络IP并将其放入appsetting.json中来解决了这个问题。
 "ConnectionStrings": {
    "DefaultConnection": "Server=172.17.0.2;Database=VehicleKey;User Id=sa;Password=p@ssW0rd;"
  }

检查Docker网络

查找SQLSERVER的名称 输入图像描述


1
这不会一直是手动操作来查找IP并连接吗..? 我更喜欢Elton上面的答案使用容器名称。 - eRaisedToX
另一个答案看起来更干净,但容器的名称将无法解析为桥接中的DNS条目。可能是我配置中的某些问题。 - Kieran

2

首先,在使用两个或更多容器时,不能有任何本地主机连接。每个Docker容器都有自己的内部网络IP。 一旦您启动了一个具有公开端口的容器,为了能够连接到该容器,您需要指定主机IP(容器实际运行的位置)。

因此,例如,您应该有下一个字符串进行连接:

Server=192.168.1.99,1433;Database=student;User Id=sa;Password=!Abcd123;

位置:192.168.1.99 - Docker容器运行的主机的实际IP地址。


0
你必须知道Docker容器的IP地址。可以在命令提示符中执行ipconfig命令获取它。

Windows ipconfig

使用此IP连接到SQL Server。

Connect to Sql Server

如果您正在使用Linux或安装在WSL上的Linux,请从bash控制台执行ifconfig命令。

Linux ifconfig

Connecto to SQL

如果在本地WSL中安装了Linux,则两个IP地址都路由到同一个SQL Server实例。

Two Ip addresses to the same SQL Server Instance


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接