Моя установка
Два узла (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 это не нравится.
Простите за такую длинную стену текста. Я хотел поделиться всеми своими шагами. Буду очень признателен за вашу помощь.