Update II
Es ist jetzt der 16. Juli 2015 und die Dinge haben sich wieder geändert. Ich habe diesen automatischen Container von Jason Wilder entdeckt :
https://github.com/jwilder/nginx-proxy
und er löst dieses Problem in ungefähr so langer Zeit, wie er fürdocker run
den Container benötigt wird. Dies ist jetzt die Lösung, mit der ich dieses Problem löse.
Aktualisieren
Es ist jetzt Juli 2015 und die Dinge in Bezug auf die Vernetzung von Docker-Containern haben sich drastisch geändert. Es gibt jetzt viele verschiedene Angebote, die dieses Problem lösen (auf verschiedene Arten).
Sie sollten diesen Beitrag verwenden, um ein grundlegendes Verständnis des
docker --link
Ansatzes zur Serviceerkennung zu erlangen , der so grundlegend wie möglich ist, sehr gut funktioniert und tatsächlich weniger ausgefallenes Tanzen erfordert als die meisten anderen Lösungen. Es ist insofern begrenzt, als es ziemlich schwierig ist, Container auf separaten Hosts in einem bestimmten Cluster zu vernetzen, und Container können nach dem Netzwerk nicht neu gestartet werden, bieten jedoch eine schnelle und relativ einfache Möglichkeit, Container auf demselben Host zu vernetzen. Dies ist eine gute Möglichkeit, sich ein Bild davon zu machen, was die Software, mit der Sie dieses Problem wahrscheinlich lösen werden, tatsächlich unter der Haube tut.Darüber hinaus sollten Sie sich wahrscheinlich auch Docker's
network
, Hashicorp'sconsul
, Weaveworksweave
, Jeff Lindsay'sprogrium/consul
&gliderlabs/registrator
und Google's ansehenKubernetes
.Es gibt auch die CoreOS Angebote , die zu nutzen
etcd
,fleet
undflannel
.Und wenn Sie wirklich eine Party haben möchten, können Sie einen Cluster zum Ausführen starten
Mesosphere
, oderDeis
, oderFlynn
.Wenn Sie neu im Networking sind (wie ich), sollten Sie Ihre Lesebrille herausnehmen, "Malen Sie den Himmel mit Sternen - Das Beste von Enya" auf dem Wi-Hi-Fi und ein Bier knacken - es wird sein eine Weile, bevor Sie wirklich genau verstehen, was Sie versuchen zu tun. Hinweis: Sie versuchen, ein
Service Discovery Layer
in Ihrem zu implementierenCluster Control Plane
. Es ist eine sehr schöne Art, einen Samstagabend zu verbringen.Es macht viel Spaß, aber ich wünschte, ich hätte mir die Zeit genommen, mich besser über das Networking im Allgemeinen zu informieren, bevor ich direkt eintauchte. Schließlich fand ich ein paar Beiträge von den wohlwollenden Göttern des Digital Ocean Tutorial:
Introduction to Networking Terminology
undUnderstanding ... Networking
. Ich schlage vor, diese zuerst ein paar Mal zu lesen, bevor ich eintauche.Habe Spaß!
Ursprünglicher Beitrag
Ich kann die Portzuordnung für Docker
Container nicht verstehen . Insbesondere, wie Anforderungen von Nginx an einen anderen Container übergeben werden, der einen anderen Port auf demselben Server überwacht.
Ich habe eine Docker-Datei für einen Nginx-Container wie folgt:
FROM ubuntu:14.04
MAINTAINER Me <[email protected]>
RUN apt-get update && apt-get install -y htop git nginx
ADD sites-enabled/api.myapp.com /etc/nginx/sites-enabled/api.myapp.com
ADD sites-enabled/app.myapp.com /etc/nginx/sites-enabled/app.myapp.com
ADD nginx.conf /etc/nginx/nginx.conf
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80 443
CMD ["service", "nginx", "start"]
Und dann api.myapp.com
sieht die Konfigurationsdatei so aus:
upstream api_upstream{
server 0.0.0.0:3333;
}
server {
listen 80;
server_name api.myapp.com;
return 301 https://api.myapp.com/$request_uri;
}
server {
listen 443;
server_name api.mypp.com;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_pass http://api_upstream;
}
}
Und dann noch eine für app.myapp.com
.
Und dann renne ich:
sudo docker run -p 80:80 -p 443:443 -d --name Nginx myusername/nginx
Und alles steht gut, aber die Anfragen werden nicht an die anderen Container / Ports weitergeleitet. Und wenn ich in den Nginx-Container ssh und die Protokolle inspiziere, sehe ich keine Fehler.
Irgendeine Hilfe?
Antworten:
Die Antwort von @ T0xicCode ist richtig, aber ich dachte, ich würde die Details erweitern, da ich tatsächlich ungefähr 20 Stunden gebraucht habe, um endlich eine funktionierende Lösung zu implementieren.
Wenn Sie Nginx in einem eigenen Container ausführen und als Reverse-Proxy verwenden möchten, um mehrere Anwendungen auf derselben Serverinstanz auszugleichen, müssen Sie die folgenden Schritte ausführen:
Verknüpfen Sie Ihre Container
Wenn Sie
docker run
Ihre Container verwenden, in der Regel durch Eingabe eines Shell-SkriptsUser Data
, können Sie Links zu anderen laufenden Containern deklarieren . Dies bedeutet, dass Sie Ihre Container in der richtigen Reihenfolge starten müssen und nur die letzteren Container mit den ersteren verknüpft werden können. Wie so:So in diesem Beispiel das
API
wird Behälter aller anderen nicht verbunden, aber derApp
Behälter verknüpft istAPI
undNginx
auf beide verbundenAPI
undApp
.Das Ergebnis sind Änderungen an den
env
Variablen und/etc/hosts
Dateien, die sich in den ContainernAPI
und befindenApp
. Die Ergebnisse sehen so aus:/ etc / hosts
Wenn Sie
cat /etc/hosts
in IhremNginx
Container ausgeführt werden, wird Folgendes erzeugt:ENV Vars
Wenn Sie
env
in IhremNginx
Container ausgeführt werden, wird Folgendes erzeugt:Ich habe viele der tatsächlichen Variablen abgeschnitten, aber die oben genannten sind die Schlüsselwerte, die Sie benötigen, um den Datenverkehr auf Ihre Container zu übertragen.
Verwenden Sie Folgendes, um eine Shell zum Ausführen der oben genannten Befehle in einem laufenden Container zu erhalten:
sudo docker exec -i -t Nginx bash
Sie können sehen, dass Sie jetzt sowohl
/etc/hosts
Dateieinträge als auchenv
Variablen haben, die die lokale IP-Adresse für einen der verknüpften Container enthalten. Soweit ich das beurteilen kann, ist dies alles, was passiert, wenn Sie Container mit deklarierten Linkoptionen ausführen. Sie können diese Informationen jetzt jedoch zum Konfigurierennginx
in IhremNginx
Container verwenden.Nginx konfigurieren
Hier wird es etwas knifflig und es gibt einige Möglichkeiten. Sie können Ihre Sites so konfigurieren, dass sie auf einen Eintrag in der erstellten
/etc/hosts
Datei verweisendocker
, oder Sie können dieENV
vars verwenden und einen String-Ersatz (den ich verwendet habesed
) für Ihrenginx.conf
und alle anderen conf-Dateien ausführen, die sich möglicherweise in Ihrem/etc/nginx/sites-enabled
Ordner befinden, um die IP einzufügen Werte.OPTION A: Konfigurieren Sie Nginx mit ENV Vars
Der Hauptunterschied zwischen dieser Option und der Verwendung der
/etc/hosts
Dateioption besteht darin, wie Sie schreibenDockerfile
, um ein Shell-Skript alsCMD
Argument zu verwenden, das wiederum das Ersetzen der Zeichenfolge zum Kopieren der IP-WerteENV
in Ihre Conf-Datei (en) übernimmt.Hier sind die Konfigurationsdateien, mit denen ich am Ende fertig war:
Dockerfile
nginx.conf
api.myapp.conf
Nginx-Startup.sh
Ich überlasse es Ihnen, Ihre Hausaufgaben über die meisten Inhalte von
nginx.conf
und zu machenapi.myapp.conf
.Die Magie entsteht dort,
Nginx-Startup.sh
wo wirsed
denAPP_IP
Platzhalter, den wir in den geschrieben haben, durch Zeichenfolgen ersetzenupstream
Block unsererapi.myapp.conf
undapp.myapp.conf
-Dateien geschrieben haben.Diese ask.ubuntu.com-Frage erklärt es sehr gut: Suchen und Ersetzen von Text in einer Datei mithilfe von Befehlen
Daher hat Docker unseren Container gestartet und die
Nginx-Startup.sh
Ausführung des Skripts ausgelöst , mit demsed
der WertAPP_IP
in die entsprechendeENV
Variable geändert wurde , die wir imsed
Befehl angegeben haben. Wir haben jetzt conf-Dateien in unserem/etc/nginx/sites-enabled
Verzeichnis, die die IP-Adressen derENV
Variablen enthalten, die Docker beim Starten des Containers festgelegt hat. In Ihrerapi.myapp.conf
Datei sehen Sie, dass sich derupstream
Block wie folgt geändert hat:Die IP-Adresse, die Sie sehen, kann unterschiedlich sein, aber ich habe festgestellt, dass dies normalerweise der Fall ist
172.0.0.x
.Sie sollten jetzt alles entsprechend routen.
OPTION B: Verwenden Sie
/etc/hosts
DateieinträgeDies sollte der schnellere und einfachere Weg sein, aber ich konnte es nicht zum Laufen bringen. Angeblich haben Sie nur den Wert des
/etc/hosts
Eintrags in Ihreapi.myapp.conf
undapp.myapp.conf
Dateien eingegeben , aber ich konnte diese Methode nicht zum Laufen bringen.Hier ist der Versuch, den ich gemacht habe
api.myapp.conf
:In Anbetracht dessen, dass es einen Eintrag in meinem gibt
/etc/hosts
Datei wie den folgenden enthält:172.0.0.2 API
Ich dachte, er würde nur den Wert abrufen, aber es scheint nicht so zu sein.Ich hatte auch ein paar zusätzliche Probleme mit meiner
Elastic Load Balancer
Beschaffung von allen AZs, so dass dies möglicherweise das Problem war, als ich diese Route ausprobierte. Stattdessen musste ich lernen, wie man unter Linux mit dem Ersetzen von Strings umgeht, also hat das Spaß gemacht. Ich werde es gleich versuchen und sehen, wie es geht.quelle
Ich habe versucht, den beliebten Jason Wilder-Reverse-Proxy zu verwenden, der auf magische Weise für alle funktioniert, und festgestellt, dass er nicht für alle funktioniert (dh für mich). Und ich bin brandneu bei NGINX und mochte es nicht, dass ich die Technologien, die ich verwenden wollte, nicht verstand.
Wollte meine 2 Cent hinzufügen, da die obige Diskussion über
linking
Container zusammen jetzt veraltet ist, da es sich um eine veraltete Funktion handelt. Hier ist eine Erklärung, wie es gehtnetworks
. Diese Antwort ist ein vollständiges Beispiel für das Einrichten von nginx als Reverse-Proxy für eine statisch ausgelagerte Website mitDocker Compose
und nginx-Konfiguration.TL; DR;
Fügen Sie die Dienste, die miteinander kommunizieren müssen, zu einem vordefinierten Netzwerk hinzu. Für eine schrittweise Diskussion über Docker-Netzwerke habe ich hier einige Dinge gelernt: https://technologyconversations.com/2016/04/25/docker-networking-and-dns-the-good-the-bad-and- das hässliche/
Definieren Sie das Netzwerk
Zunächst benötigen wir ein Netzwerk, über das alle Ihre Backend-Services kommunizieren können. Ich habe meine angerufen,
web
aber es kann sein, was immer Sie wollen.Erstellen Sie die App
Wir machen einfach eine einfache Website-App. Die Website ist eine einfache index.html-Seite, die von einem Nginx-Container bereitgestellt wird. Der Inhalt ist ein für den Host bereitgestelltes Volume unter einem Ordner
content
DockerFile:
default.conf
docker-compose.yml
Beachten Sie, dass wir hier keine Portzuordnung mehr benötigen. Wir legen Port 80 einfach frei. Dies ist praktisch, um Portkollisionen zu vermeiden.
Führen Sie die App aus
Starten Sie diese Website mit
Einige lustige Überprüfungen bezüglich der DNS-Zuordnungen für Ihren Container:
Dieser Ping sollte in Ihrem Container funktionieren.
Erstellen Sie den Proxy
Nginx Reverse Proxy:
Dockerfile
Wir setzen die gesamte Konfiguration des virtuellen Hosts zurück, da wir sie anpassen werden.
docker-compose.yml
Führen Sie den Proxy aus
Starten Sie den Proxy mit unserem Trusty
Unter der Annahme, dass keine Probleme vorliegen, werden zwei Container ausgeführt, die unter Verwendung ihrer Namen miteinander kommunizieren können. Lass es uns testen.
Richten Sie den virtuellen Host ein
Das letzte Detail besteht darin, die virtuelle Hosting-Datei so einzurichten, dass der Proxy den Datenverkehr basierend darauf leiten kann, wie Sie Ihren Abgleich einrichten möchten:
sample-site.conf für unsere virtuelle Hosting-Konfiguration:
Abhängig davon, wie der Proxy eingerichtet wurde, benötigen Sie diese Datei in Ihrem lokalen
conf.d
Ordner, den wir über dievolumes
Deklaration in der Datei bereitgestellt habendocker-compose
Datei bereitgestellt haben.Zu guter Letzt weisen Sie nginx an, die Konfiguration neu zu laden.
Diese Abfolge von Schritten ist der Höhepunkt stundenlanger Kopfschmerzen, als ich mit dem immer schmerzhaften 502 Bad Gateway-Fehler kämpfte und zum ersten Mal Nginx lernte, da der größte Teil meiner Erfahrung mit Apache war.
Diese Antwort soll zeigen, wie der 502 Bad Gateway-Fehler behoben werden kann, der darauf zurückzuführen ist, dass Container nicht miteinander kommunizieren können.
Ich hoffe, diese Antwort erspart jemandem da draußen stundenlange Schmerzen, da es aus irgendeinem Grund sehr schwierig war, Container dazu zu bringen, miteinander zu sprechen, obwohl dies ein offensichtlicher Anwendungsfall war. Aber andererseits bin ich dumm. Und bitte lassen Sie mich wissen, wie ich diesen Ansatz verbessern kann.
quelle
502 Gateway Error
, heutzutage ein berüchtigter Klassiker. Vielen Dank an @gdbj, dass Sie sich die Zeit genommen haben, um das Gespräch voranzutreiben und eine so detaillierte Lösung bereitzustellen.Mithilfe von Docker-Links können Sie den Upstream-Container mit dem Nginx-Container verknüpfen. Eine zusätzliche Funktion ist, dass Docker die Hostdatei verwaltet. Dies bedeutet, dass Sie auf den verknüpften Container mit einem Namen und nicht mit der potenziell zufälligen IP verweisen können.
quelle
AJBs "Option B" kann mithilfe des Ubuntu-Basisimages und der Einrichtung von nginx selbst zum Laufen gebracht werden. (Es hat nicht funktioniert, als ich das Nginx-Image von Docker Hub verwendet habe.)
Hier ist die Docker-Datei, die ich verwendet habe:
Meine Nginx-Konfiguration (aka: conf / mysite.com):
Und schließlich, wie ich meine Container starte:
Dies brachte mich zum Laufen, sodass mein Nginx den Upstream auf den zweiten Docker-Container richtete, der Port 3000 freilegte.
quelle
upstream website {
definiert den Website-Wert für Nginx. Das verwenden Sie dann in Ihremproxy_pass
. Der Docker-Teil verwendet aus Gründen der Konsistenz nur denselben Namen, hat jedoch nichts mit dem Nginx-Setup zu tun. Um es etwas klarer zu machen, sollte der Proxy-Pass lauten:upstream website { server localhost:3000; }
Die Antwort von @ gdbj ist eine großartige Erklärung und die aktuellste Antwort. Hier ist jedoch ein einfacherer Ansatz.
Wenn Sie also den gesamten Datenverkehr von Nginx umleiten möchten, während ein
80
anderer Container verfügbar gemacht wird8080
, kann die Mindestkonfiguration so gering sein wie:nginx.conf:
docker-compose.yml
Docker-Dokumente
quelle
Ich habe gerade einen Artikel von Anand Mani Sankar gefunden, der eine einfache Möglichkeit zeigt, Nginx Upstream Proxy mit Docker Composer zu verwenden.
Grundsätzlich muss man die Instanzverknüpfung und die Ports in der Docker-Compose-Datei konfigurieren und den Upstream unter nginx.conf entsprechend aktualisieren.
quelle
links
die veraltet sind. Verwenden Sie jetzt Netzwerke: docs.docker.com/engine/userguide/networking