Ich brauche Hilfe beim Debuggen des folgenden Setups:
Ich habe 3 VPs-Cloud-Instanzen von einem Hosting-Unternehmen. (Ich glaube, die VPS sind VMWare, aber ich kann auf der Website des Host-Unternehmens keine Dokumentation finden.)
- Alle laufen unter Ubuntu 18.04.
- Ich habe Docker auf allen 3 installiert.
Alle Docker-Versionen sind gleich:
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
Server: Docker Engine - Community
Engine:
Version: 19.03.5
API version: 1.40 (minimum version 1.12)
Go version: go1.12.12
Git commit: 633a0ea838
Built: Wed Nov 13 07:28:22 2019
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.2.4
GitCommit: e6b3f5632f50dbc4e9cb6288d911bf4f5e95b18e
runc:
Version: 1.0.0-rc6+dev
GitCommit: 6635b4f0c6af3810594d2770f662f34ddc15b40d
docker-init:
Version: 0.18.0
GitCommit: fec3683
Auf einem Knoten 1 habe ich den folgenden Init-Befehl ausgeführt:
docker swarm init --advertise-addr NODE_1_IP --data-path-port=7789
Und auf den Knoten 2 und 3 habe ich die folgenden Join-Befehle ausgeführt
docker swarm join --token XXX -advertise-addr NODE_2/3_IP NODE_1_IP:2377
Das Token wird von dem Wert übernommen, den mir Knoten 1 gegeben hat. Ich habe ein früheres Problem gelöst, indem ich den Datenpfad-Port angegeben habe. Ich denke, das liegt daran, dass die VPS VMWare sind und es mit dem Standarddatenport in Konflikt steht.
Mein Cloud-Anbieter stellt mir eine Benutzeroberfläche zur Verfügung, mit der ich Firewall-Regeln auf einzelne VPS anwenden kann. Ich habe eine Firewall-Gruppe verwendet, um die folgenden Regeln auf alle 3 Server anzuwenden:
TCP ACCEPT to dest ports 80, 443, (and my SSH port)
ICMP ACCEPT any
TCP ACCEPT 2376
TCP, UDP ACCEPT 7789
UDP ACCEPT 7789
TCP ACCEPT 2377
ESP ACCEPT
Um dies zu testen, habe ich die folgenden Befehle auf Knoten 1 ausgeführt
docker network create --driver=overlay --attachable testnet
docker network create --opt encrypted --driver=overlay --attachable testnet_encrypted
docker service create --network=testnet --name web --publish 80 --replicas=5 nginx:latest
Sobald der Dienst im gesamten Cluster ausgeführt wird, gehe ich wie folgt vor:
docker run --rm --name alpine --net=testnet -ti alpine:latest sh
apk add --no-cache curl
Ich mache dann fünfmal Curl:
curl web
Alle 5 Male bekomme ich eine Antwort. Wenn ich weitermache, bekomme ich weiterhin Antworten. Ich denke, das bedeutet, dass alle Container Verkehr haben.
Anschließend schalte ich den Server auf das verschlüsselte Netz um und wiederhole den gleichen Test:
docker service rm web
docker service create --network=testnet_encrypted --name web --publish 80 --replicas=5 nginx:latest
docker run --rm --name alpine --net=testnet_encrypted -ti alpine:latest sh
apk add --no-cache curl
Wieder führe ich curl 5 mal aus:
curl web
Manchmal funktioniert es, aber manchmal bleibt es einfach hängen, bis ich Strg+C drücke.
Wenn ich es fünfmal ausführe, wiederholt sich das Muster von funktionierenden und unterbrochenen Vorgängen. Ich denke, das liegt daran, dass einige Container auf NODE_1 laufen und diese funktionieren, aber die Kommunikation mit den Knoten 2 und 3 nicht funktioniert.
Die ESP ACCEPT-Regel wurde nach einigen Untersuchungen zu diesem Problem zum Firewall-Regelsatz meines Cloud-Anbieters hinzugefügt.
Ich habe versucht, den Cluster neu zu starten, aber ohne Erfolg.
Jetzt stecke ich fest. Gibt es Empfehlungen, wie ich mit dem Debuggen fortfahren kann? Danke, Robert
Aktualisierung 1
Zum Debuggen habe ich den Test so geändert, dass der Webdienst nur auf einer einzigen Instanz auf NODE_3 ausgeführt wurde. Dann habe ich zwei Konsolen für Knoten 3 geladen und die folgenden Befehle ausgeführt:
sudo tcpdump src NODE_1_IP and dst NODE_3_IP and port 7789
sudo tcpdump src NODE_3_IP and dst NODE_1_IP and port 7789
Eine Konsole zeigt mir den Datenverkehr in NODE_3 und den anderen Datenverkehr aus NODE_3.
Dann habe ich den unverschlüsselten Test erneut ausgeführt. Ich sehe, dass auf beiden Eingangskonsolen etwa 7 Zeilen und auf der Ausgangskonsole 5 Zeilen erscheinen. Es gibt also Verkehr, der in NODE_3 hineingeht und Verkehr, der aus NODE_3 herausgeht, und der Test funktioniert.
Dann habe ich den Verschlüsselungstest ausgeführt. Diesmal sehe ich eine einzelne Zeile auf der Eingangskonsole und nichts auf der Ausgangskonsole. Es gelangt also ein einzelnes Paket zu NODE_3. Ich bin nicht sicher, ob es entschlüsselt und an den Container zurückgesendet wird.
Aktualisierung 2
Ein Konfigurationsbereich, den ich vergessen habe zu erwähnen, ist, dass ich das folgende /etc/docker/daemon.json-Setup habe:
{
"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
}
Damit kann ich SSL-Client-Zertifikate für die Remote-Verbindung verwenden. Diese Datei wurde auf allen Knoten eingerichtet, bevor ich den Schwarm erstellt habe.
Da die Entschlüsselung der Pakete eine mögliche Ursache zu sein scheint, habe ich meine daemon.json wie folgt geändert:
{
"hosts": []
}
Ich habe dann jede Maschine neugestartet. Die Testergebnisse sind die gleichen – es funktioniert immer noch nicht.
Anschließend habe ich den Befehl „docker swarm ca --rotate“ ausgeführt und die Tests erneut ausgeführt. Das Ergebnis ist dasselbe.
Ich habe den Cluster nicht entfernt und mit der neuen Konfiguration neu initialisiert. (Ich könnte das tun, wenn jemand denkt, dass es helfen würde, aber ich habe viele Docker-Geheimnisse und -Konfigurationen, die ich dabei verlieren würde.)
Aktualisierung 3
ich habe den Cluster jetzt komplett entfernt und neu initialisiert. Das hat nicht funktioniert.
Einige Quellen geben an, dass der folgende Befehl:
sudo tcpdump -p esp
Beim Ausführen auf den Knoten sollte Datenverkehr angezeigt werden. Ich habe dies auf allen Knoten im Cluster ausgeführt und alle Tests wiederholt, aber es gibt nirgendwo eine Ausgabe.
ufw es auf allen Knoten inaktiv:
robert@metcaac6:/var/log$ sudo ufw status
[sudo] password for robert:
Status: inactive
aber wenn ich iptables -LI ausführe, erhalte ich auf jedem Knoten die gleichen Regeln:
robert@metcaac6:/var/log$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT udp -- anywhere anywhere policy match dir in pol ipsec udp dpt:7789 u32 "0x0>>0x16&0x3c@0xc&0xffffff00=0x100300"
DROP udp -- anywhere anywhere udp dpt:7789 u32 "0x0>>0x16&0x3c@0xc&0xffffff00=0x100300"
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-INGRESS all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DROP all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (2 references)
target prot opt source destination
Chain DOCKER-INGRESS (1 references)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:https
ACCEPT tcp -- anywhere anywhere state RELATED,ESTABLISHED tcp spt:https
ACCEPT tcp -- anywhere anywhere tcp dpt:http
ACCEPT tcp -- anywhere anywhere state RELATED,ESTABLISHED tcp spt:http
ACCEPT tcp -- anywhere anywhere tcp dpt:30001
ACCEPT tcp -- anywhere anywhere state RELATED,ESTABLISHED tcp spt:30001
ACCEPT tcp -- anywhere anywhere tcp dpt:30000
ACCEPT tcp -- anywhere anywhere state RELATED,ESTABLISHED tcp spt:30000
RETURN all -- anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Ich habe dmesg und /var/log/syslog auf mögliche Probleme untersucht, konnte aber keine finden.
Ich habe immer noch keine Ahnung, wo ich nach dem Problem suchen soll.