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 запускается и отлично работает с тех пор.

это мой docker-compose.yml file:

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 51

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, и скорее контейнеры должны сами выполнять проверку работоспособности.

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

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

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

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

resolver 127.0.0.11

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

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

links:
  - php:waapi_php_1

Хост в разделе nginx config 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 создает записи в / etc / hosts для каждого контейнера из присвоенных имен каждому контейнеру.

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

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

container_name

в вашем 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