AWS ECS jwilder / nginx-proxy не может создать серверы внутри восходящего потока

Я пытаюсь настроить jwilder / nginx-proxy как обратный прокси-сервер для запросов прокси к различным контейнерам которые предоставляют переменные среды VIRTUAL_HOST = example.com.

Настройка работает, если контейнер запускается непосредственно на узле кластера ec2, но завершается ошибкой со следующей ошибкой: «ошибка при выполнении команды уведомления: nginx -s reload, exit status 1», если он создан из ECS.

Журнал докеров контейнера, в котором запущен контейнер jwilder / nginx-proxy: WARNING: /etc/nginx/dhparam/dhparam.pem was not found. A pre-generated dhparam.pem will be used for now while a new one is being generated in the background. Once the new dhparam.pem is in place, nginx will be reloaded. forego | starting dockergen.1 on port 5000 forego | starting nginx.1 on port 5100 dockergen.1 | 2018/08/19 10:43:37 Generated '/etc/nginx/conf.d/default.conf' from 4 containers dockergen.1 | 2018/08/19 10:43:37 Running 'nginx -s reload' dockergen.1 | 2018/08/19 10:43:37 **Error running notify command: nginx -s reload, exit status 1** dockergen.1 | 2018/08/19 10:43:37 Watching docker events dockergen.1 | 2018/08/19 10:43:37 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification 'nginx -s reload' 2018/08/19 10:48:23 [emerg] 38#38: no servers are inside upstream in /etc/nginx/conf.d/default.conf:55 nginx: [emerg] no servers are inside upstream in /etc/nginx/conf.d/default.conf:55 Generating DH parameters, 2048 bit long safe prime, generator 2 This is going to take a long time dhparam generation complete, reloading nginx

Среда настроена следующим образом:

services: 
- name: proxy
  *volumes*:
  Name: docker-socket
  Source Path: /var/run/docker.sock
  *containers*: 
    - name: proxy
      image: jwilder/nginx-proxy
      port: 80:80
      Mount Points:
        Container Path: /tmp/docker.sock
        Source Volume: docker-socket
        Read only: true 
- name: site
  *containers*:
    - name: site
      image: nginx
      port: 0:80
      environment:
      - VIRTUAL_HOST=example.com

Команда для проверки:

curl -H "Host: example.com" localhost:80   

Теперь он возвращает страницу nginx по умолчанию, потому что файл конфигурации nginx не смог сгенерировать допустимую конфигурацию из-за отсутствия восходящих хостов.

Сгенерированный неверный конфиг nginx

proxy_set_header Proxy "";
server {
  server_name _; # This is just an invalid value which will never trigger on a real hostname.
  listen 80;
  access_log /var/log/nginx/access.log vhost;
  return 503;
}
# example.com
upstream example.com {
}
server {
  server_name example.com;
  listen 80 ;
  access_log /var/log/nginx/access.log vhost;
  location / {
    proxy_pass http://example.com
  }
}

Прокси работает по назначению, если используется следующая команда:

docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy

Если выполнить указанную выше команду, она выдаст следующий результат: WARNING: /etc/nginx/dhparam/dhparam.pem was not found. A pre-generated dhparam.pem will be used for now while a new one is being generated in the background. Once the new dhparam.pem is in place, nginx will be reloaded. forego | starting dockergen.1 on port 5000 forego | starting nginx.1 on port 5100 dockergen.1 | 2018/08/19 10:18:48 Generated '/etc/nginx/conf.d/default.conf' from 10 containers dockergen.1 | 2018/08/19 10:18:48 Running 'nginx -s reload' dockergen.1 | 2018/08/19 10:18:48 Watching docker events dockergen.1 | 2018/08/19 10:18:48 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification 'nginx -s reload' 2018/08/19 10:19:09 [notice] 40#40: signal process started Generating DH parameters, 2048 bit long safe prime, generator 2 This is going to take a long time dhparam generation complete, reloading nginx Сгенерированная действительная конфигурация nginx:

proxy_set_header Proxy "";
server {
  server_name _; # This is just an invalid value which will never trigger on a real hostname.
  listen 80;
  access_log /var/log/nginx/access.log vhost;
  return 503;
}
# example.com
upstream example.com {
        ## Can be connected with "bridge" network
      # ecs-site-site-add8hjasd
      server 172.17.0.3:80;
}
server {
  server_name example.com;
  listen 80 ;
  access_log /var/log/nginx/access.log vhost;
  location / {
    proxy_pass http://example.com;
  }
}

Мой вопрос: почему это не работает, это из-за разрешений или подключения к сокету докера?


person MaartenDev    schedule 19.08.2018    source источник


