2015-11-10 7 views
46

Ich habe kürzlich mit der Migration auf die Netzwerkfunktionen von Docker 1.9 und Docker-Compose 1.5 begonnen, um die Verwendung von Links zu ersetzen.Docker-Netzwerk - nginx: [emerg] -Host nicht im Upstream gefunden

Bis jetzt gab es keine Probleme mit Nginx Verbindung zu meinem php5-fpm Fastcgi Server in einem anderen Server in einer Gruppe über Docker-Compose. Neu obwohl, wenn ich docker-compose --x-networking up meine php-fpm, Mongo und nginx Container booten laufen, aber nginx mit [emerg] 1#1: host not found in upstream "waapi_php_1" in /etc/nginx/conf.d/default.conf:16 sofort beendet

Allerdings, wenn ich die Docker-compose Befehl erneut ausführen, während die PHP und Mongo Behälter laufen (nginx beendet), nginx startet und funktioniert von da an einwandfrei.

Das ist mein docker-compose.yml Datei:

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 

Das ist mein default.conf für nginx:

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

Wie kann ich nginx erhalten mit nur einem einzigen Docker-compose Aufruf zu arbeiten?

+1

Ich begegne dies auch. Ich bin mir nicht sicher, ob es sich um einen Fehler in der Compose-Datei oder um einen Fehler beim Docker-Netzwerk selbst handelt. – jrdn

Antwort

13

Es gibt eine Möglichkeit, "volumes_from" als Workaround zu verwenden, bis die Funktion depends_on (siehe unten) eingeführt wird. Alles was Sie tun müssen, ist Ihre Docker-compose Datei wie unten ändern:

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 

Ein großer Nachteil in der obigen Ansatz ist, dass nginx die Volumina von PHP ausgesetzt sind, was nicht erwünscht ist.Im Moment ist dies jedoch eine dockerspezifische Problemumgehung, die verwendet werden könnte.

depends_on Funktion Dies wäre wahrscheinlich eine futuristische Antwort. Weil die Funktionalität noch nicht in Docker implementiert ist (ab 1.9)

Es gibt einen Vorschlag, "depends_on" in die neue Netzwerkfunktion einzuführen, die von Docker eingeführt wurde. Aber es gibt eine lange laufende Debatte über das gleiche @https://github.com/docker/compose/issues/374 Daher, sobald es implementiert ist, könnte das Feature depends_on verwendet werden, um den Container Start-up, aber im Moment müssen Sie auf eine der folgenden:

  1. make nginx wiederholen, bis der pHP-Server aktiv ist - ich würde diese Verwendung volums_from Abhilfe eines
  2. bevorzugen, wie oben beschrieben - ich mag vermeiden, dies zu verwenden, da das Volumen Leckage in unnötige Behälter.
+2

Das hat es nicht für mich behoben. – Gijs

+0

@Gijs wenn Sie Ihren genauen Fall posten können und was nicht funktioniert hat, könnte jemand im Forum helfen. – Phani

-1

Fügen Sie den Abschnitt zu Ihrer nginx-Containerkonfiguration hinzu.

Sie müssen den php Container zum nginx Container sichtbar machen.

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

Ich kenne Links, aber Docker markiert sie veraltet in der Version 1.9, die vor einer Woche zugunsten der Verwendung von Docker-Netzwerk kam. Ich hätte gerne eine Lösung, die das nutzt, zum Teil, weil Links ein Problem mit der zirkulären Verknüpfung haben, die das Netzwerk nicht haben sollte. –

+1

