容器之间的通信在 docker 网络中不起作用

communication between containers does not work in docker network

我正在尝试通过 docker 网络连接两个容器(spring 启动应用程序和 mongo 数据库)。

我创建了 docker 网络:

docker network create springmongo

然后,我创建 docker 数据库容器:

docker run --network=springmongo --name=mongocontainer mongo

然后,我创建了 spring 启动应用程序容器:

docker run --network=springmongo --name=mongo-client-api mongo-client-api

docker ps 命令显示:

CONTAINER ID        IMAGE                  COMMAND                  CREATED              STATUS              PORTS               NAMES
213526cf2bd4        mongo-client-api       "/bin/sh -c 'exec ja…"   31 seconds ago       Up 29 seconds       8080/tcp            mongo-client-api
8f3e19c3b631        mongo                  "docker-entrypoint.s…"   About a minute ago   Up About a minute   27017/tcp           mongocontainer

我在 spring 启动应用程序中的配置是:

spring.data.mongodb.uri=mongodb://mongocontainer:27017/test

当 spring 引导容器启动时,它无法连接到 mongo db:

2020-04-14 08:15:20.525  INFO 1 --- [           main] p.c.e.m.MongoClientApiApplication        : Starting MongoClientApiApplication v0.0.1-SNAPSHOT on 213526cf2bd4 with PID 1 (/opt/app.jar started by root in /opt)
2020-04-14 08:15:20.536  INFO 1 --- [           main] p.c.e.m.MongoClientApiApplication        : No active profile set, falling back to default profiles: default
2020-04-14 08:15:21.923  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data MongoDB repositories in DEFAULT mode.
2020-04-14 08:15:22.036  INFO 1 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 105ms. Found 1 MongoDB repository interfaces.
2020-04-14 08:15:23.015  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-04-14 08:15:23.033  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-04-14 08:15:23.035  INFO 1 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.33]
2020-04-14 08:15:23.156  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-04-14 08:15:23.157  INFO 1 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 2436 ms
2020-04-14 08:15:23.523  INFO 1 --- [           main] org.mongodb.driver.cluster               : Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
2020-04-14 08:15:23.617  INFO 1 --- [localhost:27017] org.mongodb.driver.cluster               : Exception in monitor thread while connecting to server localhost:27017

com.mongodb.MongoSocketOpenException: Exception opening socket
        at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:70) ~[mongodb-driver-core-3.11.2.jar!/:na]
        at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:128) ~[mongodb-driver-core-3.11.2.jar!/:na]
        at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:117) ~[mongodb-driver-core-3.11.2.jar!/:na]
        at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
        at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:na]

为什么我无法连接这两个容器?

提前致谢

更新 1

我从 mongo 容器添加日志:

