programing

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

cafebook 2023. 9. 20. 20:43
반응형

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

최근에 도커 1.9와 도커 컴포지트 1.5의 네트워킹 기능으로 링크를 교체하기 시작했습니다.

지금까지 링크와 관련하여 nginx가 도커 컴포지트를 통해 한 그룹의 다른 서버에 위치한 나의 php5-fpm fastcgi 서버에 연결하는 데 문제가 없었습니다.요.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

그러나 php와 mongo container가 실행되는 동안 docker-compose 명령을 다시 실행하면(nginx가 종료됨), 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를 한 번의 도커 합성 통화만으로 작동시킬 수 있습니까?

에 언급된 할 수 있습니다.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

자세한 내용은 설명서에서 확인할 수 있습니다.

또한 이 주제를 다루는 매우 흥미로운 기사도 있습니다.구성에서 시작 순서 제어

아래에서 설명하는 depends_on feature가 도입될 때까지 "volumes_from"을 해결책으로 사용할 수 있습니다.도커 작성 파일을 아래와 같이 변경하기만 하면 됩니다.

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에 기능이 구현되지 않았기 때문입니다(1.9 기준).

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

  1. php 서버가 작동할 때까지 nginx를 다시 시도합니다. 나는 이것을 선호합니다.
  2. 위에서 설명한 대로 volums_from 해결 방법 사용 - 불필요한 용기에 볼륨이 누출되므로 사용하지 않습니다.

만약 당신이 그렇게 길을 잃는다면 마지막 댓글을 읽어보세요.저는 다른 해결책에 도달했습니다.

가장 큰 문제는 서비스 이름을 지정하는 방식입니다.

이 에 ,docker-compose.yml는 " 것이라고 에서 php 에는 "api" , 를 확실히 합니다.nginx.conf하는 행fastcgi_passphp 서비스와 같은 이름을 가지고 있습니다. 즉.fastcgi_pass api:9000;

이 pp 이라고 해 보겠습니다.php_service그러면 코드는 다음과 같습니다.
edocker-compose.yml

php_service:
    build:
        dockerfile: ./docker/php/Dockerfile

nginx.conf

location ~ \.php$ {
    fastcgi_pass php_service:9000;
    fastcgi_param SCRIPT_FILENAME$document_root$fastcgi_script_name;
    include fastcgi_params; 
}

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;
    }
}