In [CHANGELOG.md] (https://github.com/docker/docker/blob/master/CHANGELOG.md) sehe ich nicht, dass "link" veraltet ist. Fehle ich etwas? – nessuno

+0

Ich habe das dort auch nicht gesehen; Aber wenn ich "docker-compose --x-networking up" mit Links in meinem "docker-compose.yml" starte, bekomme ich diese klare Warnung: 'WARNUNG: " nginx "definiert Links, die nicht mit Docker kompatibel sind Vernetzung und wird ignoriert. Zukünftige Versionen von Docker werden keine Links unterstützen - Sie sollten sie für die Vorwärtskompatibilität entfernen. –

0

Mit Links wird eine Reihenfolge des Container-Startvorgangs erzwungen. Ohne Links können die Container in beliebiger Reihenfolge (oder wirklich alle auf einmal) starten.

Ich denke, das alte Setup könnte das gleiche Problem haben, wenn der waapi_php_1 Container war langsam zu starten.

Ich denke, um es zum Laufen zu bringen, könnten Sie ein nginx entrepoint-Skript erstellen, das abfragt und darauf wartet, dass der php-Container gestartet und fertig ist.

Ich bin mir nicht sicher, ob Nginx irgendeine Möglichkeit hat, die Verbindung zum Upstream automatisch zu versuchen, aber wenn es das tut, wäre das eine bessere Option.

+0

Und wie mache ich polling? –

4

Sie können die max_fails und fail_timeout Richtlinien festgelegt von nginx, um anzuzeigen, dass das nginx die x-Anzahl von Verbindungsanforderungen an das c erneut versuchen sollte ontainer vor dem Ausfall der Nichtverfügbarkeit des Upstream-Servers.

Sie können diese beiden Nummern gemäß Ihrer Infrastruktur und Geschwindigkeit einstellen, mit der das gesamte Setup durchgeführt wird.Sie können weitere Informationen über den Gesundheits-Checks Abschnitt der folgenden URL lesen: http://nginx.org/en/docs/http/load_balancing.html

Es folgt der Auszug aus http://nginx.org/en/docs/http/ngx_http_upstream_module.html#server max_fails=number

setzt die Anzahl der erfolglosen Versuche mit dem -Server zu kommunizieren, was passieren soll In der durch den Parameter fail_timeout festgelegten Dauer wird der für eine Dauer nicht verfügbare Server ebenfalls durch den Parameter fail_timeout auf gesetzt. Standardmäßig ist die Anzahl der fehlgeschlagenen Versuche auf 1 gesetzt. Der Nullwert deaktiviert die Abrechnung von Versuchen. Was als erfolgloser Versuch angesehen wird, wird durch die Anweisungen proxy_next_upstream, fastcgi_next_upstream, uwsgi_next_upstream, scgi_next_upstream und memcached_next_upstream definiert.

fail_timeout=time

setzt die Zeit, während der die angegebene Anzahl erfolgloser Versuche mit dem Server zu kommunizieren sollte den Server nicht verfügbar betrachten passieren; und der Zeitraum, in dem der Server sein wird, ist nicht verfügbar. Standardmäßig ist der Parameter auf 10 Sekunden eingestellt.

Um genau zu Ihrer modifizierten nginx Config-Datei soll wie folgt sein (das Skript wird unter der Annahme, dass alle Behälter von 25 Sekunden bis mindestens, wenn nicht, bitte den fail_timeout oder max_fails im folgenden vorgeschalteten Abschnitt aus): Hinweis: Ich habe das Skript nicht selbst getestet, also können Sie es versuchen!

upstream phpupstream { 
    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; 
    } 
} 

