it-swarm.com.de

Richten Sie nginx so ein, dass es nicht abstürzt, wenn Host im Upstream nicht gefunden wird

In Docker gibt es mehrere Rails-Apps unter einer gemeinsamen Domäne, und wir verwenden nginx, um Anfragen an bestimmte Apps zu richten.

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

Config sieht so aus:

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

Wenn eine dieser Apps nicht gestartet wird, schlägt nginx fehl und stoppt:

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

Wir brauchen sie nicht alle auf, aber nginx versagt sonst.

73
Morozov
  1. Wenn Sie eine statische IP-Adresse verwenden können, verwenden Sie diese einfach. Sie wird gestartet und gibt nur 503 zurück, wenn sie nicht antwortet. 

  2. Verwenden Sie die Anweisung resolver, um auf etwas hinzuweisen, das den Host auflösen kann, unabhängig davon, ob er gerade aktiv ist oder nicht. 

  3. Lösen Sie es auf der location-Ebene auf, wenn Sie die oben genannten nicht ausführen können (dadurch wird Nginx gestartet/ausgeführt) :

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

Der Hauptvorteil der Verwendung von upstream ist die Definition von eine Gruppe von Servern, die unterschiedliche Ports überwachen kann und die Lastverteilung und das Failover between between konfigurieren. 

In Ihrem Fall sind Sie es wird nur ein primärer Server pro Upstream definiert, dh es muss up sein}.

Verwenden Sie stattdessen Variablen für Ihren proxy_pass (es) und denken Sie daran, die möglichen Fehler (404s, 503s) zu behandeln, die Sie möglicherweise erhalten, wenn ein Zielserver ausgefallen ist.

9
danielgpm

Für mich löste Option 3 der Antwort von @ Justin/@ duskwuff das Problem, aber ich musste die Resolver-IP auf 127.0.0.11 (Dockers DNS-Server) ändern:

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

Wie @ Justin/@ duskwuff erwähnt, können Sie jedoch auch andere externe DNS-Server verwenden.

1
neumann