또한 다음 도커의 참고사항(https://github.com/docker/docker.github.io/blob/master/compose/networking.md#update-containers), 에 따르면, 다른 컨테이너의 상태를 확인하기 위한 재시도 로직은 도커의 책임이 아니며 컨테이너 자체가 상태를 확인해야 합니다.

컨테이너 업데이트 중

서비스에 대한 구성을 변경하고 도커 컴포지트를 실행하여 업데이트하면 이전 컨테이너가 제거되고 새 컨테이너는 다른 IP 주소로 네트워크에 연결되지만 이름은 같습니다.실행 중인 컨테이너는 해당 이름을 조회하고 새 주소로 연결할 수 있지만 이전 주소는 작동을 중지합니다.

기존 컨테이너에 열려 있는 컨테이너가 있으면 해당 컨테이너는 닫힙니다.이 상태를 감지하고 이름을 다시 찾아보고 다시 연결하는 것은 컨테이너의 책임입니다.

문제는 pph-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

Nginx는 Docker resolver(127.0.0.11)를 고려하지 않은 것으로 생각되므로, 다음을 추가해 주실 수 있나요?

resolver 127.0.0.11

nginx 구성 파일에?

에 두.docker-compose.yml 하나의 뒷단과 하나의 앞단.
동일한 기본 네트워크에서 컨테이너를 실행하도록 변경했을 때 모든 것이 정상적으로 작동하기 시작했습니다.

지역 개발을 위해 비활성화될 수 있는 서비스에 대한 해결책을 찾았습니다.긴급차단을 방지하고 서비스가 가능한 후 작동하는 변수만 사용하면 됩니다.

server {
    location ^~ /api/ {
        # other config entries omitted for breavity
    
        set $upstream http://api.awesome.com:9000;

        # nginx will now start if host is not reachable
        fastcgi_pass    $upstream; 
        fastcgi_index   index.php;
    }
}

출처 : https://sandro-keil.de/blog/let-nginx-start-if-upstream-host-is-unavailable-or-down/

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

links:
  - php:waapi_php_1

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

언뜻 보기에는 내 "웹" 서비스가 실제로 시작되지 않아서 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

두 가지 언급할 가치가 있습니다.

  • 동일한 네트워크 브리지 사용
  • 으로.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

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

링크 섹션을 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

링크와 함께 컨테이너 시작 순서가 적용됩니다.링크가 없으면 컨테이너를 순서에 상관없이(또는 한 번에) 시작할 수 있습니다.

내 생각엔 예전 설정이 같은 문제에 부딪혔을 수도 있다고 생각해요, 만약 그가waapi_php_1컨테이너 시작이 느렸습니다.

pp 컨테이너가 시작되고 준비될 때까지 폴링하고 기다리는 nginx 엔트리 포인트 스크립트를 만들면 될 것 같습니다.

nginx가 업스트림에 자동으로 연결을 재시도할 수 있는 방법이 있는지는 잘 모르겠지만, 가능하다면 더 나은 방법이 될 것입니다.

백엔드가 작동할 때 nginx 구성을 동적으로 업데이트하려면 도커-젠과 같은 것을 사용해야 합니다.

참조:

Nginx+(premium 버전)에도 해결 매개 변수가 포함되어 있다고 생각합니다(http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream) .

컨테이너 연결 문제를 피하기 위한 최선의 선택은 도커 네트워킹 기능일 것입니다.

그러나 이 작업을 수행하기 위해 도커는 각 컨테이너에 할당된 이름에서 각 컨테이너에 대한 /etc/hosts에 항목을 생성합니다.

docker-compose --x-networking-up은 [docker_compose_folder]-[service]-[incremental_number]와 같습니다.

이러한 이름의 예기치 않은 변경에 의존하지 않으려면 매개 변수를 사용해야 합니다.

컨테이너_이름

다음과 같이 도커- 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

이 서비스에 대해 구성 파일에 할당된 이름과 동일한지 확인합니다.이를 위한 더 나은 방법이 있을 거라고 확신하지만, 시작하는 것은 좋은 접근법입니다.

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

  • 이 문제를 해결하기 위해서는 를 실행하여 찾은 '업스트림' 도커 컨테이너의 전체 이름을 얻어야 했습니다.docker network inspect my-special-docker-network배불리 먹는 것도name다음과 같은 업스트림 컨테이너의 속성:

    "Containers": {
         "39ad8199184f34585b556d7480dd47de965bc7b38ac03fc0746992f39afac338": {
              "Name": "my_upstream_container_name_1_2478f2b3aca0",
    
  • 그럼 NGINX에서 이걸 사용했습니다.my-network.local.conf줄을 늘어놓다location한 블록의proxy_passproperty: (컨테이너 이름에 GUID 추가 참고):

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

이전에 작업했던 것과 달리 지금은 고장이 났습니다.

    location / {
        proxy_pass http://my_upstream_container_name_1:3000

가장 가능한 원인은 여기에 나열된 컨테이너의 기본 명명 방식에서 최근에 Docker Composition이 변경되었기 때문입니다.

와 제 에게도 이런 것 같습니다.nginx지:

  • 여기 도커/작곡 GitHub에서 문제가 발생했습니다.

이 의 요.php-fpmdcron 그런지 요, .

docker-composite.yml 파일에서 Nginx 서비스를 다음과 같이 변경합니다.

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

제 경우에는 그랬습니다.nginx: [emerg] host not found in upstream또한, 그래서 나는 그것을 해결할 수 있었습니다, 를 추가함으로써.depends_on to toginx 서비스docker-compose.yml일.

(new tongginx) 나의 경우 폴더 이름이 틀렸습니다.

구성의 경우

upstream serv {
    server ex2_app_1:3000;
}

앱 폴더가 ex2 폴더에 있는지 확인합니다.

ex2/앱/...

언급URL : https://stackoverflow.com/questions/33639138/docker-networking-nginx-emerg-host-not-found-in-upstream

반응형