kubernetes中的两个单独的hazelcast群集

时间:2018-10-10 07:35:19

标签: java kubernetes hazelcast

为了在Kubernetes命名空间中的两个不同服务的pod之间共享事件,我打算使用Hazelcast。这不是问题,但是,每个服务还具有一个包含其所有Pod的集群。

因此,我有两个使用相同吊舱的集群。我通过为其中一个集群设置一个组名来实现集群的分离,而另一个具有默认的组配置。这可以在本地正常运行,并具有测试应用程序的多个实例。但是,这是启用多播的。

但是,在Kubernetes中,Hazelcast使用HazelcastKubernetesDiscoveryStrategy并禁用了多播。

两个服务都有一个标签:

metadata:
  name: service-1
  labels:
    hazelcast-group: bc-events

metadata:
  name: service-2
  labels:
    hazelcast-group: bc-events

事件集群的hazelcast配置如下:

Config hzConfig = new Config("events-instance");

NetworkConfig nwConfig = new NetworkConfig();
JoinConfig joinConfig = new JoinConfig();
joinConfig.setMulticastConfig(new MulticastConfig().setEnabled(false));
joinConfig.setTcpIpConfig(new TcpIpConfig().setEnabled(false));

DiscoveryStrategyConfig k8sDiscoveryStrategy = new DiscoveryStrategyConfig("com.hazelcast.kubernetes.HazelcastKubernetesDiscoveryStrategy");
k8sDiscoveryStrategy.addProperty("namespace", "dev");
k8sDiscoveryStrategy.addProperty("resolve-not-ready-addresses", true);
k8sDiscoveryStrategy.addProperty("service-label-name", "hazelcast-group");
k8sDiscoveryStrategy.addProperty("service-label-value", "bc-events");

DiscoveryConfig discoveryConfig = new DiscoveryConfig();
discoveryConfig.addDiscoveryStrategyConfig(k8sDiscoveryStrategy);
joinConfig.setDiscoveryConfig(discoveryConfig);
nwConfig.setJoin(joinConfig);

hzConfig.setNetworkConfig(nwConfig);
hzConfig.setProperty("hazelcast.discovery.enabled", "true");

GroupConfig groupConfig = new GroupConfig("bc-events");
hzConfig.setGroupConfig(groupConfig);

共享缓存群集(没有一组的缓存)的配置是这样的(对于服务1,服务2是相同的):

Config hzConfig = new Config("service-1-app-hc");

NetworkConfig nwConfig = new NetworkConfig();
JoinConfig joinConfig = new JoinConfig();
joinConfig.setMulticastConfig(new MulticastConfig().setEnabled(false));
joinConfig.setTcpIpConfig(new TcpIpConfig().setEnabled(false));

DiscoveryStrategyConfig k8sDiscoveryStrategy = new DiscoveryStrategyConfig("com.hazelcast.kubernetes.HazelcastKubernetesDiscoveryStrategy");

k8sDiscoveryStrategy.addProperty("namespace", "dev");
k8sDiscoveryStrategy.addProperty("service-name", "service-1");
k8sDiscoveryStrategy.addProperty("resolve-not-ready-addresses", true);

DiscoveryConfig discoveryConfig = new DiscoveryConfig();
discoveryConfig.addDiscoveryStrategyConfig(k8sDiscoveryStrategy);
joinConfig.setDiscoveryConfig(discoveryConfig);
nwConfig.setJoin(joinConfig);

hzConfig.setNetworkConfig(nwConfig);
hzConfig.setProperty("hazelcast.discovery.enabled", "true");

这些hazelcast实例可以找到对方,但随后抱怨对方具有不同的组名并将IP列入黑名单。

在调试代码的同时,在处理连接请求的配置验证期间,它会尝试比较组名(bc-eventsdev),显然这是不同的。但这会被列入黑名单(我相信),从而阻止对具有相同组名的另一个实例进行验证检查。

我不确定下一步要去哪里。我无法在本地测试此配置,因为如果没有多播,它将找不到其他要加入集群的节点。我也认为配置没有任何问题。

使用的库为:

<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast</artifactId>
    <version>3.7.8</version>
</dependency>
<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast-kubernetes</artifactId>
    <version>1.1.0</version>
