Elasticsearch 集群不适用于 Docker Swarm
Posted
技术标签:
【中文标题】Elasticsearch 集群不适用于 Docker Swarm【英文标题】:Elasticsearch cluster doesn't work on Docker Swarm 【发布时间】:2022-01-05 12:29:22 【问题描述】:当与docker compose
命令一起使用时,下面的 docker-compose YAML 文件会启动一个 3 节点 Elasticsearch 集群。这对于调试来说没问题,但我想转向部署,所以我想部署在一个容器可以在不同系统上运行的集群上。
所以
docker compose up
有效,但是
docker stack deploy -c docker-compose.yml p3es
创建相同的容器(尽管在不同的系统上)和覆盖网络,但是 elasticsearch 实例无法通过端口 9300 相互通信。因此,master 永远不会被分配,尽管 elasticsearch 响应 HTTP 请求,但它们只是出错出去。
在日志中,每个容器上都会出现以下异常/堆栈跟踪:
p3es_es01.1.sv26uqp4i4s3@carbon | "stacktrace": ["org.elasticsearch.transport.RemoteTransportException: [es03][10.0.12.9:9300][internal:cluster/coordination/join]",
p3es_es01.1.sv26uqp4i4s3@carbon | "Caused by: org.elasticsearch.transport.ConnectTransportException: [es01][10.0.0.53:9300] connect_exception",
(etc)
异常的原因原来是:
p3es_es01.1.sv26uqp4i4s3@carbon | "Caused by: java.io.IOException: connection timed out: 10.0.0.53/10.0.0.53:9300",
以下是我尝试过的一些方法:
-
我在其中一个容器上调用了一个 shell。我可以 ping 其他每个容器。我还可以对每个容器执行
curl -XGET
并从端口 9200 获得响应。
如果我在其中一个容器的端口 9300 上执行 curl -XGET,我会收到“不是 HTTP 端口”消息。但至少它能够解析地址。
Docker 堆栈喜欢为对象的名称添加前缀。因此,如果您将网络命名为 xyz,该网络实际上会被命名为 project_xyz。所以我改变了环境变量,告诉elasticsearch谁是集群的一部分,包括项目名称前缀。不走运。
我的想法已经用完了。有什么建议吗?
version: '3.9'
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.5.2
environment:
- HOSTNAME=es01
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es02,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
networks:
- es9300
volumes:
- nfs-es01:/usr/share/elasticsearch/data
ports:
- 9200:9200
es02:
image: docker.elastic.co/elasticsearch/elasticsearch:7.5.2
environment:
- HOSTNAME=es02
- node.name=es02
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es01,es03
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
networks:
- es9300
volumes:
- nfs-es02:/usr/share/elasticsearch/data
es03:
image: docker.elastic.co/elasticsearch/elasticsearch:7.5.2
environment:
- HOSTNAME=es03
- node.name=es03
- cluster.name=es-docker-cluster
- discovery.seed_hosts=es01,es02
- cluster.initial_master_nodes=es01,es02,es03
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: -1
hard: -1
networks:
- es9300
volumes:
- nfs-es03:/usr/share/elasticsearch/data
volumes:
nfs-es01:
driver_opts:
type: nfs
o: addr=10.2.0.1,rw,nfsvers=4,local_lock=all
device: :/sbn/process3/elasticsearch01
nfs-es02:
driver_opts:
type: nfs
o: addr=10.2.0.1,rw,nfsvers=4,local_lock=all
device: :/sbn/process3/elasticsearch02
nfs-es03:
driver_opts:
type: nfs
o: addr=10.2.0.1,rw,nfsvers=4,local_lock=all
device: :/sbn/process3/elasticsearch03
networks:
es9300:
driver: overlay
attachable: true
【问题讨论】:
【参考方案1】:事实证明,当 Docker 为其提供多个覆盖网络时,Elasticsearch 会感到困惑。所以指令:
ports:
- 9200:9200
使 Docker 在指定的覆盖网络之外提供一个覆盖网络(在本例中为 es9300)。由于某种原因,当 Elasticsearch 在容器中运行时,它在解析服务/DNS“es01”时获取了错误的 IP 地址。
我还没有确定为什么会这样,但是删除 ports 指令以发布端口 9200 可以解决问题。
希望这篇文章能帮助遇到同样问题的人。
【讨论】:
以上是关于Elasticsearch 集群不适用于 Docker Swarm的主要内容,如果未能解决你的问题,请参考以下文章
使用docker方式运行elasticsearch-head
Spring Data REST 似乎不适用于 elasticsearch
ElasticSearch 索引适用于 REST API,但不适用于 C# 代码