업스트림의 호스트를 찾을 수없는 경우 nginx가 충돌하지 않도록 설정


117

Docker의 공통 도메인 아래에 여러 개의 레일 앱이 있으며 nginx를 사용하여 특정 앱에 요청을 보냅니다.

our_dev_server.com/foo # proxies to foo app
our_dev_server.com/bar # proxies to bar

구성은 다음과 같습니다.

upstream foo {
  server foo:3000;
}

upstream bar {
  server bar:3000;
}

# and about 10 more...

server {
  listen *:80 default_server;

  server_name our_dev_server.com;

  location /foo {
      # this is specific to asset management in rails dev
      rewrite ^/foo/assets(/.*)$ /assets/$1 break;
      rewrite ^/foo(/.*)$ /foo/$1 break;
      proxy_pass http://foo;
  }

  location /bar {
      rewrite ^/bar/assets(/.*)$ /assets/$1 break;
      rewrite ^/bar(/.*)$ /bar/$1 break;
      proxy_pass http://bar;
  }

  # and about 10 more...
}

이러한 앱 중 하나가 시작되지 않으면 nginx가 실패하고 중지됩니다.

host not found in upstream "bar:3000" in /etc/nginx/conf.d/nginx.conf:6

모두 작동 할 필요는 없지만 그렇지 않으면 nginx가 실패합니다. nginx가 실패한 업스트림을 무시하도록 만드는 방법은 무엇입니까?


1
앱 컨테이너를 Nginx 컨테이너와 연결하거나 서로 별도로 실행하고 있습니까? upstream블록 내의 호스트 가 해결되지 않으면 런타임에 Nginx가 위의 오류와 함께 종료됩니다.
Justin

1
IP를 사용할 수 있으면 정상적으로 시작됩니다. 사용겠습니까 resolver( nginx.org/en/docs/http/ngx_http_core_module.html#resolver 귀하의 경우) 작업을?
Justin

@Justin 우리는 nginx도 별도의 컨테이너에 각 앱을 가지고 있습니다. 도커와 연결
Morozov

@Justin 시작 순서는 괜찮습니다. nginx는 다른 앱 이후에 시작됩니다. 우리는 그들 중 일부만 실행하고 싶습니다. :)
Morozov

1
비슷한 설정이 있습니다 (앱 컨테이너 가있는 Nginx 컨테이너) . proxy.sh환경 변수를 읽고 upstream각각에 대한 항목을 동적으로 추가 하는 스크립트 를 포함하는 Nginx 이미지를 만든 다음 Nginx를 시작합니다. 이것은 프록시 컨테이너를 실행할 때 런타임에 필요한 업스트림을 전달할 수 있다는 점에서 훌륭하게 작동합니다. 실행시 특정 업스트림을 활성화 / 비활성화하는 것과 유사한 작업을 수행 할 수 있습니다 (또는 내 설정과 마찬가지로 런타임에 필요한 항목 만 추가)
Justin

답변:


90
  1. 고정 IP를 사용할 수 있다면 그것을 사용하면 시작되고 503응답하지 않으면 's를 반환합니다.

  2. resolver지시문을 사용하여 현재 작동 여부에 관계없이 호스트를 확인할 수있는 항목을 가리 킵니다.

  3. location위의 작업을 수행 할 수없는 경우 수준 에서 해결하십시오 (이렇게하면 Nginx를 시작 / 실행할 수 있음) .

    location /foo {
      resolver 127.0.0.1 valid=30s;
      # or some other DNS (you company/internal DNS server)
      #resolver 8.8.8.8 valid=30s;
      set $upstream_foo foo;
      proxy_pass http://$upstream_foo:80;
    }
    
    location /bar {
      resolver 127.0.0.1 valid=30s;
      # or some other DNS (you company/internal DNS server)
      #resolver 8.8.8.8 valid=30s;
      set $upstream_bar foo;
      proxy_pass http://$upstream_bar:80;
    }
    

