#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 для namenode5.
mode: global
Позволяет вам использовать некоторый порт на хост-компьютере, например 8088 или 8080 (панели управления Hadoop и Spark). Если вам не нужен доступ к этим страницам, вы можете удалить глобальное пространство имен и использоватьreplicas: 1
Ответ №2:
Я не смог решить ее с помощью сети наложения swarm, поэтому я переключился на использование хост-сети. После этого я настроил Hadoop на использование общедоступного IP-адреса namenode и resourcemanager, и это сработало!