Aktualisierung 1

Aktualisierung 1

Ich versuche, einen Docker-Schwarm einzurichten.

Meine Knoten müssen über TLS kommunizieren.

Ich habe ein Zertifikat für den Managerknoten mit extendedKeyUsage = serverAuth erstellt

Ich habe den Managerknoten mit dem folgenden daemon.json konfiguriert:

{
    "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"],
    "tlscacert": "/var/docker/ca.pem",
    "tlscert": "/var/docker/server-cert.pem",
    "tlskey": "/var/docker/server-key.pem",
    "tlsverify": true
}

Um dies zu testen, habe ich ein Client-Zertifikat erstellt, es verwendet, um von meinem Laptop aus eine Verbindung mit der Docker-API herzustellen, und ich kann erfolgreich eine Verbindung herstellen.

Jetzt muss ich dem Schwarm einen Worker-Knoten hinzufügen.

Ich habe es auf die gleiche Weise wie den Manager-Knoten eingerichtet; mit einem ähnlichen daemon.json. Ich habe einen SSL-Schlüssel mit extendedKeyUsage = serverAuth verwendet und die Client-Verbindung auf die gleiche Weise wie auf dem Manager-Knoten nachgewiesen.

Dann habe ich im Manager Docker Swarm Init ausgeführt

Um den Worker-Knoten dem Swarm hinzuzufügen, verwende ich den folgenden Befehl: docker swarm join --token XXX dockman.myhost.com:2376

Aber ich erhalte eine Fehlermeldung:

Error response from daemon: rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: authentication handshake failed: remote error: tls: bad certificate"

Ich dachte, ich könnte es weiter testen, indem ich versuche, vom Worker-Knoten aus eine Verbindung zur Docker-API auf dem Manager-Knoten herzustellen:

sudo docker --tlsverify --tlscacert=/var/docker/ca.pem --tlscert=./server-cert.pem --tlskey=./server-key.pem -H=127.0.0.1:2376 version

Das Ergebnis ist:

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea838
 Built:             Wed Nov 13 07:29:52 2019
 OS/Arch:           linux/amd64
 Experimental:      false
The server probably has client authentication (--tlsverify) enabled. Please check your TLS client certification settings: Get https://127.0.0.1:2376/v1.40/version: remote error: tls: bad certificate

Dieser zweite Test hat mir viel mehr Stoff zum Nachdenken gegeben. Natürlich wird er fehlschlagen, weil ich versuche, eine Verbindung mit einem Server-Zertifikat und nicht mit einem Client-Zertifikat herzustellen, aber ist das nicht genau das, was der Docker Swarm Join versucht? Es ergibt für mich keinen Sinn, das Client-Zertifikat in daemon.json einzufügen. Ich habe gegoogelt, wie man ein einziges Zertifikat sowohl für den Server als auch für den Client erstellt, und es ist möglich, scheint aber eine schlechte Praxis zu sein. Ich hätte gedacht, dass es im Tutorial behandelt würde, wenn es erforderlich wäre.

Ich stecke an diesem Punkt fest. Ich kann nicht herausfinden, welche Zertifikatskonfiguration erforderlich ist.

Ich habe verfolgt https://github.com/docker/docker.github.io/blob/master/swarm/configure-tls.md Hier wird die Erstellung von Zertifikaten beschrieben, die Client- oder Serverauthentifizierung wird jedoch überhaupt nicht erwähnt.

Aktualisierung 1

Ich habe ein Dokument gefunden, in dem stand, dass Zertifikate Client und Server sein müssen

https://hub.docker.com/_/swarm/

Also habe ich das Knotenzertifikat so umgestaltet, dass es sowohl als Client als auch als Server fungiert. Jetzt funktioniert der Befehl der Docker-Version, wenn er vom Knoten ausgeführt wird, aber nicht der Swarm-Join.

Antwort1

Sie verwechseln den Swarm-Modus ( docker swarmund ähnliche CLIs) mit dem klassischen containerbasierten Swarm (gehostet als Container auf Docker Hub). Dies sind zwei verschiedene Tools.

Die beiden Dokumentationssätze finden Sie unter:

Im Swarm-Modus ist keine manuelle TLS-Konfiguration erforderlich, da alles integriert ist und die Ports für den Swarm-Modus nicht mit den Ports für den Docker-API-Socket übereinstimmen. Sie möchten die Docker-API nicht ohne triftigen Grund im Netzwerk verfügbar machen (dies ist eine häufige Quelle von Hacks), und der Swarm-Modus ist kein Grund.

Daher sollten Sie die -HOption aus dem dockerdBefehl entfernen, zusammen mit allen dort vorhandenen TLS-Optionen. Führen Sie den Befehl dann docker swarm initauf dem ersten Manager aus, der die TLS-Anmeldeinformationen generiert und ein Token bereitstellt, das einen Hash der selbst signierten Zertifikate enthält. Anschließend führen die anderen Manager und Worker einen aus, docker swarm joinum die Client-Zertifikate zu generieren, eine Verbindung zum Manager herzustellen, den Hash der Manager-Zertifikate anhand des Tokens zu validieren und sich mit dem geheimen Teil des Join-Tokens gegenüber dem Manager zu authentifizieren.

Das Obige verschlüsselt die Managementebene zwischen Managern und Arbeitern. Um die in Overlay-Netzwerken zwischen Arbeitern übertragenen Daten zu verschlüsseln, müssen Sie IPSec in den von Ihnen erstellten Overlay-Netzwerken aktivieren:

docker network create --opt encrypted --driver overlay app-overlay-net

Die Dokumentation zu dieser Funktion finden Sie unter:https://docs.docker.com/v17.09/engine/userguide/networking/overlay-security-model/

Antwort2

Ich hatte Recht, dass alle Zertifikate sowohl Client- als auch Server-Zertifikate sein mussten, damit sie funktionierten.

Dann stieß ich auf weitere Probleme. Das Hauptproblem war, dass die virtuellen Maschinen auf dem von mir verwendeten Host die Verwendung von Port 4789 verbieten, da dieser von VMWare verwendet wird. Dies ist der Standard-Datenpfad-Port, der für das Overlay-Netzwerk verwendet wird.

Ich musste alle Knoten und Manager vollständig aus dem Schwarm entfernen (und ihn effektiv löschen) und ihn mit dem Parameter „data-path-port“ neu starten:

docker swarm init --data-path-port=7777

(Ich habe auch die Werbeadresse als IP für jeden Knoten angegeben, aber ich glaube nicht, dass das erforderlich war.)

Natürlich gingen bei diesem Vorgang alle meine Docker-Geheimnisse, die Docker-Konfiguration und einige meiner Docker-Netzwerke verloren und mussten neu erstellt werden.

Nachdem ich dies abgeschlossen und die Firewall so geändert hatte, dass sie UDP-Kommunikation zwischen Knoten über den Datenpfad-Port zuließ, funktionierte alles wieder.

Da das Schwarmnetzwerk verschlüsselt ist, sollte meiner Meinung nach alles funktionieren.

verwandte Informationen