Docker Swarm host не может разрешить хосты на других узлах - PullRequest
0 голосов
/ 05 октября 2018

Я следую этому очень хорошему учебнику: https://github.com/binblee/springcloud-swarm

Когда я развертываю стек в рое Docker, которое содержит один узел (только узел менеджера), он отлично работает.

docker stack deploy -c all-in-one.yml springcloud-demo

У меня есть четыре док-контейнера, один из них - Eureka Service Discovery, с которыми все три других контейнера успешно регистрируются.

Проблема в том, что когда я добавляю рабочий узел в рой, то дваконтейнеры будут развернуты на работнике, а два - на менеджере, а службы, развернутые на рабочем узле, не смогут найти сервер Eureka.

java.net.UnknownHostException: eureka: Name does not resolve

Это мой составной файл:

version: '3'
services:
  eureka:
    image: demo-eurekaserver
    ports:
      - "8761:8761"

  web:
    image: demo-web
    environment:
      - EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka

  zuul:
    image: demo-zuul
    environment:
      - EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
    ports:
      - "8762:8762"

  bookservice:
    image: demo-bookservice
    environment:
      - EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka

Кроме того, я могу получить доступ только к серверу Eureka Service Discovery на хосте, на котором он развернут.

Я думал, что при использовании «развертывания стека докера» автоматически создается оверлейная сеть, в которой все открытые портыбудет перенаправлен на хост, на котором запущена соответствующая служба:

С https://docs.docker.com/engine/swarm/ingress/:

Все узлы участвуют в iNgress маршрутизация сетки.Сетка маршрутизации позволяет каждому узлу в рое принимать соединения через опубликованные порты для любой службы, работающей в рое, даже если на узле не выполняется ни одной задачи.

Это вывод Docker Service ls :

manager:~/springcloud-swarm/compose$ docker service ls

ID                  NAME                           MODE                REPLICAS            IMAGE                                                  PORTS
rirdysi0j4vk        springcloud-demo_bookservice   replicated          1/1                 demo-bookservice:latest
936ewzxwg82l        springcloud-demo_eureka        replicated          1/1                 demo-eurekaserver:latest   *:8761->8761/tcp
lb1p8nwshnvz        springcloud-demo_web           replicated          1/1                 demo-web:latest
0s52zecjk05q        springcloud-demo_zuul          replicated          1/1                 demo-zuul:latest           *:8762->8762/tcp

и стек док-станции ps springcloud-demo :

manager:$ docker stack ps springcloud-demo
ID                  NAME                             IMAGE                      NODE            DESIRED STATE       CURRENT STATE        
o8aed04qcysy        springcloud-demo_web.1           demo-web:latest            workernode      Running             Running 2 minutes ago
yzwmx3l01b94        springcloud-demo_eureka.1        demo-eurekaserver:latest   managernode     Running             Running 2 minutes ago
rwe9y6uj3c73        springcloud-demo_bookservice.1   demo-bookservice:latest    workernode      Running             Running 2 minutes ago
iy5e237ca29o        springcloud-demo_zuul.1          demo-zuul:latest           managernode     Running             Running 2 minutes ago

ОБНОВЛЕНИЕ:

Я успешно добавил другой хост, но теперь не могу добавить третий.Я попытался пару раз, выполнив те же действия (установка докера, открытие необходимых портов, присоединение к рою) - но узел не может найти сервер Eureka с именем хоста контейнера).

ОБНОВЛЕНИЕ 2:

При проверке, что порты были открыты, я проверил конфигурацию брандмауэра:

workernode:~$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
8080                       ALLOW       Anywhere
4789                       ALLOW       Anywhere
7946                       ALLOW       Anywhere
2377                       ALLOW       Anywhere
8762                       ALLOW       Anywhere
8761                       ALLOW       Anywhere
22                         ALLOW       Anywhere

Однако - когда я пытаюсь подключиться к порту 2377 на рабочем узле изузел менеджера, я не могу:

managernode:~$ telnet xx.xx.xx.xx 2377

Trying xx.xx.xx.xx...
telnet: Unable to connect to remote host: Connection refused

Ответы [ 4 ]

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

Разобьем решение на части.Каждая часть пытается дать вам представление о решении и взаимосвязана друг с другом.

Контейнерная сеть Docker

Всякий раз, когда мы создаем контейнер без указания сети, Docker присоединяет его к мостовой сети по умолчанию. Согласно этому, .Обнаружение службы недоступно в сети по умолчанию.Для правильной работы службы обнаружения служб мы должны создать определенную пользователем сеть, поскольку она обеспечивает изоляцию, разрешение DNS и многие другие функции. Все это применимо, когда мы используем команду docker run.

Когда docker-compose используется для запуска контейнера, а сеть не указана, он создает свою собственную мостовую сеть. , которая имеет все свойства пользовательских сетей.