2020-04-14T08:14:30.464+0000 I  CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2020-04-14T08:14:30.467+0000 W  ASIO     [main] No TransportLayer configured during NetworkInterface startup
2020-04-14T08:14:30.467+0000 I  CONTROL  [initandlisten] MongoDB starting : pid=1 port=27017 dbpath=/data/db 64-bit host=8f3e19c3b631
2020-04-14T08:14:30.467+0000 I  CONTROL  [initandlisten] db version v4.2.5
2020-04-14T08:14:30.467+0000 I  CONTROL  [initandlisten] git version: 2261279b51ea13df08ae708ff278f0679c59dc32
2020-04-14T08:14:30.467+0000 I  CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.1.1  11 Sep 2018
2020-04-14T08:14:30.467+0000 I  CONTROL  [initandlisten] allocator: tcmalloc
2020-04-14T08:14:30.467+0000 I  CONTROL  [initandlisten] modules: none
2020-04-14T08:14:30.467+0000 I  CONTROL  [initandlisten] build environment:
2020-04-14T08:14:30.467+0000 I  CONTROL  [initandlisten]     distmod: ubuntu1804
2020-04-14T08:14:30.467+0000 I  CONTROL  [initandlisten]     distarch: x86_64
2020-04-14T08:14:30.467+0000 I  CONTROL  [initandlisten]     target_arch: x86_64
2020-04-14T08:14:30.467+0000 I  CONTROL  [initandlisten] options: { net: { bindIp: "*" } }
2020-04-14T08:14:30.468+0000 I  STORAGE  [initandlisten]
2020-04-14T08:14:30.468+0000 I  STORAGE  [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine
2020-04-14T08:14:30.468+0000 I  STORAGE  [initandlisten] **          See http://dochub.mongodb.org/core/prodnotes-filesystem
2020-04-14T08:14:30.468+0000 I  STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=556M,cache_overflow=(file_max=0M),session_max=33000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000,close_scan_interval=10,close_handle_minimum=250),statistics_log=(wait=0),verbose=[recovery_progress,checkpoint_progress],
2020-04-14T08:14:31.134+0000 I  STORAGE  [initandlisten] WiredTiger message [1586852071:134123][1:0x7f8c32783b00], txn-recover: Set global recovery timestamp: (0, 0)
2020-04-14T08:14:31.677+0000 I  RECOVERY [initandlisten] WiredTiger recoveryTimestamp. Ts: Timestamp(0, 0)
2020-04-14T08:14:31.697+0000 I  STORAGE  [initandlisten] Timestamp monitor starting
2020-04-14T08:14:31.703+0000 I  CONTROL  [initandlisten]
2020-04-14T08:14:31.703+0000 I  CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2020-04-14T08:14:31.704+0000 I  CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2020-04-14T08:14:31.704+0000 I  CONTROL  [initandlisten]
2020-04-14T08:14:31.705+0000 I  STORAGE  [initandlisten] createCollection: admin.system.version with provided UUID: b82de6d0-72bb-4387-b456-79827a0bc50c and options: { uuid: UUID("b82de6d0-72bb-4387-b456-79827a0bc50c") }
2020-04-14T08:14:31.742+0000 I  INDEX    [initandlisten] index build: done building index _id_ on ns admin.system.version
2020-04-14T08:14:31.743+0000 I  SHARDING [initandlisten] Marking collection admin.system.version as collection version: <unsharded>
2020-04-14T08:14:31.743+0000 I  COMMAND  [initandlisten] setting featureCompatibilityVersion to 4.2
2020-04-14T08:14:31.744+0000 I  SHARDING [initandlisten] Marking collection local.system.replset as collection version: <unsharded>
2020-04-14T08:14:31.744+0000 I  STORAGE  [initandlisten] Flow Control is enabled on this deployment.
2020-04-14T08:14:31.745+0000 I  SHARDING [initandlisten] Marking collection admin.system.roles as collection version: <unsharded>
2020-04-14T08:14:31.745+0000 I  STORAGE  [initandlisten] createCollection: local.startup_log with generated UUID: 51de49e8-f4fc-4873-a5ed-ddc3ecedbec4 and options: { capped: true, size: 10485760 }
2020-04-14T08:14:31.782+0000 I  INDEX    [initandlisten] index build: done building index _id_ on ns local.startup_log
2020-04-14T08:14:31.786+0000 I  SHARDING [initandlisten] Marking collection local.startup_log as collection version: <unsharded>
2020-04-14T08:14:31.794+0000 I  FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory '/data/db/diagnostic.data'
2020-04-14T08:14:31.801+0000 I  SHARDING [LogicalSessionCacheRefresh] Marking collection config.system.sessions as collection version: <unsharded>
2020-04-14T08:14:31.802+0000 I  STORAGE  [LogicalSessionCacheRefresh] createCollection: config.system.sessions with provided UUID: 4e27e6b9-10d2-457c-ac54-b34d9bae09c9 and options: { uuid: UUID("4e27e6b9-10d2-457c-ac54-b34d9bae09c9") }
2020-04-14T08:14:31.802+0000 I  NETWORK  [listener] Listening on /tmp/mongodb-27017.sock
2020-04-14T08:14:31.802+0000 I  NETWORK  [listener] Listening on 0.0.0.0
2020-04-14T08:14:31.802+0000 I  NETWORK  [listener] waiting for connections on port 27017
2020-04-14T08:14:31.815+0000 I  INDEX    [LogicalSessionCacheRefresh] index build: done building index _id_ on ns config.system.sessions
2020-04-14T08:14:31.825+0000 I  INDEX    [LogicalSessionCacheRefresh] index build: starting on config.system.sessions properties: { v: 2, key: { lastUse: 1 }, name: "lsidTTLIndex", ns: "config.system.sessions", expireAfterSeconds: 1800 } using method: Hybrid
2020-04-14T08:14:31.825+0000 I  INDEX    [LogicalSessionCacheRefresh] build may temporarily use up to 200 megabytes of RAM
2020-04-14T08:14:31.825+0000 I  INDEX    [LogicalSessionCacheRefresh] index build: collection scan done. scanned 0 total records in 0 seconds
2020-04-14T08:14:31.827+0000 I  INDEX    [LogicalSessionCacheRefresh] index build: inserted 0 keys from external sorter into index in 0 seconds
2020-04-14T08:14:31.828+0000 I  INDEX    [LogicalSessionCacheRefresh] index build: done building index lsidTTLIndex on ns config.system.sessions
2020-04-14T08:14:31.830+0000 I  SHARDING [LogicalSessionCacheReap] Marking collection config.transactions as collection version: <unsharded>
2020-04-14T08:14:32.003+0000 I  SHARDING [ftdc] Marking collection local.oplog.rs as collection version: <unsharded>

您正在使用 Docker 容器的名称 (mongocontainer) 作为 SpringBoot 应用程序中的主机名。

改用 host.docker.internal,它解析为主机内部 IP。端口号很好,因为这是 Mongo 容器公开的端口号。

我可以解决我的问题。

我没有注意到,当 spring 启动容器 运行 时,它会在应该连接到主机 mongo 容器时尝试连接到本地主机。这是由于 Spring Dat Mongo 默认连接到本地主机。所以,我必须为 mongo 数据库创建自定义配置:

spring.data.mongodb.uri=mongodb://mongocontainer:27017/test

配置class:

@Configuration
public class MongoConfig {

    @Value("${spring.data.mongodb.uri}")
    private String uri;

    @Bean
    public MongoTemplate mongoTemplate() throws Exception {
        return new MongoTemplate(new SimpleMongoClientDbFactory(new ConnectionString(this.uri)));
    }
}

并排除一些自动配置 classes:

@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
public class MongoClientApiApplication {

    public static void main(String[] args) {
        SpringApplication.run(MongoClientApiApplication.class, args);
    }

}

然后我再次 运行 我的 mongo 和 spring 引导容器:

docker run --network=springmongo --name=mongocontainer mongo(我没有必要指定端口)

在 运行 spring 引导容器之前,我必须再次创建映像以使用上次更改更新我的 spring 引导应用程序(非常重要):

docker build -t mongo-client-api .

然后运行spring引导容器:

docker run --network=springmongo -p 8080:8080 --rm --name=mongo-client-api mongo-client-api

现在,为了获取我的 spring 启动应用程序的 IP,我 运行 这个命令:

minikube ip(我正在使用 minikube)

作为附加数据:当我使用 host.docker.internal 而不是 mongocontainer 时,我永远无法连接到我的 mongo 容器。我 运行 从 spring 引导容器 ping 到 host.docker.internal 但我都无法连接