Docker Networking-nginx: [emerg] хост не найден в upstream

недавно я начал переход на Docker 1.9 и Docker-Compose 1.5 сетевые функции для замены с помощью ссылок.

до сих пор со ссылками не было проблем с подключением nginx к моему серверу php5-fpm fastcgi, расположенному на другом сервере в одной группе через docker-compose. Недавно, хотя, когда я бегу docker-compose --x-networking up мои php-fpm, Mongo и nginx контейнеры загружаются, однако nginx выходит сразу с [emerg] 1#1: host not found in upstream "waapi_php_1" in /etc/nginx/conf.d/default.conf:16

однако, если я снова запустил команду docker-compose пока контейнеры php и mongo работают (nginx вышел), nginx запускается и отлично работает с этого момента.

это мой :

nginx:
  image: nginx
  ports:
    - "42080:80"
  volumes:
    - ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro

php:
  build: config/docker/php
  ports:
    - "42022:22"
  volumes:
    - .:/var/www/html
  env_file: config/docker/php/.env.development

mongo:
  image: mongo
  ports:
    - "42017:27017"
  volumes:
    - /var/mongodata/wa-api:/data/db
  command: --smallfiles

это мой default.conf для nginx:

server {
    listen  80;

    root /var/www/test;

    error_log /dev/stdout debug;
    access_log /dev/stdout;

    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/.+.php(/|$) {
        # Referencing the php service host (Docker)
        fastcgi_pass waapi_php_1:9000;

        fastcgi_split_path_info ^(.+.php)(/.*)$;
        include fastcgi_params;

        # We must reference the document_root of the external server ourselves here.
        fastcgi_param SCRIPT_FILENAME /var/www/html/public$fastcgi_script_name;

        fastcgi_param HTTPS off;
    }
}

как я могу заставить nginx работать только с одним вызовом docker-compose?

12 ответов


существует возможность использовать" volumes_from " в качестве обходного пути, пока не будет введена функция depends_on (обсуждается ниже). Все, что вам нужно сделать, это изменить файл docker-compose, как показано ниже:

nginx:
  image: nginx
  ports:
    - "42080:80"
  volumes:
    - ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
  volumes_from:
    - php

php:
  build: config/docker/php
  ports:
    - "42022:22"
  volumes:
    - .:/var/www/html
  env_file: config/docker/php/.env.development

mongo:
  image: mongo
  ports:
    - "42017:27017"
  volumes:
    - /var/mongodata/wa-api:/data/db
  command: --smallfiles

одно большое предостережение в приведенном выше подходе заключается в том, что Тома php подвергаются воздействию nginx, что нежелательно. Но на данный момент это один конкретный обходной путь docker, который можно использовать.

функция depends_on Это, вероятно, будет футуристическим ответ. Потому что функциональность еще не реализована в Docker (по состоянию на 1.9)

есть предложение ввести "depends_on" в новую сетевую функцию, введенную Docker. Но есть долгая дискуссия о том же @ https://github.com/docker/compose/issues/374 следовательно, как только он будет реализован, функция depends_on может быть использована для заказа запуска контейнера, но на данный момент вам придется прибегнуть к одному из следующий:

  1. сделать nginx повторить попытку, пока сервер php не будет-я бы предпочел этот
  2. используйте volums_from обходной путь, как описано выше - я бы избегал этого, из-за утечки объема в ненужные контейнеры.

Это можно решить с помощью упомянутого depends_on директива, так как она реализована сейчас (2016):

version: '2'
  services:
    nginx:
      image: nginx
      ports:
        - "42080:80"
      volumes:
        - ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
      depends_on:
        - php

    php:
      build: config/docker/php
      ports:
        - "42022:22"
      volumes:
        - .:/var/www/html
      env_file: config/docker/php/.env.development
      depends_on:
        - mongo

    mongo:
      image: mongo
      ports:
        - "42017:27017"
      volumes:
        - /var/mongodata/wa-api:/data/db
      command: --smallfiles

успешно протестировано с помощью:

$ docker-compose version
docker-compose version 1.8.0, build f3628c7

найти более подробную информацию в документация.

есть также очень интересная статья, посвященная этой теме: управление порядком запуска в Compose


вы можете установить директивы max_fails и fail_timeout nginx, чтобы указать, что nginx должен повторить x количество запросов на подключение к контейнеру перед сбоем на недоступности вышестоящего сервера.

вы можете настроить эти два номера в соответствии с вашей инфраструктурой и скоростью, с которой вся настройка подходит. Вы можете прочитать более подробную информацию о разделе проверки работоспособности ниже URL-АДРЕС: http://nginx.org/en/docs/http/load_balancing.html

Ниже приводится выдержка из http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server max_fails=number

устанавливает количество неудачных попыток связаться с сервер, который должен произойти в течение времени, заданного fail_timeout параметр, чтобы считать сервер недоступным в течение срока также установлен параметром fail_timeout. По умолчанию количество неудачных попытки устанавливается в 1. Нулевое значение отключает учет попытки. Что считается неудачной попыткой определяется proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, директивы scgi_next_upstream и memcached_next_upstream.

fail_timeout=time

