Почему мы (не) должны балансировать нагрузку между несколькими хосты в кластере Docker Swarm?

У нас есть 3 хоста в кластере роя, и у нас есть веб-приложение, развернутое в этом кластере. Веб-приложение будет работать только на 1 хосте в любой момент времени. Если один хост выходит из строя, веб-приложение будет перемещено на другой хост.

Docker позаботится о маршрутизации вашего запроса в веб-приложение независимо от того, на каком хосте ваш запрос попал.

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

У нас есть два подхода для этого.

A. Мы бы просто "циклически перебирали" запросы через хосты.

Это простой подход. Мы бы использовали Nginx для отключения сервисов, когда они выходили из строя. Однако, несмотря на то, что Nginx получил ошибку 500 от хоста 1, возможно, веб-приложение вернуло эту ошибку 500 с хоста 3. Nginx ошибочно подумал бы, что служба не работает на хосте 1, и отключит службу на этом хосте.

Б. Мы бы направили все запросы лидеру роя.

Мы не используем Nginx для балансировки нагрузки между хостами. Мы просто отправляем все запросы лидеру Docker Swarm (с помощью различных скриптов мы настраиваем Nginx для этого). Таким образом, мы не выполняем «двойную» балансировку нагрузки (как Nginx, так и Docker Swarm), но весь трафик проходит только через лидера Docker Swarm.

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

Какой подход мы должны - с чисто технической точки зрения - предпочесть?

1
задан 26 April 2017 в 10:17
1 ответ

Я думаю, что это комментарий к варианту 1.

Я тоже смотрю на это, и из того, что я могу сказать в Docker Swarm> 1.12, все, что вам нужно сделать, это создать реверс прокси к сервису / сайту. В своем доказательстве концепции я сделал следующее: 1) создал две оверлейные сети, одну для прокси-сети, которая будет обращена к внешней стороне, и одну для моей служебной сети, которая является внутренней только тогда; 2) развернул 3 реплики службы, прикрепив ее к служебный оверлей и оверлейный сетевой прокси-сервер (--network proxy --network my-service). Наконец, я установил обратный прокси-сервер nginx, привязанный к моему корпоративному псевдониму, который будет принимать входящие соединения на портах 80 и 443.

sudo docker service create --name proxy \ 
-p 80:80 \
-p 443:443 \
--network proxy \
--mount type=volume,source=reverse-proxy,target=/etc/nginx/conf.d,volume-driver=azurefile \
--mount type=volume,source=ssl,target=/etc/nginx/ssl,volume-driver=azurefile \
nginx

Монтирования просто есть, поэтому мне не нужно копировать файлы на каждый хост. Это подключение указывает на учетную запись хранилища файлов Azure, которая делает развертывание большего количества контейнеров более удобным для обслуживания.

Обратный прокси-сервер выглядит следующим образом:

location /my-service/ {
    proxy_read_timeout 900;                
    proxy_pass http://my-service/;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

http: // my-service - это внутренняя запись DNS для роя. который всегда указывает на VIP, на котором размещается моя служба, будь то 1 узел или 1000 узлов. Насколько я могу судить, каждая развертываемая вами служба получает собственный диапазон подсети, а главные узлы отслеживают, где работают контейнеры, и обрабатывают маршрутизацию за вас.

В настоящее время у нас есть несколько A-записей, указывающих на разные IP-адреса хоста, и для этого используется циклический перебор, однако мы можем переместить это из управляемого DNS Windows Server в диспетчер трафика Azure для большего контроля.

1
ответ дан 3 December 2019 в 23:35

Теги

Похожие вопросы