Назад | Перейти на главную страницу

Прокси-сервер Nginx для многих контейнеров, работающих на разных узлах CoreOS

Путешествуя по сети, я нашел множество руководств по проксированию в разные контейнеры 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"который проведет вас через три контейнера.

  1. Вам нужен общий контейнер «данных», в котором вы можете хранить динамически сгенерированные конфигурации nginx.
  2. Вам нужен запущенный контейнер конфд, который будет читать значения из etcd и динамически сгенерировать для вас конфигурацию nginx (она сохраняется в томе из общего контейнера "данных")
  3. Наконец, вам понадобится 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 проверит их.

Для перемещения услуг вы можете взглянуть на парк для простого планирования.