Проблема Hadoop в Docker Swarm с доступом к узлам данных

#hadoop #hdfs #docker-swarm

#hadoop #hdfs #docker-swarm

Вопрос:

В настоящее время я настраиваю кластер Hadoop на четырех машинах. У меня запущен один namenode и четыре datanode, и они взаимодействуют через оверлейную сеть docker swarm.

Теперь к проблеме: при попытке записи в HDFS извне namenode делегирует узлы данных, поэтому клиент HDFS пытается получить к ним доступ. Но адреса узлов данных, которые предоставляет namenode, находятся в интерфейсе оверлейной сети docker swarm (в моем случае 10.0.7.0 / 24), и по этой причине они не могут быть доступны извне.

Есть ли способ заставить namenode возвращать адреса узлов данных, которые доступны извне? Например, использовать общедоступные IP-адреса серверов, на которых запущены узлы данных?

Заранее спасибо!

Ответ №1:

Похоже, это проблема с VIP-режимом в оверлейной сети (по умолчанию), который, по-видимому, заставляет имя хоста главного узла указывать на другой IP, а не на соответствующий из-за поведения оверлейной сети с балансом нагрузки (источник).

Читая этот раздел в сетевой документации, я решил проблему, изменив endpoint_mode dnsrr значение, которое предотвращает сетку маршрутизации.

Обратите внимание, что dnsrr mode не поддерживает режим входа, поэтому вам необходимо указать все порты в режиме хоста, как указано в этом разделе. Имейте в виду следующее предостережение:

Если вы ожидаете запуска нескольких служебных задач на каждом узле (например, когда у вас 5 узлов, но выполняется 10 реплик), вы не можете указать статический целевой порт. Либо разрешить Docker назначать случайный порт с высоким номером (не включая опубликованный), либо гарантировать, что на данном узле выполняется только один экземпляр службы, используя глобальную службу, а не реплицируемую, или используя ограничения размещения.

Вот почему вам также необходимо добавить mode: global параметр при развертывании. Это мой последний docker-compose.yml файл, готовый к запуску в Docker Swarm:

 version: "3.6"
services:
  # Master
  master-node:
    [...] # Extra config
    ports:
      - target: 8088
        published: 8088
        protocol: tcp
        mode: host
      - target: 8080
        published: 8080
        protocol: tcp
        mode: host
      [...] # Extra ports
    deploy:
      endpoint_mode: dnsrr
      mode: global # Required by Docker Swarm to make published ports work

  # Workers (here it's not necessary to change the endpoint mode)
  worker:
    [...] # Extra config
  

Комментарии:

1. под master вы подразумеваете namenode? а рабочие узлы данных? Потому что namenode необходимо реплицировать только один раз, а не во всех узлах. только узлы данных должны быть глобальными

2. Да, именно так, как вы говорите! 🙂

3. это привело меня к некоторой путанице mode:global в вашем коде. Если это namenode, разве это не должно быть replicated: 1 ?

4. просто чтобы добавить, решение с endpoint_mode: dnsrr работает для меня 🙂 единственное отличие в том, что я не использую режим global для namenode

5. mode: global Позволяет вам использовать некоторый порт на хост-компьютере, например 8088 или 8080 (панели управления Hadoop и Spark). Если вам не нужен доступ к этим страницам, вы можете удалить глобальное пространство имен и использовать replicas: 1

Ответ №2:

Я не смог решить ее с помощью сети наложения swarm, поэтому я переключился на использование хост-сети. После этого я настроил Hadoop на использование общедоступного IP-адреса namenode и resourcemanager, и это сработало!