it-swarm.com.de

Zuweisen von vhosts zu Docker-Ports

Ich habe ein Wildcard-DNS eingerichtet, damit alle Webanforderungen an eine benutzerdefinierte Domain (* .foo) der IP-Adresse des Docker-Hosts zugeordnet werden. Wenn mehrere Container Apache- (oder Nginx-) Instanzen ausführen, ordnet jeder Container den Apache-Port (80) einem externen Eingangsport zu.

Was ich tun möchte, ist eine Anfrage an container-1.foo, die bereits über meinen benutzerdefinierten DNS-Server der richtigen IP-Adresse (des Docker-Hosts) zugeordnet ist, aber die Standard-Port-80-Anfrage an den richtigen Docker-externen Proxy sendet Port so, dass die richtige Apache-Instanz aus dem angegebenen Container basierend auf der benutzerdefinierten Domäne antworten kann. Ebenso würde container-2.foo den Apache eines zweiten Containers ersetzen und so weiter.

Gibt es eine vorgefertigte Lösung dafür, ist es meine beste Wahl, einen Nginx-Proxy auf dem Docker-Host auszuführen, oder sollte ich einen node.js-Proxy mit der Möglichkeit zum Verwalten von Docker-Containern (Starten/Stoppen/Wiederherstellen über das Web) erstellen ), oder...? Welche Optionen stehen mir zur Verfügung, um die Verwendung der Docker-Container eher als ein natürliches Ereignis und nicht als ein Ereignis mit externen Ports und Container-Jonglage zu betrachten?

81
ringmaster

Diese Antwort mag etwas spät sein, aber Sie benötigen einen automatischen Reverse-Proxy. Ich habe zwei Lösungen dafür verwendet:

  • jwilder/nginx-proxy
  • Traefik

Mit der Zeit bevorzuge ich Traefik. Vor allem, weil es gut dokumentiert und gepflegt ist und über mehr Funktionen verfügt (Lastenausgleich mit verschiedenen Strategien und Prioritäten, Integritätsprüfungen, Leistungsschalter, automatische SSL-Zertifikate mit ACME/Let's Encrypt, ...).


Verwendung von jwilder/nginx-proxy

Wenn Sie einen Docker-Container ausführen Jason Wilders nginx-proxy Docker-Image , wird ein nginx-Server als Reverse-Proxy für Ihre anderen Container eingerichtet, für den keine Konfiguration zu pflegen ist.

Führen Sie einfach Ihre anderen Container mit dem VIRTUAL_Host Die Umgebungsvariableund der Nginx-Proxy ermitteln ihren IP-Port und aktualisieren die Nginx-Konfiguration für Sie.

Angenommen, Ihr DNS ist so eingerichtet, dass *.test.local wird der IP-Adresse Ihres Docker-Hosts zugeordnet. Starten Sie dann einfach die folgenden Container, um eine schnelle Demo auszuführen:

# start the reverse proxy
docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy

# start a first container for http://tutum.test.local
docker run -d -e "VIRTUAL_Host=tutum.test.local" tutum/hello-world

# start a second container for http://deis.test.local
docker run -d -e "VIRTUAL_Host=deis.test.local" deis/helloworld

Traefik benutzen

Wenn Sie einen Traefik -Container ausführen, wird ein Reverse-Proxy-Server eingerichtet, der seine Weiterleitungsregeln neu konfiguriert, wenn Docker-Labelsauf Ihren Containern gefunden werden.

Angenommen, Ihr DNS ist so eingerichtet, dass *.test.local wird der IP-Adresse Ihres Docker-Hosts zugeordnet. Starten Sie dann einfach die folgenden Container, um eine schnelle Demo auszuführen:

# start the reverse proxy
docker run --rm -it -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock traefik --docker

# start a first container for http://tutum.test.local
docker run -d -l "traefik.frontend.rule=Host:tutum.test.local" tutum/hello-world

# start a second container for http://deis.test.local
docker run -d -l "traefik.frontend.rule=Host:deis.test.local" deis/helloworld
78
Thomasleveil

Hier sind zwei mögliche Antworten: (1) Richten Sie die Ports direkt mit Docker ein und verwenden Sie Nginx/Apache als Proxy für die VHosts, oder (2) verwenden Sie Dokk , um die Ports und VHosts für Sie zu verwalten (wie ich gelernt habe) Methode 1) zu tun.

Methode 1a (Ports direkt mit Docker zuweisen)

Schritt 1: Richten Sie nginx.conf oder Apache auf dem Host mit den gewünschten Portnummernzuweisungen ein. Dieser Webserver, der auf dem Host ausgeführt wird, führt den vhost-Proxy aus. In Bezug auf Docker ist das nichts Besonderes - es ist normales vhost-Hosting. Als nächstes folgt in Schritt 2 der spezielle Teil, mit dem Docker die richtige Host-Portnummer verwenden kann.

Schritt 2: Erzwingen Sie die Zuweisung von Portnummern in Docker mit "-p", um die Portzuordnungen von Docker festzulegen, und "-e", um benutzerdefinierte Umgebungsvariablen in Docker wie folgt festzulegen:

