Путешествуя по сети, я нашел множество руководств по проксированию в разные контейнеры Docker, работающие на одном хосте, с использованием Nginx / Confd (или Haproxy, или Vulcand). Однако то, что мне нужно сделать, это другое. После обзора моей инфраструктуры:
Теперь мне нужно иметь, скажем, один прокси Nginx, который направляет мой трафик в различные контейнеры в зависимости от vhost. Следуя примеру:
Nginx (с pub IP) получает запрос xxx.domain.com
-> node-1
-> container
с автоматически назначаемым ip (прослушивание 80 порта)
Nginx (с pub IP) получает запрос yyy.domain.com
-> node-2
-> container
с автоматически назначаемым ip (прослушивание 80 порта)
Вот мои вопросы:
Заранее спасибо!
Для этого вы можете использовать трио nginx, etcd & confd. В блоге есть отличный пост под названием "Балансировка нагрузки с CoreOS, confd и nginx"который проведет вас через три контейнера.
Ключ тогда состоит в том, чтобы каждый HTTP-бэкэнд объявлял о себе через etcd, а затем confd примет изменения и перенастроит nginx на лету. Этот процесс очень близок к тому, что @Julian упомянул в предыдущем ответе:
ExecStart=<do something>
ExecStartPost=/usr/bin/etcdctl set /services/<your_service>/%i/location '{\"host\": "%H", \"port\": <your containers exposed port>}'
ExecStop=/usr/bin/docker stop <your service>
ExecStopPost=/usr/bin/etcdctl rm --recursive /services/<your_service>/%i
Проверьте confd шаблоны документов для большего количества примеров, но у вас будет что-то примерно такое:
{{range $dir := lsdir "/services/web"}}
upstream {{base $dir}} {
{{$custdir := printf "/services/web/%s/*" $dir}}{{range gets $custdir}}
server {{$data := json .Value}}{{$data.IP}}:80;
{{end}}
}
server {
server_name {{base $dir}}.example.com;
location / {
proxy_pass {{base $dir}};
}
}
{{end}}
Обратите внимание: вам понадобится только одна из этих «троек», если вы не хотите более высокую доступность, и в этом случае вам понадобятся две или более. Когда вы переходите на HA, вы, вероятно, захотите предоставить им экземпляр ELB.
Не знаю, правильно ли я понял. Но вот как я это сделаю:
Поместите балансировщик нагрузки (HAProxy, Nginx, Amazon ELB (если вы используете EC2)) за пределами кластера, маршрутизируя каждый трафик внутри него.
Внутри вы можете попробовать Гогету: https://github.com/arkenio/gogeta
Это обратный прокси-сервер, работающий глобально (на каждом узле) и маршрутизирующий трафик на основе записей домена в etcd в определенные контейнеры. Затем вы можете настроить свои служебные файлы, добавляя и удаляя их присутствие в etcd, который отслеживает gogeta.
ExecStart=<do something>
ExecStartPost=/usr/bin/etcdctl set /services/<your_service>/%i/location '{\"host\": "%H", \"port\": <your containers exposed port>}'
ExecStop=/usr/bin/docker stop <your service>
ExecStopPost=/usr/bin/etcdctl rm --recursive /services/<your_service>/%i
Он работает и запрашивает балансировку нагрузки со стратегией Round Robin. Хотя, похоже, есть проблема, которую я подал https://github.com/arkenio/gogeta/issues/10
Вам это поможет?
Для того, чтобы nginx мог «находить» контейнеры, работающие на узлах, вам нужен какой-то тип обнаружения служб. Вы можете записать в etcd запись при запуске контейнера и удалить его при выходе, а nginx проверит их.
Для перемещения услуг вы можете взглянуть на парк для простого планирования.