localhost ist ein per Internetstandard definierter Domainname, der über eine Loopback-Schnittstelle auf die gerade genutzte Maschine verweist, meistens auf die IP-Adresse 127.0.0.1.[1]

In diesem Beitrag geht es darum, was das localhost aus den verschiedenen Perspektiven beim Einsatz von Docker ist. Dafür setzen wir die folgende Testumgebung auf:

  • Service A mit Webserver auf Port 80
  • Service B mit Webserver auf Port 81

In dem Repository docker-localhost habe ich die zwei Dockerfiles inkl. der Konfigurationsdateien bereitgestellt. Darin ist auch beschrieben, wie man die Images erstellen kann.

Test-Perspektiven

Wir schauen uns mal localhost aus Sicht des Hosts und der Container genauer an.

localhost aus Sicht des Hosts

Durch die Angabe des -p <host>:<con> Parameters mit den Ports binden wir den Port vom Host an den Port vom Container.

docker run --name ServiceA -p 9080:80 --rm -d test/service-a

und

docker run --name ServiceB -p 9081:81 --rm -d test/service-b

Damit sind Aufrufe im Browser oder per Tool mit http://localhost:9080 und http://localhost:9081 möglich.

Das funktioniert, da über ein Port-Mapping eine Art Portweiterleitung eingerichtet wird. Somit greift man nur indirekt vom Host über localhost auf die Container zu.

localhost aus Sicht eines Containers

Das sieht man am besten, wenn man sich überlegt auf welche Endpunkte man mit localhost aus einem Container zugreifen könnte.

2 und 4 sind nur zwei Beispiele für Ports auf der Loopback-Schnittstelle des Host-Systems.

# 1. Zugriff den eigenen Webserver über http://localhost:80
PS> docker exec -it ServiceA curl http://localhost:80
Service: Service A
Server address: 127.0.0.1:80
Server name: c70d9a8f2d56
Date: 22/Apr/2019:13:48:20 +0000
URI: /
Request ID: 5aa8964a53891b4d1da0e7b09f8b6676

# 2. Zugriff auf den Webserver von Service B über http://localhost:9081
PS> docker exec -it ServiceA curl http://localhost:9081
curl: (7) Failed to connect to localhost port 9081: Connection refused

# 3. Zugriff über den Webserver von Service B über http://localhost:81
PS> docker exec -it ServiceA curl http://localhost:81
curl: (7) Failed to connect to localhost port 81: Connection refused

# 4. Zugriff auf den eigenen Webserver über http://localhost:9080
PS> docker exec -it ServiceA curl http://localhost:9080
curl: (7) Failed to connect to localhost port 9080: Connection refused

Damit haben wir allein durch Ausprobieren herausgefunden, was das localhost aus Sicht eines Containers ist. Mit localhost spricht man innerhalb eines Systems immer nur sich selber an.

Host-Netzwerk unter Linux

Beim Einsatz von Docker unter Linux gibt es noch eine weitere Möglichkeit. Es ist möglich das Host-Netzwerk zu benutzen, damit werden alle Docker-Container direkt an die Netzwerk-Schnittstelle des Hosts angebunden. [2]

Da bei dieser Variante die Aufrufe aus Containern und Host identische sind, scheint dies erst mal einfacher zu sein.

Man läuft aber in Probleme, wenn im Container Ports verwendet werden, die von anderen Containern oder Programmen auf dem Host verwendet werden bzw. werden müssen. Da diese Möglichkeit ausschließlich für Linux als Host existiert, erschwert man damit zusätzlich die Zusammenarbeit mit Kollegen.

Empfehlung: Abstand von dieser Variante nehmen.


Quellen

[1] Wikipedia, https://de.wikipedia.org/wiki/Localhost, 22.04.2019

[2] docker docs, https://docs.docker.com/network/network-tutorial-host/, 22.04.2019