port=12345 # <-- the vhost port setting used in nginx/Apache
IMAGE=myapps/container-1
id=$(docker run -d -p :$port -e PORT=$port $IMAGE)
# -p :$port will establish a mapping of 12345->12345 from outside docker to
# inside of docker.
# Then, the application must observe the PORT environment variable
# to launch itself on that port; This is set by -e PORT=$port.

# Additional goodies:
echo $id # <-- the running id of your container
echo $id > /app/files/CONTAINER # <-- remember Docker id for this instance
docker ps # <-- check that the app is running
docker logs $id # <-- look at the output of the running instance
docker kill $id # <-- to kill the app

Methode 1b: Hartcodierter Anwendungsport

... wenn Ihre Anwendung einen fest codierten Port verwendet, z. B. Port 5000 (d. h. nicht über die PORT-Umgebungsvariable wie in Methode 1a konfiguriert werden kann), kann dieser wie folgt über Docker fest codiert werden:

publicPort=12345
id=$(docker run -d -p $publicPort:5000 $IMAGE)
# -p $publicPort:5000 will map port 12345 outside of Docker to port 5000 inside
# of Docker. Therefore, nginx/Apache must be configured to vhost proxy to 12345,
# and the application within Docker must be listening on 5000.

Methode 2 (lassen Sie Dokku die Ports herausfinden)

Momentan ist Dokk eine ziemlich gute Option zum Verwalten von Docker-Vhosts. Möglicherweise ist die Verwendung von Flynn eine Option, aber Flynn ist derzeit noch in den Anfängen und noch nicht ganz fertig. Deshalb haben wir uns für Dokku entschieden: Aktivieren Sie vhosts, nachdem Sie die Dokku-Installationsanweisungen für eine einzelne Domain befolgt haben, indem Sie die Datei "VHOST" erstellen:

echo yourdomain.com > /home/git/VHOST
# in your case: echo foo > /home/git/VHOST

Wenn nun eine App per SSH an Dokku gesendet wird (siehe Dokku-Dokumentation, wie das geht), schaut Dokku auf die VHOST-Datei und generiert sie für die jeweilige gesendete App (sagen wir, Sie haben "container-1" gedrückt) die folgende Datei:

/home/git/container-1/nginx.conf

Und es wird den folgenden Inhalt haben:

upstream container-1 { server 127.0.0.1:49162; }
server {
  listen      80;
  server_name container-1.yourdomain.com;
  location    / {
    proxy_pass  http://container-1;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_Host;
    proxy_set_header X-Forwarded-For $remote_addr;
  }
}

Wenn der Server neu gestartet wird, stellt Dokku sicher, dass Docker die Anwendung mit dem Port startet, der dem ursprünglich bereitgestellten Port zugeordnet ist (hier 49162), anstatt nach dem Zufallsprinzip einen anderen Port zuzuweisen. Um diese deterministische Zuweisung zu erreichen, speichert Dokku den ursprünglich zugewiesenen Port in /home/git/container-1/PORT Und setzt beim nächsten Start die PORT -Umgebung auf diesen Wert und ordnet Dockers Portzuweisungen beiden Ports zu die Host-Seite und die App-Seite. Dies steht im Gegensatz zum ersten Start, bei dem Dokku PORT=5000 Setzt und dann herausfindet, welcher zufällige Port Dokku auf der VPS-Seite zu 5000 auf der App-Seite zugeordnet ist. Es ist ungefähr (und könnte sich in Zukunft sogar ändern), aber es funktioniert!

Die Art und Weise, wie VHOST unter der Haube funktioniert, ist: Wenn Dokku einen Git-Push der App über SSH ausführt, werden Hooks ausgeführt, die in /var/lib/dokku/plugins/nginx-vhosts Leben. Diese Hooks befinden sich auch im Dokku-Quellcode hier und sind für das Schreiben der nginx.conf - Dateien mit den richtigen vhost-Einstellungen verantwortlich. Wenn Sie dieses Verzeichnis nicht unter /var/lib/dokku Haben, versuchen Sie, dokku plugins-install Auszuführen.

42
David Baird

Mit Docker möchten Sie, dass die internen IPS normal bleiben (z. B. 80) und herausfinden, wie die zufälligen Ports verdrahtet werden.

Ein Weg, mit ihnen umzugehen, ist mit einem Reverse-Proxy wie Hipache. Zeigen Sie mit Ihrem DNS darauf, und Sie können den Proxy neu konfigurieren, wenn Ihre Container auf und ab gehen. Schauen Sie sich http://txt.fliglio.com/2013/09/protyping-web-stuff-with-docker/ an, um zu sehen, wie dies funktionieren könnte.

Wenn Sie nach etwas Robusterem suchen, sollten Sie sich "Service Discovery" ansehen. (Ein Blick auf die Serviceerkennung mit Docker: http://txt.fliglio.com/2013/12/service-discovery-with-docker-docker-links-and-beyond/ )

3
ben schwartz