簡體   English   中英

無法從 Docker 容器連接到外部 SQL 服務器

[英]Can't Connect to External SQL Server From Docker Container

我開發了一個 SpringBoot(Java) 應用程序,該應用程序調用端口 1433 上的外部 SQL 服務器。SQL 服務器實例位於本地(不是本地 Z9778840A0100CB30C52ZB 實例7) 但是,可以使用 IntelliJ 或 SQL 客戶端從我的桌面訪問它。

我正在使用 Microsoft SQL 服務器 JDBC 連接器與實例通信。

如果我從 IntelliJ 運行應用程序一切正常,應用程序可以調用 SQL 服務器,執行命令並返回結果集。

但是,現在我正在嘗試 Dockerize api 應用程序。 容器執行通常的 SpringBoot 初始化,但是當它嘗試調用 SQL 服務器時,我收到以下錯誤:

com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host myexternalsqlserver.domain, port 1433 has failed. Error: "myexternalsqlserver.domain. Verify the connection properties. Make sure that an instance of SQL Server is running on the host and accepting TCP/IP connections at the port. Make sure that TCP connections to the port are not blocked by a firewall.".
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:234)
    at com.microsoft.sqlserver.jdbc.SQLServerException.ConvertConnectExceptionToSQLServerException(SQLServerException.java:285)
    at com.microsoft.sqlserver.jdbc.SocketFinder.findSocket(IOBuffer.java:2434)
    at com.microsoft.sqlserver.jdbc.TDSChannel.open(IOBuffer.java:659)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:2546)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:2216)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:2067)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1204)
    at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:825)
    at java.sql/java.sql.DriverManager.getConnection(Unknown Source)
    at java.sql/java.sql.DriverManager.getConnection(Unknown Source)
    at com.symetra.SdsApi.SqlConnector.getResultSet(SqlConnector.java:26)

這是我的 Docker 文件

FROM openjdk:11.0.4-jre-slim-buster
VOLUME /tmp

COPY target/myapi-1.0-SNAPSHOT.jar app.jar
EXPOSE 8080
EXPOSE 1433
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Dspring.profiles.active=docker -jar /app.jar" ]

這些是我用來構建和運行容器的 Docker 命令:

docker build -t myapi . && docker run -p 8080:8080 -p 1433:1433 --name myapi myapi "java","-jar","myapi-1.0-SNAPSHOT.jar"

1433端口的映射我覺得沒必要,只是個實驗。 我應該能夠通過主機上的端口 1433 在容器外部進行通信。 主機上的端口 1433 沒有被阻止,因為我在容器外運行它沒有問題。

最后,這是我正在使用的連接字符串:

//Create Connection Url.
String connectionUrl="jdbc:sqlserver://myexternalsqlserver.domain:1433;database=mydb;user=MyUser;password=MyPassword";

我不確定我在這里做錯了什么。 我想知道是否需要設置 Docker 網絡。

謝謝你的幫助!

它應該工作。

注意我假設myexternalsqlserver.domain不是您使用的。

測試您的容器的一種方法是對其進行 shell(或創建一個變體)並嘗試解析 SQL Server 的主機名:

docker run --interactive --tty openjdk:11.0.4-jre-slim-buster /bin/bash

# then from within the container's shell
apt update && apt install -y dnsutils
nslookup ${SQL_SERVER}

如果成功,那就是你的代碼。

如果沒有,那就是網絡。

注意您的容器不需要發布 1443 ( --publish=1433:1433 ),因為它正在使用該端口(在 SQL Server 上)而不是公開端口本身。

同樣的問題困擾了我好幾天,終於能夠按照以下步驟解決它。

在我的例子中,SQL 服務器托管在 Azure 托管實例上,並暴露了一個私有端點。 docker 能夠將 Azure 托管實例的 DNS 名稱解析到私有 ZA12A3079E14CED46E69B2 地址(如預期)。 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也跌倒。 因此,docker 假定 SQL 服務器托管在同一本地網絡中,而不是外部(此處為企業網絡)。 就我而言,我正在工作的 Windows VM 已經在企業的專用網絡上。

解決方案:

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>" . 重新啟動 docker 桌面,問題應該得到解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM