Обновление II
Сейчас 16 июля 2015 года, и все снова изменилось. Я обнаружил этот автомагический контейнер от Джейсона Уайлдера :
https://github.com/jwilder/nginx-proxy
и он решает эту проблему примерно столько же, сколько требуется дляdocker run
контейнера. Теперь это решение, которое я использую для решения этой проблемы.
Обновить
Сейчас июль 2015 года, и ситуация кардинально изменилась в отношении сетевых контейнеров Docker. Сейчас существует множество различных предложений, которые решают эту проблему (разными способами).
Вы должны использовать этот пост, чтобы получить общее представление о
docker --link
подходе к обнаружению сервисов, который настолько прост, насколько это возможно, работает очень хорошо и на самом деле требует меньше фантазий, чем большинство других решений. Он ограничен тем, что довольно сложно объединить контейнеры на отдельные хосты в любом данном кластере, и контейнеры не могут быть перезапущены после подключения к сети, но предлагают быстрый и относительно простой способ объединения контейнеров в сеть на одном и том же хосте. Это хороший способ получить представление о том, что программное обеспечение, которое вы, вероятно, будете использовать для решения этой проблемы, на самом деле делает под капотом.Кроме того, вы , вероятно , хотите , чтобы также проверить зарождающейся Docker в
network
, Hashicorp - хconsul
, Weaveworksweave
, Джефф Линдсейprogrium/consul
иgliderlabs/registrator
, и компании GoogleKubernetes
.Там также CoreOS предложения , которые используют
etcd
,fleet
иflannel
.И если вы действительно хотите устроить вечеринку, вы можете запустить кластер
Mesosphere
, илиDeis
, илиFlynn
.Если вы новичок в нетворкинге (как и я), то вам следует достать очки для чтения, включить «Раскрась небо звездами - лучшее из Энии» по Wi-Fi и выпить пива - это будет некоторое время, прежде чем вы действительно поймете, что именно вы пытаетесь сделать. Подсказка: вы пытаетесь реализовать
Service Discovery Layer
в своемCluster Control Plane
. Это очень хороший способ провести субботний вечер.Это очень весело, но мне жаль, что я не нашел время, чтобы лучше узнать о сетях в целом, прежде чем сразу погрузиться в них. В конце концов я нашел пару сообщений от доброжелательных богов Digital Ocean Tutorial:
Introduction to Networking Terminology
иUnderstanding ... Networking
. Я предлагаю сначала прочитать их несколько раз, прежде чем погрузиться в них.Радоваться, веселиться!
Исходный пост
Кажется, я не могу понять отображение портов для Docker
контейнеров. В частности, как передавать запросы от Nginx в другой контейнер, прослушивая другой порт на том же сервере.
У меня есть Dockerfile для контейнера Nginx:
FROM ubuntu:14.04
MAINTAINER Me <me@myapp.com>
RUN apt-get update && apt-get install -y htop git nginx
ADD sites-enabled/api.myapp.com /etc/nginx/sites-enabled/api.myapp.com
ADD sites-enabled/app.myapp.com /etc/nginx/sites-enabled/app.myapp.com
ADD nginx.conf /etc/nginx/nginx.conf
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80 443
CMD ["service", "nginx", "start"]
И тогда api.myapp.com
конфигурационный файл выглядит так:
upstream api_upstream{
server 0.0.0.0:3333;
}
server {
listen 80;
server_name api.myapp.com;
return 301 https://api.myapp.com/$request_uri;
}
server {
listen 443;
server_name api.mypp.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
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_cache_bypass $http_upgrade;
proxy_pass http://api_upstream;
}
}
А потом еще один app.myapp.com
.
А потом бегу:
sudo docker run -p 80:80 -p 443:443 -d --name Nginx myusername/nginx
И все это работает нормально, но запросы не проходят через другие контейнеры / порты. И когда я ssh в контейнер Nginx и просматриваю журналы, я не вижу ошибок.
Любая помощь?
Ответы:
Ответ @T0xicCode правильный, но я подумал, что расскажу подробнее, поскольку на самом деле мне потребовалось около 20 часов, чтобы наконец реализовать рабочее решение.
Если вы хотите запустить Nginx в собственном контейнере и использовать его в качестве обратного прокси для балансировки нагрузки нескольких приложений на одном экземпляре сервера, вам необходимо выполнить следующие шаги:
Свяжите свои контейнеры
Когда вы используете
docker run
свои контейнеры, обычно путем ввода сценария оболочкиUser Data
, вы можете объявлять ссылки на любые другие запущенные контейнеры. Это означает, что вам нужно запускать свои контейнеры по порядку, и только последние контейнеры могут связываться с первыми. Вот так:Таким образом , в этом примере,
API
контейнер не связан ни с какими другими, ноApp
контейнер связанAPI
иNginx
связан с какAPI
иApp
.Результатом этого является изменения в
env
Варс и/etc/hosts
файлы , которые находятся в пределахAPI
иApp
контейнеров. Результаты выглядят так:/ etc / hosts
Запуск
cat /etc/hosts
в вашемNginx
контейнере приведет к следующему:ENV Vars
Запуск
env
в вашемNginx
контейнере приведет к следующему:Я усек многие фактические вары, но это ключевые значения, необходимые для прокси-трафика в ваши контейнеры.
Чтобы получить оболочку для выполнения вышеуказанных команд в работающем контейнере, используйте следующее:
sudo docker exec -i -t Nginx bash
Вы можете видеть, что теперь у вас есть как
/etc/hosts
записи файлов, так иenv
вары, содержащие локальный IP-адрес для любого из связанных контейнеров. Насколько я могу судить, это все, что происходит, когда вы запускаете контейнеры с объявленными параметрами ссылки. Но теперь вы можете использовать эту информацию для настройкиnginx
в своемNginx
контейнере.Настройка Nginx
Здесь все становится немного сложнее, и есть несколько вариантов. Вы можете настроить свои сайты так, чтобы они указывали на запись в созданном
/etc/hosts
файлеdocker
, или вы можете использоватьENV
vars и запустить замену строки (я использовалsed
) в вашемnginx.conf
и любых других файлах conf, которые могут быть в вашей/etc/nginx/sites-enabled
папке, чтобы вставить IP ценности.ВАРИАНТ А. Настройка Nginx с использованием переменных ENV
Ключевое различие между этой опцией и использованием
/etc/hosts
опции файла заключается в том, как вы пишете,Dockerfile
чтобы использовать сценарий оболочки в качествеCMD
аргумента, который, в свою очередь, обрабатывает замену строки для копирования значений IPENV
в ваш файл (ы) conf.Вот набор файлов конфигурации, которые у меня остались:
Dockerfile
nginx.conf
api.myapp.conf
Nginx-Startup.sh
Я оставлю вам делать домашнюю работу по большей части содержимого
nginx.conf
иapi.myapp.conf
.Магия происходит в
Nginx-Startup.sh
которой мы используем ,sed
чтобы сделать замену строки наAPP_IP
заполнитель , который мы написали вupstream
блок нашихapi.myapp.conf
иapp.myapp.conf
файлов.Этот вопрос на ask.ubuntu.com очень хорошо объясняет: поиск и замена текста в файле с помощью команд
Итак, докер запустил наш контейнер и запустил
Nginx-Startup.sh
скрипт для запуска, который использовалсяsed
для изменения значенияAPP_IP
соответствующейENV
переменной, которую мы указали вsed
команде. Теперь у нас есть файлы conf в нашем/etc/nginx/sites-enabled
каталоге, которые имеют IP-адреса изENV
переменных, которые докер установил при запуске контейнера. В вашемapi.myapp.conf
файле вы увидите, чтоupstream
блок изменился на этот:Видимый вами IP-адрес может быть другим, но я заметил, что это обычно
172.0.0.x
.Теперь у вас должна быть правильная маршрутизация.
ВАРИАНТ Б: Использование
/etc/hosts
файловых записейЭто должен быть более быстрый и простой способ сделать это, но я не мог заставить его работать. Якобы вы просто ввести значение
/etc/hosts
вступления в вашихapi.myapp.conf
иapp.myapp.conf
файлов, но я не мог получить этот метод работы.Вот попытка, которую я предпринял
api.myapp.conf
:Учитывая, что в моем
/etc/hosts
файле есть такая запись :172.0.0.2 API
я подумал, что она просто получит значение, но, похоже, это не так.У меня также была пара дополнительных проблем с моими
Elastic Load Balancer
источниками из всех АЗ, так что это могло быть проблемой, когда я пробовал этот маршрут. Вместо этого мне пришлось научиться обрабатывать замену строк в Linux, так что это было весело. Я попробую через некоторое время и посмотрю, как это пойдет.источник
Я попытался использовать популярный обратный прокси-сервер Джейсона Уайлдера, который волшебным образом работает для всех, и узнал, что он работает не для всех (то есть для меня). И я новичок в NGINX, и мне не понравилось, что я не разбирался в технологиях, которые пытался использовать.
Хотел добавить свои 2 цента, потому что приведенное выше обсуждение
linking
контейнеров вместе теперь устарело, поскольку это устаревшая функция. Итак, вот объяснение того, как это сделать с помощьюnetworks
. Этот ответ является полным примером настройки nginx в качестве обратного прокси для статически выгружаемого веб-сайта с использованиемDocker Compose
конфигурации nginx.TL; DR;
Добавьте службы, которым необходимо общаться друг с другом, в заранее заданную сеть. Для пошагового обсуждения сетей Docker я кое-что узнал здесь: https://technologyconversations.com/2016/04/25/docker-networking-and-dns-the-good-the-bad-and- уродливый /
Определите сеть
Прежде всего, нам нужна сеть, по которой могут общаться все ваши серверные службы. Я позвонил в свой,
web
но это может быть что угодно.Создайте приложение
Мы просто сделаем простое приложение для веб-сайта. Веб-сайт представляет собой простую страницу index.html, обслуживаемую контейнером nginx. Содержимое - это подключенный том к хосту в папке
content
DockerFile:
default.conf
docker-compose.yml
Обратите внимание, что здесь нам больше не нужно сопоставление портов. Мы просто открываем порт 80. Это удобно, чтобы избежать конфликтов портов.
Запустите приложение
Запустите этот сайт с помощью
Несколько забавных проверок сопоставлений DNS для вашего контейнера:
Этот пинг должен работать внутри вашего контейнера.
Создайте прокси
Обратный прокси Nginx:
Dockerfile
Мы сбрасываем всю конфигурацию виртуального хоста, так как собираемся настроить ее.
docker-compose.yml
Запустите прокси
Запустите прокси с помощью наших надежных
Предполагая, что проблем нет, у вас есть два запущенных контейнера, которые могут общаться друг с другом, используя свои имена. Давайте проверим это.
Настроить виртуальный хост
Последняя деталь - настроить файл виртуального хостинга, чтобы прокси мог направлять трафик в зависимости от того, что вы хотите настроить:
sample-site.conf для конфигурации нашего виртуального хостинга:
В зависимости от того, как был настроен прокси, вам понадобится этот файл, хранящийся в вашей локальной
conf.d
папке, которую мы смонтировали с помощьюvolumes
объявления вdocker-compose
файле.И последнее, но не менее важное: скажите nginx перезагрузить его конфигурацию.
Эта последовательность шагов - кульминация многих часов головной боли, когда я боролся с болезненной ошибкой 502 Bad Gateway и впервые изучал nginx, поскольку большую часть моего опыта я получил с Apache.
Этот ответ демонстрирует, как устранить ошибку 502 Bad Gateway, которая возникает из-за того, что контейнеры не могут взаимодействовать друг с другом.
Я надеюсь, что этот ответ избавит кого-то от нескольких часов боли, поскольку по какой-то причине было действительно сложно понять, как контейнеры разговаривают друг с другом, несмотря на то, что я ожидал очевидного варианта использования. Но опять же, я тупой. И, пожалуйста, дайте мне знать, как я могу улучшить этот подход.
источник
502 Gateway Error
, печально известная классика наших дней. Спасибо @gdbj за потраченное время на продвижение разговора и предоставление такого подробного решения.Используя ссылки докеров , вы можете связать восходящий контейнер с контейнером nginx. Дополнительная функция заключается в том, что докер управляет файлом хоста, что означает, что вы сможете ссылаться на связанный контейнер, используя имя, а не потенциально случайный IP-адрес.
источник
«Вариант B» AJB можно заставить работать, используя базовый образ Ubuntu и настраивая nginx самостоятельно. (Это не сработало, когда я использовал образ Nginx из Docker Hub.)
Вот файл Docker, который я использовал:
Моя конфигурация nginx (также известная как conf / mysite.com):
И наконец, как я запускаю свои контейнеры:
Это заставило меня работать, поэтому мой nginx направил восходящий поток на второй контейнер докеров, который открыл порт 3000.
источник
upstream website {
определяет ценность сайта для nginx. Это то, что вы затем используете в своемproxy_pass
. Часть этого докера просто использует то же имя для согласованности, но не имеет ничего общего с настройкой nginx. Чтобы было немного понятнее, прокси-пропуск должен читать:upstream website { server localhost:3000; }
Ответ @gdbj - отличное объяснение и самый последний ответ. Однако есть более простой подход.
Поэтому, если вы хотите перенаправить весь трафик с nginx, прослушивающего
80
другой контейнер8080
, минимальная конфигурация может быть всего:nginx.conf:
docker-compose.yml
Документы Docker
источник
Только что нашел статью от Ананда Мани Санкара, в которой показан простой способ использования прокси-сервера nginx с docker composer.
По сути, необходимо настроить связывание экземпляров и порты в файле docker-compose и соответственно обновить восходящий поток в nginx.conf.
источник
links
устаревшие. Используйте сети прямо сейчас: docs.docker.com/engine/userguide/networking