Эти мостовые сети по умолчанию недоступны, но они позволяют подключать к ним док-контейнеры на локальном компьютере.

Сеть роя Docker

В Сеть роя Docker и сетка маршрутизации в режиме роя Всякий раз, когда мы внедряем в нее службу без указания внешней сети, к которой она подключаетсявходная сеть.

Когда вы указываете внешнюю оверлейную сеть, вы можете заметить, что созданная оверлейная сеть будет доступна только для менеджера, а не на рабочем узле, если служба не создана и не реплицирована на нее.Они также не могут быть подключены по умолчанию и не позволяют другим контейнерам вне сервисов Swarm подключаться к ним.Таким образом, вам не нужно объявлять сеть как подключаемую, пока вы не подключите к ней контейнер вне роя.

Docker Swarm

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

Более того, вы не можете развернуть сервис непосредственно на рабочем узле.Все службы развернуты на узле диспетчера, и он заботится о репликации и масштабировании служб на основе предоставленных конфигурации и режима.

Брандмауэр

Как указано в Начало работы с режимом роя

  • TCP-порт 2377 для связи управления кластером
  • TCP и UDP-порт 7946 для связи между узлами
  • UDP-порт 4789 для наложения сетевого трафика
  • IP-протокол 50 (ESP) для зашифрованной оверлейной сети

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

Дополнительные шаги, которые необходимо выполнить в брандмауэре

Помимо внесения в белый список вышеупомянутыхпорты.Вам может понадобиться белый список IP-адресов docker0, docker_gw_bridge, br-123456 с маской сети 16. Остальное обнаружение службы не будет работать на том же хосте.то есть, если вы пытаетесь подключиться к eureka в 192.168.0.12 , где служба eureka находится в том же 192.168.0.12 , она не будет разрешена, поскольку брандмауэр заблокирует трафик. См. Это (НЕТ ROUTE TO HOST сетевой запрос от контейнера к host-ip: порт опубликован из другого контейнера)

Java

Иногда Java работает так странно, что выдает java.net.MalformedURLException и аналогичные исключения.У меня есть собственный опыт такого случая с решением .Здесь пинг разрешен правильно, но Java RMI выдает ошибку.Таким образом, вы можете определить свой собственный псевдоним при подключении к определенной пользователем сети.

Обнаружение службы Docker

По умолчанию вы можете разрешить доступ к службе, используя имя контейнера.Кроме того, вы также можете разрешить услугу как <container_name>.<network_name>.Конечно, вы также можете определить псевдоним.И даже вы можете разрешить его как <alias_name>.<network_name>.

Решение

Поэтому вы должны создать пользовательскую оверлейную сеть после присоединения к рою, а затем развернуть сервисы.В сервисах Вы должны упомянуть внешнюю сеть, как определено здесь вместе с внесением изменений в брандмауэр.

Если вы хотите разрешить внешним контейнерам подключаться к сети, вы должны создать сетьприсоединяемый.

Поскольку вы не предоставили достаточно подробностей о том, что происходит с третьим сервером.Я предполагаю, что вы пытаетесь развернуть там контейнер, который запрещен сетью наложения Docker, так как сеть не подключаема.

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

Вам необходимо создать сеть для сервисов, например:

version: '3'
services:
  eureka:
    image: demo-eurekaserver
    networks:
      - main
    ports:
      - "8761:8761"

  web:
    image: demo-web
    networks:
      - main
    environment:
      - EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka

  zuul:
    image: demo-zuul
    networks:
      - main
    environment:
      - EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka
    ports:
      - "8762:8762"

  bookservice:
    image: demo-bookservice
    networks:
      - main
    environment:
      - EUREKA_SERVER_ADDRESS=http://eureka:8761/eureka

networks:
  main:
    driver: overlay
    attachable: true

attachable: true позволяет подключаться к этой сети из другого файла компоновки (вы можете удалить его, если этоне тот случай)

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

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

Я обновил версию файла compose до «3.3», потому что, согласно документам, «endpoint_mode»: dnsrr "доступен только в версии 3.3.

С этим изменением я смог заставить его работать.

Спасибо всем, что нашли время взглянуть на мою проблему и попытатьсяразрешите это.

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

У меня такая же проблема в Amazon AWS.

Моя проблема во входе в сеть докеров.Я решил эти открытые порты в моих хостах и ​​VPC.

https://docs.docker.com/network/overlay/#customize-the-docker_gwbridge-interface

Вам нужны следующие порты, открытые для трафика к каждому хосту Docker, участвующему в оверлейной сети, и от него:

TCP-порт 2377 для связи управления кластером

TCP и UDP-порт 7946 для связи между узлами

UDP-порт 4789 для наложения сетевого трафика

...