在Swarm模式下运行Elasticsearch容器

13

Elasticsearch旨在以集群模式运行,只需通过环境变量定义相关节点的IP地址,只要网络连接可用,它将连接并加入到集群中的其他节点。

我有3个节点,其中1个充当Docker Swarm管理器,另外两个是工作节点。我已经初始化了管理器并加入了工作节点,从这一点来看一切都很正常。

现在我正在尝试以某种方式运行elasticsearch容器,使我能够将所有节点加入到同一个elasticsearch集群,但是我希望节点使用其覆盖网络接口进行连接,这意味着我需要在运行docker service create命令时知道容器内部IP地址,我该怎么做?我是否必须使用像consul这样的内容来实现这一点?

一些澄清:

我需要在服务创建的同时知道所有Elasticsearch参与者的IP地址(或DNS名称),以便我可以正确启动集群。这必须在创建时而不是之后进行。此外,据我所知,我可以为所有服务公开端口9200/9300,并使用外部机器IP进行操作,并使其正常工作,但我想使用覆盖网络来完成所有通信(我认为这就是Swarm模式的目的)。


除了Consul之外,还有Zookeeper和Etcd。 - Matt Schuchard
@MattSchuchard 我不能使用Swarm的核心来完成这个吗?我必须使用外部服务发现吗? - Or Weinberger
不知道,因此只能发表评论而非回答。我个人不太喜欢Swarm,更喜欢Mesosphere(Zookeeper)或Kubernetes(Consul/Etcd?)。对我来说,Swarm似乎太过拼凑。 - Matt Schuchard
1个回答

2
这里只提供了部分解决方案。 因此,当将您的服务附加到自定义覆盖网络时,您确实可以访问Docker的自定义服务发现功能。在尝试将其与您的问题联系起来之前,我将详细介绍Docker Swarm模式的网络功能。
我将使用不同的术语“服务”和“任务”,其中服务可以是“elasticsearch”,而任务是该elasticsearch服务的单个实例。
Docker网络
思路是为每个创建的服务分配虚拟IP(VIP)和自定义DNS别名。您可以使用“docker service inspect myservice”命令检索此VIP。
但是,有两种模式可以将服务附加到覆盖网络中:dnsrr和VIP。您可以使用“docker service create”的“--endpoint-mode”选项选择这些选项。
VIP模式(我认为它是默认模式,或者至少是最常用的模式)会影响服务的DNS别名的虚拟IP。这意味着执行“nslookup servicename”会向您返回一个VIP,在幕后,它会以轮换方式链接到您的容器之一。但是,还有一个特殊的DNS别名,可让您访问所有实例IP(所有任务IP):“tasks.myservice”。
因此,在VIP模式下,您可以使用简单的“nslookup tasks.myservice”检索所有任务IP,其中myservice是服务名称。
另一种模式是dnsrr。此模式仅摆脱VIP,并以轮换方式将DNS别名连接到不同的任务(=服务实例)。这样,您只需执行“nslookup myservice”即可检索不同的服务实例IP。
Elasticsearch集群
首先,我不太熟悉elasticsearch让您如何进行集群。从您的问题中了解到的是,运行elasticsearch二进制文件时,需要将其作为参数给出需要与之集群的其他所有节点的地址。
因此,我会创建一个自定义的Elasticsearch映像,可能基于默认库中的映像,其中我会添加一个自定义Entrypoint,首先运行一个脚本以检索其他任务IP。
我认为保持在VIP模式下适合您,因为有“tasks.myservice”DNS别名。然后,您将需要解析输出以检索任务IP(并可能删除您的IP)。然后,您将能够将它们保存在配置文件环境变量中,或将它们用作运行时选项,用于您的elasticsearch二进制文件。

编辑:要创建自定义覆盖网络,您需要使用docker network create命令,并使用docker service create--network选项。

这个答案主要基于Swarm模式网络文档


1
这听起来是一个有效的解决方案,感谢您的撰写,我很快会尝试并告诉您它的效果如何。 - Or Weinberger
现在正在运行一个名为“elastic”的服务,使用“--endpoint-mode vip”在每台机器上各有一个副本,以测试一些东西。我在其中一个弹性容器中运行bash,但无法解析任何内容。如果我执行“ping elastic”或“ping <container_name>”或“ping node02.elastic”(node02是其中一台机器的名称),则所有这些命令都会返回“无法解析主机”。 - Or Weinberger
@OrWeinberger 你可能还需要使用 docker network create mynet 创建自己的网络,并使用 docker service create--network 选项将服务连接到该网络。 - MagicMicky
谢谢,这有点帮助,现在我可以正确解决 tasks.elastic 了,但是我现在面临一个不同的问题 - 在我的 Elasticsearch 配置中,我绑定了 0.0.0.0_eth0_,但由于某种原因,在运行覆盖网络时,我可以看到所有容器都分配了两个 IP 地址 在同一网络接口上,一个 IP 地址在所有容器之间共享(10.0.0.2),另一个 IP 地址似乎是正确的容器 IP,并且在容器之间是唯一的。当我绑定 0.0.0.0 时,它也会绑定 10.0.0.2 地址,这会阻止节点相互连接。 - Or Weinberger
这似乎很合理,因为绑定到0.0.0.0意味着绑定到所有接口。您尝试使用实际的IP地址(可能是来自eth1接口的IP地址)了吗? - MagicMicky
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接