Назад | Перейти на главную страницу

Сеть Docker Swarm Mode и балансировка нагрузки не работают для моей второй службы

Моя установка

Два узла (2 ГБ ОЗУ, 2 виртуальных процессора), на которых запущен механизм докеров (v17.06.1-ce) - один рой и один рабочий. Пропускная способность внутренней сети: 10 Гбит / с. Все файлы и базы данных находятся за пределами этого кластера докеров (AWS S3 и разные экземпляры для базы данных).

Чего я пытаюсь достичь?

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

Что я сделал до сих пор?

Во-первых, я создал оверлейную сеть и назвал ее «общедоступной». (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 не существует. Итак, я приступил к устранению неполадок.

Из swarm я нашел идентификатор экземпляра докера и попытался запустить команду из прокси 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 и сервис был создан в рабочем узле. Затем я приостановил службу в рое, используя docker pause app1-id. Когда я зашел на app1.example.com, он работал в половине случаев. Я думаю, это все еще было странно, потому что я ожидал, что Docker узнает, что служба приостановлена, и проксирует службу только на рабочий узел, но что-то еще. По крайней мере, это работало. Однако репликация app2 не помогла. Я все еще получал ошибку, что имя хоста не существует. После этого я пошел дальше и сказал рабочему узлу покинуть рой: docker swarm leave и кстати все нормально заработало ...

Потратив на это не менее 10 часов, я не понимаю, что я здесь делаю неправильно. По какой-то причине, когда сервис сначала создается в worker, Docker это не нравится.

Простите за такую ​​длинную стену текста. Я хотел поделиться всеми своими шагами. Буду очень признателен за вашу помощь.