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

Просматривая сеть, я нашел много уроков по проксированию для различных контейнеров Docker, работающих на одном хосте, с использованием Nginx/Confd (или Haproxy, или Vulcand). Однако то, что мне нужно сделать, это другое. После обзора моей инфраструктуры:

  • Онлайн-кластер CoreOS с 5 узлами, все работают под управлением etcd
  • На каждом узле кластера запускаются различные контейнеры Docker (веб-серверы Nginx, на которых выполняются приложения WordPress) с использованием флота, без указания порта и записи своих ips (Docker ip, взятый с помощью docker inspect) на etcd.
  • Если узел выходит из строя, мои услуги автоматически перемещаются на другой доступный узел

Теперь мне нужно иметь, скажем, один прокси-сервер Nginx, который направляет мой трафик в различные контейнеры в зависимости от vhost. Следующий пример:

Nginx (с IP-адресом паба) получает запрос xxx.domain.com -> node-1 -> container с автоматически назначенным ip (прослушивание порта 80)

Nginx (с IP-адресом паба) получает запрос yyy.domain.com -> node-2 -> container с автоматически назначенным ip (прослушивание порта 80)

Вот мои вопросы:

  • Это мой сценарий правильный? Я думаю, что-то не так?
  • Мой прокси Nginx должен быть вне кластера CoreOS? Или я должен запустить его на каждом узле CoreOS?
  • Как я могу добиться этой конфигурации? Какой лучший способ?

Заранее спасибо!

3 ответа

Чтобы nginx мог "найти" контейнеры, работающие на узлах, вам нужно найти какой-то тип службы. Вы можете записать запись в etcd при запуске контейнера и удалить при выходе, чтобы nginx проверил их.

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

Вы можете использовать трио nginx, etcd & confd, чтобы сделать это. В блоге под названием " Балансировка нагрузки с помощью CoreOS, confd и nginx " рассказывается о запуске трех контейнеров.

  1. Вам нужен общий контейнер данных, в котором вы можете хранить динамически сгенерированные конфигурации nginx
  2. Вам нужен контейнер, запускающий confd, который будет считывать значения из etcd и динамически генерировать для вас конфигурацию nginx (она сохраняется в томе из общего контейнера "data")
  3. Наконец, вам понадобится nginx, который просто использует этот общий том "data" для своих конфигураций.

Ключом к этому является то, что каждый 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)) вне кластера, маршрутизирующего каждый трафик внутри него.

Внутри вы можете попробовать Gogeta: 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

Это тебе помогает?

Другие вопросы по тегам