本地Java应用无法连接Docker Compose部署的Elasticsearch
本地Java应用无法连接Docker部署的Elasticsearch问题排查
环境配置
使用以下docker-compose.yml启动基础设施:
version: "3.9" services: redis: image: redis:3 ports: - "6379:6379" #network_mode: host rabbitmq: image: rabbitmq:3-management ports: - "5672:5672" - "15672:15672" #network_mode: host mongo: image: mongo:3.6.3 ports: - "27017:27017" #network_mode: host elasticsearch: image: xxxx/elasticsearch:latest ports: - "9200:9200" - "9300:9300" x-service: build: context: ../../x-service dockerfile: Dockerfile environment: - CONFIG_FILE=x-service.ini ports: - "4003:4003"
问题现象
执行docker-compose start后所有服务正常启动,容器内的x-service Java应用可成功连接Elasticsearch并运行,但本地启动同一应用时连接失败,报错如下:
14:47:36.107 [WARN] io.dexi.search.index.SearchEngineIndex - [main] Failed while looking up index org.elasticsearch.client.transport.NoNodeAvailableException: None of the configured nodes are available: [{#transport#-1}{127.0.0.1}{localhost/127.0.0.1:9300}] at org.elasticsearch.client.transport.TransportClientNodesService.ensureNodesAreAvailable(TransportClientNodesService.java:290) ~[elasticsearch-2.1.1.jar:2.1.1] at org.elasticsearch.client.transport.TransportClientNodesService.execute(TransportClientNodesService.java:207) ~[elasticsearch-2.1.1.jar:2.1.1] at org.elasticsearch.client.transport.support.TransportProxyClient.execute(TransportProxyClient.java:55) ~[elasticsearch-2.1.1.jar:2.1.1] at org.elasticsearch.client.transport.TransportClient.doExecute(TransportClient.java:283) ~[elasticsearch-2.1.1.jar:2.1.1] at org.elasticsearch.client.support.AbstractClient.execute(AbstractClient.java:347) ~[elasticsearch-2.1.1.jar:2.1.1] at org.elasticsearch.client.support.AbstractClient$IndicesAdmin.execute(AbstractClient.java:1183) ~[elasticsearch-2.1.1.jar:2.1.1] at org.elasticsearch.action.ActionRequestBuilder.execute(ActionRequestBuilder.java:85) ~[elasticsearch-2.1.1.jar:2.1.1] at org.elasticsearch.action.ActionRequestBuilder.execute(ActionRequestBuilder.java:59) ~[elasticsearch-2.1.1.jar:2.1.1] at org.elasticsearch.action.ActionRequestBuilder.get(ActionRequestBuilder.java:67) ~[elasticsearch-2.1.1.jar:2.1.1]
已验证信息
- 通过Elasticsearch head客户端可确认Elasticsearch可从localhost访问
- 本地与容器内应用的Elasticsearch集群名称配置一致
- Elasticsearch节点详细信息:
"name": "Sally Floyd", "transport_address": "172.18.0.5:9300", "host": "172.18.0.5", "ip": "172.18.0.5", "version": "2.1.1", "build": "40e2c53", "http_address": "172.18.0.5:9200", "settings": { "name": "Sally Floyd", "client": { "type": "node" }, "cluster": { "name": "elasticsearch" }, "path": { "logs": "/usr/share/elasticsearch/logs", "home": "/usr/share/elasticsearch" }, "config": { "ignore_system_properties": "true" }, "network": { "host": "0.0.0.0" } }, "os": { "refresh_interval_in_millis": 1000, "name": "Linux", "arch": "amd64", "version": "5.10.102.1-microsoft-standard-WSL2", "available_processors": 8, "allocated_processors": 8 }, "process": { "refresh_interval_in_millis": 1000, "id": 1, "mlockall": false }, "jvm": { "pid": 1, "version": "1.8.0_66-internal", "vm_name": "OpenJDK 64-Bit Server VM", "vm_version": "25.66-b17", "vm_vendor": "Oracle Corporation", "start_time_in_millis": 1678878835905, "mem": { "heap_init_in_bytes": 268435456, "heap_max_in_bytes": 1037959168, "non_heap_init_in_bytes": 2555904, "non_heap_max_in_bytes": 0, "direct_max_in_bytes": 1037959168 }, "gc_collectors": [ "ParNew" , "ConcurrentMarkSweep" ], "memory_pools": [ "Code Cache" , "Metaspace" , "Compressed Class Space" , "Par Eden Space" , "Par Survivor Space" , "CMS Old Gen" ] }, "thread_pool": { "force_merge": { "type": "fixed", "min": 1, "max": 1, "queue_size": -1 }, "percolate": { "type": "fixed", "min": 8, "max": 8, "queue_size": 1000 }, "fetch_shard_started": { "type": "scaling", "min": 1, "max": 16, "keep_alive": "5m", "queue_size": -1 }, "listener": { "type": "fixed", "min": 4, "max": 4, "queue_size": -1 }, "index": { "type": "fixed", "min": 8, "max": 8, "queue_size": 200 }, "refresh": { "type": "scaling", "min": 1, "max": 4, "keep_alive": "5m", "queue_size": -1 }, "suggest": { "type": "fixed", "min": 8, "max": 8, "queue_size": 1000 }, "generic": { "type": "cached", "keep_alive": "30s", "queue_size": -1 }, "warmer": { "type": "scaling", "min": 1, "max": 4, "keep_alive": "5m", "queue_size": -1 }, "search": { "type": "fixed", "min": 13, "max": 13, "queue_size": 1000 }, "flush": { "type": "scaling", "min": 1, "max": 4, "keep_alive": "5m", "queue_size": -1 }, "fetch_shard_store": { "type": "scaling", "min": 1, "max": 16, "keep_alive": "5m", "queue_size": -1 }, "management": { "type": "scaling", "min": 1, "max": 5, "keep_alive": "5m", "queue_size": -1 }, "get": { "type": "fixed", "min": 8, "max": 8, "queue_size": 1000 }, "bulk": { "type": "fixed", "min": 8, "max": 8, "queue_size": 50 }, "snapshot": { "type": "scaling", "min": 1, "max": 4, "keep_alive": "5m", "queue_size": -1 } }, "transport": { "bound_address": [ "0.0.0.0:9300" ], "publish_address": "172.18.0.5:9300", "profiles": { } }, "http": { "bound_address": [ "0.0.0.0:9200" ], "publish_address": "172.18.0.5:9200", "max_content_length_in_bytes": 104857600 }, "plugins": [ { "name": "head", "version": "master", "description": "head - A web front end for an elastic search cluster", "url": "/_plugin/head/", "jvm": false, "site": true } ] }
问题原因及解决方案
核心原因
Elasticsearch的TransportClient在连接时,会先通过配置的节点(localhost:9300)建立初始连接,之后Elasticsearch节点会返回自己的publish_address(即容器内部IP 172.18.0.5:9300)给客户端,客户端后续会尝试使用这个IP进行通信。但本地客户端无法访问Docker内部网络的IP,导致连接失败。
解决方法
修改docker-compose.yml中Elasticsearch的配置,添加环境变量指定transport.publish_host和network.publish_host为宿主机可访问的地址(如localhost或宿主机IP):
elasticsearch: image: xxxx/elasticsearch:latest ports: - "9200:9200" - "9300:9300" environment: - network.publish_host=localhost - transport.publish_host=localhost
或者如果是通过配置文件挂载,在elasticsearch.yml中添加:
network.publish_host: localhost transport.publish_host: localhost
修改后重启Elasticsearch容器,本地Java应用即可正常连接。
内容的提问来源于stack exchange,提问作者Rando Shtishi
相关产品推荐
相关产品推荐

