繁体   English   中英

无法通过主机名连接到 docker 容器中的 MongoDB

[英]Can't connect to MongoDB in docker container via hostname

我正在从事一个小型个人项目,最近从 PostgreSQL 切换到 MongoDB。 Mongo 在 docker 容器中运行,在本地运行我的 API 时,一切正常。 但是,当我尝试在 docker 中运行我的 API 时,我可以让它成功连接到 Mongo 的唯一方法是使用我的本地网络 IP 作为连接字符串。 当我尝试通过主机名( host.docker.internal或 mongo 容器名称mongo )连接时,它无法连接。 我已经确认curl host.docker.internal:27017curl mongo:27017都成功了。

换句话说,连接字符串的格式为mongodb://user:pwd@host/database 在本地运行时,它适用于host = "localhost" ,它适用于 docker 和host = "my.local.ip" ,但不适用于host = "host.docker.internal"host = "mongo"

连接:

var mongoClient = new MongoClient(
                $"mongodb://{dbCreds.Username}:{dbCreds.Password}@{dbCreds.Host}/{dbCreds.Database}");

docker_compose.yaml:

version: '3.7'
services:
    homenotify.api:
        build: ./HomeNotify.API
        ports:
            - '5000:80'
        networks:
            - api
            - db
        environment:
            - GOOGLE_CREDENTIAL=service_account_key.json
            - DB_CREDENTIALS=db_credentials_docker.json
networks:
    api:
        name: api
        driver: bridge
    db:
        name: db
        external: true

堆栈跟踪:

Unhandled exception. System.TimeoutException: A timeout occured after 30000ms selecting a server using CompositeServerSelector{ Selectors = MongoDB.Driver.MongoClient+AreSessionsSupportedServerSelector, LatencyLimitingServerSelector{ AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster state is { ClusterId : "1", ConnectionMode : "Automatic", Type : "Unknown", State : "Disconnected", Servers : [{ ServerId: "{ ClusterId : 1, EndPoint : "Unspecified/mongo:27017" }", EndPoint: "Unspecified/mongo:27017", ReasonChanged: "Heartbeat", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server.

---> System.PlatformNotSupportedException: Sockets on this platform are invalid for use after a failed connection attempt.

at System.Net.Sockets.Socket.ThrowMultiConnectNotSupported()

at System.Net.Sockets.Socket.BeginConnect(String host, Int32 port, AsyncCallback requestCallback, Object state)

at MongoDB.Driver.Core.Connections.TcpStreamFactory.ConnectAsync(Socket socket, EndPoint endPoint, CancellationToken cancellationToken)

at MongoDB.Driver.Core.Connections.TcpStreamFactory.CreateStreamAsync(EndPoint endPoint, CancellationToken cancellationToken)

at MongoDB.Driver.Core.Connections.BinaryConnection.OpenHelperAsync(CancellationToken cancellationToken)

显然,dotnet 存在 sockets 不支持非 Windows 平台上的主机名的问题。 这就是为什么它在本地工作但在 docker 中不起作用的原因:在本地运行时它在 Windows 上,在 Linux 中运行时在 Z0306AFD6.DADF6.DA 据说这在几年前就已经解决了,但这就是问题所在。

从主机名手动解析 IP 地址,并改用 IP 连接,解决了我的问题。 这里找到了代码片段。

dbCreds.Host = Dns.GetHostAddresses(dbCreds.Host)
                .FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork)?.ToString();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM