爪哇岛库伯内特斯的两个单独的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-events
和dev
),显然这是不同的。但这会被列入黑名单(我相信),阻止对具有相同组名的其他实例进行验证检查
我不知道下一步该去哪里。我无法在本地测试此配置,因为如果没有多播,它将找不到加入集群的其他节点。我也不认为配置有任何问题
使用的库包括:
<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>
更新:
我应该注意到,在当前的设置中,这个组名为“按服务名发现”的集群(因此,它只包含一个服务的pod)实际上可以工作。没有组的集群和有组的集群同时运行。只有当我切换到基于标签的发现(以及其他服务参与)时,它才会中断
更新:
在更改events集群的端口时,我注意到它仍然尝试连接到5701(默认设置),尽管它被设置为5801。当然,这是可行的,因为第一个集群正在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;
}
对于hazelcast端口配置,此方法检查kubernetes客户端返回的每个端点的附加属性。如果不存在,则使用默认的5701。我猜这是需要配置的,但是,它不能影响其他集群,因此我可能必须使用自己的一些逻辑来扩展策略
# 1 楼答案
可以将多个Hazelcast实例嵌入部署在单个POD中的应用程序中。然后,您可以控制集群的形成方式。它需要额外的配置,但您不必修改
HazelcastKubernetesDiscoveryStrategy
示例应用程序
我创建了一个示例应用程序来演示它的工作原理。请在这里查看:https://github.com/leszko/hazelcast-code-samples/tree/kubernetes-embedded-multiple/hazelcast-integration/kubernetes/samples/embedded
配置步骤
Hazelcast配置
应用程序中有两个Hazelcast实例,因此需要指定它们使用的端口。此外,通过hazelcast-kubernetes插件的参数,您可以配置哪些Hazelcast实例一起构成集群
例如,假设第一个Hazelcast实例应该与当前Kubernetes命名空间中的所有其他Hazelcast实例形成一个集群,其配置可以如下所示
然后,第二个Hazelcast实例只能使用相同的应用程序形成集群。我们可以通过给它一个带有环境变量值的
service-name
参数来实现这种分离Kubernetes模板
然后,在Kubernetes部署模板中,您需要配置两个端口:
5701
和5702
以及具有服务名称的环境变量:
另外,您需要为每个Hazelcast实例创建两个服务
显然,以同样的方式,您可以使用服务标签而不是服务名称来分离Hazelcast集群