Hazelcast TCP/IP 在 DCOS/Marathon 和 docker 上的发现

Hazelcast TCP/IP discovery on DCOS/ Marathon and docker

我在 marathon 上部署了一个 dockerized dropwizard 服务。我正在使用 Hazelcast 作为分布式缓存,我开始使用它作为我的 dropwizard 服务的一部分。我设置了一个约束以确保每个容器都在唯一的主机上启动。

   "constraints": [
        [
            "hostname",
            "UNIQUE"
        ]
    ],

我在 docker 容器上公开了 2 个端口,10012 用于我的服务,10013 用于 Hazelcast。我正在使用 Zookeeper 进行 Dropwizard 服务发现。因此,当我启动我的 Hazelcast 实例时,我可以访问我的 docker 容器所在的所有机器的主机名 运行 并且我将它们全部添加如下。

TcpIpConfig tcpIpConfig = join.getTcpIpConfig();
// finder is a handle to a service discovery service and the following gets me all the hosts on which my docker containers will run.
List<ServiceNode<ShardInfo>> nodes = finder.getAllNodes();
nodes.stream()
     .peek(serviceNode -> log.info("Adding " + serviceNode.representation() + " to hazelcast."))
     .map(serviceNode -> serviceNode.getHost())
     .forEach(host -> tcpIpConfig.addMember(host));
tcpIpConfig.setRequiredMember(null).setEnabled(true);

现刊: 如果我在 Marathon 上部署时使用网络类型作为 BRIDGE,那么我不知道 docker 容器主机,因此我的 2 docker 容器彼此不认识。它看起来像这样:

ip-10-200-2-219.ap-southeast-1.compute.internal (docker host) - 172.12.1.18 (docker container ip)

ip-10-200-2-220.ap-southeast-1.compute.internal (docker host) - 172.12.1.20 (docker container ip)

从 zookeeper 我得到 docker 主机 IP 但不是 docker 容器 IP。

如果我将网络类型用作 HOST,那么一切正常,但问题是我必须确保我的 docker 容器所在的端口 运行 始终有端口 1001 和 10013 可用。 (使用 BRIDGE,docker 容器端口绑定到随机端口)。

您可以使用 TCP/IP 发现机制并确保 hazelcast 节点绑定到 docker 容器的 public ip。尽管如果您在部署之前知道 docker 个容器 IP,此解决​​方案可能会有所帮助。

<hazelcast> ... <network> ... <join> <multicast enabled="false"> </multicast> <tcp-ip enabled="true"> <member>docker-host1</member> <member>docker-host2</member> <member>172.12.1.20</member> <member>192.168.1.21</member> </tcp-ip> ... </join> ... </network> ... </hazelcast>

分析:

这两个 docker 容器位于它们自己的网络中,本地化为从站。他们需要使用从站的 public IP 和桥接端口 5701(或您使用的任何 hazelcast 端口)相互识别。

解决方案

在TCP/IP配置中设置启动实例时的Public地址和端口。所有实例都将执行此操作,并且它们将使用马拉松从属 IP 和用于它的随机端口相互通信。

使用 marathon 提供并在容器内可用的 HOST 和 PORT_5701 变量来执行此操作。

Config hzConfig = new Config();
hzConfig.getNetworkConfig().setPublicAddress(
                             String.format("%s:%s", 
                                 System.getenv("HOST"),    
                                 System.getenv("PORT_5701")));

请参阅 hazelcast network config documentation 以进一步了解 public 地址选项。

让 hazelcast 成员发现彼此并形成一个集群是很棘手的。我最终听从了@bitsofinfo 的建议 - https://github.com/hazelcast/hazelcast/issues/9219

@santanu 的回答是正确的。 Public 需要正确设置地址,hazelcast 成员才能发现彼此。这是执行此操作的参数化方法:https://github.com/gagangoku/hazelcast-docker