
Ich habe einen einzelnen kleinen VPS, auf dem verschiedene Dienste laufen, wie zum Beispiel eine WordPress-Installation und ein paar Web-Apps. Seit einiger Zeit lasse ich alle Dienste darauf als Docker-Container laufen. Da ich eine Vielzahl von Domänen und Subdomänen habe, die auf diese Box verweisen, verwende ich den Frontend-Proxy Traefik, um die Web-Ports zu erfassen und sie dann intern in einem Docker-Netzwerk weiterzuleiten.
Ich starte Traefik so:
#!/bin/bash
# Removes the restart policy from previous containers
CONTAINER_LABEL=traefik-instance
../../bin/remove-restart.sh $CONTAINER_LABEL
mkdir --parents /var/log/traefik
mkdir --parents /etc/letsencrypt-traefik
docker run \
--label $CONTAINER_LABEL \
--publish 80:80 \
--publish 443:443 \
--volume $PWD/traefik.toml:/etc/traefik/traefik.toml \
--volume $PWD/rules:/etc/traefik/rules \
--volume /etc/letsencrypt-traefik:/etc/letsencrypt-traefik \
--volume /var/log/traefik:/log \
--network dockernet \
--detach \
--restart always \
traefik:1.6
Das funktioniert alles sehr gut. Ich habe Docker Swarm vor Kurzem entdeckt und möchte alle meine Container in Dienste umwandeln, die mir Replikationsdienste, fortlaufende Updates und Bereitstellungen ohne Ausfallzeiten bieten. Ich möchte die Änderung jedoch schrittweise vornehmen, sodass Traefik sowohl zu Swarm-Diensten als auch zu gewöhnlichen (nicht zu Swarm gehörenden) Containern weiterleiten kann.
Um Traefik als Dienst zu starten, gehe ich nun wie folgt vor. Sie werden feststellen, dass ich zu Testzwecken nicht standardmäßige Ports verwende:
#!/bin/bash
# Using "traefik2" while I am experimenting with multiple services
mkdir --parents /var/log/traefik2
mkdir --parents /etc/letsencrypt-traefik
docker service create \
--publish 8080:80 \
--publish 8443:443 \
--mount type=bind,source=$PWD/traefik.toml,target=/etc/traefik/traefik.toml \
--mount type=bind,source=$PWD/rules,target=/etc/traefik/rules \
--mount type=bind,source=/etc/letsencrypt-traefik,target=/etc/letsencrypt-traefik \
--mount type=bind,source=/var/log/traefik2,target=/log \
--network traefiknet \
traefik:1.6
Dies funktioniert auch, wenn auf einen Swarm-Webdienst verwiesen wird, der im selben Netzwerk erscheint.
Ich habe also zwei Docker-Netzwerke (neben den verschiedenen Standardeinstellungen, die Docker für sich selbst erstellt), und zwar wie folgt:
root@box:~/docker# docker network ls
NETWORK ID NAME DRIVER SCOPE
1aa479f13faa dockernet bridge local
k71hpg1n0lo9 traefiknet overlay swarm
Dies führt dazu, dass ich einen funktionierenden Traefik-Container habe, der Docker-Container sehen kann, und einen funktionierenden Traefik-Dienst, der Swarm-Dienste sehen kann. Sie können sich jedoch nicht gegenseitig sehen.
Um dies zu beheben, habe ich versucht, das Docker-Netzwerk zum Start des Traefik Swarm-Dienstes hinzuzufügen:
--network dockernet \
Mit anderen Worten, ich möchte, dass dieser Dienst sowohl mit dem Bridge-Netzwerk (alt) als auch mit dem Overlay-Netzwerk (neu) verbunden wird. Leider erhalte ich folgendes:
Fehlerantwort vom Daemon: Das Netzwerk Dockernet kann nicht mit Diensten verwendet werden. Es können nur Netzwerke verwendet werden, die auf den Swarm beschränkt sind, wie z. B. solche, die mit dem Overlay-Treiber erstellt wurden.
Gibt es eine Möglichkeit, wie mein neuer Dienst eine Verbindung zum alten Netzwerk herstellen kann, oder gibt es überhaupt eine Möglichkeit, wie meine alten Container eine Verbindung zum neuen Netzwerk herstellen können? Ich habe versucht, nach dem Fehler zu suchen, aber es scheint nicht viele Erwähnungen davon zu geben. Ich frage mich, ob diese Randfallverwendung von Swarm noch nicht vielen Leuten begegnet ist.
(Eine Lösung für mich besteht natürlich darin, alle meine Container in Dienste umzuwandeln, aber um eine radikale Änderung zu vermeiden, würde ich es wenn möglich lieber langsam tun.)
Anschließbare Netzwerke ausprobieren
Ich habe dann meine Dienste gelöscht und Folgendes versucht:
docker network rm traefiknet
docker network create driver=overlay --attachable traefiknet
Ich habe dann den Traefik-Dienst neu erstellt und er startet. Er funktioniert offensichtlich immer noch, da er den Verkehr an einen Dienst weiterleitet, der ebenfalls dem Traefiknet-Overlay beigetreten ist.
Ich habe jedoch einen Nicht-Service-Container erstellt und diesen ausschließlich mit verbunden traefiknet
, und die --network-alias
von mir damit erstellte Datei kann vom Service nicht gesehen werden. Seltsamerweise, wenn ich in diesen Nicht-Swarm-Container schalte,dürfenPingen Sie den Swarm-Traefik-Container an, damit das Netzwerk funktioniert. (Ich habe versucht, einen Alpine-Shell-Dienst zu erstellen, der mit verbunden ist traefiknet
, und von hier aus kann ich weder den Containernamen meines Nicht-Swarm-Containers noch dessen pingen --network-alias
.)
Docker aktualisieren
Ich habe versucht, Docker von 17.03.2-ce auf 18.06.1-ce zu aktualisieren, weil ein Satzim Handbuchdeutete darauf hin, dass meine alte Docker-Version die Ursache des Problems sein könnte:
Die Kommunikation zwischen einem Container und einem Swarm-Dienst richtet die Kommunikation zwischen einem eigenständigen Container und einem Swarm-Dienst unter Verwendung eines anschließbaren Overlay-Netzwerks ein. Dies wird in Docker 17.06 und höher unterstützt.
Allerdings hat auch dies nicht geholfen.
Antwort1
Ich glaube, ich habe eine Lösung dafür, obwohl es noch einige Dinge gibt, die ich nicht verstehe. Um den Kontext für diese Antwort festzulegen, installiere ich jetzt wie folgt einen Docker-Nicht-Swarm-Container:
#!/bin/bash
# Save pwd and then change dir to the project root
STARTDIR=`pwd`
cd `dirname $0`/../..
# Removes the restart policy from previous containers
CONTAINER_LABEL=ilovephp-staging
NETWORK_ALIAS=${CONTAINER_LABEL}
./bin/remove-restart.sh $CONTAINER_LABEL
docker run \
--network swarmnet \
--network-alias ${NETWORK_ALIAS} \
--env TUTORIAL_ENVIRONMENT_NAME=staging \
--detach \
--restart always \
ilovephp:2018-08-19
# Go back to original dir
cd $STARTDIR
Wie Sie sehen, kann ich gemäß der Aktualisierung meiner Frage jetzt einen Container in ein anschließbares Swarm-Netzwerk einfügen.
Ich habe herausgefunden, dass der Grund, warum dies nicht von einem Swarm-Dienst angepingt werden kann, darin liegt, dass ein fehlt --name
. Sobald ich ein hinzufüge --name
, ist es erreichbar. Interessanterweise funktioniert es jedoch, wenn ich versuche, den Swarm-Dienst oder den Swarm-Container vom Docker-Container aus anzupingen:
root@server:~# docker exec -it loving_allen sh
/ # # *** Ping a specific Swarm container ***
/ # ping alpine-swarm.1.9llv2hvv5xnc1c8diuhfh5m09
PING alpine-swarm.1.9llv2hvv5xnc1c8diuhfh5m09 (10.0.1.23): 56 data bytes
64 bytes from 10.0.1.23: seq=0 ttl=64 time=0.516 ms
^C
--- alpine-swarm.1.9llv2hvv5xnc1c8diuhfh5m09 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.516/0.516/0.516 ms
/ # # *** Ping the Swarm service ***
/ # ping alpine-swarm
PING alpine-swarm (10.0.1.22): 56 data bytes
64 bytes from 10.0.1.22: seq=0 ttl=64 time=0.376 ms
^C
--- alpine-swarm ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.137/0.231/0.376 ms
Mein ursprünglicher Plan war also, meine Traefik-Instanz von einem Container in einen Swarm-Dienst umzuwandeln, aber das wird nicht funktionieren, weil unbenannte Nicht-Swarm-Container nicht erreichbar sind. Meine Lösung besteht jetzt darin, zuerst alle meine Systeme von Containern in Dienste umzuwandeln, und wenn das alles erledigt ist, kann ich die Traefik-Instanz zuletzt umwandeln. Auf diese Weise verbinde ich immer vom Container zum Dienst und nicht umgekehrt.
(Ich kann kein --name
s hinzufügen, da der Docker-Host beim Neustart versucht, Container mit demselben Namen neu zu erstellen. Dies schlägt fehl, da die alten Container noch immer diese kollidierenden Namen aufweisen. Und ich kann --rm
das nicht beheben, da es nicht mit kompatibel ist --restart
!Mehr dazu hier).
Ich verstehe immer noch nicht, warum ein von Docker generierter Containername nicht von einem Swarm-Container aus pingbar ist, und auch nicht, warum ein --network-alias
nicht hilft. Aber da meine Lösung nur vorübergehend sein muss, bis alle meine Systeme Swarm-Dienste sind, spielt das wahrscheinlich keine Rolle.