1
귀하의 옵션 3은 저에게 잘 맞습니다. 확인자를 지정하지 않으면 nginx가 확인하는 IP를 얼마나 오래 캐시할지 알고 있습니까?
Riley Lark

14
감사! 변수를 사용하는 것만으로도 nginx가 똑똑해지지 않는 것 같습니다
Blanka

1
: 나는 정규식 캡처 그룹이 나를 변수 생략 할 수 있음을 발견location ~ ^/foo/(.*)$ { proxy_pass http://foo/$1; }
대니 Kirchmeier

2
TCP 프록시에서는 어떻게 작동합니까? tcp 프록시에 대해 옵션 3을 시도 할 방법이없는 것 같습니다.
krish7919

1
@Charlie nginx에서 이러한 종류의 오류는 거의 항상 ";"누락 과 관련이 있습니다 . 줄 끝에 서명하십시오 :)
SteveB

18

나를 위해 @ Justin / @ duskwuff의 답변 중 3 번 옵션이 문제를 해결했지만 해결 프로그램 IP를 127.0.0.11 (Docker의 DNS 서버) 로 변경해야했습니다 .

location /foo {
  resolver 127.0.0.11 valid=30s;
  set $upstream_foo foo;
  proxy_pass http://$upstream_foo:80;
}

location /bar {
  resolver 127.0.0.11 valid=30s;
  set $upstream_bar foo;
  proxy_pass http://$upstream_bar:80;
}

그러나 @ Justin / @ duskwuff가 언급했듯이 다른 외부 DNS 서버를 사용할 수 있습니다.


15

사용의 주요 이점은 서로 다른 포트에서 수신 대기 할 수있는 서버 그룹upstream 을 정의 하고 이들간에 로드 밸런싱 및 장애 조치 를 구성하는 것 입니다.

귀하의 경우 업스트림 당 1 개의 주 서버 만 정의하고 있으므로 반드시 작동해야합니다 .

대신 변수를 사용 proxy_pass하고 대상 서버가 다운되었을 때 발생할 수있는 가능한 오류 (404, 503)를 처리해야합니다.


1
> 대신 proxy_pass에 대한 변수를 사용하고 대상 서버가 다운되었을 때 발생할 수있는 가능한 오류 (404, 503s)를 처리해야합니다. 그 방법에 대해 자세히 설명해 주시겠습니까? 내가 할 경우 set $variable http://fooproxy_pass $variable와 "상류"푸 유지 나는 여전히 OP에 의해 언급 된 문제를 치는거야 (당신이 언급 한 장점을 유지).
Tibor Vass

6
다른 예에서 볼 수 있듯이 다음 set $variable foo과 같습니다.proxy_pass http://$variable
danielgpm

2
@danielgpm 언급했듯이 proxy_pass에 대한 변수를 사용하면 완벽하게 작동하고 내 문제가 해결되었습니다. 답변을 업데이트하고 예를 들어 언급 할 수 있다면 다른 사람들에게 도움이 될 것입니다
Nitb

3
둘 이상이 있고 해결할 수없는 항목을 무시하려면 어떻게합니까?
talabes

0

내 호스트의 일부가 $uri대신 다음을 사용하여 매핑 되었기 때문에 동일한 "호스트를 찾을 수 없음"문제가 발생했습니다 $request_uri.

proxy_pass http://one-api-service.$kubernetes:8091/auth;

그리고 요청이 auth 하위 요청으로 변경되면 $uri초기 값을 잃었습니다. 내 문제 $request_uri$uri해결 하는 대신 사용할 매핑 변경 :

map $request_uri $kubernetes {
    # ...
}

-8

--link옵션을 사용할 수 없습니다 . 대신 포트 매핑을 사용하고 nginx를 호스트 주소에 바인딩 할 수 있습니다.

예 : -p 180:80옵션으로 첫 번째 도커 컨테이너를 실행하고 옵션으로 두 번째 컨테이너를 -p 280:80실행합니다.

nginx를 실행하고 프록시에 다음 주소를 설정합니다.

proxy_pass http://192.168.1.20:180/; # first container
proxy_pass http://192.168.1.20:280/; # second container
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.