задает время, в течение которого указанное число неудачных попытки связаться с сервером должны учитывать сервер недоступен; и период времени, в течение которого сервер будет считается недоступным. По умолчанию параметр имеет значение 10 считанные секунды.

чтобы быть точным, ваш измененный файл конфигурации nginx должен быть следующим (этот скрипт предполагает, что все контейнеры по крайней мере на 25 секунд, если нет, измените fail_timeout или max_fails в разделе ниже по потоку): Примечание: Я не тестировал сценарий сам, так что вы можете попробовать!

upstream phpupstream {
   waapi_php_1:9000 fail_timeout=5s max_fails=5;
}
server {
    listen  80;

    root /var/www/test;

    error_log /dev/stdout debug;
    access_log /dev/stdout;

    location / {
        # try to serve file directly, fallback to app.php
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/.+\.php(/|$) {
        # Referencing the php service host (Docker)
        fastcgi_pass phpupstream;

        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;

        # We must reference the document_root of the external server ourselves here.
        fastcgi_param SCRIPT_FILENAME /var/www/html/public$fastcgi_script_name;

        fastcgi_param HTTPS off;
    }
}

также, согласно следующая записка от докера (https://github.com/docker/compose/blob/master/docs/networking.md), очевидно, что логика повтора для проверки работоспособности других контейнеров не является ответственностью докера, а контейнеры должны сами выполнять проверку работоспособности.

обновление контейнеров

Если вы измените конфигурацию службы и запустите docker-compose чтобы обновить его, старый контейнер будет быть удалены и новый присоединится к сети под другим IP-адресом, но с тем же именем. Запущенные контейнеры смогут найти это имя и подключиться к новый адрес, но старый адрес перестанет работать.

Если любые контейнеры имеют соединения открытые к старому контейнеру, то они будут закрывать. Это ответственность контейнера, чтобы обнаружить это условие, найдите имя снова и снова подключитесь.


Я считаю, что Nginx не учитывает Docker resolver (127.0.0.11), поэтому, пожалуйста, попробуйте добавить:

resolver 127.0.0.11

в вашем файле конфигурации nginx?


имел ту же проблему и решил ее. Пожалуйста, добавьте следующую строку в docker-compose.раздел yml nginx:

links:
  - php:waapi_php_1

Хост в разделе конфигурации nginx fastcgi_pass должен быть связан внутри docker-compose.конфиг nginx в формате YML.


если вы не так потеряны для чтения последнего комментария. Я пришел к другому решению.

основная проблема заключается в том, как вы назвали имена служб.

в этом случае, если в вашей docker-compose.yml, сервис для php называется " api " или что-то в этом роде, вы должны убедиться, что в файле nginx.conf строка, начинающаяся с fastcgi_pass имеют то же имя, что и служба php. я.е fastcgi_pass api:9000;


имеют ту же проблему, пока не было в docker-compose.YML определены две сети: backend и frontend. При запуске всех контейнеров в одной сети по умолчанию все работает нормально.


со ссылками применяется порядок запуска контейнера. Без ссылок контейнеры могут запускаться в любом порядке (или действительно все сразу).

Я думаю, что старая настройка могла бы поразить ту же проблему, если waapi_php_1 контейнер медленно запускался.

Я думаю, чтобы заставить его работать, вы можете создать скрипт nginx entrypoint, который опрашивает и ждет, пока контейнер php будет запущен и готов.

Я не уверен, что nginx имеет какой-либо способ повторить попытку подключение к восходящему потоку автоматически, но если это так, это было бы лучшим вариантом.


вы должны использовать что-то вроде docker-gen для динамического обновления конфигурации nginx, когда ваш бэкэнд вверх.

посмотреть:

Я считаю, что Nginx+ (премиум-версия) также содержит параметр resolve (http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream)


возможно, лучший выбор, чтобы избежать проблем с контейнерами, - это docker networking особенности

но чтобы сделать эту работу, docker создает записи в /и т. д./хосты для каждого контейнера из присвоенных имен каждому контейнеру.

с docker-compose --x-networking-up это что-то вроде [docker_compose_folder]-[сервис]-[incremental_number]

чтобы не зависеть от неожиданных изменений в этих названиях вы должны использовать параметр

имя контейнера

в вашем docker-compose.yml следующим образом:

php:
      container_name: waapi_php_1
      build: config/docker/php
      ports:
        - "42022:22"
      volumes:
        - .:/var/www/html
      env_file: config/docker/php/.env.development

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


добавить ссылки раздел конфигурации контейнера nginx.

вы должны сделать видимыми php контейнер nginx контейнер.

nginx:
  image: nginx
  ports:
    - "42080:80"
  volumes:
    - ./config/docker/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
  links:
    - php:waapi_php_1

вот как я это сделаю, лучший способ, который я могу придумать.

ADD root /

RUN cp /etc/hosts /etc/hosts.tmp && \
    echo -e "\
127.0.0.1 code_gogs_1 \n\
127.0.0.1 pm_zentao_1 \n\
127.0.0.1 ci_drone_1 \n\
    " >> /etc/hosts && \
    nginx -t && \
# mv: can't rename '/etc/hosts.tmp': Resource busy
# mv /etc/hosts.tmp /etc/hosts
    cat /etc/hosts.tmp > /etc/hosts && \
    rm /etc/hosts.tmp