Два отдельных кластера лесных орехов в Куберне - PullRequest
0 голосов
/ 10 октября 2018

Для обмена событиями между модулями двух разных служб в пространстве имен Kubernetes я намерен использовать Hazelcast.Это не проблема, однако, у каждой службы также есть кластер, который содержит все свои модули.

Итак, у меня есть два кластера, использующих одни и те же модули.Я достиг разделения кластеров, установив имя группы для одного из кластеров, в то время как другой имеет конфигурацию группы по умолчанию.Это работает хорошо локально, с несколькими экземплярами тестового приложения.Однако это с включенной многоадресной рассылкой.

Однако в 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>

ОБНОВЛЕНИЕ:

Я долженобратите внимание, что текущая настройка, в которой этот кластер с именем группы обнаруживается по имени службы (как таковая, она содержит только модули одной службы), фактически работает.Кластер без группы и кластер с группой работают рядом друг с другом.Только когда я переключаюсь на обнаружение на основе меток (и вовлекается другая служба), он прерывается.

ОБНОВЛЕНИЕ:

При изменении портаКластер событий, я заметил, что он все еще пытается подключиться к 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;
}

Этот метод проверяет дополнительные свойства, которые возвращаются для каждой конечной точки, возвращаемой клиентом kubernetes, для конфигурации порта Hazelcast.Если ничего не существует, он использует значение по умолчанию 5701. Я предполагаю, что это то, что нужно настроить, однако, оно не должно влиять на другой кластер, поэтому мне, возможно, придется расширить стратегию с помощью некоторой моей собственной логики.

1 Ответ

0 голосов
/ 16 октября 2018

Можно встроить несколько экземпляров 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 должен сформировать кластер со всеми другимиЭкземпляры Hazelcast в текущем пространстве имен Kubernetes, его конфигурация может выглядеть следующим образом.

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));

Тогда второй экземпляр Hazelcast мог сформировать кластер только с одним и тем же приложением.Мы могли бы сделать это разделение, задав ему параметр service-name со значением из переменных среды.

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");

Шаблон Kubernetes

Затем в шаблоне развертывания Kubernetes необходимо настроить оба параметра.порты: 5701 и 5702.

ports:
- containerPort: 5701
- containerPort: 5702

И переменная среды с именем службы:

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

Плюс, вам нужно создать две службы для каждого экземпляра Hazelcast.

kind: Service
metadata:
  name: hazelcast-shared-1
spec:
  type: ClusterIP
  selector:
    app: hazelcast-app
  ports:
  - name: hazelcast-shared
    port: 5701

kind: Service
metadata:
  name: hazelcast-separate-1
spec:
  type: ClusterIP
  selector:
    app: hazelcast-app
  ports:
  - name: hazelcast-separate
  port: 5702

Очевидно, таким же образом вы можете разделять кластеры Hazelcast, используя метки сервисов вместо имен сервисов.

...