Ответы (2)


3 дня назад наша команда встретила этот вопрос. Мы потратили на это много времени.

Причина проблемы должна быть в AWS ecs-agent (у нас 2 среды, одна версия ecs-agent 1.21, другая 1.24)

Вчера мы решили эту проблему: с помощью консоли AWS обновить ecs-agent до последней версии: 1.34 и перезапустить ecs-agent (docker contianer). После этого проблема была решена.

Просто вставьте этот раствор сюда. Надеюсь, это будет полезно другим!

person kain    schedule 30.11.2019

Во-первых, рекомендуется избегать использования доменных имен в конфигурации Nginx, особенно при определении вышестоящих серверов. Это как минимум сбивает с толку.

Все ли ваши значения для example.com одинаковы? Если это так, у вас есть восходящий блок, который определяет восходящий серверный кластер с именем example.com, тогда у вас есть серверный блок с директивой имени сервера example.com, а затем вы пытаетесь proxy_pass на example.com.

Обычно вы указываете восходящий блок как метод балансировки нагрузки, если у вас есть несколько серверов, способных обрабатывать один и тот же запрос. Отредактируйте свой восходящий блок и включите адрес всех вышестоящих серверов: порт, вы можете включить другие параметры, чтобы настроить, как Nginx распределяет нагрузку между ними, если хотите, см. Документацию Nginx для получения дополнительной информации. Имя, которое вы даете своему восходящему блоку, используется только Nginx и может быть любым, не используйте здесь свое доменное имя. Что-то вроде:

upstream dockergroup {

Затем добавьте IP-адрес перед портом в директиве listen в блоке сервера и измените директиву proxy_pass на http://dockergroup

Я не уверен в специфике, но согласно документам на странице, которую вы связали:

вы можете. Чтобы добавить настройки для каждого VIRTUAL_HOST, добавьте файл конфигурации в /etc/nginx/vhost.d. В отличие от случая для всего прокси, который позволяет использовать несколько файлов конфигурации с любым именем, заканчивающимся на .conf, файл per-VIRTUAL_HOST должен быть назван точно после VIRTUAL_HOST.

Важные проблемы, которые необходимо решить, заключаются в том, что ваш восходящий блок не может быть пустым, а имя восходящего блока не должно конфликтовать с какими-либо доменами или именами хостов в вашей сети. Из того, что я прочитал, вы сможете исправить это, используя различные параметры конфигурации.

person miknik    schedule 19.08.2018
comment
Спасибо за предложение :) Но я не уверен, что это решит мою проблему. Я хочу иметь возможность запускать несколько контейнеров, которые прослушивают один и тот же домен (example.com), и nginx-proxy должен их выполнять циклически. Конфигурация nginx генерируется github.com/jwilder/nginx-proxy, поэтому изменять его нельзя т вариант - person MaartenDev; 19.08.2018
comment
Итак, несколько серверов, которые могут обрабатывать одни и те же запросы? - person miknik; 19.08.2018
comment
да, и все вышестоящие серверы должны быть IP + портами запущенных контейнеров докеров, которые указывают переменную среды VIRTUAL_HOST = example.com. - person MaartenDev; 19.08.2018
comment
Спасибо за обновление !, но я все еще не уверен, полностью ли вы понимаете проблему. Проблема, которую решает github.com/jwilder/nginx-proxy, заключается в том, что он использует демон docker для прослушивания новых / уничтоженных контейнеров докеров, если контейнер создан, он смотрит на переменные среды (VIRTUAL_HOST = example.com) этого контейнера, чтобы определить, какие запросы следует направлять в этот контейнер. Поскольку изменяющиеся контейнеры, он генерирует новую конфигурацию nginx каждый раз, когда контейнер создается или уничтожается. Из-за динамической конфигурации я не могу редактировать конфигурацию nginx, потому что она будет переопределена. - person MaartenDev; 19.08.2018
comment
Я боюсь, что ваше решение не будет жизнеспособным, потому что оно предполагает изменение файла, который постоянно создается. Моя проблема больше связана с платформой. Он отлично работает, если вы запускаете все контейнеры докеров на своем компьютере, но не работает, когда ECS запускает их. - person MaartenDev; 19.08.2018
comment
В опубликованной вами ссылке есть инструкции, которые расскажут вам, как настроить изменения, которые будут добавляться каждый раз при создании автоматически сгенерированного файла. - person miknik; 20.08.2018
comment
Но мне не нужно менять какую-либо конфигурацию, потому что она работает "из коробки" на моем локальном компьютере. Кажется, это связано с AWS ecs - person MaartenDev; 20.08.2018