Docker 容器无法连接到 MongoDB 副本集

Docker 容器无法连接到 MongoDB 副本集

我正在使用 Docker Swarm 创建 Web 应用程序和数据库集群。

我有四个容器正在运行,其中三个是单个 mongodb 副本集,最后一个是连接到副本集的 asp.net 核心应用程序。

所有四个容器均可公开访问,并连接到同一个 Docker 网络。

副本集可以在内部互相连接,主机名例如:mongo1、mongo2 和 mongo3。

但是 asp.net 应用程序无法连接到副本集。

  • 我可以通过 asp.net docker 容器中的 mongo shell 顺利连接到 mongo db。
  • 我可以单独连接到每个节点,但不能作为外部的副本集。

例外

Connection id "0HLBA78J6QB27", Request id "0HLBA78J6QB27:00000001": An unhandled exception was thrown by the application.
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/mongo1;mongo2;mongo3:27017" }", EndPoint: "Unspecified/mongo1;mongo2;mongo3:27017", State: "Disconnected", Type: "Unknown", HeartbeatException: "MongoDB.Driver.MongoConnectionException: An exception occurred while opening a connection to the server. ---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException: No such device or address

Docker 服务:

Web 应用程序:已发布端口:80->80

Mongo1:已发布端口:1234->27017

Mongo2:已发布端口:1235->27017

Mongo3:已发布端口:1236->27017

连接字符串如下所示:

“mongodb://admin:密码@mongo1,mongo2,mongo3/replicaSet=example&authSource=admin”

答案1

为了支持副本集故障转移和重新配置,具有副本集连接的客户端使用副本集中配置的主机名根据 MongoDB 的要求服务器发现和监控 (SDAM) 规范这样可以保证客户端看到的副本集和副本集的配置和状态是一致的。

我可以单独连接到每个节点,但不能作为外部的副本集。

如果外部主机/端口与副本集配置不同,则这是预期行为。如果您连接到单个服务器(即未指定副本集连接),客户端不会进行任何服务器发现。这对于连接到特定副本集成员以进行备份或管理非常有用,或者当您通过与副本集配置不匹配的转发主机名或端口组合进行连接时避免服务器发现非常有用。

使用副本集连接,客户端连接并运行isMaster命令发现副本集的当前配置和状态。根据 SDAM 规范,客户端随后设置副本集监控,以便客户端自动检测到配置或状态的任何变化。

Mongo1:发布端口:1234->27017 Mongo2:发布端口:1235->27017 Mongo3:发布端口:1236->27017

要使用与公开的 Docker 端口的副本集连接,您需要:

  • 确保副本集配置(Mongo1、、)中使用的主机名可以在您尝试连接的容器中解析Mongo2Mongo3
  • 使 Docker 镜像中的端口唯一,并在主机环境中公开相同的端口(例如:27017、27018、27019)。

如果您可以从应用程序容器连接,则看起来名称解析已经正常工作,但是副本集配置中的端口与您通过 Docker 公开的端口不匹配。

相关内容