web-dev-qa-db-ja.com

アップストリームのホストが見つからない場合、nginxがクラッシュしないようにセットアップします

Dockerの共通ドメインにいくつかのRailsアプリがあり、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に無視させる方法は?

86
Morozov
  1. 静的IPを使用できる場合、それを使用するだけで起動し、応答しない場合は503を返します。

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

upstreamを使用する主な利点は、異なるポートでリッスンできるサーバーのグループを定義し、負荷分散とフェイルオーバーを構成することですそれらの間.

あなたの場合、アップストリームごとに1つのプライマリサーバーのみを定義しているため、upでなければなりません。

代わりに、proxy_pass(es)の変数を使用し、ターゲットサーバーがダウンしたときに発生する可能性のあるエラー(404、503)を処理することを忘れないでください。

12
danielgpm

私にとって、@ 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サーバーを使用できます。

9
neumann