Docker 네트워킹-nginx : [emerg] 호스트를 업스트림에서 찾을 수 없음


98

최근에 링크를 사용하여 대체하기 위해 Docker 1.9 및 Docker-Compose 1.5의 네트워킹 기능으로 마이그레이션하기 시작했습니다.

지금까지 링크로 nginx가 docker-compose를 통해 한 그룹의 다른 서버에있는 내 php5-fpm fastcgi 서버에 연결하는 데 문제가 없었습니다. 새로 docker-compose --x-networking upphp-fpm을 실행 하면 mongo 및 nginx 컨테이너가 부팅되지만 nginx는 즉시 종료됩니다.[emerg] 1#1: host not found in upstream "waapi_php_1" in /etc/nginx/conf.d/default.conf:16

그러나 php와 mongo 컨테이너가 실행되는 동안 (nginx 종료) docker-compose 명령을 다시 실행하면 nginx가 시작되고 그때부터 제대로 작동합니다.

이것은 내 docker-compose.yml파일입니다.

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.confnginx입니다.

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 호출로만 작동하도록하려면 어떻게해야합니까?


3
나는 이것도 만나고 있습니다. 작성 파일의 오류인지 아니면 도커 네트워킹 자체의 버그인지 잘 모르겠습니다.
jrdn

답변:


26

Depend_on 기능 (아래에서 설명)이 도입 될 때까지 "volumes_from"을 해결 방법으로 사용할 수 있습니다. 다음과 같이 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에 노출되어 바람직하지 않다는 것입니다. 그러나 현재 이것은 사용할 수있는 하나의 도커 특정 해결 방법입니다.

dependent_on feature 이것은 아마도 미래의 대답이 될 것입니다. 기능이 아직 Docker에서 구현되지 않았기 때문에 (1.9 기준)

Docker가 도입 한 새로운 네트워킹 기능에 "depends_on"을 도입하라는 제안이 있습니다. 그러나 동일한 @ https://github.com/docker/compose/issues/374 에 대한 오랜 논쟁이 있습니다. 따라서 일단 구현되면 기능 의존 _ 온을 사용하여 컨테이너 시작을 주문할 수 있지만 순간, 다음 중 하나에 의지해야합니다.

  1. PHP 서버가 올라갈 때까지 nginx를 재 시도하십시오-나는 이것을 선호합니다
  2. 위에서 설명한대로 volums_from 해결 방법을 사용하십시오. 불필요한 컨테이너로의 볼륨 누출 때문에 이것을 사용하지 않을 것입니다.

3
이것은 나를 위해 그것을 고치지 않았습니다.
Gijs

@Gijs 귀하의 정확한 케이스가 무엇인지, 무엇이 작동하지 않았는지 게시 할 수 있다면 누군가 포럼에서 도움을 줄 수 있습니다.
Phani

4
volume_from은 더 이상 사용되지 않습니다
Roma Rush

이 문제로 Azure App Service Docker Compose (미리보기)에서 문제가 발생했습니다. 또한 links:nginx에 포함 된 모든 서비스 - my-service:my-service가이 예제 와 같은 서비스와 동일한 이름을 사용 하는지 확인해야했습니다 - mongo:mongo.
greg

29

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에서 시작 순서 제어


12

nginx의 max_fails 및 fail_timeout 지시문을 설정하여 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로 설정됩니다. 값이 0이면 시도 계산이 비활성화됩니다. 실패한 시도로 간주되는 것은 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 {
   server 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;
    }
}

