#nginx #docker #load-balancing #docker-swarm
#nginx #docker #балансировка нагрузки #docker-swarm
Вопрос:
У меня есть контейнер nginx, работающий как сервис в Docker Swarm внутри созданной пользователем оверлейной сети. Оба созданы с:
docker network create --driver overlay proxy
docker service create --name proxy --network proxy -p 80:80 nginx
При доступе к сайту nginx через браузер в журнале удаленного доступа nginx адрес регистрируется как 10.255… форматированный адрес, который, как я полагаю, является адресом балансировщика нагрузки Swarm. Вопрос в том, как узнать / зарегистрировать адрес конечного клиента, обращающегося к сайту, а не адрес балансировщика нагрузки.
Ответ №1:
Хороший улов!, Большинство людей, анализирующих nginx access.log
и IP-адрес клиента, являются важной частью этого.
В версии docker 1.12.1 проблема существует. nginx будет регистрировать наложенный IP-адрес swarm. Но IP-адрес клиента регистрируется нормально как отдельный контейнер. В качестве обходного пути вы можете reverse proxy
указать на службу swarm. Я знаю, что это противоречит High availablity
концепции swarm и Self Healing
концепции swarm, но, похоже, сейчас это единственное решение.
пример конфигурации: (предположим, что служба swarm прослушивает 8081 на локальном хосте)
server {
listen 80 default_server;
location / {
proxy_set_header Host $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;
proxy_pass http://localhost:8181;
proxy_read_timeout 90;
}
}
Дополнительную информацию можно найти по этой проблеме на github.
Другой вариант:
Вы можете использовать сеть в режиме хоста.
docker service create
--name nginx
--network <your overlay network>
--publish mode=host,target=80,published=80
--publish mode=host,target=443,published=443
--replicas 1
nginx
Комментарии:
1. Я хотел бы отметить, что использование этого в производственной среде представляет угрозу безопасности, особенно если ваше приложение использует эти значения для проверки клиента. Заголовки X-Real-IP и X-Forwarded могут быть легко подделаны, и на них не следует полагаться.
2. @tkeeler с помощью haproxy вы можете отменить настройку переменных в http-запросе и установить реальное значение в ответе
3. @c4f4t0r — только если вы ограничиваете все HTTP-запросы haproxy. В противном случае кто-то может отправить запрос непосредственно на сервер, минуя вашу перезапись haproxy.
4. @tkeeler Я думаю, что сервис должен быть доступен миру только с использованием lb, и никто не может использовать один единственный сервер.
Ответ №2:
Итак, способ, которым я работал над этим на данный момент, заключается в использовании mode=host
опции для публикации порта и привязки прокси-контейнера к одному узлу следующим образом:
docker service create
--name proxy
--network proxy
--publish mode=host,target=80,published=80
--publish mode=host,target=443,published=443
--constraint 'node.hostname == myproxynode'
--replicas 1
letsnginx
Комментарии:
1.
mode=host
опция была добавлена в Docker 1.13, и это то, что я сейчас тоже делаю.
Ответ №3:
Нам пришлось решить проблему идентификации реальных IP-адресов клиентов для нашего производственного развертывания Docker Swarm, работающего https://www.newsnow.co.uk / ( mode=host
это был не вариант, так как нам нужно было запустить несколько реплик на нескольких узлах).
Чтобы решить эту проблему, мы создали: https://github.com/newsnowlabs/docker-ingress-routing-daemon , демон, который изменяет маршрутизацию входящей ячеистой сети, чтобы предоставлять истинные IP-адреса клиентов сервисным контейнерам.