У меня настроен DNS с подстановочными знаками, чтобы все веб-запросы к пользовательскому домену (* .foo) сопоставлялись с IP-адресом хоста Docker. Если у меня есть несколько контейнеров с экземплярами Apache (или Nginx), каждый контейнер сопоставляет порт Apache (80) с некоторым внешним входящим портом.
Что я хотел бы сделать, так это сделать запрос к container-1.foo, который уже сопоставлен с правильным IP-адресом (хоста Docker) через мой собственный DNS-сервер, но проксирует запрос порта 80 по умолчанию на правильный внешний Docker. порт, чтобы правильный экземпляр Apache из указанного контейнера мог отвечать на основе личного домена. Точно так же container-2.foo будет прокси-сервером для apache второго контейнера и так далее.
Есть ли для этого готовое решение, лучше всего запустить прокси Nginx на хосте Docker, или я должен написать прокси node.js с потенциалом для управления контейнерами Docker (запуск / остановка / восстановление через Интернет ), или же...? Какие у меня есть варианты, которые сделали бы использование контейнеров Docker более естественным явлением, а не чем-то с посторонними портами и манипуляциями с контейнерами?
Ответы:
Этот ответ может быть немного запоздалым, но вам нужен автоматический обратный прокси. Я использовал для этого два решения:
Со временем я предпочитаю использовать Traefik. В основном потому, что он хорошо документирован и поддерживается, а также имеет больше функций (балансировка нагрузки с разными стратегиями и приоритетами, проверки работоспособности, автоматические выключатели, автоматические сертификаты SSL с ACME / Let's Encrypt, ...).
Использование jwilder / nginx-proxy
При запуске образа Docker Джейсона Уайлдера nginx-proxy для контейнера Docker вы получаете сервер nginx, настроенный как обратный прокси-сервер для других ваших контейнеров без конфигурации для поддержки.
Просто запустите другие контейнеры с
VIRTUAL_HOST
переменной окружения, и nginx-proxy обнаружит их ip: port и обновит конфигурацию nginx за вас.Допустим, ваш DNS настроен так, что
*.test.local
сопоставляется с IP-адресом вашего хоста Docker, а затем просто запустите следующие контейнеры, чтобы запустить быструю демонстрацию:# start the reverse proxy docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy # start a first container for http://tutum.test.local docker run -d -e "VIRTUAL_HOST=tutum.test.local" tutum/hello-world # start a second container for http://deis.test.local docker run -d -e "VIRTUAL_HOST=deis.test.local" deis/helloworld
Использование Traefik
При запуске контейнера Traefik вы получаете настроенный обратный прокси-сервер, который будет перенастраивать свои правила пересылки с учетом меток докеров, найденных на ваших контейнерах.
Допустим, ваш DNS настроен так, что
*.test.local
сопоставляется с IP-адресом вашего хоста Docker, а затем просто запустите следующие контейнеры, чтобы запустить быструю демонстрацию:# start the reverse proxy docker run --rm -it -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock traefik:1.7 --docker # start a first container for http://tutum.test.local docker run -d -l "traefik.frontend.rule=Host:tutum.test.local" tutum/hello-world # start a second container for http://deis.test.local docker run -d -l "traefik.frontend.rule=Host:deis.test.local" deis/helloworld
источник
-v /var/run/docker.sock:/tmp/docker.sock
Это опасное решение? Контейнер этого прокси-сервера nginx имеет доступ к демону хоста докеров? Может ли это быть дыра в безопасности?/var/run/docker.sock
не является гарантией того, что хост докера не может быть использован из контейнера. Безопасность Docker - это отдельная тема.Вот два возможных ответа: (1) настроить порты напрямую с помощью Docker и использовать Nginx / Apache для прокси-сервера vhosts или (2) использовать Dokku для управления портами и vhosts для вас (именно так я научился использовать метод 1).
Метод 1а (прямое назначение портов с помощью докера)
Шаг 1. Настройте nginx.conf или Apache на хосте с желаемыми назначениями номеров портов. Этот веб-сервер, работающий на хосте, будет выполнять проксирование виртуального хоста. Что касается Docker, то здесь нет ничего особенного - это обычный хостинг vhost. Далее, на шаге 2, следует особая часть, чтобы заставить Docker использовать правильный номер порта хоста.
Шаг 2. Принудительно назначьте номера портов в Docker с помощью «-p», чтобы установить сопоставление портов Docker, и «-e», чтобы установить пользовательские переменные среды в Docker, как показано ниже:
port=12345 # <-- the vhost port setting used in nginx/apache IMAGE=myapps/container-1 id=$(docker run -d -p :$port -e PORT=$port $IMAGE) # -p :$port will establish a mapping of 12345->12345 from outside docker to # inside of docker. # Then, the application must observe the PORT environment variable # to launch itself on that port; This is set by -e PORT=$port. # Additional goodies: echo $id # <-- the running id of your container echo $id > /app/files/CONTAINER # <-- remember Docker id for this instance docker ps # <-- check that the app is running docker logs $id # <-- look at the output of the running instance docker kill $id # <-- to kill the app
Метод 1b Жестко запрограммированный порт приложения
... если ваше приложение использует жестко запрограммированный порт, например порт 5000 (т.е. не может быть настроен через переменную среды PORT, как в методе 1a), то его можно жестко запрограммировать через Docker следующим образом:
publicPort=12345 id=$(docker run -d -p $publicPort:5000 $IMAGE) # -p $publicPort:5000 will map port 12345 outside of Docker to port 5000 inside # of Docker. Therefore, nginx/apache must be configured to vhost proxy to 12345, # and the application within Docker must be listening on 5000.
Метод 2 (пусть Докку выяснит порты)
На данный момент довольно неплохим вариантом для управления хостами Docker является Dokku . Возможным вариантом может стать использование Флинна , но на данный момент Флинн только начинает работать и еще не совсем готов. Поэтому пока мы переходим к Dokku: после выполнения инструкций по установке Dokku для одного домена включите vhosts, создав файл "VHOST":
echo yourdomain.com > /home/git/VHOST # in your case: echo foo > /home/git/VHOST
Теперь, когда приложение отправляется через SSH в Dokku (см. Документацию Dokku, чтобы узнать, как это сделать), Dokku будет смотреть на файл VHOST и для конкретного отправленного приложения (скажем, вы нажали «контейнер-1»), он сгенерирует следующий файл:
И в нем будет следующее содержание:
Когда сервер перезагружается, Dokku гарантирует, что Docker запускает приложение с портом, сопоставленным с его первоначально развернутым портом (здесь 49162), вместо того, чтобы случайным образом назначать другой порт. Для достижения этого детерминированного назначения Dokku сохраняет изначально назначенный порт
/home/git/container-1/PORT
и при следующем запуске устанавливает дляPORT
среды это значение, а также сопоставляет назначения портов Docker с этим портом как на стороне хоста, так и на стороне приложения. Это отличается от первого запуска, когда Dokku установит,PORT=5000
а затем определит, какой случайный порт Dokku отображает на стороне VPS на 5000 на стороне приложения. Это нормально (и может даже измениться в будущем), но это работает!Под капотом VHOST работает так: после выполнения git push приложения через SSH Dokku выполнит обработчики, которые находятся внутри
/var/lib/dokku/plugins/nginx-vhosts
. Эти хуки также находятся здесь в исходном коде Dokku и отвечают за записьnginx.conf
файлов с правильными настройками vhost. Если у вас нет этого каталога/var/lib/dokku
, попробуйте запуститьdokku plugins-install
.источник
С помощью docker вы хотите, чтобы внутренние IP-адреса оставались нормальными (например, 80), и выясните, как подключить случайные порты.
Один из способов справиться с ними - использовать обратный прокси, такой как hipache. Направьте на него свой DNS, а затем вы сможете перенастроить прокси по мере того, как ваши контейнеры поднимаются и опускаются. Взгляните на http://txt.fliglio.com/2013/09/protyping-web-stuff-with-docker/, чтобы узнать, как это может работать.
Если вы ищете что-то более надежное, вы можете взглянуть на «обнаружение служб». (посмотрите на обнаружение службы с помощью докера: http://txt.fliglio.com/2013/12/service-discovery-with-docker-docker-links-and-beyond/ )
источник