通过名称从另一个容器连接到SQL Server容器

时间:2020-04-08 19:50:46

标签: sql-server windows docker containers

我才刚刚开始接触Docker,到目前为止,我喜欢我的进步。但是我为以下问题感到困惑。我试图在一个容器中运行SQL Server数据库,并在另一个容器中运行.Net Framework 4.5 Web服务。如果Web服务容器中的连接字符串使用db容器的IP地址,则说明连接成功。如果我尝试使用指定的主机名,则会引发以下异常:

System.Data.Entity.Core.EntityException:基础提供程序在打开时失败。

System.Data.SqlClient.SqlException:建立与SQL Server的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称正确,并且已将SQL Server配置为允许远程连接。 (提供者:命名管道提供者,错误:40-无法打开与SQL Server的连接)

System.ComponentModel.Win32Exception:找不到网络路径

我正在Windows 10 Enterprise上运行适用于Windows Engine 19.03.8的Docker,并使用Windows容器。这是我使用的命令和docker文件。我的测试应用程序是一个简单的控制台应用程序,它使用Entity Framework 6调用存储过程,该存储过程从表中返回数据。

docker network create --driver nat mynat

用于DB容器的Docker文件

FROM microsoft/mssql-server-windows-developer

ENV sa_password "Password123"
ENV attach_dbs "[]"

COPY . /

WORKDIR /

RUN powershell sqlcmd -S localhost,1433 -i CreateEMLDatabase.sql


RUN powershell set-itemproperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord 

CMD powershell ./start -sa_password Password123 -attach_dbs \"%attach_dbs%\" -Verbose -ACCEPT_EULA 'Y'

docker build --rm --no-cache --tag mailservicedb:latest。

docker run --net mynat --ip 172.30.157.42 -d --name maildbctr --hostname maildbctr mailservicedb:latest

测试仪控制台的连接字符串:

connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=System.Data.SqlClient;provider connection string="data source=maildbctr;initial catalog=EML;User Id=MyLogin;Password=MyPassword;MultipleActiveResultSets=True;App=EntityFramework""

用于Tester Console的Docker文件

FROM mcr.microsoft.com/windows/servercore:1903

WORKDIR /tester

COPY . .

#FIX DNS issues currently in Windows Containers
RUN powershell set-itemproperty -path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord 

CMD ContainerDbTester.exe

docker build --rm --no-cache --tag dbtester:latest。

docker run -it --net mynat --ip 172.30.157.43 --name dbtestctr --hostname dbtestctr dbtester:最新cmd

在Tester容器中,我可以ping数据库容器名称:

ping maildbctr

Pinging maildbctr [fe80::11c5:f48c:92c1:7a36%4] with 32 bytes of data:
Reply from fe80::11c5:f48c:92c1:7a36%4: time<1ms
Reply from fe80::11c5:f48c:92c1:7a36%4: time<1ms
Reply from fe80::11c5:f48c:92c1:7a36%4: time<1ms
Reply from fe80::11c5:f48c:92c1:7a36%4: time=1ms

Ping statistics for fe80::11c5:f48c:92c1:7a36%4:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 1ms, Average = 0ms

但是当我运行控制台exe时,我得到了上面抛出的异常。

非常感谢您找出我所缺少的步骤。

2 个答案:

答案 0 :(得分:1)

我有一个类似的问题。我的设置是这样:

  • 数据库容器将端口1433映射到主机端口31433;
  • 在主机上运行的应用A;
  • 应用B在另一个容器中;

App A能够使用auth/requires-recent-login正常连接到数据库,而App B无法使用localhost连接。

经过一些研究,我能够使App B使用IDENTIFICATION DIVISION. PROGRAM-ID. SOQUEST. ENVIRONMENT DIVISION. DATA DIVISION. WORKING-STORAGE SECTION. 01 FLAGS. 03 WS-VALIDATION PIC 9 VALUE ZERO. 88 WS-VALIDATION-OK VALUE 0. 88 WS-VALIDATION-ERROR VALUE 1. PROCEDURE DIVISION. MAIN. PERFORM A100-INITIALIZE PERFORM A200-VALIDATE IF WS-VALIDATION-ERROR EXIT PARAGRAPH END-IF PERFORM B200-PROCESS-STEP-1 . CLOSE-FILES. CLOSE XXXX CLOSE YYY . EXIT-PROGRAM. GOBACK . A100-INITIALIZE. DISPLAY "INITIALIZED" . A200-VALIDATE. * Do next when validation fails ... MOVE 1 TO WS-VALIDATION ANY-VALIDATION-HERE IF ERROR-FOUND EXIT PARAGRAPH END-IF CONTINUE-WITH-OTHER-VALIDATIONS IF ERROR-FOUND EXIT PARAGRAPH END-IF * Arriving here .. MEANS VALIDATION IS ok MOVE O TO WS-VALIDATION . B200-PROCESS-STEP-1. DISPLAY "COMPLETED STEP 1" . 而不是localhost,31433连接到数据库。

答案 1 :(得分:0)

我已经使用类似的设置(数据库+ Web平台)进行了多次工作,并且我曾经使用docker-compose方法,通常它更简单(默认情况下,它会为每个组合创建一个网络)并允许我以便随时跟踪多个不同的配置。 DC的文档甚至向我们介绍了an example以及网络如何工作:

version: "3"
services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres
    ports:
      - "8001:5432"

在此示例中,您可以使用“ db”来引用Web应用程序中的数据库IP。