또한 docker ( https://github.com/docker/docker.github.io/blob/master/compose/networking.md#update-containers ) 의 다음 참고 사항 에 따라 확인을위한 재시도 논리가 분명합니다. 다른 컨테이너의 상태는 도커의 책임이 아니며 컨테이너가 자체적으로 상태 확인을 수행해야합니다.

컨테이너 업데이트

서비스에 대한 구성을 변경하고이를 업데이트하기 위해 docker-compose를 실행하면 이전 컨테이너가 제거되고 새 컨테이너가 다른 IP 주소이지만 동일한 이름으로 네트워크에 연결됩니다. 실행중인 컨테이너는 해당 이름을 찾아 새 주소에 연결할 수 있지만 이전 주소는 작동을 멈 춥니 다.

이전 컨테이너에 대한 연결이 열려있는 컨테이너가 있으면 닫힙니다. 이 조건을 감지하고 이름을 다시 찾은 다음 다시 연결하는 것은 컨테이너의 책임입니다.


3
작동하지 않습니다. nginx 문서의이 섹션 끝에있는주의 사항을 읽으십시오. "그룹에 단일 서버 만있는 경우 max_fails, fail_timeout 및 slow_start 매개 변수는 무시되며 이러한 서버는 사용할 수없는 것으로 간주되지 않습니다."
Ferguzz

1
@Ferguzz는 좋은 캐치였습니다. 해결 방법으로 동일한 컨테이너의 별칭 항목 두 개를 추가하여 동일한 컨테이너에서 그룹을 만들 수 있습니다.
Phani

대체 솔루션으로 동일한 질문에서 "volumes_from"을 사용하여 컨테이너를 연결하고 다른 컨테이너가로드 될 때까지 기다리도록했습니다. 이것은 나를 위해 일하고 있습니다.
Phani

7

Nginx가 Docker resolver (127.0.0.11)를 고려하지 않는다고 생각하므로 다음을 추가해보십시오.

resolver 127.0.0.11

nginx 구성 파일에 있습니까?


같은 여러 해결자를 추가하십시오resolver 127.0.0.11 8.8.8.8;
Leonardo Chaia

1
문서에 명시된대로 라운드 로빈으로 쿼리하므로 아니요 : 이름 서버는 라운드 로빈 방식으로 쿼리됩니다.
dalore

6

당신이 너무 길을 잃었다면 마지막 코멘트를 읽으십시오. 나는 다른 해결책에 도달했습니다.

주요 문제는 서비스 이름을 지정하는 방법입니다.

이 경우에서 docker-compose.ymlphp 용 서비스가 "api"또는 이와 유사한 이름 인 경우 파일 nginx.conf에서로 시작하는 줄이 fastcgi_passphp 서비스와 동일한 이름을 갖는지 확인해야합니다. 즉fastcgi_pass api:9000;


3

두 개의 네트워크가 정의 되었기 때문에 동일한 문제가 발생했습니다 docker-compose.yml. 하나는 백엔드이고 하나는 프런트 엔드입니다.
동일한 기본 네트워크에서 컨테이너를 실행하도록 변경했을 때 모든 것이 제대로 작동하기 시작했습니다.


이것은 대답과는 거리가 멀다.
dargmuesli '1910.07

2

같은 문제가 있었고 그것을 해결했습니다. docker-compose.yml nginx 섹션에 다음 줄을 추가하십시오.

links:
  - php:waapi_php_1

nginx config fastcgi_pass 섹션의 호스트는 docker-compose.yml nginx 구성 내부에 연결되어야합니다.


1

언급 할 가치가있는 두 가지 :

  • 동일한 네트워크 브리지 사용
  • links호스트 해결을 추가하는 데 사용

내 예 :

version: '3'
services:
  mysql:
    image: mysql:5.7
    restart: always
    container_name: mysql
    volumes:
      - ./mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: tima@123
    network_mode: bridge
  ghost:
    image: ghost:2
    restart: always
    container_name: ghost
    depends_on:
      - mysql
    links:
      - mysql
    environment:
      database__client: mysql
      database__connection__host: mysql
      database__connection__user: root
      database__connection__password: xxxxxxxxx
      database__connection__database: ghost
      url: https://www.itsfun.tk
    volumes:
      - ./ghost-data:/var/lib/ghost/content
    network_mode: bridge
  nginx:
    image: nginx
    restart: always
    container_name: nginx
    depends_on:
      - ghost
    links:
      - ghost
    ports:
      - "80:80"
      - "443:443"
    volumes:
       - ./nginx/nginx.conf:/etc/nginx/nginx.conf
       - ./nginx/conf.d:/etc/nginx/conf.d
       - ./nginx/letsencrypt:/etc/letsencrypt
    network_mode: bridge

특별한 네트워크 브리지를 지정하지 않으면 모두 동일한 기본 브리지를 사용합니다.


1

언뜻보기에 "웹"서비스가 실제로 시작되지 않았다는 사실을 놓쳤습니다. 그래서 nginx가 호스트를 찾을 수 없습니다.

web_1    | python3: can't open file '/var/www/app/app/app.py': [Errno 2] No such file or directory
web_1 exited with code 2
nginx_1  | [emerg] 1#1: host not found in upstream "web:4044" in /etc/nginx/conf.d/nginx.conf:2

저도 같은 문제가 있습니다. 내 응용 프로그램이 실행되고 있지 않아 동일한 오류가 발생합니다. 나는 app.ini에 uwsgi-file을 run.py로 넣었습니다. app.ini는 앱을 실행해야하지만 발생하지 않습니다
isrj5

0

링크를 사용하면 컨테이너 시작 순서가 적용됩니다. 링크가 없으면 컨테이너는 임의의 순서로 (또는 실제로 한 번에 모두) 시작할 수 있습니다.

waapi_php_1컨테이너가 시작 속도가 느리면 이전 설정이 동일한 문제를 일으킬 수 있다고 생각합니다 .

나는 그것을 작동시키기 위해 PHP 컨테이너가 시작되고 준비 될 때까지 폴링하고 기다리는 nginx 진입 점 스크립트를 만들 수 있다고 생각합니다.

nginx가 업스트림에 대한 연결을 자동으로 재 시도 할 수있는 방법이 있는지 확실하지 않지만, 그렇다면 더 나은 옵션이 될 것입니다.


투표는 어떻게합니까?
Attila Szeremi 2015


0

컨테이너 연결 문제를 방지하는 최선의 선택은 Docker 네트워킹 기능 일 것입니다.

그러나이 작업을 수행하기 위해 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

이 서비스에 대한 구성 파일에 지정된 이름과 동일한 지 확인하십시오. 이 작업을 수행하는 더 좋은 방법이 있다고 확신하지만 시작하기에 좋은 방법입니다.


0

내 해결 방법 (많은 시행 착오 후) :

  • 이 문제를 해결 하려면 업스트림 컨테이너 의 전체 속성을 실행 하고 가져 와서 찾은 '업스트림'Docker 컨테이너 의 전체 이름 을 가져와야했습니다 .docker network inspect my-special-docker-networkname

    "Containers": {
         "39ad8199184f34585b556d7480dd47de965bc7b38ac03fc0746992f39afac338": {
              "Name": "my_upstream_container_name_1_2478f2b3aca0",
    
  • 그런 다음 속성 블록의 NGINX my-network.local.conf파일에서 다음을 사용 했습니다. (컨테이너 이름에 GUID 추가에 유의하십시오) :locationproxy_pass

    location / {
        proxy_pass http://my_upsteam_container_name_1_2478f2b3aca0:3000;
    

이전에 작동했지만 지금은 깨졌습니다.

    location / {
        proxy_pass http://my_upstream_container_name_1:3000

대부분의 원인은 여기에 나열된 컨테이너에 대한 기본 이름 지정 체계에서 Docker Compose에 대한 최근 변경 사항 입니다.

이것은 최신 버전의 Docker nginx이미지 를 사용하여 나와 내 팀에서 발생하는 것 같습니다 .

  • 나는 docker / compose GitHub 에서 문제를 열었습니다.

0

(nginx 신규) 제 경우에는 폴더 이름이 잘못되었습니다.

구성 용

upstream serv {
    server ex2_app_1:3000;
}

앱 폴더가 ex2 폴더에 있는지 확인하십시오.

ex2 / 앱 / ...


0

이 오류는 내 php-fpm이미지가 활성화 되었기 때문에 나에게 나타 났 cron으며 그 이유를 모르겠습니다.


0

내 문제는 php-fpm의 docker-compose.yml에서 네트워크 별칭 을 지정하는 것을 잊었다는 것입니다.

    networks:
      - u-online

잘 작동합니다!

version: "3"
services:

  php-fpm:
    image: php:7.2-fpm
    container_name: php-fpm
    volumes:           
      - ./src:/var/www/basic/public_html
    ports:
      - 9000:9000
    networks:
      - u-online
      
  nginx: 
    image: nginx:1.19.2
    container_name: nginx   
    depends_on:
      - php-fpm       
    ports:
      - "80:8080"
      - "443:443"
    volumes:
      - ./docker/data/etc/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
      - ./docker/data/etc/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./src:/var/www/basic/public_html
    networks:
      - u-online

#Docker Networks
networks:
  u-online:
    driver: bridge

-1

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

1
나는 링크에 대해 알고 있지만 Docker는 Docker의 네트워킹을 사용하기 위해 일주일 전에 나온 버전 1.9에서 링크를 사용하지 않는 것으로 표시했습니다. 부분적으로는 링크에 네트워킹이 없어야하는 순환 링크에 문제가 있기 때문에이를 사용하는 솔루션을 원합니다.
Attila Szeremi 2015

1
에서 CHANGELOG.md 나는 볼 수 없습니다 link사용되지. 내가 뭔가를 놓치고 있습니까?
nessuno

나는 거기에서도 그것을 보지 못했습니다. 그러나 docker-compose --x-networking updocker-compose.yml에서 정의 된 링크로 실행하면 다음 과 같은 명확한 경고가 표시됩니다.WARNING: "nginx" defines links, which are not compatible with Docker networking and will be ignored. Future versions of Docker will not support links - you should remove them for forwards-compatibility.
Attila Szeremi

좋아 , 지원 중단이 어디 있는지 찾았 습니다. 내가 가진 유일한 아이디어는 : 당신은있다 docker-compose.yml라는 이름의 폴더에 파일을 waapi?
nessuno

예, 폴더에 있습니다waapi
Attila Szeremi 2011
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.