Auch gemäß dem folgenden Hinweis von Docker (https://github.com/docker/compose/blob/master/docs/networking.md), ist es offensichtlich, dass die Wiederholungslogik, die Gesundheit der anderen Behälter für die Überprüfung nicht in der Verantwortung ist Andockfenster und eher die Behälter sollten die Gesundheit überprüft selbst tun.

aktualisiert Container

Wenn Sie eine Konfigurationsänderung zu einem Dienst zu machen und führen -Docker komponieren, um ihn zu aktualisieren, wird der alte Behälter entfernt werden und die neue wird auf das Netzwerk zugreifen unter eine andere IP-Adresse, aber der gleiche Name. Laufende Container können diesen Namen nachschlagen und mit die neue Adresse verbinden, aber die alte Adresse funktioniert nicht mehr.

Wenn irgendwelche Container Verbindungen zu dem alten Container haben, werden sie geschlossen. Es liegt in der Verantwortung eines Containers, diesen -Zustand zu erkennen, den Namen erneut zu suchen und erneut zu verbinden.

+0

Dies wird nicht funktionieren. Lesen Sie den Vorbehalt am Ende dieses Abschnitts in der nginx-Dokumentation: "Wenn es nur einen Server in einer Gruppe gibt, werden die Parameter max_fails, fail_timeout und slow_start ignoriert, und ein solcher Server wird niemals als nicht verfügbar betrachtet." – Ferguzz

+1

@Ferguzz das war ein schöner Fang. Als Workaround können Sie zwei Alias-Einträge desselben Containers hinzufügen, um eine Gruppe aus demselben Container zu erstellen. – Phani

+0

Als alternative Lösung habe ich in der gleichen Frage die Verwendung von "volumes_from" bereitgestellt, um die Container zu verknüpfen und sie warten zu lassen, bis andere Container geladen sind. Das funktioniert für mich. – Phani

0

Vielleicht ist die beste Wahl verknüpfen Container Themen sind die Docker Vernetzung Funktionen

Aber um diese Arbeit zu machen, schafft Docker Einträge in den /etc/hosts für jeden Container von zugewiesenen Namen zu vermeiden jeder Behälter.

mit Docker-komponieren --x-Networking-up ist so etwas wie [docker_compose_folder] - [Service] - [incremental_number]

nicht in diesem Namen auf unerwartete Änderungen abzuhängen Sie verwenden sollen, der Parameter

container_name

in Ihrem docker-compose.yml wie folgt:

php: 
     container_name: waapi_php_1 
     build: config/docker/php 
     ports: 
     - "42022:22" 
     volumes: 
     - .:/var/www/html 
     env_file: config/docker/php/.env.development 

Stellen Sie sicher, dass es sich um denselben Namen handelt, der in Ihrer Konfigurationsdatei für diesen Dienst vergeben wurde. Ich bin mir ziemlich sicher, dass es bessere Möglichkeiten gibt, dies zu tun, aber es ist ein guter Anfang.

9

Dies kann mit der genannten depends_on Richtlinie gelöst werden, da sie jetzt (2016) implementiert ist:

$ docker-compose version 
docker-compose version 1.8.0, build f3628c7 

mehr Details in den documentation finden:

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 

Erfolgreich mit getestet.

Es gibt auch einen sehr interessanten Artikel zu diesem Thema gewidmet: Controlling startup order in Compose

-1

Dies ist, wie ich es über die beste Weise, die ich mir vorstellen kann.

ADD root/

RUN cp /etc/hosts /etc/hosts.tmp && \ 
    echo -e "\ 
127.0.0.1 code_gogs_1 \n\ 
127.0.0.1 pm_zentao_1 \n\ 
127.0.0.1 ci_drone_1 \n\ 
    " >> /etc/hosts && \ 
    nginx -t && \ 
# mv: can't rename '/etc/hosts.tmp': Resource busy 
# mv /etc/hosts.tmp /etc/hosts 
    cat /etc/hosts.tmp > /etc/hosts && \ 
    rm /etc/hosts.tmp 
+0

docker-komponieren (Autor verwendet) bietet eigene Host-Bindung und besser, es zu verwenden. Container, die dasselbe Netzwerk nach Namen teilen. Der Name kann über die Option 'container_name' in der Konfigurationsdatei angegeben werden. – Dmitry

4

Ich glaube, Nginx nicht berücksichtigen Docker Resolver (127.0.0.11), also bitte, können Sie versuchen, hinzuzufügen:

resolver 127.0.0.11 

in Ihrer Nginx-Konfigurationsdatei?

+0

Fügen Sie mehrere Resolver wie' 'resolver 127.0.0.11 8.8.8.8;' 'hinzu –

1

Hatte das gleiche Problem und löste es. Bitte fügen Sie die folgende Zeile in Andockfenster-compose.yml nginx Abschnitt:

links: 
    - php:waapi_php_1 

Gastgeber in nginx Config fastcgi_pass Abschnitt sollte innerhalb Docker-compose.yml nginx Konfiguration verknüpft werden.

1

Wenn Sie so verloren sind, lesen Sie den letzten Kommentar. Ich habe eine andere Lösung erreicht.

Das Hauptproblem ist die Art, wie Sie die Namen der Dienste benannt haben.

In diesem Fall, wenn in Ihrem docker-compose.yml, ist der Dienst für PHP namens „api“ oder so ähnlich, müssen Sie, dass in der Datei sicherzustellen nginx.conf die Zeile, die mit fastcgi_pass haben die gleichen Namen wie der PHP-Dienst beginnt. d. h. fastcgi_pass api:9000;

0

haben das gleiche Problem, bis in einem docker-compose.yml zwei Netzwerke definiert wurden: Backend und Frontend. Wenn alle Container auf demselben Standardnetzwerk ausgeführt werden, funktioniert alles einwandfrei.

Verwandte Themen