Сеть Docker Swarm Mode и балансировка нагрузки не работают для моего второго сервиса
Моя настройка
Два узла (2 ГБ ОЗУ, 2 vCPU) работают с механизмом докера (v17.06.1-ce) - один рой и один рабочий. Пропускная способность внутренней сети: 10 Гбит / с. Все файлы и базы данных находятся вне этого док-кластера (AWS S3 и различные экземпляры для базы данных).
Чего я пытаюсь достичь?
Я пытаюсь создать основанную на докере "платформу", где я запускаю службы без сохранения состояния и докер обрабатывает балансировку нагрузки, обновления и т. Д. Кроме того, я также пытаюсь настроить обратный прокси-сервер и разрешить определенным службам иметь доступ к этому прокси-серверу.
Что я уже сделал?
Во-первых, я создал оверлейную сеть и назвал ее "общедоступной". (10.0.9.0/24) Затем я создал сервис nginx в "глобальном" режиме. Сервис сам по себе подключен к "публичной" сети. Я проверил и мой рабочий, и роевой узлы, и служба работает в обоих из них без проблем.
Во-вторых, я создал файл docker compose для быстрого развертывания нескольких сервисов. Для моих тестов я сохранил один сервис для каждого файла:
version: '3.3'
services:
web:
image: app1_image:latest
networks:
- public
networks:
public:
external:
name: public
Для второго сервиса я просто изменил имя изображения и оставил все остальное таким же. Побежал оба "стека":
docker stack deploy --with-registry-auth --compose-file compose1.yml app1
docker stack deploy --with-registry-auth --compose-file compose2.yml app2
После проверки обеих служб я вижу, что обе службы находятся в "наложенной" сети с IP-адресами, такими как 10.0.9.5 (app1_web) и 10.0.9.6 (app2_web). app1_web
создается в роевом узле и app2_web
создается в рабочем узле.
Итак, я создаю два файла конфигурации nginx для обоих моих сервисов следующим образом:
server {
listen 80;
server_name app1.example.com;
location / {
proxy_pass http://app1_web; # This line is important
# Other proxy parameters
}
}
Как видите, я передаю имя сервиса в конфигурации nginx. Для более простого управления конфигурацией я использую настройки докера:
docker config create nginx_app1.conf app1.conf
docker config create nginx_app1.conf app1.conf
docker service update --config-add source=nginx_app1.conf,target=/etc/nginx/conf.d/app1.conf nginx_proxy
docker service update --config-add source=nginx_app2.conf,target=/etc/nginx/conf.d/app2.conf nginx_proxy
Добавление этих конфигов автоматически перезапускает службы nginx и запускает их. Это все. Я хотел дать вам суть моего процесса, прежде чем двигаться вперед.
Эта проблема
app1_web
создан в рое; поэтому, когда я захожу на app1.example.com, nginx передает мой запрос в службу, и я получаю правильный вывод. Это то, что ожидается, и я доволен результатом.
Тем не менее, потому что app2_web
создается в рабочем узле, nginx выдает мне ошибку, app2_web
не существует. Итак, я начал устранять неисправности.
Из роя я нашел идентификатор экземпляра докера и попытался запустить команду из прокси nginx:
docker exec nginx-proxy-id ping app2_web
Это дало мне ошибку "Неверный адрес". Итак, я вошел в compose2.yml и добавил порты:
ports:
- 5380:80
Когда я зашел на swarm.example.com:5380, он в основном дал мне 404. Однако, открыв тот же порт с worker.example.com:5380, открыл app2.
Я тестировал то же самое для app1. Я реплицировал app1 используя docker service scale app1=2
и служба создана в рабочем узле. Затем я приостановил службу в Swarm, используя docker pause app1-id
, Когда я заходил на app1.example.com, он работал бы в половине случаев. Я думаю, что это все еще было странно, потому что я ожидал, что Docker узнает, что служба приостановлена и только передает службу на рабочий узел, но не на что. По крайней мере, это работало. Репликация app2 не помогла, хотя. Я все еще получал ошибку, что имя хоста не существует. После этого я пошел дальше и сказал рабочему узлу покинуть рой: docker swarm leave
и по совпадению все работало нормально...
Потратив на это хотя бы 10 часов, я теряюсь из-за того, что я делаю здесь неправильно. По какой-то причине, когда служба создается в рабочем сначала, Docker это не нравится.
Извините за такую длинную стену текста. Я хотел поделиться всеми шагами, которые я сделал. Буду очень признателен за вашу помощь.