</dependency>

更新:

我应该注意,在当前设置下,具有组名的集群可以通过服务名称发现(因此,它仅包含一项服务的容器)。没有组的群集和具有组的群集彼此并排运行。只有当我切换到基于标签的发现(并且涉及其他服务)时,它才会中断。

更新:

当更改事件集群的端口时,我注意到它尽管安装在5801上,仍然尝试连接到5701(默认)。当然,这是有效的,因为第一个集群在5701上运行。HazelcastKubernetesDiscoveryStrategy内部有以下方法:

protected int getServicePort(Map<String, Object> properties) {
    int port = NetworkConfig.DEFAULT_PORT;
    if (properties != null) {
        String servicePort = (String) properties.get(HAZELCAST_SERVICE_PORT);
        if (servicePort != null) {
            port = Integer.parseInt(servicePort);
        }
    }
    return port;
}

此方法检查kubernetes客户端返回的每个端点返回的其他属性,以进行hazelcast端口配置。如果不存在,它将使用默认值5701。我猜这是需要配置的内容,但是,它一定不会影响其他群集,因此我可能必须使用自己的一些逻辑来扩展该策略。

1 个答案:

答案 0 :(得分:1)

可以将多个Hazelcast实例嵌入到单个POD中部署的应用程序中。然后,您可以控制集群的形成方式。它需要其他配置,但是您不必修改permalink: /:title/

样品申请

我创建了一个示例应用程序来演示其工作方式。请在此处进行检查:https://github.com/leszko/hazelcast-code-samples/tree/kubernetes-embedded-multiple/hazelcast-integration/kubernetes/samples/embedded

配置步骤

Hazelcast配置

您的应用程序中有两个Hazelcast实例,因此您需要指定它们使用的端口。另外,使用hazelcast-kubernetes插件的参数,您可以配置哪些Hazelcast实例一起构成集群。

例如,假设第一个Hazelcast实例应与当前Kubernetes命名空间中的所有其他Hazelcast实例组成一个群集,则其配置如下所示。

HazelcastKubernetesDiscoveryStrategy

然后,第二个Hazelcast实例只能与同一应用程序一起形成集群。我们可以通过给Config config = new Config(); config.getNetworkConfig().setPort(5701); config.getProperties().setProperty("hazelcast.discovery.enabled", "true"); JoinConfig joinConfig = config.getNetworkConfig().getJoin(); joinConfig.getMulticastConfig().setEnabled(false); HazelcastKubernetesDiscoveryStrategyFactory discoveryStrategyFactory = new HazelcastKubernetesDiscoveryStrategyFactory(); Map<String, Comparable> properties = new HashMap<>(); joinConfig.getDiscoveryConfig().addDiscoveryStrategyConfig(new DiscoveryStrategyConfig(discoveryStrategyFactory, properties)); 参数加上环境变量的值来进行分离。

service-name

Kubernetes模板

然后,在Kubernetes部署模板中,您需要配置两个端口:Config config = new Config(); config.getNetworkConfig().setPort(5702); config.getProperties().setProperty("hazelcast.discovery.enabled", "true"); JoinConfig joinConfig = config.getNetworkConfig().getJoin(); joinConfig.getMulticastConfig().setEnabled(false); HazelcastKubernetesDiscoveryStrategyFactory discoveryStrategyFactory = new HazelcastKubernetesDiscoveryStrategyFactory(); Map<String, Comparable> properties = new HashMap<>(); String serviceName = System.getenv("KUBERNETES_SERVICE_NAME"); properties.put("service-name", serviceName); properties.put("service-port", "5702"); joinConfig.getDiscoveryConfig().addDiscoveryStrategyConfig(new DiscoveryStrategyConfig(discoveryStrategyFactory, properties)); GroupConfig groupConfig = new GroupConfig("separate"); 5701

5702

以及带有服务名称的环境变量:

ports:
- containerPort: 5701
- containerPort: 5702

此外,您需要为每个Hazelcast实例创建两个服务。

env:
- name: KUBERNETES_SERVICE_NAME
  value: hazelcast-separate-1

很显然,您可以用相同的方式使用服务标签而不是服务名称来分隔Hazelcast群集。