Moby: Die IP-Adresse des Benutzers kann im Docker-Schwarmmodus nicht abgerufen werden

Erstellt am 9. Aug. 2016  ·  324Kommentare  ·  Quelle: moby/moby

Ausgabe von docker version :

Client:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   8eab29e
 Built:        Thu Jul 28 22:00:36 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.12.0
 API version:  1.24
 Go version:   go1.6.3
 Git commit:   8eab29e
 Built:        Thu Jul 28 22:00:36 2016
 OS/Arch:      linux/amd64

Ausgabe von docker info :

Containers: 155
 Running: 65
 Paused: 0
 Stopped: 90
Images: 57
Server Version: 1.12.0
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 868
 Dirperm1 Supported: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: host overlay null bridge
Swarm: active
 NodeID: 0ddz27v59pwh2g5rr1k32d9bv
 Is Manager: true
 ClusterID: 32c5sn0lgxoq9gsl1er0aucsr
 Managers: 1
 Nodes: 1
 Orchestration:
  Task History Retention Limit: 5
 Raft:
  Snapshot interval: 10000
  Heartbeat tick: 1
  Election tick: 3
 Dispatcher:
  Heartbeat period: 5 seconds
 CA configuration:
  Expiry duration: 3 months
 Node Address: 172.31.24.209
Runtimes: runc
Default Runtime: runc
Security Options: apparmor
Kernel Version: 3.13.0-92-generic
Operating System: Ubuntu 14.04.4 LTS
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 31.42 GiB
Name: ip-172-31-24-209
ID: 4LDN:RTAI:5KG5:KHR2:RD4D:MV5P:DEXQ:G5RE:AZBQ:OPQJ:N4DK:WCQQ
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Username: panj
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Insecure Registries:
 127.0.0.0/8

Zusätzliche Umgebungsdetails (AWS, VirtualBox, physisch usw.):

Schritte zum Reproduzieren des Problems:

  1. folgenden Dienst ausführen, der Port 80 veröffentlicht
docker service create \
--name debugging-simple-server \
--publish 80:3000 \
panj/debugging-simple-server
  1. Versuchen Sie, eine Verbindung mit http://<public-ip>/ herzustellen.

Beschreiben Sie die Ergebnisse, die Sie erhalten haben:
Weder ip noch header.x-forwarded-for ist die richtige IP-Adresse des Benutzers.

Beschreiben Sie die erwarteten Ergebnisse:
ip oder header.x-forwarded-for sollte die IP-Adresse des Benutzers sein. Das erwartete Ergebnis kann mit dem eigenständigen Docker-Container docker run -d -p 80:3000 panj/debugging-simple-server archiviert werden. Sie können beide Ergebnisse über die folgenden Links einsehen,
http://swarm.issue-25526.docker.takemetour.com :81/
http://container.issue-25526.docker.takemetour.com :82/

Zusätzliche Informationen, die Sie für wichtig erachten (z. B. ein Problem tritt nur gelegentlich auf):
Dies geschieht sowohl im global Modus als auch im replicated Modus.

Ich bin mir nicht sicher, ob ich etwas übersehen habe, das dieses Problem leicht lösen sollte.

In der Zwischenzeit muss ich meiner Meinung nach einen Workaround machen, der einen Proxy-Container außerhalb des Swarm-Modus ausführt und ihn im Swarm-Modus an den veröffentlichten Port weiterleiten lässt (SSL-Beendigung sollte auch auf diesem Container durchgeführt werden), was den Zweck von Swarm unterbricht Modus für Selbstheilung und Orchestrierung.

arenetworking areswarm kinenhancement statuneeds-attention versio1.12

Hilfreichster Kommentar

Ich bin auch auf das Problem gestoßen, als ich versucht habe, Logstash im Schwarmmodus auszuführen (zum Sammeln von Syslog-Nachrichten von verschiedenen Hosts). Das Logstash-Feld "host" wird immer als 10.255.0.x anstelle der tatsächlichen IP des verbindenden Hosts angezeigt. Dies macht es völlig unbrauchbar, da Sie nicht erkennen können, von welchem ​​Host die Protokollnachrichten stammen. Gibt es eine Möglichkeit, die Übersetzung der Quell-IP zu vermeiden?

Alle 324 Kommentare

/cc @aluzzardi @mrjana fragte

@PanJ können Sie bitte einige Details dazu ip ? Was ist auch zu erwarten, wenn ein Dienst auf mehr als 1 Replik über mehrere Hosts (oder im globalen Modus) skaliert wird?

@mavenugo es ist das koa , das das remoteAddress net Modul des Knotens aus dem

Es wird erwartet, dass das Feld ip unabhängig von jeglicher Konfiguration immer eine Remote-Adresse sein sollte.

@PanJ Sie verwenden immer noch Ihren Workaround oder haben eine bessere Lösung gefunden?

@PanJ Wenn ich Ihre App als eigenständigen Container ausführe..

docker run -it --rm -p 80:3000 --name test panj/debugging-simple-server

und greifen Sie von einem anderen Host auf den veröffentlichten Port zu

vagrant@net-1:~$ curl 192.168.33.12
{"method":"GET","url":"/","header":{"user-agent":"curl/7.38.0","host":"192.168.33.12","accept":"*/*"},"ip":"::ffff:192.168.33.11","ips":[]}
vagrant@net-1:~$

192.168.33.11 ist die IP des Hosts, auf dem ich curl ausführe. Ist das das erwartete Verhalten?

@sanimej Ja, es ist das erwartete Verhalten, das auch im Schwarmmodus sein sollte.

@marech Ich verwende immer noch den eigenständigen Container als Problemumgehung, was gut funktioniert.

In meinem Fall gibt es 2 nginx-Instanzen, Standalone- und Schwarm-Instanzen. SSL-Terminierung und Reverse-Proxy werden auf eigenständigem nginx durchgeführt. Die Schwarminstanz wird verwendet, um basierend auf dem Anforderungshost an andere Dienste weiterzuleiten.

@PanJ Der ingress Netzwerk. 10.255.0.x ist die Adresse der ingress Netzwerkschnittstelle auf dem Host im Cluster, von der aus Sie versuchen, den veröffentlichten Port zu erreichen.

@sanimej Ich habe irgendwie gesehen, wie es funktioniert, als ich mich mit dem Problem befasst habe. Aber der Anwendungsfall (Fähigkeit, die IP des Benutzers abzurufen) ist ziemlich häufig.

Ich habe nur begrenzte Kenntnisse darüber, wie der Fix implementiert werden sollte. Vielleicht ein spezieller Netzwerktyp, der die Quell-IP-Adresse nicht ändert?

Rancher ähnelt dem Docker-Schwarmmodus und scheint das erwartete Verhalten zu haben. Vielleicht ist es ein guter Anfang.

@sanimej eine gute Idee könnte sein, alle IPs zum X-Forwarded-For-Header hinzuzufügen, wenn es möglich ist, dann können wir die gesamte Kette sehen.

@PanJ hmm, und wie kommuniziert Ihr eigenständiger nignx-Container über den Dienstnamen oder die IP mit der Schwarminstanz? Vielleicht können Sie den nginx-Konfigurationsteil freigeben, wo Sie ihn an die Schwarminstanz übergeben.

@marech Standalone-Container lauscht auf Port 80 und stellt dann Proxys an localhost:8181

server {
  listen 80 default_server;
  location / {
    proxy_set_header        Host $host;
    proxy_set_header        X-Real-IP $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header        X-Forwarded-Proto $scheme;
    proxy_pass          http://localhost:8181;
    proxy_read_timeout  90;
  }
}

Wenn Sie eine SSL-Terminierung durchführen müssen, fügen Sie einen weiteren Serverblock hinzu, der auf Port 443 lauscht, dann führen Sie die SSL-Terminierung und Proxys auch an localhost:8181 durch

nginx des Schwarmmodus veröffentlicht 8181:80 und leitet basierend auf dem Anforderungshost zu einem anderen Dienst weiter.

server {
  listen 80;
  server_name your.domain.com;
  location / {
    proxy_pass          http://your-service:80;
    proxy_set_header Host $host;
    proxy_read_timeout  90;
  }
}

server {
  listen 80;
  server_name another.domain.com;
  location / {
    proxy_pass          http://another-service:80;
    proxy_set_header Host $host;
    proxy_read_timeout  90;
  }
}

In unserem Fall hängen unsere API RateLimit und andere Funktionen von der IP-Adresse des Benutzers ab. Gibt es eine Möglichkeit das Problem im Schwarmmodus zu überspringen?

Ich bin auch auf das Problem gestoßen, als ich versucht habe, Logstash im Schwarmmodus auszuführen (zum Sammeln von Syslog-Nachrichten von verschiedenen Hosts). Das Logstash-Feld "host" wird immer als 10.255.0.x anstelle der tatsächlichen IP des verbindenden Hosts angezeigt. Dies macht es völlig unbrauchbar, da Sie nicht erkennen können, von welchem ​​Host die Protokollnachrichten stammen. Gibt es eine Möglichkeit, die Übersetzung der Quell-IP zu vermeiden?

+1 für eine Lösung für dieses Problem.

Ohne die Möglichkeit, die IP des Benutzers abzurufen, können wir Überwachungslösungen wie Prometheus nicht verwenden.

Vielleicht wären die IPVS-Fähigkeiten des Linux-Kernels hier von Nutzen. Ich vermute, dass die IP-Änderung stattfindet, weil die Verbindungen im Benutzerbereich Proxys werden. IPVS hingegen kann Anfragen im Kernel-Space umleiten und laden, ohne die Quell-IP-Adresse zu ändern. IPVS könnte sich auch für den Einbau erweiterter Funktionen eignen, wie z. B. verschiedene Lastausgleichsalgorithmen, Floating-IP-Adressen und direktes Routing.

Für mich würde es ausreichen, wenn ich irgendwie die Beziehung zwischen der virtuellen IP und der IP des Servers herausfinden könnte, zu dem der Endpunkt gehört. Auf diese Weise kann ich, wenn Prometheus eine Warnung bezüglich einer virtuellen IP-Adresse sendet, herausfinden, welcher Server betroffen ist. Es wäre keine gute Lösung, aber besser als nichts.

@vfarcic Ich glaube nicht, dass das so ist, wie es jetzt funktioniert. Alle Clientverbindungen stammen von derselben IP, sodass Sie sie nicht zurückübersetzen können. Die einzige Möglichkeit, die funktionieren würde, wäre, wenn der Proxy/Nat der Verbindungen ein Verbindungsprotokoll mit Zeitstempel, Quell-IP und Quellport speicherte. Selbst dann wäre es in den meisten Anwendungsfällen, in denen die Quell-IP benötigt wird, nicht viel hilfreich.

Ich habe den Anwendungsfall wahrscheinlich nicht gut erklärt.

Ich verwende Prometheus, das so konfiguriert ist, dass es Exporteure verschrottet, die als globale Swarm-Dienste ausgeführt werden. Es verwendet Aufgaben.um die IPs aller Replikate zu erhalten. Es verwendet also nicht den Dienst, sondern Replikatendpunkte (kein Lastausgleich). Was ich brauche, ist, irgendwie die IP des Knotens herauszufinden, von dem jede dieser Replik-IPs stammt.

Mir ist gerade der "Docker Network Inspect" aufgefallen" liefert Informationen über Container und IPv4-Adressen eines einzelnen Knotens. Kann dies so erweitert werden, dass es eine clusterweite Information eines Netzwerks zusammen mit Knoten gibt?

Etwas wie:

       "Containers": {
            "57bc4f3d826d4955deb32c3b71550473e55139a86bef7d5e584786a3a5fa6f37": {
                "Name": "cadvisor.0.8d1s6qb63xdir22xyhrcjhgsa",
                "EndpointID": "084a032fcd404ae1b51f33f07ffb2df9c1f9ec18276d2f414c2b453fc8e85576",
                "MacAddress": "02:42:0a:00:00:1e",
                "IPv4Address": "10.0.0.30/24",
                "IPv6Address": "",
                "Node": "swarm-4"
            },
...

Beachten Sie das Hinzufügen des "Knotens".

Wenn solche Informationen für den gesamten Cluster verfügbar wären, nicht nur für einen einzelnen Knoten mit dem Argument --filter , hätte ich alles, was ich brauche, um die Beziehung zwischen einer Container-IPv4-Adresse und der Knoten. Es wäre keine großartige Lösung, aber immer noch besser als nichts. Wenn Prometheus jetzt ein Problem erkennt, muss ich auf jedem Knoten "Docker Network Inspect" ausführen, bis ich den Standort der Adresse herausgefunden habe.

Ich stimme @dack zu , da das Ingress-Netzwerk IPVS verwendet, sollten wir dieses Problem mit IPVS lösen, damit die Quell-IP beibehalten und dem Dienst korrekt und transparent präsentiert wird.

Die Lösung muss auf IP-Ebene funktionieren, damit jeder Dienst, der nicht auf HTTP basiert, auch noch ordnungsgemäß funktionieren kann (Kann nicht auf http-Header vertrauen...).

Und ich kann nicht betonen, wie wichtig das ist, ohne es gibt viele Dienste, die im Schwarmmodus einfach überhaupt nicht funktionieren.

@kobolog könnte angesichts seines Vortrags über IPVS auf der DockerCon etwas Licht in diese Angelegenheit bringen.

Füge mich gerade in die Liste ein. Ich verwende Logstash, um Syslog-Nachrichten zu akzeptieren, und sie werden alle in Elasticsearch mit der Host-IP auf 10.255.0.4 verschoben, was sie unbrauchbar macht, und ich muss zu meiner nicht containerisierten Logstash-Bereitstellung zurückkehren wenn es dafür keine Lösung gibt.

@mrjana können Sie bitte den Vorschlag hinzufügen, den Sie zur Umgehung dieses Problems hatten?

IPVS ist kein Userspace-Reverse-Proxy, der Dinge in der HTTP-Schicht reparieren kann. Das ist der Unterschied zwischen einem Userspace-Proxy wie HAProxy und diesem. Wenn Sie HAProxy verwenden möchten, können Sie dies tun, indem Sie einen HAProxy in den Cluster einfügen und alle Ihre Dienstinstanzen und HAProxy am selben Netzwerk teilnehmen. Auf diese Weise kann HAProxy HTTP header.x-forwarded-for reparieren. Oder wenn sich der L7-Load-Balancer außerhalb des Clusters befindet, können Sie die kommende (in 1.13) Funktion für ein neues PublishMode namens Host PublishMode verwenden, das jede einzelne Instanz des Dienstes verfügbar macht in einem eigenen individuellen Port und Sie können Ihren externen Load Balancer darauf verweisen.

@mrjana Die ganze Idee der Verwendung von IPVS (anstelle von allem, was Docker derzeit im Schwarmmodus tut) besteht darin, zunächst die Übersetzung der Quell-IP zu vermeiden. Das Hinzufügen eines X-Forwarded-For kann für einige HTTP-Anwendungen hilfreich sein, aber es nützt nichts für alle anderen Anwendungen, die durch das aktuelle Verhalten gestört werden.

@dack Mein Verständnis ist, dass das Docker-Ingress-Netzwerk bereits IPVS verwendet.

Wenn Sie HAProxy verwenden möchten, können Sie dies tun, indem Sie einen HAProxy in den Cluster einfügen und alle Ihre Dienstinstanzen und HAProxy am selben Netzwerk teilnehmen. Auf diese Weise kann HAProxy HTTP header.x-forwarded-for . reparieren

Das würde auch nicht @mrjana funktionieren , die einzige Möglichkeit für HAProxy, die Client-IP zu erhalten, besteht darin, außerhalb des Ingress-Netzwerks mit Docker Run oder direkt auf dem Host zu laufen, aber dann können Sie keine Ihrer Dienste verwenden, da sie sich in einem anderen Netzwerk befinden und Sie können nicht auf sie zugreifen.

Einfach ausgedrückt gibt es meines Wissens absolut keine Möglichkeit, damit umzugehen, sobald Sie Docker-Dienste und den Schwarmmodus verwenden.

Es wäre interessant, wenn sich die Autoren des Docker-Ingress-Netzwerks an der Diskussion beteiligen könnten, da sie wahrscheinlich einen Einblick haben, wie IPVS unter der Haube konfiguriert / betrieben wird (es gibt viele Modi für IPVS) und wie wir es beheben können Das Thema.

@tlvenn Weißt du, wo das im Quellcode ist? Ich könnte mich irren, aber ich glaube nicht, dass IPVS verwendet wird, basierend auf einigen Dingen, die ich beobachtet habe:

  • Der Quellport wird übersetzt (der ganze Grund für dieses Problem). IPVS tut dies nicht. Auch im NAT-Modus übersetzt es nur die Zieladresse. Sie müssen die Standardroute oder das Richtlinienrouting verwenden, um Rückgabepakete an den IPVS-Host zurückzusenden.
  • Wenn ein Port im Schwarmmodus veröffentlicht wird, hören alle Dockerd-Instanzen im Schwarm auf dem veröffentlichten Port. Wenn IPVS verwendet würde, würde es im Kernel-Space passieren und dockerd würde nicht auf dem Port lauschen.

Hallo @dack ,

Aus ihrem Blog:

Intern sorgen wir dafür, dass dies mit Linux IPVS funktioniert, einem im Kernel integrierten Layer-4-Multiprotokoll-Load-Balancer, der seit mehr als 15 Jahren im Linux-Kernel enthalten ist. Mit IPVS-Routing-Paketen innerhalb des Kernels bietet das Routing-Mesh von swarm einen hochleistungsfähigen Container-aware Load-Balancing.

Die Codequelle sollte im Swarmkit-Projekt leben, wenn ich mich nicht irre.

Ich frage mich, ob @stevvooe uns helfen kann, das zugrunde liegende Problem hier zu verstehen.

OK, ich habe den Code kurz durchgesehen und denke, dass ich ihn jetzt etwas besser verstehe. Es scheint tatsächlich IPVS zu verwenden, wie im Blog angegeben. SNAT erfolgt über eine iptables-Regel, die in service_linux.go eingerichtet wird. Wenn ich das richtig verstehe, sieht die Logik dahinter ungefähr so ​​aus (vorausgesetzt, Knoten A erhält ein Client-Paket für den Dienst, der auf Knoten B läuft):

  • Schwarmknoten A empfängt das Client-Paket. IPVS/iptables übersetzt (src ip)->(node ​​a ip) und (dst ip)->(node ​​B ip)
  • Das Paket wird an den Knoten B weitergeleitet
  • Knoten B sendet seine Antwort an Knoten A (da dies als src-IP angesehen wird)
  • Knoten A übersetzt src und dst zurück in die ursprünglichen Werte und leitet die Antwort an den Client weiter

Ich denke, der Grund für die SNAT ist, dass die Antwort über denselben Knoten gehen muss, über den die ursprüngliche Anfrage gesendet wurde (da dort der NAT/IPVS-Zustand gespeichert wird). Da Anfragen über jeden Knoten kommen können, wird die SNAT verwendet, damit der Dienstknoten weiß, über welchen Knoten die Anfrage zurückgeleitet werden soll. In einem IPVS-Setup mit einem einzelnen Lastausgleichsknoten wäre das kein Problem.

Die Frage ist also, wie man das SNAT vermeidet und gleichzeitig allen Knoten erlaubt, eingehende Client-Anfragen zu bearbeiten. Ich bin mir nicht ganz sicher, was der beste Ansatz ist. Vielleicht gibt es eine Möglichkeit, eine Zustandstabelle auf dem Dienstknoten zu haben, damit er Richtlinien-Routing verwenden kann, um Antworten zu leiten, anstatt sich auf SNAT zu verlassen. Oder vielleicht könnte eine Art Kapselung helfen (VXLAN?). Oder das direkte Routing-Verfahren von IPVS könnte verwendet werden. Dies würde es dem Dienstknoten ermöglichen, dem Client direkt zu antworten (anstatt über den Knoten, der die ursprüngliche Anfrage empfangen hat) und würde das Hinzufügen neuer Floating-IPs für Dienste ermöglichen. Dies würde jedoch auch bedeuten, dass der Dienst nur über die Floating-IP und nicht über die einzelnen Node-IPs erreicht werden kann (nicht sicher, ob das für alle Anwendungsfälle ein Problem darstellt).

Ziemlich interessante Entdeckung @dack !

Hoffentlich wird eine Lösung gefunden, um diese SNAT alle zusammen zu überspringen.

In der Zwischenzeit gibt es vielleicht eine Problemumgehung, die vor nicht allzu langer Zeit festgeschrieben wurde und eine Port-Veröffentlichung auf Host-Ebene mit PublishMode einführt, wodurch das Ingress-Netzwerk effektiv umgangen wird.

https://github.com/docker/swarmkit/pull/1645

Hey, vielen Dank für das große Feedback - wir werden uns dieses Thema nach dem Wochenende genauer ansehen.

Ein paar Infos in der Zwischenzeit:

@tlvenn : @mrjana ist der Hauptautor der Ingress-Netzwerkfunktion. Quelle lebt meistens in Docker/Libnetwork, einige in SwarmKit

@dack : Es wird tatsächlich von IPVS unterstützt

@tlvenn Soweit ich weiß, verwendet Docker Swarm Maskierung, da dies der einfachste Weg ist und in den meisten Konfigurationen garantiert funktioniert. Außerdem ist dies der einzige Modus, der es tatsächlich ermöglicht, auch Ports zu maskieren [re: @dack], was praktisch ist. Theoretisch könnte dieses Problem durch die Verwendung des IPIP-Kapselungsmodus gelöst werden – der Paketfluss sieht dann so aus:

  • Ein Paket kommt am Gateway-Server an – in unserem Fall an jedem Knoten des Schwarms – und IPVS auf diesem Knoten stellt anhand seiner Ziel-IP-Adresse und seines Ports fest, dass es sich tatsächlich um ein Paket für einen virtuellen Dienst handelt.
  • Das Paket wird in ein anderes IP-Paket gekapselt und an den realen Server gesendet, der basierend auf dem Lastausgleichsalgorithmus ausgewählt wurde.
  • Der reale Server empfängt das umgebende Paket, entkapselt es und sieht die reale Client-IP als Quelle und die virtuelle Dienst-IP als Ziel. Alle realen Server sollen einen nicht-ARP-fähigen Schnittstellenalias mit der virtuellen Dienst-IP haben, so dass sie annehmen würden, dass dieses Paket tatsächlich für sie bestimmt ist.
  • Der reale Server verarbeitet das Paket und sendet die Antwort direkt an den Client zurück. Die Quell-IP ist in diesem Fall die IP des

Es gibt natürlich viele Vorbehalte und Dinge, die schief gehen können, aber im Allgemeinen ist dies möglich und der IPIP-Modus wird in der Produktion häufig verwendet.

Wir hoffen, dass dafür bald eine Lösung gefunden wird, da die IP-Fixierung und andere Sicherheitskontrollen die richtige externe IP erhalten müssen.

Aufpassen. Unser Produkt nutzt Quell-IP-Informationen für Sicherheit und Analysen.

@aluzzardi ein Update für uns?

Bump, wir brauchen dies, um für ein sehr großes Projekt zu arbeiten, das wir Anfang nächsten Jahres beginnen.

Bei der Untersuchung des Flows scheint es derzeit so zu funktionieren (in diesem Beispiel empfängt Knoten A den eingehenden Datenverkehr und Knoten B führt den Dienstcontainer aus):

  • Knoten A führt DNAT durch, um das Paket in den Netzwerk-Namespace ingress_sbox zu leiten (/var/run/docker/netns/ingress_sbox)
  • ingress_sbox auf Knoten A führt IPVS im NAT-Modus aus, der DNAT ausführt, um das Paket an den Container auf Knoten B zu leiten (über das Ingress-Overlay-Netzwerk) und auch SNAT, um die Quell-IP in die Ingress-Overlay-Netzwerk-IP von Knoten A zu ändern
  • das Paket wird durch das Overlay zum realen Server geleitet
  • die Rückpakete folgen dem gleichen Weg in umgekehrter Richtung, wobei die Quell-/Zieladressen auf die ursprünglichen Werte zurückgeschrieben werden

Ich denke, die SNAT könnte mit so etwas vermieden werden:

  • Knoten A leitet das Paket ohne NAT an ingress_sbox weiter (iptables/policy routing?)
  • Node A ingress_sbox führt IPVS im Direct-Routing-Modus aus, der Pakete über das Ingress-Overlay-Netzwerk an Node B sendet
  • Container auf Knoten B empfängt das unveränderte Paket (der Container muss Pakete für alle öffentlichen IPs akzeptieren, aber kein ARP für sie senden. Es gibt mehrere Möglichkeiten, dies zu tun, siehe IPVS-Dokumente).
  • die Rückpakete werden direkt von Knoten B an den Client gesendet (muss nicht über das Overlay-Netzwerk oder Knoten A zurückgehen)

Als zusätzlicher Bonus muss kein NAT-Zustand gespeichert werden und der Overlay-Netzwerkverkehr wird reduziert.

@aluzzardi @mrjana Irgendein Update dazu bitte? Ein kleines Feedback von Docker wäre sehr dankbar.

Aufpassen. Ohne Quell-IP-Informationen können die meisten unserer Dienste nicht wie erwartet funktionieren

Wie ist das passiert ?
unassign_bug

@tlvenn scheint ein Fehler in Github zu sein?

@PanJ @tlvenn @vfarcic @dack und andere, PTAL #27917. Wir haben die Möglichkeit eingeführt, den Veröffentlichungsmodus des Dienstes = host zu aktivieren, der dem Dienst eine Möglichkeit bietet, IPVS zu umgehen und ein docker run -p ähnliches Verhalten wiederherzustellen und die Quell-IP für Fälle beizubehalten, die brauchen.

Bitte versuchen Sie 1.13.0-rc2 und geben Sie Feedback.

du ziemlich komisch @mavenugo ..

In Bezug auf den Veröffentlichungsmodus hatte ich dies bereits oben aus dem Swarm-Kit verlinkt, dies könnte ein Workaround sein, aber ich hoffe wirklich, dass Docker 1.13 eine richtige Lösung bietet, um dieses Problem endgültig zu beheben.

Dieses Problem könnte sehr wohl als Fehler kategorisiert werden, da die Beibehaltung der Quell-IP das Verhalten ist, das wir von den Benutzern erwarten, und es ist derzeit eine sehr ernsthafte Einschränkung der Docker-Dienste.

Ich glaube, sowohl @kobolog als auch @dack haben einige potenzielle Problems gefunden, und es sind fast 2 Wochen

Könnten wir bitte einen Überblick darüber haben, wer dieses Problem bei Docker untersucht, und ein Statusupdate? Danke im Voraus.

Außer #27917 gibt es keine andere Lösung für 1.13. Die Direct-Return-Funktionalität muss für verschiedene Anwendungsfälle analysiert werden und sollte nicht auf die leichte Schulter genommen werden, um als Bugfix betrachtet zu werden. Wir können dies für 1.14 untersuchen. Dies fällt jedoch auch in die Kategorie des konfigurierbaren LB-Verhaltens, das den Algorithmus (rr vs 10 andere Methoden), den Datenpfad (LVS-DR, LVS-NAT & LVS-TUN) umfasst. Wenn jemand bereit ist, dazu beizutragen, machen Sie bitte eine PR und wir können das in Gang bringen.

Fair genug, denke ich, @mavenugo, da wir jetzt eine Alternative haben.

Können wir zumindest das Dokument für 1.13 ändern, damit es klar sagt, dass bei Verwendung von Docker-Diensten mit dem standardmäßigen Ingress-Veröffentlichungsmodus die Quell-IP nicht beibehalten wird und auf die Verwendung des Host-Modus hinweisen, wenn dies eine Voraussetzung für die Ausführung des Dienstes ist? ?

Ich denke, es wird Menschen helfen, die zu Diensten migrieren, um nicht von diesem unerwarteten Verhalten verbrannt zu werden.

Sicher und ja, ein Doc-Update, das dieses Verhalten anzeigt, und die Problemumgehung der Verwendung der Veröffentlichung mode=host wird für solche Anwendungsfälle nützlich sein, die im LVS-NAT-Modus fehlschlagen.

Einfach nochmal reinschauen, um zu sehen, ob es keine neuen Entwicklungen gab, um dieses echte Ding herauszufinden? Es ist sicherlich auch für uns eine große Einschränkung

Ist eine Lösung auf der Roadmap für Docker 1.14? Die Bereitstellung unserer Lösungen mit Docker verzögert sich teilweise aufgrund dieses Problems.

Ich würde gerne einen benutzerdefinierten Header zur http/https-Anfrage hinzufügen, der die Client-IP beibehält. Das sollte doch möglich sein, oder? Es macht mir nichts aus, wenn X_Forwarded_for überschrieben wird, ich möchte nur ein benutzerdefiniertes Feld haben, das nur beim ersten Mal gesetzt wird, wenn die Anfrage den Schwarm betritt.

Ich würde gerne einen benutzerdefinierten Header zur http/https-Anfrage hinzufügen, der die Client-IP beibehält. Das sollte doch möglich sein, oder? Es macht mir nichts aus, wenn X_Forwarded_for überschrieben wird, ich möchte nur ein benutzerdefiniertes Feld haben, das nur beim ersten Mal gesetzt wird, wenn die Anfrage den Schwarm betritt.

Der Lastenausgleich erfolgt bei L3/4. Das Hinzufügen eines http-Headers ist nicht möglich.

Ein Fix beinhaltet das Entfernen des Neuschreibens der Quelladresse.

@mavenugo Ich habe heute auf Docker 1.13 aktualisiert und mode=host für meinen Proxy-Dienst verwendet. Derzeit funktioniert es, Client-IP wird beibehalten, aber ich hoffe auf eine bessere Lösung :) Danke für Ihre Arbeit!

Sorry für Doppelpost...
Wie kann ich eine Stack-Datei (yml v3) verwenden, um das gleiche Verhalten zu erzielen, als würde ich --publish mode=host,target=80,published=80 über den Docker-Dienst erstellen verwenden?

Ich habe es versucht

...
services:
  proxy:
    image: vfarcic/docker-flow-proxy:1.166
    ports:
      - "80:80/host"
      - "443:443/host" 
...

aber das funktioniert nicht (verwendet das gleiche Muster wie in https://docs.docker.com/docker-cloud/apps/stack-yaml-reference/#/ports)

Wie kann ich eine Stack-Datei (yml v3) verwenden, um das gleiche Verhalten zu erzielen, als würde ich --publish mode=host,target=80,published=80 via docker service create verwenden?

@hamburml - behalte https://github.com/docker/docker/issues/30447 im Auge, es ist ein offenes Problem/Feature.

Leider kann ich mode=host als Problemumgehung verwenden, da ich meinen Dienst benötige, um mit dem Schwarmnetzwerk zu kommunizieren und auch auf allen Knoten zu hören, nicht nur auf der Host-Schnittstelle...

@tkeeler33 Ich denke, Sie sollten in der Lage sein, den Dienst als global Dienst bereitzustellen (der eine Instanz auf jedem Knoten im Schwarm bereitstellt) und ihn mit einem Schwarmnetzwerk zu verbinden, um mit anderen Diensten im Schwarm zu kommunizieren

@thaJeztah - Ja, aber ich kann einen Container nicht gleichzeitig mit einem mode=host hosten. Das ist momentan meine größte Einschränkung.

@tkeeler33 scheint für mich zu funktionieren;

$ docker network create -d overlay swarm-net

$ docker service create \
  --name web \
  --publish mode=host,published=80,target=80 \
  --network swarm-net \
  --mode=global \
  nginx:alpine

$ docker service create --name something --network swarm-net nginx:alpine

Testen Sie, ob sich der web Dienst mit dem something Dienst im selben Netzwerk verbinden kann;

docker exec -it web.xczrerg6yca1f8ruext0br2ow.kv8iqp0wdzj3bw7325j9lw8qe sh -c 'ping -c3 -w1 something'
PING something (10.0.0.4): 56 data bytes
64 bytes from 10.0.0.4: seq=0 ttl=64 time=0.251 ms

--- something ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.251/0.251/0.251 ms

@thaJeztah - Danke! Nachdem ich tiefer gegraben hatte, stellte ich fest, dass mein Problem darin bestand, dass ich mein Docker-Netzwerk mit der Option --opt encrypted hatte, was dazu führte, dass der Container keine Verbindungen vom Host herstellte. Nachdem ich Ihre Schritte ausprobiert hatte, konnte ich die Ursache schnell eingrenzen. Diese Option kann eine gute Übergangslösung sein, ich muss mich nur mit allen Sicherheitsauswirkungen auseinandersetzen.

Schätze die Infos sehr!

@tkeeler33 --opt encrypted sollte sich nicht auf die Host-Port-Zuordnung auswirken. Der einzige Zweck der verschlüsselten Option besteht darin, den vxlan-Tunnelverkehr zwischen den Knoten zu verschlüsseln. Aus docs: "Wenn Sie planen, ein Overlay-Netzwerk mit Verschlüsselung (--opt verschlüsselt) zu erstellen, müssen Sie auch sicherstellen, dass der Datenverkehr des Protokolls 50 (ESP) zulässig ist." Können Sie bitte Ihre Konfigurationen überprüfen, um sicherzustellen, dass ESP zulässig ist?
Außerdem ist die Option --opt encrypted eine reine Verschlüsselung auf Datenebene. Der gesamte Datenverkehr auf der Steuerungsebene (Routing-Austausch, Service Discovery-Verteilung usw.) wird standardmäßig auch ohne die Option verschlüsselt.

@mavenugo Du hast recht. Als ich ein neues Netzwerk mit --opt encrypted es gut funktioniert. Als ich das neu erstellte Netzwerk mit meinem bestehenden verglich, bemerkte ich, dass "Internal": true gesetzt war. Das war wahrscheinlich das Problem und war ein Fehler bei der anfänglichen Netzwerkerstellung... Danke für Ihre Hilfe & Klarstellung, Es war ein langer Tag...

@dack @kobolog In typischen Bereitstellungen des LVS-

@thaJeztah Ich denke, wir sollten dies in der Dokumentation klären, vorschlagen, den Host-Mod zu verwenden, wenn die Client-IP beibehalten werden muss, und dieses Problem schließen.

@sanimej Ich

@thaJeztah danke für die
Wenn Sie Ihren Proxy mit Compose Version 3 bereitstellen, wird die neue Veröffentlichungssyntax nicht unterstützt, sodass wir den bereitgestellten Dienst mit diesem Befehl patchen können (ersetzen Sie nginx_proxy durch den Dienstnamen).

docker service update nginx_proxy \
    --publish-rm 80 \
    --publish-add "mode=host,published=80,target=80" \
    --publish-rm 443 \
    --publish-add "mode=host,published=443,target=443"

@dack Im regulären LVS-DR-Flow ist die Ziel-IP der Service-VIP. So kann der LB das Paket ohne Änderung der Ziel-IP an das Backend senden. Dies ist bei Routing-Mesh nicht der Fall, da die Ziel-IP des eingehenden Pakets eine der IP-Adressen des Hosts ist.

@sanimej Feedback zu dem obigen Vorschlag, den IPIP-Kapselungsmodus zu verwenden, um dieses Problem zu lösen?

@tlvenn LVS-IP-Tunnel funktioniert sehr ähnlich wie LVS-DR, außer dass das Backend das Paket über einen IP-in-IP-Tunnel erhält und nicht über ein Mac-Rewrite. Es hat also das gleiche Problem für den Anwendungsfall Routing Mesh.

Aus dem von Ihnen genannten Vorschlag..
The real server receives the enclosing packet, decapsulates it and sees real client IP as source and virtual service IP as destination.

Die Ziel-IP des Pakets wäre die IP des Hosts, an den der Client das Paket gesendet hat, und nicht die VIP. Wenn es nicht neu geschrieben wurde, würde der reale Server es löschen, nachdem der äußere IP-Header entfernt wurde. Wenn die Ziel-IP umgeschrieben wird, weist die Antwort des realen Servers an den Client eine falsche Quell-IP auf, was zu einem Verbindungsfehler führt.

Danke für die Klarstellung @sanimej. Könnten Sie vielleicht das PROXY-Protokoll implementieren? Es würde keine nahtlose Lösung bieten, aber es würde dem Dienst zumindest eine Lösung zum Auflösen der Benutzer-IP bieten.

Es gibt einen klügeren Weg, um die Beibehaltung der Quell-IP zu erreichen, indem Sie den Quell-Port-Bereich in Blöcke aufteilen und jedem Host im Cluster einen Block zuweisen. Dann ist es möglich, einen hybriden NAT+DR-Ansatz durchzuführen, bei dem der Ingress-Host das übliche SNAT durchführt und das Paket an einen echten Server sendet. Führen Sie auf dem Host, auf dem der reale Server ausgeführt wird, basierend auf der Quell-IP eine SNAT aus, um den Quellport in einen Port im Bereich zu ändern, der dem Ingress-Host zugewiesen ist. Vergleichen Sie dann das Rückpaket vom Container mit dem Quellportbereich (und dem Zielport) und ändern Sie die Quell-IP in die des Eingangs-Hosts.

Technisch würde dies funktionieren, aber in realen Bereitstellungen, bei denen die Clustermitglieder schnell hinzugefügt und entfernt werden, unpraktisch und fragil. Dadurch wird auch der Portraum deutlich reduziert.

Der erwähnte NAT+DR-Ansatz würde nicht funktionieren, da die Quell-IP im Ingress-Host nicht geändert werden kann. Es kann eine Option sein, nur den Quellport in einen im Bereich für diesen bestimmten Host zu ändern und die Routing-Richtlinie vom Back-End-Host zu verwenden, um das Paket zurück zum Ingress-Host zu bringen. Dies hat noch andere Probleme, die ich bereits erwähnt habe.

@thaJeztah
Gibt es derzeit eine Problemumgehung, um die echte IP-Adresse vom Nginx-Container an den Web-Container weiterzuleiten?
Ich habe einen Nginx-Container, der im global Modus ausgeführt und in host , sodass der Nginx-Container eine korrekte IP-Adresse erhält. Beide Container sehen sich gut, aber der Web-Container erhält die IP-Adresse des Nginx-Containers, keine Client-Adresse.
Nginx ist ein Reverse-Proxy für das Web, und das Web führt uwsgi auf Port 8000 aus:

server {
    resolver 127.0.0.11;
    set $web_upstream http://web:8000;

    listen 80;
    server_name domain.com;
    location / {
        proxy_pass $web_upstream;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        proxy_redirect off;
        proxy_buffering off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

@lpakula Bitte überprüfen Sie meine Antwort oben + diese funktionierende nginx-Konfiguration

@pi0 Danke für die Antwort

Ich verwende die nginx-Konfiguration über den Link, aber die IP-Adresse ist immer noch falsch, in meiner Konfiguration muss etwas fehlen

Ich habe einen Docker ( 17.03.0-ce )

    docker service create --name nginx --network overlay_network --mode=global \
        --publish mode=host,published=80,target=80 \
        --publish mode=host,published=443,target=443 \
        nginx:1.11.10

    docker service create --name web --network overlay_network \
        --replicas 1 \
        web:newest

Nginx-Container verwendet den neuesten offiziellen Container https://hub.docker.com/_/nginx/
Webcontainer führt uwsgi-Server auf Port 8000 . aus

Ich verwende globales nginx.conf aus dem Link und conf.d/default.conf sieht wie folgt aus:

   server {
       resolver 127.0.0.11;
       set $web_upstream http://web:8000;

       listen 80;
       server_name domain.com;
       location / {
        proxy_pass $web_upstream;
      }
  }

Und dann nginx-Container-Logs:

  194.168.X.X - - [17/Mar/2017:12:25:08 +0000] "GET / HTTP/1.1" 200

Web-Container-Logs:

  10.0.0.47 - - [17/Mar/2017 12:25:08] "GET / HTTP/1.1" 200 -

Was fehlt da?

Die IP-Adresse wird immer noch falsch sein. Aber es werden HTTP-Header hinzufügen, die
echte IP-Adresse enthalten. Sie müssen Ihren Webserver Ihrer Wahl konfigurieren
dem Proxy vertrauen (Header anstelle der Quell-IP verwenden)
Am Fr, 17. März 2560 um 19:36 Uhr Lukasz Pakula [email protected]
schrieb:

@pi0 https://github.com/pi0 Danke für die Antwort

Ich verwende die nginx-Konfiguration über den Link, aber die IP-Adresse ist immer noch vorhanden
falsch, in meiner Konfiguration muss etwas fehlen

Ich habe einen Docker ( 17.03.0-ce )
Dienstleistungen

docker service create --name nginx --network overlay_network --mode=global \
    --publish mode=host,published=80,target=80 \
    --publish mode=host,published=443,target=443 \
    nginx:1.11.10

docker service create --name web --network overlay_network \
    --replicas 1 \
    web:newest

Nginx-Container verwendet den neuesten offiziellen Container
https://hub.docker.com/_/nginx/ http://url
Webcontainer führt uwsgi-Server auf Port 8000 . aus

Ich verwende globale nginx.conf aus dem Link und conf.d/default.conf sieht aus
wie folgt:

Server {
Resolver 127.0.0.11;
setze $web_upstream http://web :8000;

   listen 80;
   server_name domain.com;
   location / {
    proxy_pass $web_upstream;
  }

}

Und dann nginx-Container-Logs:

194.168.XX - - [17/Mär/2017:12:25:08 +0000] "GET / HTTP/1.1" 200

Web-Container-Logs:

10.0.0.47 - - [17.03.2017 12:25:08] "GET / HTTP/1.1" 200 -

Was fehlt da?


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/docker/docker/issues/25526#issuecomment-287342795 ,
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/ABtu97EFaCmLwAZiOrYT4nXi4oXPCbLQks5rmn43gaJpZM4Jf2WK
.

>

PanJ,
Panjamapong Sermsawatsri
Tel.-Nr. (+66)869761168

@lpakula Ah, Ihr web:newest Bild sollte auch den X-Real-IP Header berücksichtigen. nginx ändert die IP des Absenders nicht automatisch, sondern sendet nur einen Hinweis-Header.

@pi0 @PanJ
Es macht Sinn, danke Leute!

Binden Sie den Port im Hostmodus.

nginx unterstützt IP-Transparenz mithilfe des TPROXY-Kernelmoduls .

@stevvooe Kann Docker so etwas auch tun?

nginx unterstützt IP-Transparenz mithilfe des TPROXY-Kernelmoduls.
@stevvooe Kann Docker so etwas auch tun?

Unwahrscheinlich, da der Eintrag über Knoten hinweg verfolgt werden muss. Ich lasse @sanimej oder @mavenugo.

Kann swarm die REST-API bereitstellen, um die Client-IP-Adresse zu erhalten?

@tonysongtl das hat nichts mit diesem Problem zu

Darüber hinaus ist zu berücksichtigen, wie Ihr Datenverkehr in einem hochverfügbaren Setup an Ihre Knoten geliefert wird. Ein Knoten sollte in der Lage sein, herunterzufahren, ohne Fehler für Clients zu verursachen. Die aktuelle Empfehlung lautet, einen externen Load Balancer (ELB, F5 usw.) zu verwenden und einen Lastausgleich auf Layer 4 auf jeden Swarm-Knoten mit einer einfachen Layer-4-Zustandsprüfung durchzuführen. Ich glaube, F5 verwendet SNAT, daher besteht der beste Fall in dieser Konfiguration darin, die einzelne IP Ihres F5 und nicht die echte Client-IP zu erfassen.

Verweise:
https://docs.docker.com/engine/swarm/ingress/#configure -an-external-load-balancer
https://success.docker.com/Architecture/Docker_Reference_Architecture%3A_Docker_EE_Best_Practices_and_Design_Considerations
https://success.docker.com/Architecture/Docker_Reference_Architecture%3A_Universal_Control_Plane_2.0_Service_Discovery_and_Load_Balancing

Spiegelung des obigen Kommentars - kann das Proxy-Protokoll nicht verwendet werden? Alle Cloud-Load-Balancer und Haproxy verwenden dies zur Erhaltung der Quell-IP.

Calico hat auch den IPIP-Modus – https://docs.projectcalico.org/v2.2/usage/configuration/ip-in-ip – was einer der Gründe ist, warum github ihn verwendet. https://githubengineering.com/kubernetes-at-github/

Hi.

Lassen Sie mich aus Gründen des Verständnisses und der Vollständigkeit zusammenfassen und korrigieren Sie mich bitte, wenn ich falsch liege:

Das Hauptproblem besteht darin, dass Container keine ursprüngliche src-IP, sondern Schwarm-VIP erhalten. Ich habe dieses Problem mit dem folgenden Szenario repliziert:

create docker swarm
docker service create --name web --publish 80:80 nginx
access.log source IP is 10.255.0.7 instead of client's browser IP

Es scheint:

Wenn Dienste innerhalb von swarm (Standard-) Mesh verwenden, verwendet swarm NAT, um sicherzustellen, dass Datenverkehr vom selben Ursprung immer an denselben Host-Running-Service gesendet wird?
Daher verliert es die ursprüngliche src-IP und ersetzt sie durch die Service-VIP von swarm.

Scheint @kobolog https://github.com/moby/moby/issues/25526#issuecomment -258660348 und @dack https://github.com/moby/moby/issues/25526#issuecomment -260813865 Vorschläge wurden von @sanimej abgelehnt https://github.com/moby/moby/issues/25526#issuecomment -280722179 https://github.com/moby/moby/issues/25526#issuecomment -281289906 aber, TBH, seine Argumente sind nicht ganz klar Ich verstehe noch nicht, warum der Thread nicht geschlossen wurde, wenn dies definitiv unmöglich ist.

@sanimej würde das nicht funktionieren?:

  1. Schwarm empfängt Nachricht mit src-IP=A und destination="my-service-virtual-address"
  2. Das Paket wird an einen Schwarmknoten gesendet, auf dem dieser Dienst ausgeführt wird, und kapselt die ursprüngliche Nachricht ein.
  3. Knoten leitet an Aufgabe weiter
    Schwarm und Knoten könnten Tabellen pflegen, um sicherzustellen, dass Verkehr vom gleichen Ursprung nach Möglichkeit an denselben Knoten weitergeleitet wird.

Würde eine Option zum Aktivieren von "Reverse-Proxy anstelle von NAT" für bestimmte Dienste nicht all diese Probleme lösen und alle zufriedenstellen?

Auf der anderen Seite ist IIUC die einzige verbleibende Option, https://docs.docker.com/engine/swarm/services/#publish -a-services-ports-directly-on-the-swarm-node zu verwenden, was -wiederum scheint IIUC- so zu sein, als würde man Mesh überhaupt nicht verwenden, daher sehe ich die Vorteile der Verwendung des Schwarmmodus (im Vergleich zum Compose) nicht. Tatsächlich sieht es aus wie ein Schwarm vor 1.12, der _Consul_ braucht und so.

Danke für deine Hilfe und Geduld.
Grüße

@sanimej
Mehr noch ... warum macht Docker nicht einfach eine Portweiterleitung NAT (ändert nur Ziel-IP/Port) ?

  1. Schwarm-Empfangsnachricht "von A zu myservice"
  2. Swarm leitet die Nachricht an den Host weiter, der diesen Dienst ausführt, und setzt dest=node1
  3. Node1 empfängt die Nachricht "von A an Node1" und leitet die Einstellung dest=container1 weiter
  4. Container1 empfängt Nachricht "von A zu Container1"
  5. Um zu antworten, verwendet der Container die Standard-Gateway-Route

Ich würde mich gerne einklinken; Ich verstehe zwar, dass dies nicht einfach ist, aber wenn die ursprüngliche IP-Adresse nicht in irgendeiner Weise beibehalten wird, behindert eine Reihe von Anwendungsfällen erheblich. Hier sind ein paar, die mir spontan einfallen:

  • Für das Netzwerk-/Service-Engineering ist es von entscheidender Bedeutung, über Metriken zu verfügen, die detailliert beschreiben, woher Ihre Benutzer stammen.

  • In vielen Sicherheitsanwendungen benötigen Sie Zugriff auf die ursprüngliche IP-Adresse, um ein dynamisches Blacklisting basierend auf Dienstmissbrauch zu ermöglichen.

  • Standorterkennungsdienste müssen oft in der Lage sein, auf die IP-Adresse zuzugreifen, um den allgemeinen Standort des Benutzers zu lokalisieren, wenn andere Methoden fehlschlagen.

Nach meiner Lektüre dieses Problemthreads scheint es, dass die angegebenen Workarounds nicht sehr gut funktionieren, wenn Sie skalierbare Dienste in einem Docker Swarm haben möchten. Wenn Sie sich auf eine Instanz pro Workerknoten beschränken, verringert sich die Flexibilität des Angebots erheblich. Auch die Beibehaltung eines hybriden Ansatzes, bei dem ein LB/Proxy am Edge als nicht von Swarm orchestrierter Container ausgeführt wird, bevor er in Swarm-orchestrierte Container eingespeist wird, scheint eine Zeitreise zu sein. Warum sollte der Benutzer zwei verschiedene Paradigmen für die Service-Orchestrierung pflegen müssen? Wie wäre es mit der dynamischen Skalierung des LB/Proxy am Edge? Das müsste manuell gemacht werden, oder?

Könnte das Docker-Team vielleicht diese Kommentare berücksichtigen und sehen, ob es eine Möglichkeit gibt, diese Funktionalität einzuführen, während die Qualität und Flexibilität des Docker-Ökosystems erhalten bleiben?

Als weiterer Nebeneffekt werde ich jetzt gerade davon getroffen. Ich habe eine Webanwendung, die autorisierte/authentifizierte Anfragen an einen nachgelagerten Webserver weiterleitet. Unsere Servicetechniker müssen überprüfen können, ob Personen den Downstream-Server erreicht haben, wofür sie gerne Webzugriffsprotokolle verwenden. Im aktuellen Szenario kann ich diese Funktionalität nicht bereitstellen, da mein Proxyserver die ursprüngliche IP-Adresse nie sieht. Ich möchte, dass meine Anwendung leicht skalierbar ist, und anscheinend kann ich dies mit den vorgestellten Workarounds nicht tun, zumindest nicht, ohne für jede skalierte Instanz neue VMs herumzuwerfen.

@Jitsusama könnte Kubernetes Ihr Problem lösen?

@thaJeztah gibt es eine Möglichkeit, die Arbeit mit Docker-Compose zu

Ich habe es versucht

`services:
  math:
    build: ./math
    restart: always
    ports:
    - target: 12555
      published: 12555
      mode: host

Aber es scheint 172.xx1 als Quell-IP zu nehmen

@trajano , ich habe keine Ahnung. Schafft Kubernetes es irgendwie, dieses Problem zu umgehen?

@Jitsusama
Ja, sie haben eine Dokumentation, die sich darauf bezieht, wie sie die Quell-IP beibehalten . Es ist funktional, aber nicht so schön, wenn Sie keinen Load Balancer verwenden, da das Paket auf Knoten ohne diese Endpunkte verworfen wird. Wenn Sie Rancher als Ihren selbst gehosteten Load Balancer verwenden möchten, wird dieser derzeit leider

@trajano

Aber es scheint 172.xx1 als Quell-IP zu nehmen

Wenn Sie lokal auf Ihre Anwendung zugreifen, sollte diese IP korrekt sein (wenn Sie swarm verwenden), da docker_gwbridge die Schnittstelle ist, die mit Ihrem Proxy-Container interagiert. Sie können versuchen, von einem anderen Computer in Ihrem IP-Netzwerk auf die App zuzugreifen, um zu sehen, ob sie die richtige Adresse findet.

Was die Problemumgehung beim Verfassen angeht, ist dies möglich. Hier verwende ich das Image jwilder/nginx-proxy als Frontend-Reverse-Proxy (um die Konzepte zu vereinfachen) zusammen mit einem offiziellen Build-Image von nginx als Backend-Dienst. Ich stelle den Stack im Docker Swarm Mode bereit:

version: '3.3'

services:

  nginx-proxy:
    image: 'jwilder/nginx-proxy:alpine'
    deploy:
      mode: global
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro

  nginx:
    image: 'nginx:1.13.5-alpine'
    deploy:
      replicas: 3
    ports:
      - 80
      - 443
    environment:
      - VIRTUAL_HOST=website.local
$ echo '127.0.0.1 website.local' | sudo tee -a /etc/hosts
$ docker stack deploy --compose-file docker-compose.yml website

Dadurch wird ein website_default Netzwerk für den Stack erstellt. Mein Endpunkt ist in der Umgebungsvariablen VIRTUAL_HOST und der Zugriff auf http://website.local gibt mir:

website_nginx-proxy.0.ny152x5l9sh7<strong i="30">@Sherry</strong>    | nginx.1    | website.local 172.18.0.1 - - [08/Sep/2017:21:33:36 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36"
website_nginx.1.vskh5941kgkb<strong i="33">@Sherry</strong>    | 10.0.1.3 - - [08/Sep/2017:21:33:36 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.79 Safari/537.36" "172.18.0.1"

Beachten Sie, dass das Ende des Headers für website_nginx.1.vskh5941kgkb einen Hinweis auf die ursprüngliche IP enthält ( 172.18.0.1 ). X-Forwarded-For & X-Real-IP werden standardmäßig in nginx.tmpl von jwilder/nginx-proxy .

Für Port 443 konnte ich nicht beide Ports in der docker-compose-Datei hinzufügen, also verwende ich einfach:

docker service update website_nginx-proxy \
    --publish-rm 80 \
    --publish-add "mode=host,published=80,target=80" \
    --publish-rm 443 \
    --publish-add "mode=host,published=443,target=443" \
    --network-add "<network>"

beim Hinzufügen von Netzwerken, die ich mit Apps umkehren möchte, die die Umgebungsvariable VIRTUAL_HOST . Detailliertere Optionen sind in der Dokumentation für jwilder/nginx-proxy , oder Sie können Ihr eigenes Setup erstellen.

Ingress-Controller auf Kubernetes tun im Wesentlichen dasselbe, da Ingress-Diagramme (normalerweise) X-Forwarded-For und X-Real-IP mit etwas mehr Flexibilität bei der Auswahl und Art der Ingresse und auch deren Bereitstellungsreplikate unterstützen.

Die Kubernetes-Dokumentation ist also nicht vollständig. Ein anderer Weg, der ist
ziemlich häufig ist eigentlich Ingress+Proxy-Protokoll.

https://www.haproxy.com/blog/haproxy/proxy-protocol/

Das Proxy-Protokoll ist ein weithin akzeptiertes Protokoll, das die Quelle beibehält
Information. Haproxy wird mit integrierter Unterstützung für das Proxy-Protokoll geliefert. Nginx
kann das Proxy-Protokoll lesen, aber nicht injizieren.

Sobald das Proxy-Protokoll eingerichtet ist, können Sie von jedem aus auf diese Informationen zugreifen
nachgelagerte Dienste wie
https://github.com/nginxinc/kubernetes-ingress/blob/master/examples/proxy-protocol/README.md

Sogar Openshift nutzt dies für Quell-IP-Informationen
https://docs.openshift.org/latest/install_config/router/proxy_protocol.html

Dies ist der neueste Haproxy-Ingress für k8s, der das Proxy-Protokoll injiziert.

IMHO der Weg, dies im Schwarm zu tun, besteht darin, den Ingress in der Lage zu machen, Proxy zu lesen
Protokoll (falls es Datenverkehr von einer Upstream-LB empfängt, die über
bereits injiziertes Proxy-Protokoll) sowie injiziertes Proxy-Protokoll
Informationen (falls der gesamte Verkehr tatsächlich zuerst den Ingress erreicht).

Ich bin nicht dafür, es anders zu machen, besonders wenn es ein
allgemein anerkannter Standard dafür.

Traefik hat vor einigen Wochen die Unterstützung für proxy_protocol hinzugefügt und ist ab v1.4.0-rc1 verfügbar.

Dies muss auf der Eingangsebene des Docker-Schwarms erfolgen. Wenn das Eindringen
injiziert keine Proxy-Protokolldaten, keinen der Downstream-Dienste
(einschließlich traefix, nginx usw.) können es lesen.

Am 10.09.2017 um 21:42 Uhr schrieb "monotykamary" [email protected] :

Traefik hat die Unterstützung für proxy_protocol hinzugefügt
https://github.com/containous/traefik/pull/2004 vor ein paar Wochen und ist
verfügbar ab v1.4.0-rc1.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-328352805 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU3jj5dJcpMDysjIyGQK7SGx8GwWbks5shApqgaJpZM4Jf2WK
.

Ich bin auch verwirrt über die Beziehung dieses Fehlers zu Infrakit. zB https://github.com/docker/infrakit/pull/601 Kann jemand die Richtung kommentieren, in die der Docker-Schwarm gehen wird?

Wird der Schwarm in Infrakit einrollen? Ich interessiere mich besonders für die Ingress-Seite davon.

Auch wir beschäftigen uns mit diesem Thema. Wir möchten die Client-IP und die angeforderte IP für eingehende Verbindungen kennen. Wenn der Benutzer beispielsweise eine rohe TCP-Verbindung zu unserem Server herstellt, möchten wir wissen, wie seine IP lautet und mit welcher IP auf unserem Computer er verbunden ist.

@blazedd Wie bereits erwähnt und in anderen Threads ist dies tatsächlich mit dem publishMode möglich. dh: Dienste werden nicht über ein Mesh-Netzwerk abgewickelt.

IIUC, es gibt einige Fortschritte bei der Verbesserung des Umgangs mit Ingress, aber das ist eigentlich die einzige Lösung.

Wir haben unseren nginx-Dienst mithilfe von publishmode und mode:global bereitgestellt, um eine externe LB-Konfiguration zu vermeiden

@mostolog Danke für deine Antwort. Nur ein paar Anmerkungen:

  1. publishMode behebt das Problem nicht. Die eingehende Socket-Verbindung wird immer noch in das lokale Netzwerk aufgelöst, das der Schwarm eingerichtet hat. Zumindest wenn Sie die Portliste verwenden mode: host
  2. nginx ist keine wirklich gute Lösung. Unsere Anwendung basiert auf TCP, ist aber kein Webserver. Es gibt keine Header, die wir verwenden können, ohne sie manuell zu codieren.
  3. Wenn ich docker run --net=host ... , funktioniert alles einwandfrei.
  4. Die einzige Lösung, die ich bisher gesehen habe, ist die Verwendung: https://github.com/moby/moby/issues/25873#issuecomment -319109840

@blazedd In unserem Stack haben wir:

    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host

und daher würde ich wetten, dass wir echte IPs in unseren Protokollen erhalten.

@mostolog Es funktioniert zumindest nicht unter Windows. Ich erhalte immer noch die Adresse 172.0.0.x als Quelle.

@mostolog mode: host macht Ihren Container nicht für das Hostnetzwerk verfügbar . Es entfernt den Container aus dem Ingress-Netzwerk, wie Docker normalerweise beim Ausführen eines Containers vorgeht. Es würde das --publish 8080:8080 replizieren, das in einem Docker-Run-Befehl verwendet wird. Wenn nginx echte IPs erhält, liegt dies nicht daran, dass der Socket direkt mit diesen IPs verbunden ist. Um dies zu testen, sollten Sie ernsthaft in Erwägung ziehen, eine rohe TCP-Implementierung oder einen HTTP-Server ohne Framework zu verwenden und die gemeldete Adresse zu überprüfen.

Warum nicht das IPVS-Route-Netzwerk direkt zum Container verwenden? Binden Sie die IPs aller Overlay-Schnittstellen des Schwarmknotens als virtuelle IPs, verwenden Sie ip rule from xxx table xxx , um ein Multi-Gateway zu erstellen.

@blazedd Hast du es probiert? Ich erhalte externe IP-Adressen, wenn @mostolog folge .

Ich stoße wieder auf dieses Problem.

Mein Setup ist wie folgt:

  • ipvs Load Balancer im DR-Modus (außerhalb des Docker-Schwarms)
  • 3 Docker-Knoten, wobei die Ziel-IP zu allen Knoten hinzugefügt und der Arp entsprechend für das IPVS-DR-Routing konfiguriert ist

Ich möchte dem Schwarm einen Stack bereitstellen und ihn auf Port 80 auf der virtuellen IP abhören lassen, ohne die Adressen zu verstümmeln.

Ich komme fast dorthin, indem ich Folgendes tue:
Häfen:
- Ziel: 80
veröffentlicht: 80
Protokoll: tcp
Modus: Host

Das Problem hierbei ist, dass Sie nicht angeben können, an welche IP-Adresse Sie sich binden möchten - es bindet nur an alle. Dies führt zu Problemen, wenn Sie mehr als einen einzelnen Dienst über diesen Port ausführen möchten. Es muss sich nur an die eine IP binden. Die Verwendung verschiedener Ports ist beim DR-Load-Balancing keine Option. Es scheint, dass die Entwickler davon ausgegangen sind, dass dieselbe IP niemals auf mehreren Knoten vorhanden sein wird, was bei Verwendung eines DR-Load-Balancers nicht der Fall ist.

Wenn Sie die kurze Syntax verwenden, wird die Bindungs-IP ignoriert und weiterhin an alle Adressen gebunden. Die einzige Möglichkeit, sich an eine einzelne IP zu binden, besteht darin, einen nicht gruppierten Container (keinen Dienst oder Stapel) auszuführen.

Jetzt muss ich also wieder eigenständige Container verwenden und sie selbst verwalten, anstatt mich dafür auf Service-/Stack-Funktionen zu verlassen.

Wir haben das gleiche Problem.
Ich würde für eine transparente Lösung innerhalb des Docker-Ingress stimmen, die es allen Anwendungen (einige mit rohem UDP/TCP, nicht insbesondere HTTP) ermöglicht, wie erwartet zu funktionieren.

Ich könnte die Problemumgehung "mode=host port Publishing" verwenden, da mein Dienst global bereitgestellt wird.
Es scheint jedoch, dass dies nicht mit der Verwendung des Macvlan-Netzwerktreibers kompatibel ist, den ich aus anderen Gründen benötige.
Wir erhalten Protokolle wie "Macvlan-Treiber unterstützt keine Portzuordnungen".
Ich habe versucht, mehrere Netzwerke zu verwenden, aber es hilft nicht.

Ich habe hier ein bestimmtes Ticket erstellt: https://github.com/docker/libnetwork/issues/2050
Das lässt mir vorerst keine Lösung übrig :'(

Hallo Leute
Gibt es momentan einen Workaround? Ohne es als Host-Port veröffentlicht zu haben
Hafen ?

Am 11.01.2018 00:03 schrieb "Olivier Voortman" [email protected] :

Wir haben das gleiche Problem.
Ich würde für eine transparente Lösung innerhalb des Docker-Ingress stimmen, die alle zulassen würde
Anwendungen (einige verwenden rohes UDP/TCP, nicht besonders HTTP), um als
erwartet.

Ich könnte die Problemumgehung "mode=host port Publishing" verwenden, da mein Dienst ist
weltweit eingesetzt.
Dies scheint jedoch mit der Verwendung des macvlan . nicht vereinbar zu sein
Netzwerktreiber, den ich aus anderen Gründen benötige.
Wir erhalten Protokolle wie "Macvlan-Treiber unterstützt keine Portzuordnungen".
Ich habe versucht, mehrere Netzwerke zu verwenden, aber es hilft nicht.

Ich habe hier ein bestimmtes Ticket erstellt: docker/libnetwork#2050
https://github.com/docker/libnetwork/issues/2050
Das lässt mir vorerst keine Lösung übrig :'(


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-356693751 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAEsUzlM-BMbEsDYAiYH6hKLha-aRqerks5tJQJngaJpZM4Jf2WK
.

Es ist wirklich schade, dass es nicht möglich ist, die IP des Clients zu erhalten. Dies macht die meisten der netten Funktionen des Docker-Schwarms nicht nutzbar.

In meinem Setup besteht die einzige Möglichkeit, die IP des Clients zu erhalten, darin, network_mode:host und überhaupt keinen Schwarm zu verwenden.

mit mode=host port publishing oder einem traditionellen docker run -p "80:80" ... funktionierte nicht

Einige Lösungen wurden in https://github.com/moby/moby/issues/15086 vorgeschlagen, aber die einzige Lösung, die für mich funktionierte, war das "Host" -Netzwerk ...

Ein weiteres Problem bei der fehlenden richtigen IP besteht darin, dass die nginx-Ratenbegrenzung nicht richtig funktioniert und daher nicht mit dem Docker Swarm Load Balancer verwendet werden kann, da Anfragen ratenbegrenzt und abgelehnt werden, da nginx alle zählt, da sie von einem einzelnen Benutzer/IP stammen. Die einzige Problemumgehung besteht also darin, mode=host zu verwenden, aber auf diese Weise verliere ich die Lastausgleichsfunktionen und muss DNS auf bestimmte Instanzen verweisen.

Vielleicht ist Docker nicht das ideale Werkzeug für diesen Job. Ich habe nach Vagrant gesucht, um die nach vorne gerichteten HTTP-Server einzurichten und die Client-IP als Teil der HTTP-Anforderungsheader zu platzieren.

Bis Docker in der Lage ist, Client-Informationen über Overlay-Netzwerke zu übergeben, könnte man einen Proxy wie Docker Flow Proxy oder Traefik verwenden, die gewünschten Ports im Host-Modus in diesem Dienst veröffentlichen und Anwendungsdienste damit verbinden. Keine vollständige Lösung, funktioniert aber ziemlich gut und ermöglicht einen Lastausgleich von Anwendungsdiensten / Abrufen der Client-IP.

@deeky666 Traefik und ähnliche Arbeiten nur, wenn nicht dockerisiert

Ich sehe keine Udo-Unterstützung auf traefik

von meinem Iphone gesendet

Schließlich haben wir den Docker-Container aufgegeben. Es ist nicht serienreif!

Am Mittwoch, den 24. Januar 2018 um 5:43 Uhr schrieb Efrain [email protected] :

Ich sehe keine Udo-Unterstützung auf traefik

von meinem Iphone gesendet

>


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-360091189 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AHf7rvMcH2iFBxcExfO_Ol0UttCspuTnks5tNwlkgaJpZM4Jf2WK
.

Das Problem scheint in 17.12.0-ce durch die Verwendung von mode=host teilweise gelöst zu sein.

docker service create --publish mode=host,target=80,published=80 --name=nginx nginx

Es hat einige Einschränkungen (kein Routing-Mesh), funktioniert aber!

@goetas mode=host hat eine Weile als Workaround funktioniert, daher würde ich nicht sagen, dass das Problem irgendwie gelöst ist. Die Verwendung von mode=host hat viele Einschränkungen, der Port wird offengelegt, kann keinen Schwarmlastausgleich verwenden usw.

@darklow Ich kenne die Einschränkungen, aber für meinen Anwendungsfall ist es in Ordnung (wenn nicht sogar besser!). In 17.09.1-ce funktionierte es überhaupt nicht, also für mich schon eine Verbesserung!

Ein großer Nachteil dieser Problemumgehung besteht darin, dass die Ausfallzeit während des Updates nicht vermieden werden kann.
Derzeit müssen wir uns entscheiden, ob Stabilität oder Quell-IP-Adresse aufgegeben werden soll.

Ich stimme zu. Swarm benötigt eine Hochverfügbarkeitsmethode, um die Quell-IP zu erhalten.

Wahrscheinlich mit Proxy-Protokoll. Ich denke nicht, dass es ein großer Aufwand ist, das hinzuzufügen
Unterstützung des Proxy-Protokolls für Docker Swarm.

Untersucht das jemand?

Am 28.01.2018 um 22:39 Uhr schrieb "Genki Takiuchi" [email protected] :

Ein großer Nachteil dieser Problemumgehung ist, dass der Ausfall nicht vermieden werden kann
Zeit während des Updates.
Derzeit müssen wir uns entscheiden, ob wir Stabilität oder Quell-IP aufgeben
die Anschrift.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-361078416 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU-or7fnhKTg7fhjtZYjGYHBFRE7Dks5tPKnYgaJpZM4Jf2WK
.

@sandys Ich stimme zu. Proxy-Protokoll wäre eine gute Idee.
@thaJeztah @aluzzardi @mrjana Könnte dieses Problem bitte etwas Aufmerksamkeit bekommen? Seit einiger Zeit gibt es keine Antwort vom Team. Dankeschön.

Das Proxy-Protokoll klingt für mich nach der besten Lösung. Hoffentlich wird das Team dies berücksichtigen.

@goetas es hat

Das ist SEHR schlecht, es mildert jede Geschwindigkeitsbegrenzung, Betrugsprävention, Protokollierung, sichere Anmeldungen, Sitzungsüberwachung usw.!
Das Abhören mit mode:host funktioniert, ist aber keine wirkliche Lösung, da Sie das Mesh-Loadbalancing verlieren und nur der Software-Loadbalanacer auf dem Host mit der öffentlichen IP den gesamten Datenverkehr alleine bewältigen muss.

Dies ist ein sehr kritischer und wichtiger Fehler für uns und der blockiert unseren Go-Live mit Swarm. Wir glauben auch, dass das Proxy-Protokoll dafür die richtige Lösung ist. Docker-Ingress muss die Quell-IP im Proxy-Protokoll übergeben.

Auf Twitter ist eine der vorgeschlagenen Lösungen die Verwendung von Traefik als Ingress , der außerhalb von Swarm verwaltet wird . Das ist für uns höchst suboptimal – und kein Overhead, den wir gerne bewältigen würden.

Wenn die Swarm-Entwickler überprüfen möchten, wie das Proxy-Protokoll in Swarm-ingress implementiert wird, sollten sie alle in Traefik diskutierten Fehler überprüfen (z. B. https://github.com/containous/traefik/issues/2619).

Ich habe dies konsequent mit "Verfassen" anstelle des Schwarmmodus zum Laufen gebracht. Vielleicht etwas zum Nachdenken.

Einige Bedenken bezüglich des Proxy-Protokolls:

Wird es von Docker selbst oder von der Anwendung decodiert? Wenn wir uns darauf verlassen, dass die Anwendung das Proxy-Protokoll implementiert, ist dies keine allgemeine Lösung für alle Anwendungen und funktioniert nur für Webserver oder andere Anwendungen, die das Proxy-Protokoll implementieren. Wenn Docker das Proxy-Protokoll entpackt und die Adresse übersetzt, muss es auch den Verbindungsstatus verfolgen und die umgekehrte Übersetzung für ausgehende Pakete durchführen. Ich bin nicht für eine webspezifische Lösung (die sich auf das Proxy-Protokoll in der Anwendung verlässt), da Docker auch für viele Nicht-Webanwendungen nützlich ist. Dieses Problem sollte für den allgemeinen Fall einer TCP/UDP-Anwendung behoben werden – nichts anderes in Docker ist webspezifisch.

Wie bei jedem anderen Einkapselungsverfahren gibt es auch Probleme mit der Paketgröße/MTU. Ich denke jedoch, dass dies wahrscheinlich bei fast jeder Lösung dieses Problems ein Problem sein wird. Die Antwort darauf wird wahrscheinlich sein, sicherzustellen, dass Ihr Schwarmnetzwerk eine ausreichend große MTU unterstützt, um den Overhead zu berücksichtigen. Ich würde denken, dass die meisten Schwärme in lokalen Netzwerken laufen, also ist das wahrscheinlich kein großes Problem.

@trajano - Wir wissen, dass es mit Host-Netzwerken funktioniert (was wahrscheinlich Ihre Compose-Lösung tut). Dadurch werden jedoch alle Vorteile des Clusternetzwerks von Swarm (z. B. Lastausgleich) zunichte gemacht.

@dack Backends müssen das Proxy-Protokoll kennen.
Ich denke, es löst die meisten Fälle und zumindest können Sie einen dünnen Passthrough-ähnlichen Proxy platzieren, der den Protokollheader vor Ihren Backends in Containern verarbeitet.
Da der Mangel an Informationen ein tödliches Problem ist, glaube ich, dass es notwendig ist, es so schnell wie möglich vor anderen sauberen Lösungen zu lösen.

Proxy-Protokoll hat eine breite Akzeptanz. Überprüfen Sie die Anzahl der unterstützten Tools - https://www.haproxy.com/blog/haproxy/proxy-protocol/
es deckt nicht einmal die Cloud-Load-Balancer (ELB, Google LB) und neuere Tools wie Traefik ab.

Außerdem - das ist so ziemlich der Standard in Kubernetes: https://github.com/kubernetes/ingress-nginx#proxy -protocol

Derzeit ist das Proxy-Protokoll der am weitesten verbreitete Standard zur Lösung dieses Problems. Ich sehe keinen großen Wert darin, dies neu zu erfinden und die Kompatibilität mit den Nginxen der Welt zu brechen.

Dies sind L7-Protokolle. Schwarmeintritt ist L4. Hier wird nichts neu erfunden, es ist alles IPVS mit DNAT.

@ cpuguy83 konnte nicht verstehen, was Sie gerade meinten.

Das Proxy-Protokoll ist Schicht 4.
http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

Das Ziel des PROXY-Protokolls ist es, die internen Strukturen des Servers mit den
vom Proxy gesammelte Informationen, die der Server hätte abrufen können
von selbst, wenn sich der Client direkt mit dem Server verbindet, anstatt über a
Stellvertreter. Die vom Protokoll übertragenen Informationen sind die, die der Server verwenden würde
Get mit getsockname() und getpeername() :

  • Adressfamilie (AF_INET für IPv4, AF_INET6 für IPv6, AF_UNIX)
  • Socket-Protokoll (SOCK_STREAM für TCP, SOCK_DGRAM für UDP)
  • Quell- und Zieladressen der Schicht 3
  • Layer 4 Quell- und Zielports, falls vorhanden

http://cbonte.github.io/haproxy-dconv/1.9/configuration.html#5.1 -accept-proxy

Akzeptieren-Proxy

Erzwingt die Verwendung des PROXY-Protokolls über jede Verbindung, die von einem von . akzeptiert wird
die in derselben Zeile deklarierten Sockets. Versionen 1 und 2 des PROXY-Protokolls
werden unterstützt und richtig erkannt. Das PROXY-Protokoll bestimmt die Schicht
3/4 Adressen der eingehenden Verbindung werden überall dort verwendet, wo eine Adresse ist
verwendet, mit der einzigen Ausnahme von "tcp-request connection" -Regeln, die
nur die echte Verbindungsadresse sehen. Protokolle geben die Adressen wieder
im Protokoll angegeben, es sei denn, es wird verletzt, in diesem Fall die reale
Adresse wird weiterhin verwendet. Dieses Stichwort kombiniert mit Unterstützung von außen
Komponenten können als effiziente und zuverlässige Alternative zu den
X-Forwarded-For-Mechanismus, der nicht immer zuverlässig ist und nicht einmal immer
verwendbar. Siehe auch "tcp-request connection Expect-Proxy" für eine detailliertere
Einstellung, welcher Client das Protokoll verwenden darf.

Meinten Sie, es gibt einen besseren Weg als das Proxy-Protokoll? das ist durchaus möglich und würde gerne mehr im Zusammenhang mit der Erhaltung der Quell-IP im Docker Swarm wissen. Das Proxy-Protokoll wird jedoch von anderen Tools (wie nginx usw.), die dem Schwarm-Ingress nachgelagert sind, sowie von Tools wie AWS ELB, die dem Schwarm-Ingress vorgelagert sind, in größerem Umfang unterstützt. Das waren meine einzigen 0,02$

@sandys Das Proxy-Protokoll sieht aus wie eine Kapselung (zumindest bei der Verbindungsinitiierung), die die Kenntnis der Kapselung vom Empfänger den ganzen Stack hinunter erfordert. Es gibt viele Kompromisse bei diesem Ansatz.

Ich würde dies im Kern nicht unterstützen wollen, aber vielleicht wäre es ein lohnender Ansatz, Ingress steckbar zu machen.

@sandys https://github.com/sandys Das Proxy-Protokoll sieht so aus
Kapselung (zumindest beim Verbindungsaufbau), was Kenntnisse erfordert
der Kapselung vom Empfänger bis zum Stapel hinunter. Dort
sind viele Kompromisse bei diesem Ansatz.

Das ist wahr. Das ist so ziemlich der Grund, warum es ein Standard mit einem RFC ist. Es gibt
Schwung dahinter - so ziemlich jede Komponente ist wichtig
unterstützt es. IMHO ist es keine schlechte Entscheidung, es zu unterstützen.

Ich würde das im Kern nicht unterstützen wollen, aber vielleicht eindringen
steckbar wäre ein lohnenswerter Ansatz.

Dies ist eine umfassendere Diskussion - ich könnte jedoch hinzufügen, dass die größte Einzeldiskussion ist
Vorteil von Docker Swarm gegenüber anderen ist, dass es alle Batterien hat
eingebaut.

Ich möchte Sie dennoch bitten, das Proxy-Protokoll als eine großartige Lösung zu betrachten
dieses Problem, das von der Industrie unterstützt wird.

Ist es nicht möglich, einen L3-Router unter Linux und LxCs zu simulieren (nicht speziell Docker)

@trajano Simulation ist nicht erforderlich, aber Kapselung, um dieses Problem zu lösen.
Beispielsweise kann eine Option (z. B. --use-proxy-protocol ) für Dienste bereitgestellt werden, die eine Client-IP-Adresse benötigen und wissen, wie gekapselte Pakete wie nginx behandelt werden.

Wie es derzeit funktioniert, führt der Docker-Knoten, der das Paket empfängt, SNAT aus und leitet das Paket an den Knoten mit dem Anwendungscontainer weiter. Wenn anstelle von SNAT eine Form von Tunneling/Encapsulation verwendet wurde, sollte es möglich sein, das ursprüngliche Paket unverändert an die Anwendung zu übergeben.

Dies ist ein gelöstes Problem in anderen Projekten. Mit OpenStack können Sie beispielsweise Tunnel wie GRE und VXLAN verwenden.

Ist jemand im letzten Teil dieses Threads hier, der das Docker-Team repräsentiert und zumindest sagt: "Wir hören Sie"? Es scheint etwas, dass ein Feature, von dem man erwarten würde, dass es „out of the box“ ist und von solchem ​​Interesse für die Community ist, immer noch nicht gelöst wurde, nachdem es am 9. August 2016 vor etwa 18 Monaten zum ersten Mal gemeldet wurde.

Ist jemand im letzten Teil dieses Threads hier, der das Docker-Team repräsentiert und zumindest sagt: "Wir hören Sie"?

/cc @GordonTheTurtle @thaJeztah @riyazdf @aluzzardi

@bluejaguar @ruudboon Ich bin Teil von Docker. Dies ist ein bekanntes Problem. Im Moment konzentriert sich das Netzwerkteam auf langjährige Fehler mit Overlay-Netzwerkstabilität. Aus diesem Grund gab es in den letzten Releases nicht wirklich neue Netzwerkfunktionen.

Mein Vorschlag wäre, einen konkreten Vorschlag zu unterbreiten, an dem Sie bereit sind, zur Lösung des Problems zu arbeiten, oder zumindest einen Vorschlag, der so gut ist, dass jeder ihn annehmen und damit arbeiten kann.

@cpuguy83 Ich habe einige der eingehenden Proxy-Protokollfunktionen in k8s verfolgt. ZB https://github.com/kubernetes/kubernetes/issues/42616 (PS interessanterweise fließt das Proxy-Protokoll hier von der Google Kubernetes Engine ein, die das Proxy-Protokoll nativ im HTTPS-Modus unterstützt).

Darüber hinaus hat ELB im November 2017 Unterstützung für Proxy Protocol v2 hinzugefügt (https://docs.aws.amazon.com/elasticloadbalancing/latest/network/doc-history.html).

Openstack Octavia LB-as-a-service (ähnlich unserem Ingress) hat im April letzten Jahres zusammengeführtes Proxy-Protokoll - http://git.openstack.org/cgit/openstack/octavia/commit/?id=bf7693dfd884329f7d1169eec33eb03d2ae81ace

Hier ist ein Teil der Dokumentation zum Proxy-Protokoll in Openstack - https://docs.openshift.com/container-platform/3.5/install_config/router/proxy_protocol.html
Einige der Nuancen beziehen sich auf das Proxy-Protokoll für https (sowohl in Fällen, in denen Sie Zertifikate beim Ingress beenden oder nicht).

Gibt es Updates/Workarounds zu diesem Problem? Wir müssen wirklich die Client-IP im Docker-Schwarmmodus kennen.
Jede Hilfe wäre sehr dankbar.

Meine Version:

Klient:
Version: 18.02.0-ce
API-Version: 1.36
Go-Version: go1.9.3
Git-Commit: fc4de44
Gebaut: Mi 7. Feb 21:16:33 2018
Betriebssystem/Arch: linux/amd64
Experimentell: falsch
Orchestrator: Schwarm

Server:
Motor:
Version: 18.02.0-ce
API-Version: 1.36 (Mindestversion 1.12)
Go-Version: go1.9.3
Git-Commit: fc4de44
Gebaut: Mi 7. Feb 21:15:05 2018
Betriebssystem/Arch: linux/amd64
Experimentell: falsch

@adijes und andere Benutzer, die mit diesem Problem konfrontiert sind. Sie können die Container an das bridge Netzwerk binden (wie von jemandem in diesem Thread erwähnt).

version: "3.4"

services:
  frontend:
    image: nginx
    deploy:
      placement:
        constraints:
          - node.hostname == "prod1"
    networks:
      - default
      - bridge
  # backed services...
  # ...

networks:
  bridge:
    external:
      name: bridge

Unser frontend ist an bridge und bleibt immer in einem genauen Host, dessen IP an unsere öffentliche Domain gebunden ist. Dies ermöglicht es, echte Benutzer-IP zu erhalten. Und da es auch an das default Netzwerk

Sie können das frontend auch skalieren, solange Sie es in diesem einzigen Host live halten. Dies macht den Host zu einem Single Point of Failure, aber (glaube ich) ist es für kleine Sites in Ordnung.

Bearbeitet, um weitere Informationen hinzuzufügen:

Meine nginx-Container befinden sich hinter https://github.com/jwilder/nginx-proxy , ich verwende auch https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion , um SSL zu aktivieren. Der nginx-proxy wird über den Befehl docker run ausgeführt, nicht über einen Docker-Schwarmdienst. Vielleicht habe ich deshalb echte IP von Kunden bekommen. Das bridge Netzwerk ist erforderlich, damit meine nginx-Container mit nginx-proxy kommunizieren können.

FWIW, ich verwende:

Client:
 Version:      17.09.1-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:23:40 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.09.1-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:25:03 2017
 OS/Arch:      linux/amd64
 Experimental: false

Das obige Setup funktioniert auch auf einem anderen Setup, das ausgeführt wird:

Client:
 Version:      17.09.1-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:23:40 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.09.1-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:25:03 2017
 OS/Arch:      linux/amd64
 Experimental: false

@letientai299 das funktioniert bei mir nicht, bekomme ich

Netzwerk "Bridge" ist als extern deklariert, aber nicht im richtigen Bereich: "local" statt "swarm"

Ich habe einen Master- und drei Worker-Knoten

@trajano , siehe mein Update.

@letientai299 eigentlich habe ich mich gefragt, wie Sie bridge dazu gebracht haben, im Schwarmmodus zu arbeiten. dh Sie haben den Fehler nicht bekommen, den ich habe.

@dack wenn du Host-Networking sagst,

ports:
- target: 12555
  published: 12555
  protocol: tcp
  mode: host

Leider funktioniert es im docker stack deploy Modus nicht und verliert immer noch die Quell-IP, während docker-compose up korrekt funktioniert.

Folgendes hatte ich basierend auf @goetas auch probiert

docker service create --constraint node.hostname==exposedhost \
  --publish published=12555,target=12555,mode=host \
  trajano.net/myimage

Immer noch kein Glück, die Quell-IP zu bekommen, dies ist auf Server Version: 17.12.0-ce

Scheint etwas zu sein, das sich jeder irgendwann wünschen würde, und da die Verwendung von Overlay-Netzwerken zusammen mit Bridge/Host-Netzwerken nicht wirklich möglich ist, ist dies ein Blocker, wenn Sie die Client-IP aus verschiedenen Gründen wirklich benötigen.

Klient:
Version: 17.12.0-ce
API-Version: 1.35
Go-Version: go1.9.2
Git-Commit: c97c6d6
Baujahr: Mi 27 Dez 20:03:51 2017
Betriebssystem/Arch: darwin/amd64

Server:
Motor:
Version: 17.12.1-ce
API-Version: 1.35 (Mindestversion 1.12)
Go-Version: go1.9.4
Git-Commit: 7390fc6
Gebaut: Di 27 Feb 22:17:54 2018
Betriebssystem/Arch: linux/amd64
Experimentell: wahr

Es ist 2018. Gibt es etwas Neueres zu diesem Thema?
Im Schwarmmodus kann ich nginx req limit nicht verwenden. $remote_addr hat immer 10.255.0.2 abgefangen.
Dies ist ein wirklich ernstes Problem mit dem Docker-Schwarm.
Vielleicht sollte ich Kubernetes seit heute ausprobieren.

@Maslow Ich habe gepostet, wo wir nur ein paar Kommentare oben sind.

Können wir den Scheck lockern?

networks:
  bridge:
    external:
      name: bridge

oder verlängern wie

networks:
  bridge:
    external:
      name: bridge
      scope: local

und scope: local Netzwerke sind nur zulässig, wenn der Netzwerkmodus host

Netzwerk "Bridge" ist als extern deklariert, aber nicht im richtigen Bereich: "local" statt "swarm"

oder erlauben

networks:
  bridge:
    driver: bridge

Um nicht zu scheitern

Fehler beim Erstellen des Dienstes trajano_serv: Fehlerantwort vom Daemon: Das Netzwerk trajano_bridge kann nicht mit Diensten verwendet werden. Es können nur Netzwerke verwendet werden, die dem Schwarm zugeordnet sind, z. B. solche, die mit dem Overlay-Treiber erstellt wurden.

wenn mode: host auf veröffentlichten Ports vorhanden ist.

ports:
- target: 32555
  published: 32555
  protocol: tcp
  mode: host

@trajano Sie können Netzwerke ohne Schwarmbereich bereits mit Schwarm verwenden ... z. B. funktioniert dies:

version: '3.4'

services:
  test:
    image: alpine
    command: top
    ports:
      - target: 32555
        published: 32555
        protocol: tcp
        mode: host
    networks:
      - bridge

networks:
  bridge:
    external:
      name: bridge

Haben Sie dies an einem Schwarm mit mehr als einem Worker mit Docker-Stack-Bereitstellung getestet? Ich weiß, es funktioniert mit Compose.

Am 18. März 2018 um 20:55 Uhr schrieb Brian Goff [email protected] :

@trajano Sie können Netzwerke ohne Schwarmbereich bereits mit Schwarm verwenden ... z. B. funktioniert dies:

Version: '3.4'

Dienstleistungen:
Prüfung:
Bild: alpin
Befehl: top
Häfen:
- Ziel: 32555
veröffentlicht: 32555
Protokoll: tcp
Modus: Host
Netzwerke:
- Brücke

Netzwerke:
Brücke:
extern:
Name: Brücke

Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.

Ja, ich mache das durch Schwarm...

Am Mo, 19.03.2018 um 9:12 Uhr, Archimedes Trajano <
[email protected]> schrieb:

Hast du das an einem Schwarm mit mehr als einem Arbeiter mit Docker-Stack getestet?
einsetzen. Ich weiß, es funktioniert mit Compose.

Am 18. März 2018, um 20:55 Uhr, Brian Goff [email protected]
schrieb:

@trajano Sie können Netzwerke ohne Schwarmbereich bereits mit Schwarm verwenden ...
das funktioniert zB:

Version: '3.4'

Dienstleistungen:
Prüfung:
Bild: alpin
Befehl: top
Häfen:

  • Ziel: 32555
    veröffentlicht: 32555
    Protokoll: tcp
    Modus: Host
    Netzwerke:
  • Brücke

Netzwerke:
Brücke:
extern:
Name: Brücke

Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-374206587 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAwxZsm3OohKL0sqUWhlgUNjCrqR0OaVks5tf67YgaJpZM4Jf2WK
.

--

  • Brian Goff

+1

Habe dieses Problem mit dem folgenden Docker Swarm Load Balancing mit 3 Knoten:

Overlay-Netzwerk <-> nginx-Proxy jwilder docker <-> nginx-Webhead-Docker

Ich habe die Vorschläge befolgt und die Protokolle geben weiterhin die Docker-Netzwerk-IP 10.255.0.3 anstelle der echten Client-IP zurück.

+1

@cpuguy83 Dies ist ein Blocker für unsere größeren Schwarm-Setups. Wenn wir beginnen, mehr von der Cloud zu nutzen (wo das Proxy-Protokoll de facto von Load-Balancern verwendet wird), verlieren wir diese für uns sehr wichtigen Informationen.

Hast du eine Idee von einer ETA? das würde uns sehr helfen.

@sandys Eine ETA für was genau?

@cpuguy83 Hallo, danke für deine Antwort. Ich bin mir bewusst, dass es keine breite Übereinstimmung darüber gibt, wie Sie es lösen möchten. Ich kommentiere irgendwie, wie das Team mit Stabilitätsproblemen beschäftigt war und für dieses Problem nicht frei ist.
Wann würde man dieses Thema Ihrer Meinung nach aufgreifen (wenn überhaupt) ?

Beachten Sie, dass Sie dieses Problem lösen können, indem Sie einen globalen Dienst ausführen und Ports mit PublishMode=host veröffentlichen. Wenn Sie wissen, auf welchem ​​Knoten sich die Leute verbinden werden, brauchen Sie das nicht einmal, verwenden Sie einfach eine Einschränkung, um sie an diesem Knoten zu fixieren.

@kleptog Teilweise kannst du es nicht. Es kann Ausfallzeiten während der Aktualisierung des Dienstes nicht vermeiden.

Testszenario - genauere Betrachtung von lvs/ipvs.

  • nsenter zum versteckten Ingress-Container und lösche die Snat-Regel
  • nsenter zum Dienst mit veröffentlichten Ports, lösche Standard-GW und füge Standardroute zu Ingress-Container-IP hinzu.

Jetzt wird die Quell-IP beibehalten.

Ich versuche immer noch, die Auswirkungen des Overheads zu verstehen, indem ich das richtlinienbasierte Routing in jedem Service-Container aufrechterhalte, anstatt nur die Snat-Regel im Ingress-Container zu haben.
Es wäre aber wirklich entlastend, wenn das funktioniert.

Entschuldigung für mein naives Herumfummeln, aber könnte mir jemand ( @dack ? ) den Docker-Code zeigen, wo das gemacht wird?

Ah, jetzt habe ich es verstanden. In einem Multinode-Schwarm muss die IP die des lvs-Direktors sein, um den Weg zurück zum richtigen Node zu finden, ist die Anfrage eingegangen...

Es wäre trotzdem interessant, den Code zu sehen. Es könnte mir etwas Zeit sparen, wenn es jemand schon weiß. Dankeschön

Alle Updates dazu, mit drei Clustern in verschiedenen Ländern und sogar Azure Traffic Manager benötigen echte Benutzer-IPs, wenn nicht, leitet er den Benutzer nicht an einen guten Cluster usw. weiter. Wird dies bald oder jemals überprüft? Vielen Dank

Brauche auch ein Update dazu - das ist ein großer Fallstrick - die einzige Möglichkeit, die ich gefunden habe, besteht darin, einen weiteren Proxy vorne hinzuzufügen und x-forwarded-for an den Stack zu senden, was bedeutet, dass Swarm eine Nicht-Option für die Öffentlichkeit ist für viele Szenarien mit Verkehr konfrontiert.

@cpuguy83 @trajano
Ich kann bestätigen, dass folgendes nicht funktioniert

version: '3.4'
services:
  nginx:
    ports:
      - mode: host
        protocol: tcp
        published: 80
        target: 80
      - mode: host
        protocol: tcp
        published: 443
        target: 81
networks:
  bridge:
    external:
      name: bridge

Es schlägt mit network "bridge" is declared as external, but it is not in the right scope: "local" instead of "swarm" fehl.

Docker-Version

Client:
 Version:       18.03.0-ce-rc4
 API version:   1.37
 Go version:    go1.9.4
 Git commit:    fbedb97
 Built: Thu Mar 15 07:33:59 2018
 OS/Arch:       windows/amd64
 Experimental:  false
 Orchestrator:  swarm

Server:
 Engine:
  Version:      18.03.0-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.4
  Git commit:   0520e24
  Built:        Wed Mar 21 23:08:31 2018
  OS/Arch:      linux/amd64
  Experimental: false

@Mobe91
Versuchen Sie, den Schwarm nachzubilden. Ich hatte auch einen Fehler. Nach der Neuinitiierung des Schwarms hat bei mir alles funktioniert.
Meine docker-compose.yml Datei:

version: "3.6"

services:
    nginx:
        image: nginx:latest
        depends_on:
            - my-app
            - my-admin
        ports: 
            - target: 80
              published: 80
              protocol: tcp
              mode: host
            - target: 443
              published: 443
              protocol: tcp
              mode: host
            - target: 9080
              published: 9080
              protocol: tcp
              mode: host
        volumes:
            - /etc/letsencrypt:/etc/letsencrypt:ro
            - /home/project/data/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
            - /home/project/data/nginx/conf.d:/etc/nginx/conf.d
            - /home/project/public:/var/public
        networks:
            - my-network
            - bridge
        deploy:
            placement:
                constraints: [node.role == manager]

    my-app:
        image: my-app
        ports:
            - 8080:8080
        volumes:
            - /usr/src/app/node_modules
            - /home/project/public:/usr/src/app/public
        networks:
            - my-network

    my-admin:
        image: my-admin
        ports:
            - 9000:9000
        networks:
            - my-network

networks:
    my-network:
    bridge:
        external: true
        name: bridge

mein docker version :

Client:
 Version:   18.03.0-ce
 API version:   1.37
 Go version:    go1.9.4
 Git commit:    0520e24
 Built: Wed Mar 21 23:10:01 2018
 OS/Arch:   linux/amd64
 Experimental:  false
 Orchestrator:  swarm

Server:
 Engine:
  Version:  18.03.0-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.4
  Git commit:   0520e24
  Built:    Wed Mar 21 23:08:31 2018
  OS/Arch:  linux/amd64
  Experimental: false

Entschuldigung für mein Englisch.

@ Mobe91 das habe ich verwendet, aber ich stelle es von "portainer" oder auf dem Linux-Computer bereit. Ich kann es nicht richtig von Windows bereitstellen.

version: '3.4'
services:
  hath:
    image: trajano.net/hath
    deploy:
      placement:
        constraints:
        - node.hostname==docker-engine
    networks:
    - host
    ports:
    - target: 12555
      published: 12555
      protocol: tcp
      mode: host
    secrets:
    - hath_client_login
    volumes:
    - hath:/var/lib/hath
volumes:
  hath:
    name: 'noriko/s/hath'
    driver: cifs
networks:
  host:
    external:
      name: host
secrets:
  hath_client_login:
    external:
      name: hath_client_login

Der Hauptunterschied ist, dass ich host anstelle von bridge In meinem Fall betreibe ich meine Hosts auch als VirtualBox-VMs und ich verwende den Router, der NAT-Routing durchführt und die eingehende IP bis zum der Kontainer.

Natürlich gibt es keine Load-Balancing-Funktion, ich denke, wenn Sie Load-Balancing wünschen, müssen Sie etwas wie einen L3-Router vor sich haben, der Load-Balancing durchführen würde

@trajano hat recht, der Windows-Client war das Problem, das Deployment mit dem Linux-Client hat funktioniert.

Aber ich verstehe nicht, warum Sie das Netzwerk host oder bridge überhaupt brauchen?
Folgendes funktioniert bei mir einwandfrei, dh ich bekomme echte Client-IP-Adressen in nginx:

version: '3.4'
services:
  nginx:
    ports:
      - mode: host
        protocol: tcp
        published: 80
        target: 80

@ Mobe91 danke, ich wollte dafür ein Problem eröffnen. Grundsätzlich mit https://github.com/moby/moby/issues/32957 binden, da es immer noch mit dem 18.03-ce-Client für Windows auftrat.

Hat jemand Cilium verwendet? http://cilium.readthedocs.io/en/latest/gettingstarted/docker/ .

Es scheint, als ob es in der Lage sein könnte, dies zu beheben, ohne Dienste an den Host zu binden.

@sandys guter Fund - ich beginne gleich mit dem Testen, hat es bei dir funktioniert? Ich bin gerade dabei, Nginx aus meinem Schwarm zu ziehen, wenn ich das nicht reparieren kann.....

Wir haben dies bei der Neugestaltung unserer Bereitstellung erreicht, um zu vermeiden, dass Proxys an einzelne Hosts angeheftet werden (die in der Produktion aus anderen Gründen an eine Schnittstelle binden und daher die Client-IP als Nebenprodukt "aufnehmen").

In unserer Testumgebung können wir uns nur verbessern, indem wir die Bereitstellung für Manager nach Einschränkungen durchführen und mode = global um sicherzustellen, dass jeder Manager eine laufende Instanz erhält. Es ist immer noch ein zusätzlicher Overhead, den wir beachten müssen, insbesondere wenn wir einen Manager-Knoten verlieren und etwas unseren Datenverkehr dorthin leitet. Es ist jedoch besser, als an einen einzelnen Host gepinnt zu sein.

@sandys hast du Cilium https://github.com/kubernetes/kubernetes/issues/51014

Ich konnte Cilium nicht verwenden, aber ich habe mich an das Cilium gewandt
Entwickler, um bei der Schwarmkonfiguration zu helfen. Aber ich bin ganz begeistert von Cilium
weil Ingress ein erklärtes Problem ist, das es lösen möchte (im Gegensatz zu Weben)

Am Do, 10. Mai 2018, 17:24 Uhr schrieb James Green,

Wir haben dies bei der Neugestaltung unserer Bereitstellung erreicht, um das Anheften von Proxys an . zu vermeiden
einzelne Hosts (die in der Produktion an eine Schnittstelle für andere binden
Gründen und daher die Client-IP als Nebenprodukt "abholen").

In unserer Testumgebung können wir uns nur verbessern, indem wir sie den Managern bereitstellen bis
Einschränkungs- und Einstellungsmodus = global, um sicherzustellen, dass jeder Manager ein
laufende Instanz. Es ist immer noch ein zusätzlicher Overhead, den man beachten muss,
vor allem, wenn wir einen Managerknoten verlieren und etwas unseren lenkt
Verkehr dazu. Es ist jedoch besser, als an einen einzelnen Host gepinnt zu sein.

@sandys https://github.com/sandys hast du Cilium probiert ? Sieht ähnlich aus wie
Weave, das zumindest bei k8s das gleiche Problem zu haben scheint:
kubernetes/kubernetes#51014
https://github.com/kubernetes/kubernetes/issues/51014


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-388032011 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAEUzQCgIeTenQIHIERxOfHKCzn1O6Aks5txCpogaJpZM4Jf2WK
.

Am 10. Mai 2018 um 17:24 Uhr schrieb "James Green" [email protected] :

Wir haben dies bei der Neugestaltung unserer Bereitstellung erreicht, um das Anheften von Proxys an . zu vermeiden
einzelne Hosts (die in der Produktion an eine Schnittstelle für andere binden
Gründen und daher die Client-IP als Nebenprodukt "abholen").

In unserer Testumgebung können wir uns nur verbessern, indem wir sie den Managern bereitstellen bis
Einschränkungs- und Einstellungsmodus = global, um sicherzustellen, dass jeder Manager zum Laufen kommt
Beispiel. Es ist immer noch ein zusätzlicher Overhead, den Sie beachten müssen, insbesondere wenn
wir verlieren einen Managerknoten und etwas leitet unseren Datenverkehr dorthin.
Es ist jedoch besser, als an einen einzelnen Host gepinnt zu sein.

@sandys https://github.com/sandys hast du Cilium probiert ? Sieht ähnlich aus wie
Weave, das zumindest bei k8s das gleiche Problem zu haben scheint:
kubernetes/kubernetes#51014
https://github.com/kubernetes/kubernetes/issues/51014


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-388032011 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAEUzQCgIeTenQIHIERxOfHKCzn1O6Aks5txCpogaJpZM4Jf2WK
.

  • 1

Hallo Leute,
wenn Sie Docker Swarm-Unterstützung in Cilium wünschen (insbesondere für Ingress und
um dieses spezielle Problem), bitte kommentieren / liken Sie diesen Fehler -
https://github.com/cilium/cilium/issues/4159

Am Freitag, den 11. Mai 2018 um 00:59 Uhr schrieb McBacker [email protected] :

>

  • 1


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-388159466 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU_18F_cNttRUaAwaRF3gVpMZ-3qSks5txJUfgaJpZM4Jf2WK
.

bei mir mit der aktuellen version funktioniert das so:
Ich kann dann auf die anderen Knoten im Schwarm zugreifen, wie es auch im 'Standard'-Netzwerk ist

  web-server:
    image: blabla:7000/something/nginx:latest
    #ports:
    #  - "80:80"
    #  - "443:443"
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host        
    deploy:
      mode: global
      restart_policy:
        condition: any
      update_config:
        parallelism: 1
        delay: 30s

Ich kann bestätigen, dass der Schlüssel ports.mode: host . Aus der Dokumentation (https://docs.docker.com/compose/compose-file/#long-syntax-1):

mode: Host zum Veröffentlichen eines Host-Ports auf jedem Knoten oder Ingress für einen Schwarmmodus-Port zum Lastausgleich.

Wenn Sie dann mode: host beenden Sie den Lastausgleich durch eingehenden Traffic und die echte IP wird angezeigt. Als Beispiel hier meine nginx-Logs:

  • mit mode: host
    metrics-agents_nginx.1.pip12ztq3y1h<strong i="14">@xxxxxxxx</strong> | 62.4.X.X - - [12/Jun/2018:08:46:04 +0000] "GET /metrics HTTP/1.1" 200 173979 "-" "Prometheus/2.2.1" "-" [CUSTOM] "request_time: 0.227" remote_addr: 62.4.X.X proxy_add_x_forwarded_for: 62.4.X.X
  • ohne mode: host
    metrics-agents_nginx.1.q1eosiklkgac<strong i="20">@xxxxxxxx</strong> | 10.255.0.2 - - [12/Jun/2018:08:50:04 +0000] "GET /metrics HTTP/1.1" 403 162 "-" "Prometheus/2.2.1" "-" [CUSTOM] "request_time: 0.000" remote_addr: 10.255.0.2 proxy_add_x_forwarded_for: 10.255.0.2

Und wenn Sie sich fragen, warum das letzte Protokoll eine 403 Forbidden-Antwort ist, liegt dies an der Verwendung einer Whitelist auf nginx ( allow 62.4.X.X und deny all ).

Kontext:
Description: Debian GNU/Linux 9.4 (stretch)
Docker version 18.03.0-ce, build 0520e24

Ich bestätige, was @nperron gesagt hat.
Die Verwendung des Host-Modus ermöglicht es, die Client-IP zu erhalten.

Docker-Version 18.03.1-ce, Build 9ee9f40
Ubuntu 16.04.4 LTS

Ich kann bestätigen, dass es funktioniert.

Docker-Version 18.03.1-ce, Build 9ee9f40
Ubuntu 16.04.4 LTS

VORSICHT: DIES FUNKTIONIERT NICHT, WENN SIE IPTABLES=FALSE SETZEN!
Möglicherweise haben Sie dies getan (oder zumindest ich), wenn Sie UFW zum Sichern von Ports verwenden und festgestellt haben, dass Docker Swarm diese UFW-Einstellungen überschreibt.

Es gibt einige Tutorials, die vorschlagen, iptables = false per Befehl oder in /etc/docker/daemon.json zu setzen

Hoffentlich erspart das jemandem die Frustration, die ich gerade durchgemacht habe!

Leute sollten wirklich aufhören zu sagen "Mode: host" = working, weil das nicht Ingress verwendet. Das macht es unmöglich, nur einen Container mit einem Dienst auf dem Schwarm laufen zu lassen, aber dennoch über jeden Host darauf zugreifen zu können. Entweder muss man den Dienst "Global" machen oder man kann nur auf dem Host darauf zugreifen, was den Zweck von Swarm irgendwie verfehlt.

TLDR: "Modus: Host" ist ein Workaround, keine Lösung

@r3pek Ich stimme Ihnen zwar zu, dass Sie Ingress verlieren, wenn Sie den Host-Modus verwenden, um dieses
Management replizierte Container, auf die nur über das Intranet zugegriffen werden sollte -> sie benötigen die IP des Anrufers nicht, sind daher "normal" konfiguriert und nutzen den Ingress.
nicht exponierte Container -> nichts zu sagen (ich glaube, Sie unterschätzen jedoch die Macht, über ihren Dienstnamen auf sie zugreifen zu können).
öffentlicher Dienst -> Dies ist ein Nginx-Proxy, der HTTPS- und URL-basiertes Routing durchführt. Es wurde global definiert, noch bevor die echte IP des Clients x-forward-forward, also kein wirkliches Problem.

Wenn nginx global ist und keinen Ingress hat, können Sie es über jede IP des Clusters erreichen, es ist jedoch nicht lastenausgleichend oder fehlertolerant. Daher haben wir einen sehr, sehr kostengünstigen und einfach einzurichtenden L4 Azure Load Balancer vor dem nginx hinzugefügt Service.

Wie Sie sagen, ist Host ein Workaround, aber zu sagen, dass die Aktivierung den Zweck von Docker Swarm vollständig verfehlt, ist ein wenig übertrieben.

Hallo Roberto
Ich finde es nicht übertrieben - denn der Host-Modus legt einzelne Punkte offen
des Scheiterns. Darüber hinaus erwartet es zusätzliche Managementebenen für die Last
Balancieren außerhalb des Schwarmökosystems.

Indem Sie sagen, dass Sie selbst azurblaues Pfund verwendet haben, haben Sie das irgendwie bestätigt
Streit.

Es ist gleichbedeutend damit zu sagen, dass "um Schwarm mit Client-IP-Verbreitung laufen zu lassen,
Stellen Sie sicher, dass Sie einen externen Load Balancer verwenden, den Sie eingerichtet haben. Oder verwenden Sie
einer der Cloud-Dienste".

Wir sagen nicht, dass es kein vorübergehender Workaround ist ... Aber es wäre
das Versprechen von Swarm zu ignorieren, wenn wir alle dies nicht kategorisch anerkennen
Mangel.

Am Do, 5. Juli 2018, 14:16 Roberto Fabrizi, [email protected]
schrieb:

@r3pek https://github.com/r3pek Während ich dir zustimme, dass du verlierst
Ingress, wenn Sie den Host-Modus verwenden, um dieses Dilemma zu lösen, würde ich sagen, dass es
verfehlt kaum den ganzen Zweck von Swarm, das so viel mehr tut als a
öffentlich zugängliches Ingress-Netzwerk. In unserem Nutzungsszenario haben wir das gleiche
Überlagerungsschwarm:
Management replizierter Container, auf die nur über die
Intranet -> sie brauchen die IP des Anrufers nicht, daher sind sie konfiguriert
"normal" und nutzen Sie den Ingress.
nicht exponierte Behälter -> dazu nichts zu sagen (ich glaube, Sie sind es
unterschätzen die Macht, über ihren Dienst auf sie zugreifen zu können
aber Name).
öffentlich zugänglicher Container -> Dies ist ein Nginx-Proxy, der https und URLs ausführt
basierte Streckenführung. Es wurde global definiert, noch bevor x-forward-for . erforderlich war
die echte IP des Clients, also kein wirkliches Problem.

Wenn Sie nginx global haben und keinen Ingress haben, können Sie es über . erreichen
jede IP des Clusters, aber es ist kein Load-Balancing, also haben wir eine sehr sehr . hinzugefügt
kostengünstig und einfach einzurichten L4 Azure Load Balancer vor dem nginx
Service.

Wie Sie sagen, ist Host eine Problemumgehung, aber Sie sagen, dass es vollständig aktiviert ist
den Zweck von Docker Swarm verfehlt ist imo etwas übertrieben.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-402650066 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU_ogRzwM6X0PMknXxsxmZLLTtfraks5uDdJlgaJpZM4Jf2WK
.

Es ist klar, dass für den Ingress des Docker Swarms ein schlechter Load Balancer (IPVS) ausgewählt wurde. Wenn es zumindest das L4-Proxy-Protokoll unterstützt, wäre dies kein Problem. Abgesehen davon, dass es immer noch ein L4 (TCP) Load Balancer ohne all die zusätzlichen Funktionen wäre, die L7 lb bieten kann.

In Kubernetes gibt es L4(TCP)-L7(HTTP)-Load-Balancer wie nginx ingress , L4-Proxy-Protokolls oder der L7-HTTP-Header ermöglichen, um sicherzustellen, dass X-Forwarded-For für die Weitergabe der realen Daten des Benutzers genutzt wird IP zum Backend.

Ich frage mich, was die Entwickler des Docker Swarm-Ingress sagen würden. Wahrscheinlich muss jemand diesen Fall nach https://github.com/docker/swarmkit/issues verschieben ?

In Kubernetes gibt es L4(TCP)-L7(HTTP)-Load-Balancer wie nginx-ingress, haproxy-ingress, die beide die Verwendung des L4-Proxy-Protokolls oder der L7-HTTP-Header ermöglichen, um sicherzustellen, dass X-Forwarded-For für die Weitergabe der echten IP des Benutzers genutzt wird zum Backend.

AFAICS sind diese LB-Dienste nicht in K8s eingebettet, sondern Dienste, die explizit bereitgestellt werden müssen. Dasselbe können Sie auch mit Docker Swarm tun. Ich sehe hier keinen Unterschied. (Ansonsten scheint der nginx Ingress Controller "offiziell" zu sein.)

Soweit ich weiß, besteht der Unterschied darin, dass selbst wenn Sie einen solchen Loadbalancing-Dienst bereitstellen, dieser vom swarmkit-Loadbalancer "aufgerufen" wird und Sie die Benutzer-IP verlieren. Sie können den swarmkit-Loadbalancer also nicht deaktivieren, wenn Sie den Hostmode nicht verwenden.

um fair zu sein - in k8s ist es möglich, einen benutzerdefinierten ingress zu haben. im Schwarm es
ist nicht.

swarm vertritt den Standpunkt, dass alles "eingebaut" ist. Genauso ist es bei
Netzwerke - in k8s müssen Sie Weben usw. einrichten, in Swarm ist es integriert.

Der Punkt, den Andrey macht (und dem stimme ich zu) ist, dass -
swarm sollte diese Funktion als Teil des Ingresses machen, da der Benutzer
keine Kontrolle darüber.

Am Sa., 28. Juli 2018 um 17:07 Uhr schrieb Seti [email protected] :

Soweit ich weiß, ist der Unterschied, dass e en wenn Sie eine solche einsetzen
Loadbalancing-Dienst wird er vom swarmkit-Loadbalancer 'aufgerufen'
und so verlieren Sie die Benutzer-IP. Du kannst das Swarmkit also nicht deaktivieren
Loadbalancer, wenn Hostmode nicht verwendet wird.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-408601274 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU1-Ism_S1Awml8lO8N0Aq6rtrLH4ks5uLEzugaJpZM4Jf2WK
.

Ich dachte, wir wären damit fertig, unsere Schwarmfalten auszubügeln, aber dann kamen wir zur Bühne und stellten fest, dass alle externen Zugriffe auf den Webserver-Container als Ingress-Netzwerk-IP angezeigt werden.

Ich betreibe meinen Stack auf einem Single-Node-Schwarm und werde dies zumindest in den nächsten Monaten tun. Können Sie die am wenigsten schlechte Problemumgehung für unseren aktuellen Anwendungsfall (Single-Node-Schwarm) empfehlen? Ich kann nicht auf die Client-IP verzichten - zu sehr hängt davon ab.

Unser vorübergehender Ansatz bestand darin, einen einfachen Proxy-Container im „globalen“ Modus auszuführen (der IIRC kann die tatsächliche IP-Adresse der NIC abrufen) und dann alle Verbindungen an den internen Dienst weiterleiten, der im Schwarm-Overlay-Netzwerk mit hinzugefügten Proxy-Headern ausgeführt wird.

Wenn es für Sie ausreicht, einen x-forwarded-for-Header zu erhalten, sollte dieses Setup AFAICT funktionieren.

Danke, @maximelb. Was hast du am Ende gemacht (zB nginx, haproxy)?

@jamiejackson da werden die Dinge ein bisschen anders. In unserem Fall betreiben wir einen Server, der lang laufende SSL-Verbindungen und ein benutzerdefiniertes Binärprotokoll darunter hostet, sodass HTTP-Proxys nicht möglich waren. Also haben wir einen einfachen TCP-Forwarder erstellt und einen „msgpack“-Header verwendet, den wir manuell auf dem internen Server entpacken konnten.

Ich bin mit HTTP-Proxys nicht besonders vertraut, aber ich vermute, dass die meisten von ihnen den Zweck erfüllen würden. :-/

Hallo Maxime,
das ist für uns sehr interessant. Kannst du dein docker-compose von irgendjemandem teilen?
Chance ?

Ich versuche zu verstehen, wie das funktioniert. Heute haben wir nginx als Gegenstück
Proxy (als Dienst) und mehrere Docker-Dienste dahinter.

Wird nginx in Ihrem Fall zum "Global Mode"-Proxy? oder ist es a
spezieller TCP-Forwarder. Wenn Sie also die Anzahl der Knoten skalieren, wird der Proxy-Forwarder
geht auf jeden Knoten. Ich dachte irgendwie in dieser Situation das x-weitergeleitet für
Header geht verloren .. weil das Ingress-Netzwerk die externe IP löscht
(da es kein Proxy-Protokoll gibt).

Wir wären Ihnen sehr dankbar, wenn Sie uns mit ein paar weiteren Details helfen könnten.

Grüße
Sandeep

Am Mi, 8. August 2018 um 7:18 Uhr Maxime Lamothe-Brassard <
[email protected]> schrieb:

Unser vorübergehender Ansatz bestand darin, einen einfachen Proxy-Container in
„globaler“ Modus (der IIRC kann die tatsächliche IP der NIC erhalten) und dann haben
leitet alle Verbindungen an den internen Dienst weiter, der auf dem Schwarm läuft
Overlay-Netzwerk mit hinzugefügten Proxy-Headern.

Wenn es für Sie ausreicht, einen x-forwarded-for-Header zu erhalten, sollte dieses Setup
AFAICT arbeiten.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-411257087 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAEsUx3DOjXb79FNjsuZ-RZVqkkhHAbYks5uOkOHgaJpZM4Jf2WK
.

@sandys klar , hier ein Auszug aus unserem Docker-Compose mit den entsprechenden Containern.

Dies ist der Reverse-Proxy-Docker-Compose-Eintrag:

reverseproxy:
    image: yourorg/repo-proxy:latest
    networks:
      - network_with_backend_service
    deploy:
      mode: global
    ports:
      - target: 443
        published: 443
        protocol: tcp
        mode: host

Dies ist der Back-End-Diensteintrag:

backendservice:
    image: yourorg/repo-backend:latest
    networks:
      - network_with_backend_service
    deploy:
      replicas: 2

Das Ziel des Reverseproxys (der Back-End-Seite) wäre tasks.backendservice (das A-Records für jedes Replikat hat). Sie können den Abschnitt networks überspringen, wenn sich der Back-End-Dienst im standardmäßigen Schwarm-Overlay-Netzwerk befindet.

Der global Bit sagt „diese Behälter bereitstellen genau einmal auf jedem Docker Schwarm Knoten. Die Ports mode: host ist das eine sagen : ‚binden an den nativen NIC des Knotens‘.

Ich hoffe es hilft.

Sie verwenden den Host-Modus. Sie haben also so ziemlich einen externen Load Balancer
vor dem Ganzen.
Sie können sich nicht mehr auf Swarm verlassen, da Sie sich im Host-Modus befinden.

Das ist eigentlich das Problem, über das wir schon seit einiger Zeit sprechen :(

Am Mi, 8. August 2018, 20:47 Uhr Maxime Lamothe-Brassard, <
[email protected]> schrieb:

@sandys https://github.com/sandys klar , hier ein Auszug aus unserem
docker-compose mit den entsprechenden Containern.

Dies ist der Reverse-Proxy-Docker-Compose-Eintrag:

Reverse-Proxy:
Bild: yourorg/repo- proxy:latest
Netzwerke:
- network_with_backend_service
einsetzen:
Modus: global
Häfen:
- Ziel: 443
veröffentlicht: 443
Protokoll: tcp
Modus: Host

Dies ist der Back-End-Diensteintrag:

Backend-Dienst:
Bild: yourorg/repo- backend:latest
Netzwerke:
- network_with_backend_service
einsetzen:
Repliken: 2

Das Ziel des Reverseproxys (der Backend-Seite) wäre
task.backendservice (der A-Einträge für jedes Replikat hat). Du kannst
Überspringe den Netzwerkteil, wenn der Backend-Dienst im Standardschwarm ist
Overlay-Netzwerk.

Das globale Bit sagt "Diesen Container genau einmal auf jedem Docker bereitstellen"
Schwarmknoten. Der Ports-Modus: host ist derjenige, der sagt "Binde an den nativen
NIC des Knotens".

Ich hoffe es hilft.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-411442155 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU8N7KAFtOp_cPO8wpbBQqzDfpBWOks5uOwEkgaJpZM4Jf2WK
.

Nicht 100% sicher, was Sie meinen, aber extern verwenden wir ein DNS mit einem A-Eintrag pro Clusterknoten. Dies ermöglicht ein kostengünstiges "Auswuchten", ohne ein externes bewegliches Teil zu haben. Wenn ein Client eine Anfrage stellt, wählt er einen zufälligen A-Eintrag und verbindet sich mit 443 auf einem der Cluster-Knoten.

Dort erhält der Reverse-Proxy, der auf diesem bestimmten Knoten ausgeführt wird und auf 443 lauscht, eine native Verbindung, einschließlich der tatsächlichen Client-IP. Dieser Reverse-Proxy-Container fügt dann einen Header hinzu und leitet die Verbindung über das Schwarm-Overlay-Netzwerk (tasks.backend) an einen anderen internen Container weiter. Da es das Ziel task.backend verwendet, erhält es auch einen zufälligen A-Eintrag für einen internen Dienst.

Im engeren Sinne wird also die Magie des Overlay-Netzwerks umgangen, das die Verbindung umleitet. Stattdessen repliziert es dieses Verhalten mit dem Reverse-Proxy und fügt einen Header hinzu. Der endgültige Effekt ist (in einem losen Sinne) derselbe wie die Magie des Overlay-Netzwerks. Es tut es auch parallel zum Ausführen des Schwarms, was bedeutet, dass ich alle meine anderen Dienste ausführen kann, die die Client-IP nicht auf demselben Cluster benötigen, ohne etwas anderes für diese zu tun.

Auf keinen Fall eine perfekte Lösung, aber bis ein Fix (wenn überhaupt) vorgenommen wird, kommt man ohne externe Komponenten oder größere Docker-Konfigurationen aus.

@jamiejackson Die "am wenigsten schlechte" allgemeines Beispiel in ihren Dokumenten . Wir haben einige Fehler gesehen, die möglicherweise mit diesem Setup zusammenhängen, aber Traefik ist ein großartiges Projekt und scheint auf Swarm ziemlich stabil zu sein. Es gibt einen ganzen Thread auf ihrer Problemseite (der hier zurückkehrt :) ) mit ähnlichen Problemumgehungen:
https://github.com/containous/traefik/issues/1880

Hoffe das hilft. Wir können auch keine Lösung verwenden, die es uns nicht erlaubt, die tatsächlichen IPs der Requester zu überprüfen, also bleiben wir bei dieser Fehlerkorrektur, bis sich etwas ändert. Es scheint zumindest aus Sicherheitsgründen ein ziemlich häufiges Bedürfnis zu sein.

Verstanden (und eine lose Version davon verwenden wir).

Allerdings - die Agenda dieses speziellen Fehlers bestand darin, die Entwickler anzufordern
um das in das magische Overlay-Netzwerk zu integrieren (vielleicht mit Proxy
Protokoll oder andere Mechanismen)

Am Mi, 8. August 2018, 21:22 Uhr Maxime Lamothe-Brassard, <
[email protected]> schrieb:

Ich bin mir nicht 100% sicher, was Sie meinen, aber extern verwenden wir ein DNS mit einem A
Datensatz pro Clusterknoten. Dies ermöglicht ein günstiges "Auswuchten" ohne eine
externer beweglicher Teil. Wenn ein Kunde eine Anfrage stellt, wählt er ein zufälliges A
aufzeichnen und mit 443 auf einem der Clusterknoten verbinden.

Dort der Reverse-Proxy, der auf diesem bestimmten Knoten ausgeführt wird, und
Das Abhören auf 443 erhält eine native Verbindung, einschließlich der tatsächlichen Client-IP.
Dieser Reverse-Proxy-Container fügt dann einen Header hinzu und leitet die Verbindung weiter
zu einem anderen internen Container über das Schwarm-Overlay-Netzwerk
(Aufgaben.Backend). Da es das task.backend-Ziel verwendet, wird es auch a
random Ein Datensatz für einen internen Dienst.

Im engeren Sinne umgeht es also die Magie des Overlay-Netzwerks, das
leitet die Verbindung um. Es repliziert dieses Verhalten stattdessen irgendwie mit
den Reverse-Proxy und fügt einen Header hinzu. Der Endeffekt ist der gleiche (in a
Loose sense) als die Magie des Overlay-Netzwerks. Es tut es auch in
parallel zum Betrieb des Schwarms, d. h. ich kann alle meine anderen Dienste ausführen, die
Benötigen Sie die Client-IP nicht auf demselben Cluster, ohne etwas zu tun
sonst für die.

Auf keinen Fall eine perfekte Lösung, aber bis ein Fix (wenn überhaupt) gemacht wird, wird es
Sie ohne externe Komponenten oder größere Docker-Konfiguration.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-411455384 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU5RKjGc3hEk6bk-doicDa1MbYGAyks5uOwlIgaJpZM4Jf2WK
.

TBH Ich bin mir nicht sicher, warum das Ingress-Netzwerk nicht gepatcht wird, um IP hinzuzufügen
Daten im Proxy-Protokoll.

Es ist inkrementell, es bricht keine bestehenden Stapel, es ist ein gut definiertes
Standard, es wird selbst von den großen Cloud-Anbietern weithin unterstützt, es ist weit verbreitet
durch Anwendungsframeworks unterstützt.

Ist es ein erheblicher Entwicklungsaufwand?

Am Mittwoch, 8. August 2018, 21:30 Uhr schrieb Matt Glaser, [email protected] :

@jamiejackson https://github.com/jamiejackson das "am wenigsten schlimme"
Die von uns gefundene Problemumgehung besteht darin, Traefik als globalen Dienst im Hostmodus zu verwenden.
Sie haben ein gutes allgemeines Beispiel in ihren Dokumenten
https://docs.traefik.io/user-guide/cluster-docker-consul/#full-docker-compose-file_1 .
Wir haben einige Fehler gesehen, die mit diesem Setup zusammenhängen können oder nicht, aber
Traefik ist ein großartiges Projekt und es scheint auf Swarm ziemlich stabil zu sein. Da ist ein
ganzen Thread auf ihrer Themenseite drauf (das geht hier zurück :) ), mit
ähnliche Problemumgehungen:
enthaltend/traefik#1880
https://github.com/containous/traefik/issues/1880

Hoffe das hilft. Wir können auch keine Lösung verwenden, die es uns nicht erlaubt
Überprüfen Sie die tatsächlichen IPs der Anforderer, damit wir bei dieser Fehlerkorrektur bleiben, bis
etwas ändert sich. Es scheint aus Sicherheitsgründen ein ziemlich häufiges Bedürfnis zu sein
wenigstens.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-411458326 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU7NNbsW44L95VYCvlyL_Bje-h6L9ks5uOwsUgaJpZM4Jf2WK
.

Nun, Docker berührt derzeit keinen eingehenden Datenverkehr, also definitiv zumindest nicht unbedeutend.
Denken Sie auch daran, dass dies ein Open-Source-Projekt ist. Wenn Sie etwas wirklich wollen, liegt es im Allgemeinen an Ihnen, es zu implementieren.

+1, das ist wirklich ein Showstopper.
Ich würde glauben, dass die Mehrheit der Anwendungen die echte Client-IP benötigt. Denken Sie nur an einen Mailserver-Stack - Sie können es sich nicht leisten, Mails von beliebigen Hosts anzunehmen.

Wir haben in den proxy_protocol nginx globalen Streaminstanz-Hostmodus gewechselt, der an die replizierte Anwendung proxy_nginx weiterleitet. Das funktioniert im Moment gut genug.

service global nginx_stream

stream {
    resolver_timeout 5s;
    # 127.0.0.11 is docker swarms dns server
    resolver 127.0.0.11 valid=30s;
    # set does not work in stream module, using map here
    map '' $upstream_endpoint {
        default proxy_nginx:443;
    }

    server {
        listen 443;
        proxy_pass $upstream_endpoint;
        proxy_protocol on;
    }
}

Dienst repliziert nginx_proxy

server {
    listen 443 ssl http2 proxy_protocol;
    include /ssl.conf.include;

    ssl_certificate /etc/nginx/certs/main.crt;
    ssl_certificate_key /etc/nginx/certs/main.key;

    server_name example.org;

    auth_basic           "closed site";
    auth_basic_user_file /run/secrets/default.htpasswd;

    # resolver info in nginx.conf
    set $upstream_endpoint app;
    location / {
        # relevant proxy_set_header in nginx.conf
        proxy_pass http://$upstream_endpoint;
    }
}

Wäre es möglich, die gesamte nginx-Konfiguration für nginx_stream und
nginx_proxy mit ihren Schwarmkonfigurationen?

Das ist toll, wenn es funktioniert!

Am Dienstag, 11. September 2018, 17:14 Uhr schrieb rubot, [email protected] :

Wir sind auf die globale Stream-Instanz proxy_protocol nginx umgestiegen
Weiterleitung an die replizierte Anwendung proxy_nginx. Das funktioniert gut genug
für den Moment.

service global nginx_stream

strömen {
Auflöser_Zeitüberschreitung 5s;
# 127.0.0.11 ist ein Docker-Schwarm-DNS-Server
Resolver 127.0.0.11 gültig=30s;
# set funktioniert nicht im Stream-Modul, hier wird die Karte verwendet
Karte '' $upstream_endpoint {
Standardproxy_nginx :443;
}

server {
    listen 443;
    proxy_pass $upstream_endpoint;
    proxy_protocol on;
}

}

Dienst repliziert nginx_proxy

Server {
lauschen 443 ssl http2 proxy_protocol;
include /ssl.conf.include;

ssl_certificate /etc/nginx/certs/main.crt;
ssl_certificate_key /etc/nginx/certs/main.key;

server_name example.org;

auth_basic           "closed site";
auth_basic_user_file /run/secrets/default.htpasswd;

# resolver info in nginx.conf
set $upstream_endpoint app;
location / {
    # relevant proxy_set_header in nginx.conf
    proxy_pass http://$upstream_endpoint;
}

}


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-420244262 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU5K-gK09XdI9NxLlT36IrJP7U7_cks5uZ6IrgaJpZM4Jf2WK
.

@sandys Ich habe eine haproxy-basierte Lösung für den Proxy-Protokollteil, die über Umgebungsvariablen konfiguriert wird.

Wäre es möglich, die gesamte nginx-Konfiguration für nginx_stream und nginx_proxy mit ihren Swarm-Konfigurationen zu übergeben? Das ist toll, wenn es funktioniert!

@sandys Etwas in der Art:
https://gist.github.com/rubot/10c79ee0086a8a246eb43ab631f3581f

auf das gleiche Problem stoßen, wird das behoben? scheint eine grundlegende Funktionalität zu sein, die für eine Veröffentlichung vorgesehen sein sollte.

einsetzen:
Modus: global
Häfen:

  • Ziel: 443 veröffentlicht: 443 Protokoll: TCP-Modus: Host

Das Befolgen dieser Ratschläge behebt das Problem, da der Docker Swarm Balancer jetzt nicht mehr in der Gleichung enthalten ist.
Für mich ist es eine gültige Lösung, da es immer noch HA ist und ich bereits haproxy (innerhalb des Docker-Flow-Proxy-Containers) hatte.
Das einzige Problem ist, dass die Haproxy-Statistiken auf alle Replikate verteilt sind, also muss ich diese Informationen irgendwie zusammenfassen, wenn ich den Verkehr für den gesamten Cluster überwache. In der Vergangenheit hatte ich nur eine Haproxy-Instanz, die sich hinter dem Docker Swarm Balancer befand.
Danke schön,
Jacq

Beim Lesen der Anfrage des OP ( @PanJ ) scheinen die aktuellen Funktionen dieses Problem nun zu lösen, wie es seit Monaten vorgeschlagen wird. Das OP fragte nicht nach Ingress-Routing + Client-IP AFAIK, sondern nach einer Möglichkeit, einen Schwarmdienst in Replikat- / globalen Client-IPs zu erhalten, was jetzt machbar ist. Zwei Hauptbereiche der Verbesserung ermöglichen dies:

  1. Wir können jetzt einen Swarm-Dienst erstellen, der einen Port für die Host-IP "veröffentlicht" und die Ingress-Routing-Schicht überspringt
  2. Derselbe Dienst kann sich gleichzeitig mit anderen Netzwerken wie Overlay verbinden, sodass er mit Overlay-Vorteilen auf andere Dienste zugreifen kann

Für mich mit 18.09-Motor bekomme ich beim Testen das Beste aus beiden Welten. Ein einzelner Dienst kann sich mit Back-End-Overlay-Netzwerken verbinden und auch Ports auf der Host-NIC veröffentlichen und echte Client-IPs sehen, die auf der Host-IP eingehen. Ich verwende das mit dem traefik-Reverse-Proxy, um den Client-IP-Verkehr in traefik zu protokollieren, der für Back-End-Dienste bestimmt ist . Ich habe das Gefühl, dass dies die meisten Anfragen, die ich gesehen habe, zum "Protokollieren der echten IP" lösen könnte.

@PanJ löst es das für dich?

Der Schlüssel ist, Ports in mode: host und nicht in mode: ingress (Standard) zu veröffentlichen.

Der Vorteil dieses Modus ist, dass Sie echte Client-IPs und native Host-NIC-Leistung erhalten (da es sich außerhalb der IPVS-Kapselung AFAIK befindet). Der Nachteil ist, dass es nur auf den Knoten lauscht, auf denen die Replikate ausgeführt werden.

Für mich ist die Anfrage "Ich möchte Ingress-IPVS-Routing verwenden und auch die Client-IP sehen" eine andere Funktionsanfrage von libnetwork.

Was hat sich hier geändert? Weil wir dafür den Host-Modus verwendet haben
jetzt schon lange. Tatsächlich ist dies der Workaround, der in diesem Thread vorgeschlagen wird, da
Gut.

Das Problem ist, dass Sie diesen Dienst natürlich auf eine bestimmte Funktion sperren müssen
host, damit Swarm es nicht anderswo planen kann. Was war das Problem
vollständig - dieses Proxy-Protokoll/IPVS usw. lösen dieses Problem.

Am Freitag, den 4. Januar 2019, 09:34 Uhr schrieb Bret Fisher < [email protected] :

Beim Lesen der OP-Anfrage ( @PanJ https://github.com/PanJ )
aktuelle Features scheinen dieses Problem nun zu lösen, wie es für vorgeschlagen wurde
Monate. Das OP hat nicht nach Ingress-Routing + Client-IP-AFAIK gefragt, sondern nachgefragt
für eine Möglichkeit, einen Schwarmdienst in Replikaten/globalen Client-IPs zu erhalten,
was jetzt machbar ist. Zwei Hauptbereiche der Verbesserung ermöglichen dies:

  1. Wir können jetzt einen Swarm-Dienst erstellen, der einen Port an die . "veröffentlicht".
    Host-IP, Überspringen der Ingress-Routing-Schicht
  2. Derselbe Dienst kann an andere Netzwerke wie Overlay angebunden werden
    gleichzeitig, damit es auf andere Dienste mit Overlay-Vorteilen zugreifen kann

Für mich mit 18.09-Motor bekomme ich beim Testen das Beste aus beiden Welten. EIN
Ein einzelner Dienst kann sich mit Back-End-Overlay-Netzwerken verbinden und auch veröffentlichen
Ports auf der Host-NIC und sehen Sie echte Client-IPs, die auf der Host-IP eingehen. Ich bin
Verwenden Sie dies mit dem traefik-Reverse-Proxy, um den IP-Verkehr des Clients in traefik zu protokollieren
die für Back-End-Dienste bestimmt ist
https://github.com/BretFisher/dogvscat/blob/7e9fe5b998f2cf86951df3f443714beb413d63fb/stack-proxy-global.yml#L75-L83 .
Ich habe das Gefühl, dass dies die meisten Anfragen, die ich gesehen habe, für "Logging the Real" lösen könnte
IP".

@PanJ https://github.com/PanJ löst das das Problem für dich?

Der Schlüssel besteht darin, Ports im Modus zu veröffentlichen: Host und nicht im Modus: Ingress (der
Ursprünglich).

Der Vorteil dieses Modus ist, dass Sie echte Client-IPs und native Host-NICs erhalten
Leistung (da es sich außerhalb der IPVS-Kapselung AFAIK befindet). Der Nachteil ist es
hört nur auf den Knoten, auf denen die Replikate ausgeführt werden.

Für mich ist die Anfrage "Ich möchte Ingress-IPVS-Routing verwenden und auch sehen
client IP" ist eine andere Funktionsanforderung von libnetwork.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451348906 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAEUzs15UVWOVl54FLwBJSZJKX-9D0jks5u_tLPgaJpZM4Jf2WK
.

@BretFisher das mode: host ist nur ein Workaround, aber nicht die Lösung. Da @sandys sagte, dass die

Ich bin mir nicht sicher, ob es seit der Entdeckung des Workarounds eine Verbesserung gegeben hat. Ich bin schon länger zu Kubernetes gewechselt und wundere mich immer noch, dass das Thema noch über zwei Jahre offen ist.

Ich bin immer noch etwas überrascht, warum die Leute denken, dass dies ein Bug ist. Von meinem
perspektivisch ist selbst die aussage, zu kubernetes zu wechseln, nicht adäquat
Antworten. Wie ich sehe, hat Kubernetes genau das gleiche Problem/Verhalten. Du entweder
einen externen LB haben oder etwas wie den Nginx-Ingress-Proxy verwenden, der muss
als Daemonset ausführen. Bitte korrigiert mich, wenn ich falsch liege, aber wir haben das gleiche
genaue Situation hier, aber keine vorbereitete Autosolution hier. Jemand könnte
Überprüfen und packen Sie meine oben beschriebene vorgeschlagene TCP-Stream-Lösung, um zu erhalten
so etwas wie nginx-Proxy-Verhalten. Akzeptiere einfach, dieser Schwarm muss sein
selbst angepasst

PanJ [email protected] schrieb am Fr., 4. Jan. 2019, 09:28:

@BretFisher https://github.com/BretFisher der Modus: Host ist nur ein
Abhilfe, aber nicht die Lösung. Als @sandys https://github.com/sandys
sagte, dass die Problemumgehung nur wenige Vorbehalte hat, wir sollten dieses Problem nicht berücksichtigen
als fest.

Ich bin mir nicht sicher, ob es seit der Problemumgehung eine Verbesserung gegeben hat
entdeckt. Ich bin schon lange zu Kubernetes gewechselt und bin es immer noch
überrascht, dass das Thema noch über zwei Jahre offen ist.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451382365 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK
.

Sie könnten sogar das Dockerflow-Projekt erweitern und eine nginx-Variante zum Start hinzufügen
kubernetes-ingressproxy für swarn. Definitiv das alles voller Schwarm
würde einen zusätzlichen Systemcontainer erstellen, da Sie wissen, dass es eine Menge gibt
sie mit Kubernetes. Ist es nicht die Stärke des Schwarms für eine schlanke Ressource?
Projekte schlank sein?

Ruben Nicolaides [email protected] schrieb am Fr., 4. Jan. 2019, 09:48:

Ich bin immer noch etwas überrascht, warum die Leute denken, dass dies ein Bug ist. Von meinem
perspektivisch ist selbst die aussage, zu kubernetes zu wechseln, nicht adäquat
Antworten. Wie ich sehe, hat Kubernetes genau das gleiche Problem/Verhalten. Du entweder
einen externen LB haben oder etwas wie den Nginx-Ingress-Proxy verwenden, der muss
als Daemonset ausführen. Bitte korrigiert mich, wenn ich falsch liege, aber wir haben das gleiche
genaue Situation hier, aber keine vorbereitete Autosolution hier. Jemand könnte
Überprüfen und packen Sie meine oben beschriebene vorgeschlagene TCP-Stream-Lösung, um zu erhalten
so etwas wie nginx-Proxy-Verhalten. Akzeptiere einfach, dieser Schwarm muss sein
selbst angepasst

PanJ [email protected] schrieb am Fr., 4. Jan. 2019, 09:28:

@BretFisher https://github.com/BretFisher der Modus: Host ist nur ein
Abhilfe, aber nicht die Lösung. Als @sandys https://github.com/sandys
sagte, dass die Problemumgehung nur wenige Vorbehalte hat, wir sollten dieses Problem nicht berücksichtigen
als fest.

Ich bin mir nicht sicher, ob es seit der Problemumgehung eine Verbesserung gegeben hat
entdeckt. Ich bin schon lange zu Kubernetes gewechselt und bin es immer noch
überrascht, dass das Thema noch über zwei Jahre offen ist.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451382365 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK
.

Das sind komplexe Lösungen - das Proxy-Protokoll fügt nur einen zusätzlichen Header hinzu
Informationen und ist ein sehr bekannter Standard - haproxy, nginx, AWS elb,
usw. alle folgen ihm. https://www.haproxy.com/blog/haproxy/proxy-protocol/

Die Fläche der Änderung wäre auf den eingebauten Schwarm beschränkt
ingress (wo diese Unterstützung hinzugefügt werden würde). Und alle Dienste werden es haben
erhältlich.

Am Freitag, den 4. Januar 2019, 14:36 ​​Uhr schrieb rubot < [email protected] :

Sie könnten sogar das Dockerflow-Projekt erweitern und eine nginx-Variante zum Start hinzufügen
kubernetes-ingressproxy für swarn. Definitiv das alles voller Schwarm
würde einen zusätzlichen Systemcontainer erstellen, da Sie wissen, dass es eine Menge gibt
sie mit Kubernetes. Ist es nicht die Stärke des Schwarms für eine schlanke Ressource?
Projekte schlank sein?

Ruben Nicolaides [email protected] schrieb am Fr., 4. Jan. 2019, 09:48:

Ich bin immer noch etwas überrascht, warum die Leute denken, dass dies ein Bug ist. Von meinem
perspektivisch ist selbst die aussage, zu kubernetes zu wechseln, nicht adäquat
Antworten. Wie ich sehe, hat Kubernetes genau das gleiche Problem/Verhalten. Du
entweder
einen externen LB haben oder etwas wie den Nginx-Ingress-Proxy verwenden, der muss
als Daemonset ausführen. Bitte korrigiert mich, wenn ich falsch liege, aber wir haben das gleiche
genaue Situation hier, aber keine vorbereitete Autosolution hier. Jemand könnte
Überprüfen und packen Sie meine oben beschriebene vorgeschlagene TCP-Stream-Lösung, um zu erhalten
so etwas wie nginx-Proxy-Verhalten. Akzeptiere einfach, dieser Schwarm muss sein
selbst angepasst

PanJ [email protected] schrieb am Fr., 4. Jan. 2019, 09:28:

@BretFisher https://github.com/BretFisher der Modus: Host ist nur ein
Abhilfe, aber nicht die Lösung. Als @sandys https://github.com/sandys
sagte, dass die Problemumgehung nur wenige Vorbehalte hat, wir sollten dies nicht berücksichtigen
Ausgabe
als fest.

Ich bin mir nicht sicher, ob es seit der Problemumgehung eine Verbesserung gegeben hat
entdeckt. Ich bin schon lange zu Kubernetes gewechselt und immer noch
Sein
überrascht, dass das Thema noch über zwei Jahre offen ist.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451382365 , oder
stumm
der Faden
<
https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451389574 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK
.

Wie gesagt, überprüfen Sie oben die TCP-Stream-Lösung, die bereits Proxy verwendet
Protokoll.
Das Hinzufügen des Proxy-Protokolls würde auch eine Konfiguration im Container erfordern, wenn
hinzugefügt, um stromaufwärts zu schwärmen. Ich sehe keinen Wert, außer einem saubereren und vielleicht besseren
dokumentiertes Ziel in Ihrer Anfrage

Sandeep Srinivasa [email protected] schrieb am Fr., 4. Jan. 2019,
11:37:

Das sind komplexe Lösungen - das Proxy-Protokoll fügt nur einen zusätzlichen Header hinzu
Informationen und ist ein sehr bekannter Standard - haproxy, nginx, AWS elb,
usw. alle folgen ihm. https://www.haproxy.com/blog/haproxy/proxy-protocol/

Die Fläche der Änderung wäre auf den eingebauten Schwarm beschränkt
ingress (wo diese Unterstützung hinzugefügt werden würde). Und alle Dienste werden es haben
erhältlich.

Am Freitag, den 4. Januar 2019, 14:36 ​​Uhr schrieb rubot < [email protected] :

Sie könnten sogar das Dockerflow-Projekt erweitern und eine nginx-Variante hinzufügen
Anfang
kubernetes-ingressproxy für swarn. Definitiv das alles voller Schwarm
würde einen zusätzlichen Systemcontainer erstellen, da Sie wissen, dass es eine Menge gibt
sie mit Kubernetes. Ist es nicht die Stärke des Schwarms für eine schlanke Ressource?
Projekte schlank sein?

Ruben Nicolaides [email protected] schrieb am Fr., 4. Jan. 2019, 09:48:

Ich bin immer noch etwas überrascht, warum die Leute denken, dass dies ein Bug ist. Von meinem
perspektivisch ist selbst die aussage, zu kubernetes zu wechseln, nicht adäquat
Antworten. Wie ich sehe, hat Kubernetes genau das gleiche Problem/Verhalten. Du
entweder
einen externen LB haben oder etwas wie den nginx Ingress Proxy verwenden, der
muss
als Daemonset ausführen. Bitte korrigiert mich, wenn ich falsch liege, aber wir haben das gleiche
genaue Situation hier, aber keine vorbereitete Autosolution hier. Jemand könnte
Überprüfen und packen Sie meine oben beschriebene vorgeschlagene TCP-Stream-Lösung, um zu erhalten
so etwas wie nginx-Proxy-Verhalten. Akzeptieren Sie einfach, dieser Schwarm muss
Sein
selbst angepasst

PanJ [email protected] schrieb am Fr., 4. Jan. 2019, 09:28:

@BretFisher https://github.com/BretFisher der Modus: Host ist nur ein
Abhilfe, aber nicht die Lösung. Als @sandys <
https://github.com/sandys>
sagte, dass die Problemumgehung nur wenige Vorbehalte hat, wir sollten dies nicht berücksichtigen
Ausgabe
als fest.

Ich bin mir nicht sicher, ob es seit der Problemumgehung eine Verbesserung gegeben hat
entdeckt. Ich bin schon lange zu Kubernetes gewechselt und immer noch
Sein
überrascht, dass das Thema noch über zwei Jahre offen ist.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451382365 ,
oder
stumm
der Faden
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK
>

.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451389574 , oder
stumm
der Faden
<
https://github.com/notifications/unsubscribe-auth/AAESU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK

.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451409453 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK
.

Die obige Lösung erfordert eine Hostmodusbindung. Das ist das große Thema. Es
eliminiert die Möglichkeit, den Docker-Scheduler zum Zuweisen von Containern zu verwenden
zu verschiedenen Hosts - ich bin nicht mehr Teil des Mesh-Netzwerks.

Am Freitag, den 4. Januar 2019, 17:28 Uhr schrieb rubot < [email protected] :

Wie gesagt, überprüfen Sie oben die TCP-Stream-Lösung, die bereits Proxy verwendet
Protokoll.
Das Hinzufügen des Proxy-Protokolls würde auch eine Konfiguration im Container erfordern, wenn
hinzugefügt, um stromaufwärts zu schwärmen. Ich sehe keinen Wert, außer einem saubereren und vielleicht besseren
dokumentiertes Ziel in Ihrer Anfrage

Sandeep Srinivasa [email protected] schrieb am Fr., 4. Jan. 2019,
11:37:

Das sind komplexe Lösungen - das Proxy-Protokoll fügt nur einen zusätzlichen Header hinzu
Informationen und ist ein sehr bekannter Standard - haproxy, nginx, AWS elb,
usw. alle folgen ihm. https://www.haproxy.com/blog/haproxy/proxy-protocol/

Die Fläche der Änderung wäre auf den eingebauten Schwarm beschränkt
ingress (wo diese Unterstützung hinzugefügt werden würde). Und alle Dienste haben
es
erhältlich.

Am Freitag, den 4. Januar 2019, 14:36 ​​Uhr schrieb rubot < [email protected] :

Sie könnten sogar das Dockerflow-Projekt erweitern und eine nginx-Variante hinzufügen
Anfang
kubernetes-ingressproxy für swarn. Auf jeden Fall alles vollgepackt mit
Schwarm
würde zusätzliche Systemcontainer erstellen, da Sie wissen, dass es eine Menge gibt
von
sie mit Kubernetes. Ist es nicht die Stärke des Schwarms für eine schlanke Ressource?
Projekte schlank sein?

Ruben Nicolaides [email protected] schrieb am Fr., 4. Jan. 2019, 09:48:

Ich bin immer noch etwas überrascht, warum die Leute denken, dass dies ein Bug ist. Von meinem
Perspektivisch ist selbst die Aussage, zu Kubernetes zu wechseln, keine
angemessene
Antworten. Wie ich sehe, hat Kubernetes genau das gleiche Problem/Verhalten. Du
entweder
einen externen LB haben oder etwas wie den nginx Ingress Proxy verwenden, der
muss
als Daemonset ausführen. Bitte korrigiert mich, wenn ich falsch liege, aber wir haben die
gleich
genaue Situation hier, aber keine vorbereitete Autosolution hier. Jemand
könnten
Überprüfen und packen Sie meine oben beschriebene vorgeschlagene TCP-Stream-Lösung, um zu erhalten
so etwas wie nginx-Proxy-Verhalten. Akzeptieren Sie einfach, dieser Schwarm muss
Sein
selbst angepasst

PanJ [email protected] schrieb am Fr., 4. Jan. 2019, 09:28:

@BretFisher https://github.com/BretFisher der Modus: Host ist nur
ein
Abhilfe, aber nicht die Lösung. Als @sandys <
https://github.com/sandys>
sagte, dass die Problemumgehung einige Vorbehalte hat, die wir nicht berücksichtigen sollten
Dies
Ausgabe
als fest.

Ich bin mir nicht sicher, ob es seit der Problemumgehung eine Verbesserung gibt
gewesen
entdeckt. Ich bin schon länger zu Kubernetes gewechselt und
still
Sein
überrascht, dass das Thema noch über zwei Jahre offen ist.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451382365 ,
oder
stumm
der Faden
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

>

.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451389574 , oder
stumm
der Faden
<

https://github.com/notifications/unsubscribe-auth/AAESU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK
>

.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451409453 , oder
stumm
der Faden
<
https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK

.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451424992 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK
.

Wie gesagt, Kubernetes nginx Ingress benötigt auch eine Host-Modus-Bindung, genannt
Dämonenset. Externe LB-Verbindung zu Nodeports, die auch Host-Modus erfordern
im Dienst, oder konfigurieren Sie das Proxy-Protokoll im Dienst manuell. Kubernetes
hat immer noch die gleichen Probleme.
Ein möglicher Feature-Wunsch aus meiner Sicht für swarm wäre,
machen den Netzwerkanbieter steckbar. Dies würde die Nutzung ermöglichen
andere Techniken als lvs/iptables

Sandeep Srinivasa [email protected] schrieb am Fr., 4. Jan. 2019,
13:05:

Die obige Lösung erfordert eine Hostmodusbindung. Das ist das große Thema. Es
eliminiert die Möglichkeit, den Docker-Scheduler zum Zuweisen von Containern zu verwenden
zu verschiedenen Hosts - ich bin nicht mehr Teil des Mesh-Netzwerks.

Am Freitag, den 4. Januar 2019, 17:28 Uhr schrieb rubot < [email protected] :

Wie gesagt, überprüfen Sie oben die TCP-Stream-Lösung, die bereits Proxy verwendet
Protokoll.
Das Hinzufügen des Proxy-Protokolls würde auch eine Konfiguration im Container erfordern
wenn
hinzugefügt, um stromaufwärts zu schwärmen. Ich sehe keinen Wert, außer einer Reinigungskraft und vielleicht
besser
dokumentiertes Ziel in Ihrer Anfrage

Sandeep Srinivasa [email protected] schrieb am Fr., 4. Jan.
2019,
11:37:

Das sind komplexe Lösungen - das Proxy-Protokoll fügt nur zusätzliches hinzu
Header
Informationen und ist ein sehr bekannter Standard - haproxy, nginx, AWS
Elbe,
usw. alle folgen ihm.
https://www.haproxy.com/blog/haproxy/proxy-protocol/

Die Fläche der Änderung wäre auf den eingebauten Schwarm beschränkt
ingress (wo diese Unterstützung hinzugefügt werden würde). Und alle Dienste haben
es
erhältlich.

Am Freitag, den 4. Januar 2019, 14:36 ​​Uhr schrieb rubot < [email protected] :

Sie könnten sogar das Dockerflow-Projekt erweitern und eine nginx-Variante hinzufügen
Anfang
kubernetes-ingressproxy für swarn. Auf jeden Fall alles vollgepackt mit
Schwarm
würde zusätzliche Systemcontainer erstellen, da Sie wissen, dass es eine Menge gibt
von
sie mit Kubernetes. Ist es nicht die Stärke des Schwarms für Slim
Ressource
Projekte schlank sein?

Ruben Nicolaides [email protected] schrieb am Fr., 4. Jan. 2019,
09:48:

Ich bin immer noch etwas überrascht, warum die Leute denken, dass dies ein Bug ist. Von
mein
Perspektivisch ist selbst die Aussage, zu Kubernetes zu wechseln, keine
angemessene
Antworten. Wie ich sehe, hat Kubernetes genau das gleiche Problem/Verhalten.
Du
entweder
einen externen LB haben oder so etwas wie nginx Ingress Proxy verwenden
welcher
muss
als Daemonset ausführen. Bitte korrigiert mich, wenn ich falsch liege, aber wir haben die
gleich
genaue Situation hier, aber keine vorbereitete Autosolution hier. Jemand
könnten
Überprüfen und verpacken Sie meine oben beschriebene vorgeschlagene TCP-Stream-Lösung in
werden
so etwas wie nginx-Proxy-Verhalten. Akzeptiere einfach, dieser Schwarm braucht
zu
Sein
selbst angepasst

PanJ [email protected] schrieb am Fr., 4. Jan. 2019,
09:28:

@BretFisher https://github.com/BretFisher der Modus: Host ist
nur
ein
Abhilfe, aber nicht die Lösung. Als @sandys <
https://github.com/sandys>
sagte, dass die Problemumgehung einige Vorbehalte hat, die wir nicht berücksichtigen sollten
Dies
Ausgabe
als fest.

Ich bin mir nicht sicher, ob es seit der Problemumgehung eine Verbesserung gibt
gewesen
entdeckt. Ich bin schon länger zu Kubernetes gewechselt und
still
Sein
überrascht, dass das Thema noch über zwei Jahre offen ist.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
< https://github.com/moby/moby/issues/25526#issuecomment -451382365
,
oder
stumm
der Faden
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

>

.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451389574 ,
oder
stumm
der Faden
<

https://github.com/notifications/unsubscribe-auth/AAESU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK

>

.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451409453 , oder
stumm
der Faden
<

https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK
>

.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451424992 , oder
stumm
der Faden
<
https://github.com/notifications/unsubscribe-auth/AAESU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK

.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451426276 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAPguw88UN68sw_TNTunZpuAGqgvexxMks5u_0NxgaJpZM4Jf2WK
.

Und nur zur Verdeutlichung, die obige Lösung hat TCP-Stream vor dem Dienst
Stellvertreter. Ihre Anfrage ist also definitiv kein Bug, sondern eine Funktionsanfrage. Und
diese Funktion könnte nur im Schwarm implementiert werden, wenn der Netzwerkmodus dies tun würde
ändern, da das Hauptproblem im Verlust der IP auf Nat/Host-Ebene bleibt

Ruben Nicolaides [email protected] schrieb am Fr., 4. Jan. 2019, 13:11:

Wie gesagt, Kubernetes nginx Ingress benötigt auch eine Host-Modus-Bindung, genannt
Dämonenset. Externe LB-Verbindung zu Nodeports, die auch Host-Modus erfordern
im Dienst, oder konfigurieren Sie das Proxy-Protokoll im Dienst manuell. Kubernetes
hat immer noch die gleichen Probleme.
Ein möglicher Feature-Wunsch aus meiner Sicht für swarm wäre,
machen den Netzwerkanbieter steckbar. Dies würde die Nutzung ermöglichen
andere Techniken als lvs/iptables

Sandeep Srinivasa [email protected] schrieb am Fr., 4. Jan.
2019, 13:05:

Die obige Lösung erfordert eine Hostmodusbindung. Das ist das große Thema. Es
eliminiert die Möglichkeit, den Docker-Scheduler für die Zuweisung zu verwenden
Behälter
zu verschiedenen Hosts - ich bin nicht mehr Teil des Mesh-Netzwerks.

Am Freitag, den 4. Januar 2019, 17:28 Uhr schrieb rubot < [email protected] :

Wie gesagt, überprüfen Sie oben die TCP-Stream-Lösung, die bereits Proxy verwendet
Protokoll.
Das Hinzufügen des Proxy-Protokolls würde auch eine Konfiguration im Container erfordern
wenn
hinzugefügt, um stromaufwärts zu schwärmen. Ich sehe keinen Wert, außer einer Reinigungskraft und vielleicht
besser
dokumentiertes Ziel in Ihrer Anfrage

Sandeep Srinivasa [email protected] schrieb am Fr., 4. Jan.
2019,
11:37:

Das sind komplexe Lösungen - das Proxy-Protokoll fügt nur zusätzliches hinzu
Header
Informationen und ist ein sehr bekannter Standard - haproxy, nginx, AWS
Elbe,
usw. alle folgen ihm.
https://www.haproxy.com/blog/haproxy/proxy-protocol/

Die Fläche der Änderung wäre auf den eingebauten Schwarm beschränkt
ingress (wo diese Unterstützung hinzugefügt werden würde). Und alle Dienste werden
verfügen über
es
erhältlich.

Am Freitag, den 4. Januar 2019, 14:36 ​​Uhr schrieb rubot < [email protected] :

Sie könnten sogar das Dockerflow-Projekt erweitern und eine nginx-Variante hinzufügen
Anfang
kubernetes-ingressproxy für swarn. Auf jeden Fall alles vollgepackt mit
Schwarm
würde einen zusätzlichen Systemcontainer erstellen, da Sie wissen, dass es eine gibt
Bündel
von
sie mit Kubernetes. Ist es nicht die Stärke des Schwarms für Slim
Ressource
Projekte schlank sein?

Ruben Nicolaides [email protected] schrieb am Fr., 4. Jan. 2019,
09:48:

Ich bin immer noch etwas überrascht, warum die Leute denken, dass dies ein Bug ist. Von
mein
Perspektivisch ist selbst die Aussage, zu Kubernetes zu wechseln, keine
angemessene
Antworten. Wie ich sehe, hat Kubernetes genau das gleiche Problem/Verhalten.
Du
entweder
einen externen LB haben oder so etwas wie nginx Ingress Proxy verwenden
welcher
muss
als Daemonset ausführen. Bitte korrigiert mich, wenn ich falsch liege, aber wir haben die
gleich
genaue Situation hier, aber keine vorbereitete Autosolution hier. Jemand
könnten
Überprüfen und verpacken Sie meine oben beschriebene vorgeschlagene TCP-Stream-Lösung in
werden
so etwas wie nginx-Proxy-Verhalten. Akzeptiere einfach, dieser Schwarm
muss
Sein
selbst angepasst

PanJ [email protected] schrieb am Fr., 4. Jan. 2019,
09:28:

@BretFisher https://github.com/BretFisher der Modus: Host ist
nur
ein
Abhilfe, aber nicht die Lösung. Als @sandys <
https://github.com/sandys>
sagte, dass die Problemumgehung einige Vorbehalte hat, die wir nicht berücksichtigen sollten
Dies
Ausgabe
als fest.

Ich bin mir nicht sicher, ob es seit der Problemumgehung eine Verbesserung gibt
gewesen
entdeckt. Ich bin schon länger zu Kubernetes gewechselt und
still
Sein
überrascht, dass das Thema noch über zwei Jahre offen ist.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
<
https://github.com/moby/moby/issues/25526#issuecomment-451382365>,
oder
stumm
der Faden
<

https://github.com/notifications/unsubscribe-auth/AAPgu40OJ-uNKORD-LAD12m1lafxzMiSks5u_xCcgaJpZM4Jf2WK

>

.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451389574 ,
oder
stumm
der Faden
<

https://github.com/notifications/unsubscribe-auth/AAESU2FCEGFs5v6IOEy6AqjcBMl7IqEiks5u_xmTgaJpZM4Jf2WK

>

.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451409453 ,
oder
stumm
der Faden
<

https://github.com/notifications/unsubscribe-auth/AAPgu83fSrSzfopOlDXsDooN1tMboGZaks5u_y8EgaJpZM4Jf2WK
>

.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451424992 , oder
stumm
der Faden
<
https://github.com/notifications/unsubscribe-auth/AAESU-q-I3fXVAP9JcGgTdJJOzI7b575ks5u_0HIgaJpZM4Jf2WK

.


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-451426276 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAPguw88UN68sw_TNTunZpuAGqgvexxMks5u_0NxgaJpZM4Jf2WK
.

  1. nach so einem langen thread habe ich versucht, die aktuellen funktionen anhand eines vollständigen beispiels zu dokumentieren.
  2. Ich sehe Ihren spezifischen Bedarf in der Anfrage des OP nicht. @PanJ hat darum gebeten, die Client-

Egal, ob Sie es einen Bug oder eine Funktionsanfrage nennen, Ingress Mesh ohne Source-Nat ist (meiner Meinung nach) unerlässlich. Es gibt viele Anwendungen, die kaputt gehen, wenn sie die wahre Quell-IP nicht sehen können. Sicher, bei Webservern können Sie den Proxy mithilfe eines Hostknotens umkehren und Client-IP-Header hinzufügen. Dies führt jedoch zu einem zusätzlichen Overhead und ist wahrscheinlich keine Option für nicht webbasierte Anwendungen. Bei einer Anwendung, die tatsächlich benötigt, dass die echte Quell-IP des Pakets korrekt ist, besteht die einzige Möglichkeit darin, kein Ingress-Mesh zu verwenden. Das wirft einen großen Teil des Vorteils der Verwendung von Swarm von vornherein zunichte.

Bitte teilen Sie uns mit, wann dieses Problem behoben wurde oder nicht?!
sollten wir stattdessen kuberneties verwenden?

Ich habe das gleiche Problem gehabt ... ich habe im Moment keine Lösung gefunden.

Wenn jemand eine Lösung für dieses Verhalten findet, bitte hier melden.

Vielen Dank!

Ich habe das gleiche Problem. Ich habe einen Apache httpd-Server und möchte alle Zugriffe protokollieren, um später Statistiken darüber zu extrahieren, aus welchen Ländern wir Anfragen erhalten.

Ich bin selbst über dieses Problem gestolpert, als ich versuchte herauszufinden, warum php: apache das Host-Header-Feld nicht korrekt protokollierte. Ich bin schockiert und enttäuscht, dass das nach all den Jahren noch nicht funktioniert. Wie sollen wir den Swarm-Modus für Webhosting verwenden, wenn das Host-Feld die Userland-Proxy-IP protokolliert? Mit dem Schwarmmodus konnte ich das nicht umgehen. Ich nehme an, ich könnte Classic Swarm (containerbasiert) und so etwas wie Consul verwenden, aber ich denke, das geht rückwärts.

Ich habe eine akzeptable Lösung für mein Szenario gefunden:

services:
  server:
    image: httpd:2
    deploy:
      mode: global
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host
    networks:
      - my_second_service
      - another_great_software

Dies führt dazu, dass Apache auf dem Host-Computer lauscht und nicht hinter dem Overlay-Netzwerk (die richtige Remote-IP-Adresse liest), während weiterhin Anfragen an andere Dienste über die networks Optionen weitergeleitet werden und dadurch "hohe Verfügbarkeit" erreicht wird überall laufen

@rafaelsierra - hier ist das Problem, das ich damit habe (und korrigiere mich, wenn ich falsch Hostknoten gebunden wird. Ich muss viele, viele Apache-Container mit einem Nginx-Container ausführen, der an Port 80/443 gebunden ist, und sie dann vhosten.

@SysEngDan ja, es stimmt, dass Sie nur einen einzigen Container haben können, der an die 80/443-Ports bindet, aber in meinem Fall ist das kein Problem, da der Container, der an diesen Port bindet, nur dafür verantwortlich ist, alle Anfragen an andere Container weiterzuleiten die hinter dem Overlay-Netzwerk laufen.

Sie können wahrscheinlich die gleiche Lösung verwenden, indem Sie einen einzelnen nginx/apache-Container haben, der alle Anfragen empfängt und basierend auf dem vhost an den richtigen Container weiterleitet, und diese Container müssen nicht an den Host binden

@rafaelsierra - Problem darin, dass die Client-IP nicht an die Container weitergegeben wird, die nur im Overlay-Netzwerk lauschen. Wenn ich direkt an den Host binde, kein Problem. Wenn wir uns auf das Docker-Netzwerk-Proxying von extern (Host) zu intern (Overlay) verlassen, erhält der Apache-Zielcontainer nicht die ursprüngliche Client-IP-Adresse, sondern stattdessen die IP des Proxys (vom Docker-Netzwerk).

@SysEngDan Ich verstehe das Problem, und da es in den letzten 2 Jahren keine Lösung gibt (und ich bin mir ehrlich gesagt nicht sicher, ob dies "reparierbar" ist), musste ich eine alternative Lösung finden, die meinen Anforderungen entspricht (Zugriff einschränken basierend auf der Remote-IP-Adresse).

Ein einzelner Container, der auf Port 80/443 auf dem Host lauscht und dann an andere Container weiterleitet (mit entsprechenden HTTP-Headern, die ich nicht erwähnt habe, weil sie nicht in den Rahmen dieses Problems fallen), hat mein Problem gelöst, und ich wollte diese Lösung teilen für Personen, die mit einem ähnlichen Problem konfrontiert sind, weil überlagerte Netzwerke die Remote-IP-Adresse nicht weitergeben können

Oh, ich sehe, was du da getan hast..... Entschuldigung, das habe ich übersehen. Sie schneiden das Overlay-Netzwerk aus und hängen stattdessen Ihren nach außen gerichteten Container direkt an das Dienstnetzwerk (das automatisch erstellt wird, wenn Sie einen neuen Dienst starten, ohne ein Netzwerk anzugeben). Okay, ich denke das geht. Der zusätzliche Overhead ist die Aufgabe des Hinzufügens des Dienstnetzwerks zur docker-compose-Datei. Ich frage mich, was passiert, wenn der Host-Container gestartet wird und einer dieser Dienste nicht verfügbar ist?

In diesem Fall erhalten Sie eine 502.

Ich habe keine einzige docker-compose.yml, ich habe mehrere Stacks mit mehreren Diensten, die über ein überlagertes Netzwerk miteinander kommunizieren, und dann habe ich den öffentlich zugänglichen Dienst, der an den Hostserver bindet, aber immer noch Zugriff auf die alle anderen überlagerten Netzwerke, damit alle Anfragen weitergeleitet werden können.

Die Problemumgehung für den Hostmodus wurde zu diesem Problem bereits mehrmals erörtert. Obwohl es für einige eingeschränkte Szenarien (wie bestimmte Reverse-Proxy-Webdatenverkehr-Setups) in Ordnung sein kann, ist es keine allgemeine Lösung für dieses Problem. Bitte lesen Sie die vorherigen Beiträge, anstatt die gleichen "Lösungen" noch einmal zu wiederholen.

@darrellenns es gibt hier über 200 Kommentare, ich denke, es wäre besser, dieses Problem zu sperren und zu bereinigen, indem die grundlegende Lösung "nur

Ich glaube also, dass dieser Fehler die Fähigkeit von Traefiks beeinträchtigt, IPs auf die Whitelist zu setzen. Ist das korrekt?

Wie auch immer, für alle, die den Schwarmmodus ausführen möchten, ist dies ein Beispiel für die Verwendung des Hostmodus zum Veröffentlichen von Ports.

docker service create \
--name traefik \
--constraint=node.role==manager \
--publish mode=host,target=80,published=80 \
--publish mode=host,target=443,published=443 \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--mount type=bind,source=/home/$USER/dev-ops/logs,target=/dev-ops/logs \
--mount type=bind,source=/opt/data/traefik/traefik.toml,target=/traefik.toml \
--mount type=bind,source=/opt/data/traefik/acme.json,target=/acme.json \
--network traefik \
--label traefik.frontend.rule=Host:traefik.example.com \
--label traefik.port=8080 \
traefik \
--docker \
--docker.swarmMode \
--docker.watch \
--docker.exposedByDefault

@coltenkrauter Ich weiß nicht genau, was es betrifft, aber im Host-Modus kann ich nur eine Replik des traefik-Dienstes ausführen, und ich glaube nicht, dass es nur an mir liegt. Auf diese Weise muss ich der Traefik-Stabilität voll vertrauen, ohne auf die Schwarmmodus-Funktion für Dienste angewiesen zu sein.

Außerdem hat es, wie zuerst berichtet, nicht so viel mit Traefik-Sonderbedürfnissen zu tun, es wurde mit einem generischen http-Dienst getestet, der nicht die ursprüngliche IP erhält, dh der Docker-Schwarmmodus ist defekt (diese wichtige Funktion fehlt), und es sieht so aus, als ob sich niemand darum kümmert.

Und ich möchte dieses Zeug weiter kommentieren, weil ich hoffe, dass das Rauschen jemanden stört, der es lieber reparieren würde :) (sorry, es trifft von meinen Benutzern auch auf mich zu)

Im Host-Modus kann ich nur eine Replik des traefik-Dienstes ausführen, und ich glaube nicht, dass es nur an mir liegt. Auf diese Weise muss ich der Traefik-Stabilität voll vertrauen, ohne auf die Schwarmmodus-Funktion für Dienste angewiesen zu sein.

Sie können eine Instanz pro Host ausführen

Im Host-Modus kann ich nur eine Replik des traefik-Dienstes ausführen, und ich glaube nicht, dass es nur an mir liegt. Auf diese Weise muss ich der Traefik-Stabilität voll vertrauen, ohne auf die Schwarmmodus-Funktion für Dienste angewiesen zu sein.

Sie können eine Instanz pro Host ausführen

Ja, aber traefik ist gezwungen, auf dem Manager-Knoten zu arbeiten, weil es dies benötigt, um richtig zu funktionieren. Also ein Managerknoten, ein Host, eine Instanz

traefik kann Manager-Knoten auf verschiedene Weise bearbeiten, einschließlich der Verwendung von a
Docker-Socket-Proxy, Remote-Socket oder Traefik-Unternehmen. hier ist ein
Beispiel-Stack-Datei, wie das geht:
https://github.com/BretFisher/dogvscat/blob/master/stack-proxy-global.yml

Am Sa, 16. März 2019 um 17:25 Uhr Daniele Cruciani [email protected]
schrieb:

Im Host-Modus kann ich nur eine Replik des traefik-Dienstes ausführen, und ich tue es nicht
denke das liegt nur an mir. Auf diese Weise muss ich der Stabilität des Traefik voll vertrauen
ohne die Schwarmmodusfunktion für Dienste weiterzuleiten.

Sie können eine Instanz pro Host ausführen

Ja, aber traefik ist gezwungen, am Manager-Knoten zu arbeiten, weil es das braucht
richtig zu arbeiten. Also ein Managerknoten, ein Host, eine Instanz


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-473593956 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAwW31DHIwEJE1EqN3-8qj44WopocuQTks5vXWE_gaJpZM4Jf2WK
.

Es ist interessant, es zu wissen, aber siehe, diese Funktion ist auf Kubernetes verfügbar, aber nicht im Docker-Schwarmmodus, und Sie bestehen darauf, dass es Optionen zum Ausführen mehrerer Instanzen von traefik gibt, jedoch in mehreren Knoten, wenn ich mehrere Instanzen ausführen möchte einem einzelnen Knoten ist dies nicht möglich, da dies nicht unterstützt wird.
Außerdem darf jeder andere Dienst, der nicht nur Proxy-Anfragen verarbeitet, keinen Port zuordnen, da er eine spezielle Art von Konfiguration benötigt, die ihm jeden Host zuordnen muss, und er benötigt sowieso mehrere Knoten, mindestens einen pro Instanz .

Und so weiter und so weiter. Sie können diese Diskussion nach oben scrollen und andere dazu finden. Ich glaube nicht, dass es auf eine Demonstration reduziert werden kann, wie gut Sie eine Problemumgehung erstellen können, da diese Problemumgehung nach wie vor schwer zu warten und schwer zu befolgen ist. Und die gesamte Zeit, die für die Aufrechterhaltung der Problemumgehung für Sonderfälle aufgewendet wird, ist besser für die Behebung des Problems zu verwenden.

Auf der anderen Seite, wenn diese Art von Funktion ein Sicherheitsproblem für das Docker Swarm-Modell darstellt, markieren Sie es einfach als Wontfix und ich würde planen, zu Kubernetes zu wechseln. Es wird nur ausdrücklich gesagt, dass es nie passieren würde, und so kann jeder, wenn möglich, vor der Wahl des Docker-Schwarmmodus für jede Art von Knotenschwarm-Dinge Maßnahmen ergreifen

Es gibt viele Funktionen in Kubernetes, die nicht in Swarm sind und umgekehrt. Wir alle treffen Entscheidungen darüber, welcher Orchestrator für eine bestimmte Lösung verwendet wird, basierend auf vielen Faktoren, einschließlich Funktionen. Kein Tool löst alle Probleme/Bedürfnisse.

Ich bin nur ein Community-Mitglied, das versucht zu helfen. Wenn Ihnen die aktuellen Lösungen für dieses Problem nicht gefallen, sollten Sie nach anderen Lösungsmöglichkeiten suchen, möglicherweise mit so etwas wie Kubernetes. Dies ist ein vernünftiger Grund, einen Orchestrator einem anderen vorzuziehen, wenn Sie der Meinung sind, dass die Lösung von Kubernetes Ihnen besser gefällt.

Historisch gesehen schließen die Moby- und Swarm-Maintainer solche Probleme nicht, weil morgen jemand aus der Community eine PR mit einer Lösung für dieses Problem veröffentlichen könnte. Außerdem denke ich, dass die Diskussion der Möglichkeiten, das Problem bis dahin zu umgehen, eine gültige Verwendung dieses Thementhreads ist. :)

Obwohl ich kein Schwarm-Maintainer bin, kann ich sagen, dass das Team in der Vergangenheit keine zukünftigen Funktionspläne offenlegt, die über die PRs hinausgehen, die Sie derzeit sehen können, um Commits in den Repos zu erhalten.

Ich habe vergessen zu sagen, dass Ihr Kommentar natürlich willkommen ist (oder ich habe es auf eine obskure Weise gesagt, sorry). Aber ich bekräftige gerne den ursprünglichen

In der Zwischenzeit muss ich meiner Meinung nach einen Workaround machen, der einen Proxy-Container außerhalb des Swarm-Modus ausführt und ihn im Swarm-Modus an den veröffentlichten Port weiterleiten lässt (SSL-Beendigung sollte auch auf diesem Container durchgeführt werden), was den Zweck von Swarm unterbricht Modus für Selbstheilung und Orchestrierung.

Ich meine, dies "unterbricht den Zweck des Schwarmmodus", natürlich nur zu diesem speziellen Thema, ist genug, um mehr Aufmerksamkeit zu verdienen.

Ich versuche, mein Team dazu zu bringen, einen PR zu erstellen, der das Proxy-Protokoll hinzufügt
das Ingress-Netzwerk. Wir sind keine Golang-Programmierer, also finden wir es ein bisschen
knifflig.

Aber ich hoffe inständig, dass das Docker-Team dem besten und meisten zustimmt
kompatible (über das gesamte Ökosystem) Lösung besteht darin, das Proxy-Protokoll zu überlagern
Unterstützung des Ingress-Netzwerks.

Die Komplexität liegt darin, dass das Ingress-Netzwerk nicht nur
eigene Header einfügen, aber es muss die Tatsache unterstützen, dass es
Bereits eingefügte Upstream-Proxy-Protokoll-Header (zum Beispiel Google LB oder
AWS-ELB).

Am So, 17. März 2019, 12:17 Uhr Daniele Cruciani, [email protected]
schrieb:

Ich habe vergessen zu sagen, dass Ihr Kommentar natürlich willkommen ist (oder ich sagte es in a
undurchsichtiger Weg, sorry). Aber ich mag es, das Original @PanJ zu verstärken
https://github.com/PanJ-Bericht :

In der Zwischenzeit denke ich, dass ich einen Workaround machen muss, der a läuft
Proxy-Container außerhalb des Schwarmmodus und an den veröffentlichten Port weiterleiten lassen
im Schwarmmodus (SSL-Terminierung sollte auch auf diesem Container erfolgen), was
unterbricht den Zweck des Schwarmmodus für Selbstheilung und Orchestrierung.

Ich meine das "verstößt gegen den Zweck des Schwarmmodus", natürlich nur in diesem Zusammenhang
ein spezielles Thema, ist genug, um mehr Aufmerksamkeit zu verdienen.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-473621667 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESUwNWJsGKlLejcNzS2pR0awBB4OVlks5vXeTugaJpZM4Jf2WK
.

https://stackoverflow.com/questions/50585616/kubernetes-metallb-traefik-how-to-get-real-client-ip
Wie nach k8s gefragt, wo es geschichtet, vollständig und konfigurierbar ist

Für alle, die nginx auf Digitalocean mit Docker-Schwarm betreiben und versuchen, die echten $remote_addr anstelle von nur 10.255.0.2 in Ihren nginx-Protokollen zu erhalten; Sie können die Lösung von @coltenkrauter verwenden. Der Haken ist, dass Sie mit dieser Lösung nur einen nginx-Container auf dem Host ausführen können, was für die meisten Leute in Ordnung sein sollte.

Ändern Sie einfach Ihre docker-compose.yml Datei:

FALSCH

services:
  nginx:
    ports:
      - "80:80"
      - "443:443"

KORREKT

services:
  nginx:
    ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host

_edit: jetzt bekommen wir garantiert alle die richtige Antwort_

Die Nichtverwendung von Ingress ( mode: host ) ist keine Problemumgehung, wenn das Problem besagt, dass das Problem mit dem Ingress-Netzwerk auftritt.
Niemand würde nur einen einzigen Host als Reverse-Proxy verwenden. Sie möchten mehrere Hosts mit einer Floating-IP, und das Swarm-Mesh ist obligatorisch, um dieses Setup zu erreichen.

Vielleicht ist es nicht möglich, aber ich dachte, es wäre ein Workaround, die iptables-Regeln zu ändern, um MASQUERADE zu einem bestimmten Zeitpunkt in den INGRESS Ketten auszuführen, damit die echte Quell-IP erhalten bleibt. Gibt es nicht einige iptables/netfilter-Experten?

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

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             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     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         
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            

Können Sie als Alternative nicht einfach die ursprüngliche Quell-IP nehmen und einen X-Forwarded-For Header erstellen?

Niemand würde nur einen einzigen Host als Reverse-Proxy verwenden. Sie möchten mehrere Hosts mit einer Floating-IP, und das Swarm-Mesh ist obligatorisch, um dieses Setup zu erreichen.

Jeder Knoten im Schwarm kann eine Instanz des Reverse-Proxy ausführen und den Verkehr über ein Overlay-Netzwerk an die zugrunde liegenden Dienste weiterleiten (aber nur der Proxy kennt die ursprüngliche IP-Adresse).

Stellen Sie sicher, dass Sie den gesamten Thread lesen (ich sehe, dass GitHub einige nützliche Kommentare verbirgt, also müssen Sie diese erweitern :disappointed:);

Können Sie als Alternative nicht einfach die ursprüngliche Quell-IP nehmen und einen X-Forwarded-For Header erstellen?

Siehe https://github.com/moby/moby/issues/25526#issuecomment -367642600; X-Forwarded-For ist das L7-Protokoll; Der Schwarmeintritt ist L4, mit IPVS mit DNAT

@port22 im Allgemeinen sind wir uns einig, dass eine @sandys Vorschlag zu #25526 Kommentar

Als Alternative kann man nicht schwärmen, einfach die ursprüngliche Quell-IP nehmen und erstellen

ein X-Forwarded-For-Header?
Siehe #25526 (Kommentar)
https://github.com/moby/moby/issues/25526#issuecomment-367642600 ;
X-Forwarded-For ist das L7-Protokoll; Der Schwarmeintritt ist L4, mit IPVS mit DNAT

die richtige Lösung ist hier ein Proxy-Protokoll, das bei L4 injiziert wird. dort sind einige
relevante Pro- und Contra-Diskussionen in Envoy für denselben Anwendungsfall
https://github.com/envoyproxy/envoy/issues/4128 und
https://github.com/envoyproxy/envoy/issues/1031

Am Mi, 10.04.2019 um 01:40 Uhr Sebastiaan van Stijn <
[email protected]> schrieb:

Niemand würde nur einen einzigen Host als Reverse-Proxy verwenden. Du willst mehrere
Hosts mit einer Floating-IP, und das Swarm-Mesh ist zwingend erforderlich, um dies zu erreichen
erstellen.

Jeder Knoten im Schwarm kann eine Instanz des Reverse-Proxys ausführen und routen
Datenverkehr zu den zugrunde liegenden Diensten über ein Overlay-Netzwerk (aber nur die
Proxy würde die ursprüngliche IP-Adresse kennen).

Stellen Sie sicher, dass Sie den gesamten Thread lesen (ich sehe, dass GitHub einige nützliche verbirgt
Kommentare, also musst du diese erweitern 😞);

Als Alternative kann man nicht schwärmen, einfach die ursprüngliche Quell-IP nehmen und erstellen
ein X-Forwarded-For-Header?

Siehe #25526 (Kommentar)
https://github.com/moby/moby/issues/25526#issuecomment-367642600 ;
X-Forwarded-For ist das L7-Protokoll; Der Schwarmeintritt ist L4, mit IPVS mit DNAT


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-481415217 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAESU5KdnWQ21hJx_xzc-QROJiWbAlulks5vfPOigaJpZM4Jf2WK
.

Jeder Knoten im Schwarm kann eine Instanz des Reverse-Proxy ausführen

Dadurch entfällt die Funktion des Schwarm-Load-Balancers, um die es bei diesem Problem eigentlich geht.
Und mein Problem, um genau zu sein, ist, dass traefik nicht Cluster-agil ist. Es muss eigenständig ausgeführt werden, es sei denn, Sie verwenden consul als Konfigurations-Back-End, wodurch die maximalen Zertifikate auf ~ 100 begrenzt werden, was für mich nicht zutrifft. Sicher kann man sagen, dass dies kein Schwarmproblem ist, sondern das Problem von traefik. Fun Fact: traefik sagt, dies sei ein Konsulnproblem. konsul sagt: traefik macht es falsch.

@port22 im Allgemeinen sind wir uns einig, dass ein Workaround keine Lösung ist

Mein Punkt ist, dass das KEINEN Verwenden von Ingress kein Workaround ist, wenn Sie Ingress BENÖTIGEN. Eine Problemumgehung wäre etwas, das es ermöglicht, den Schwarm-Loadbalancer weiterhin zu verwenden, während die Quell-IP beibehalten wird, auch wenn dies einige Hacker erfordert.

Verwendung von IPVS mit DNAT

Daher dachte ich, dass dies mit MASQUERADE innerhalb der DNAT-Regel/-Kette möglich ist. ?

@ port22 Ich habe Ihren Punkt verstanden, aber Docker verwaltet seine Netzwerke selbst, ich habe versucht, es mit Shorewall zum Laufen zu bringen, aber die einzige Möglichkeit besteht darin, Ausnahmen für Docker-Regeln / -Ketten zu erstellen, und ich hatte keinen Erfolg mit dem Docker-Schwarmmodus (aber es ist für Docker im Schwarmmodus ok, soweit ich alle Dienste deaktiviere, außer denen, die in den Schwarm laufen)
Vielleicht sollte es Optionen wie für das Bridge-Netzwerk geben https://docs.docker.com/network/overlay/#customize -the-docker_gwbridge-interface
Um es einfach einzurichten, aber das Hauptproblem ist immer noch die fehlende Unterstützung im Overlay-Netzwerk. Optionen sind also nicht vorhanden, da diese ignoriert würden und dockerd Regeln neu schreibt, wenn sie von außen geändert werden.

Ich habe eine Funktionsanfrage für die Unterstützung des Proxy-Protokolls gestellt, um das Problem zu lösen
Problem in diesem Fehler.

Nur für den Fall, dass jemand seine Kommentare hinzufügen möchte.

https://github.com/moby/moby/issues/39465

Am Mi, 10 Apr, 2019, 21:37 Daniele Cruciani, [email protected]
schrieb:

@port22 https://github.com/port22 Ich habe deinen Punkt verstanden, aber Docker verwalten
seine Netzwerke von selbst, ich habe versucht, es mit Shorewall zum Laufen zu bringen, aber die
Die einzige Möglichkeit besteht darin, Ausnahmen für Docker-Regeln / -Ketten zu erstellen, und ich hatte keine
Erfolg mit Docker-Schwarmmodus (aber es ist in Ordnung für Docker im Schwarmmodus, da
Bisher habe ich alle Dienste deaktiviert, außer denen, die in den Schwarm laufen)
Vielleicht sollte es Optionen wie für Bridge-Netzwerke geben
https://docs.docker.com/network/overlay/#customize -the-docker_gwbridge-interface
um es einfach zu machen, dies einzurichten, aber das Hauptproblem ist immer noch das
fehlende Unterstützung im Overlay-Netzwerk. Optionen gibt es also nicht, weil
diese würden ignoriert, und dockerd schreibt Regeln neu, wenn sie von . geändert werden
außen.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526#issuecomment-481754635 oder stumm
der Faden
https://github.com/notifications/unsubscribe-auth/AAEsUxsVQ7m9uiYbHhNKMMtkhTZV6iTNks5vfgwygaJpZM4Jf2WK
.

Nach 3 Jahren keine Lösung?

Ich habe auch das gleiche Problem, aber mit Haproxy. Obwohl es in Ordnung ist, Proxy-Server im Host-Modus und HA mit Keepalive zu haben, wäre der einzige fehlende Teil der Lastausgleich, der meiner Meinung nach für einen einfachen Web-Proxy kein großes Problem darstellt. Es sei denn, komplizierte Skripte sind enthalten oder Proxy und Backend befinden sich nicht auf derselben physischen Maschine und der Netzwerkverkehr ist zu hoch für eine NIC und...

Ist es also wirklich nicht möglich, die Quell-IP-Adresse einer Anfrage von außerhalb eines Docker-Schwarms anstelle der privaten Adresse des internen Overlay-Netzwerks zu sehen? Immer noch?

@thaJeztah Kann uns jemand aus dem Docker Inc-Team über den Status dieses Problems

@thaJeztah https://github.com/thaJeztah Kann jemand auf der Docker Inc
Das Team informiert uns über den Status dieses Problems. Wird es noch in Erwägung gezogen
und/oder bearbeitet? Irgendeine ETA? Oder wird das seit Docker komplett ignoriert
Integration mit Kubernetes ? Es wurde vor fast 3 Jahren gemeldet :/

Es wäre wirklich gut, diese Aussage ("wird nicht reparieren") zu bekommen, damit ich es vollständig kann
eine Migration zu Kubernetes rechtfertigen. So eine Schande.

Vielen Dank.

>

Es gibt eine vorgeschlagene Verbesserungsanfrage, die dies beheben sollte - https://github.com/moby/moby/issues/39465

Bitte fügen Sie dort Ihre Gedanken und Kommentare hinzu

Ich habe mich bereits zu diesem Thema geäußert :-)

Dieser ist seit einiger Zeit ein Blocker für mich. Ich muss die IP-Adressen durchgehen und habe nach langem Suchen (wow fast 3 Jahre zusammen mit den anderen in diesem Thread ...) noch keine Lösung gefunden, die mit Swarm praktikabel ist.

Ich konnte Swarm aufgrund dieses Problems nicht in der Produktion verwenden und warte auf eine offizielle Antwort, ob dies hinzugefügt werden kann oder nicht. Wenn dies nicht hinzugefügt wird, sind alternative Lösungsvorschläge willkommen.

Wir haben das gleiche Problem mit traefik hinter haproxy. Ich war überrascht, als ich sah, dass dies seit 2016 254 Kommentare hat.

@Betriebsrat Warum nicht gleich traefik-Handle-Anfragen zulassen? Ist Haproxy wirklich notwendig oder nur eine Gewohnheit? Wenn Sie traefik im Host-Modus verfügbar machen, sehen Sie die Client-IP-Adressen und dann ist alles in Ordnung :)

Ich glaube, diese "Lösung" wurde mehrmals erwähnt, aber die Leute vermissen sie immer wieder.

Ich weiß auch, dass es manchmal keine Option ist, aber ich glaube, die meiste Zeit sollte dies möglich sein.

@ajardan diese Lösung habe ich ausprobiert und ist für mich nicht praktikabel, da ich mehr als einen einzelnen Host auf dem Frontend antworte. Im Idealfall möchte ich, dass der gesamte Schwarm die Anfragen weiterleiten kann. Ich stimme zu, dass für kleine Operationen einfach das Umschalten eines Dienstes in den host Modus und die Verwendung als Ingest-Server gut funktionieren kann.

Wenn wir so etwas wie traefik in den Host-Modus versetzen, werden die Vorteile, die wir versuchen, durch die Verwendung von swarm zu nutzen, jedoch in den meisten Fällen zunichte gemacht :(

@pattonwebz Der Hostmodus kann für einen Dienst aktiviert werden, der mehrere Container auf mehreren Hosts

Ich habe dieses Setup mit einem Dienst im globalen Modus verwendet, der jedoch auf Manager-Knoten beschränkt war, und es funktionierte für Zehntausende von Anfragen / s einwandfrei

Ich erkläre gerne, wenn weitere Details erforderlich sind.

@pattonwebz @ajardan Für all diese Fälle konfigurierbaren Haproxy-Dienst . haproxy verwendet in meinem Fall nur 2 MB RAM. Ich denke, das ist vernachlässigbar.

@pattonwebz Zusätzlich zu der obigen Lösung von https://hub.docker.com/r/decentralize/swarm-tcp-proxy im globalen Modus mit Hostnetzwerk ausführen, um dem eingehenden Datenverkehr PROXY-Protokollunterstützung hinzuzufügen. und leiten Sie es dann an Traefik weiter, das so konfiguriert ist, dass es die Proxy-Protokoll-Header entschlüsselt.

Es sollte nur eine Flagge als Teil des eigentlichen Docker Swarms sein, nicht all dies
komplizierte Lösungen IMHO.

Wir verwenden nur Haproxy, um Zertifikate zu verwalten und SSL zu entladen.
Die Leute vermissen immer wieder, dass die Lösung "Laufen ist Host-Modus" keine Lösung ist.
Sie möchten, dass es mit dem Ingress-Netzwerk zusammenarbeitet, um den Docker-Load-Balancing zu nutzen.
Der ganze Thread ist im Grunde ein 'use hostmode' -> 'nicht möglich aus "Gründen"'-Kreis, der nun seit 3 ​​Jahren besteht.

Ich werde mir swarm-tcp-proxy hier noch einmal als praktikable Alternative ansehen, aber wenn ich mir in der Vergangenheit ähnliche Dinge ansehe, war etwas bei solchen Ideen immer ein Schnäppchen für mich.

In einer perfekten Welt würde mein vorhandener (und gut funktionierender, mit Ausnahme der Möglichkeit, die echte Client-IP nicht abrufen zu können) Schwarm nur arbeiten und die IP-Daten weiterleiten, ohne dass zusätzliche Serviceschichten oder mehr Proxys über Proxys erforderlich sind.

Die Leute vermissen immer wieder, dass die Lösung "Laufen ist Host-Modus" keine Lösung ist.

Es ist keine Lösung an sich , kann aber sehr erfolgreich als Workaround verwendet werden (und wird verwendet). Sie können weiterhin den nativen Load Balancer von Docker verwenden – alles, was Sie tun müssen, ist dem Host-Netzwerk-Stack eine Schicht hinzuzufügen, bevor Sie das Service Mesh von Docker erreichen.

@Betriebsrat traefik kann Zertifikate und SSL sehr gut, daher bin ich mir immer noch nicht sicher, warum dies erforderlich ist.

Auch wie von @matthanley bereits erwähnt,

Dies ist sogar pro Dienst konfigurierbar, sodass Sie ziemlich flexibel sind.

Sie können versuchen, einen anderen Nginx-Server außerhalb des Docker-Schwarmclusters einzurichten und die Anfrage an den Schwarmdienst weiterzuleiten. in dieser Niginx conf fügen Sie einfach die Forward-Header hinzu. z.B.
Lage / {
proxy_pass http://phpestate;

    #Proxy Settings
    proxy_redirect     off;
    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
    proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

Es scheint keine Lösung zu geben, um im Docker-Schwarmmodus eine echte Client-IP zu erhalten.

Wir haben das gleiche Problem gesehen und haben es umgangen, indem wir Folgendes implementiert haben:
https://github.com/moby/moby/issues/25526#issuecomment -475083415

Es ist eine nicht ideale Lösung, da wir nicht mehrere Ingress-Container auf einem einzigen Knoten ausführen können (vermutlich sind sie jetzt global).

Die Schwierigkeit besteht darin, dass Docker mit TCP/UDP handelt, während dies ein HTTP-Protokollproblem ist. Zumindest wünschte ich, dass Docker die Quell-IP als Remote-Host "fälschen" würde, anstatt seine eigene interne IP aus dem Schwarm-Mesh zu geben ... aber das würde wahrscheinlich die Dinge kaputt machen, da der Rückverkehr an den falschen Ort gehen würde.

Der einfachste Weg wäre, den Header für die ursprüngliche IP für jede http-Anfrage hinzuzufügen.

Richtig. Nur um genau zu sein - als Proxy-Protokoll-Header, der auf l4 funktioniert
und l7 und wird von den meisten bekannten Anwendungssoftwares akzeptiert (sowie die
große Cloud-Anbieter).

Ich habe dafür einen separaten Bug eingereicht, der mit ein paar Kommentaren verlinkt ist
Oben. Fügen Sie diesen Fehler hinzu, wenn Sie interessiert sind

Am Do, den 5. September 2019, 18:56 Uhr schrieb Vladimir,

Der einfachste Weg wäre, den Header für die ursprüngliche IP für alle hinzuzufügen
http-Anfrage.


Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/moby/moby/issues/25526?email_source=notifications&email_token=AAASYU7APUNJPLZ6AJ6XXMDQIECIJA5CNFSM4CL7MWFKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW61LNMVDZLOKTORDN5WWZ
oder den Thread stumm schalten
https://github.com/notifications/unsubscribe-auth/AAASYU4VZGKUFLL5STZ44GDQIECIJANCNFSM4CL7MWFA
.

Es ist 2019 und das ist immer noch ein Problem? Es macht IP-Whitelisting auf traefik zu einem Schmerz. Ich sollte nicht auf jedem Knoten Host-Ports benötigen.

@kaysond unsere Position war es, Swarm aufzugeben. Wir sind auf AWS und ECS umgestiegen. Es tut mir nur leid, dass ich nichts Konstruktiveres posten kann, aber letztendlich brauchen wir etwas, das funktioniert; Dies ist nicht der einzige große Swarm-Fehler (oder das Fehlen von Funktionen), der uns betrifft, und andere, die in den letzten Jahren keine offensichtliche Korrektur/Feedback erhalten haben. Sehr enttäuschend, aber da.

@jmkgreen wir sind in der gleichen Position und haben die letzten 6+ Monate damit verbracht, sich vom Docker-Schwarm zu anderen Dingen zu bewegen, da dieses Problem immer noch besteht. Ich habe bereits Dutzende von Stunden selbst und Hunderte von Stunden an Teammitgliedern darin investiert, ohne jemals einen akzeptablen Workaround zu finden. Die Bindung an alle Host-Ports verfehlt den Zweck unserer Floating-LBs völlig :(

Was ist dein Problem mit der Problemumgehung? Sie deklarieren Ihren Dienst im Hostmodus + global und richten Ihren LB so ein, dass er alle Knoten trifft, es funktioniert. Da der Proxy leichtgewichtig ist (ich verwende nginx, weil ich https-Offloading und andere Dinge mache), ist die Tatsache, dass er auf jedem Server bereitgestellt wird, kein Problem, da er weniger als 1% einer Serverressource verwendet. Ich kann Ihnen helfen, wenn Sie während des Vorgangs auf einen Fehler stoßen ([email protected]).

Was ist dein Problem mit der Problemumgehung? Sie deklarieren Ihren Dienst im Hostmodus + global und richten Ihren LB so ein, dass er alle Knoten trifft, es funktioniert.

@RemiBou Wenn der Proxy selbst aktualisiert/neu gestartet werden muss, erkennt der externe Load Balancer den Ausfall nicht sofort und sendet weiterhin Anfragen an Knoten, auf denen der Proxy noch neu gestartet wird. Je nach externer LB-Konfiguration kommt es also zu einem ~30-Sekunden-Ausfall.

Es gibt in Swarm auch keine Möglichkeit, einen Hook in den Dienstaktualisierungsprozess einzufügen, um den externen Load Balancer aufzurufen und einen Knoten während des Updates außer Betrieb zu nehmen. Sie können auch kein Skript auslösen innerhalb des Behälters zu laufen , bevor es aktualisiert wird (zum Beispiel ein „zu entfernen i_am_healthy “ Flagge und lassen Sie die externen LB entdecken , es wird außer Betrieb durch Polling).

Was ist dein Problem mit der Problemumgehung?

Mein Problem ist, dass es mir mit dieser Problemumgehung unmöglich ist, mehrere des gleichen Dienstes (oder mehrere Dienste, die die gleichen Ports benötigen) auf dem Host auszuführen. Das ist eine Notwendigkeit für Projekte, an denen ich arbeite.

In der Tat, aber können Sie nicht einen Proxy-Dienst bereitstellen, der nur dies tut und dann, wenn sich die IP im Schwarm befindet, sie als http-Header an Ihre anderen Dienste weiterleiten kann?

In der Tat, aber können Sie nicht einen Proxy-Dienst bereitstellen, der nur dies tut und dann, wenn sich die IP im Schwarm befindet, sie als http-Header an Ihre anderen Dienste weiterleiten kann?

Ja ... und solange dieser Thin-Proxy-Dienst nie neu konfiguriert oder aktualisiert werden muss, ist es möglich, die dahinter liegenden Komponenten mit dem Swarm LB zu aktualisieren, um Ausfallzeiten zu vermeiden.

Jemand wies auf https://hub.docker.com/r/decentralize/swarm-tcp-proxy hin , das Haproxy verwendet, um es zu erledigen.

Aber irgendwie ein Schmerz. Und wenn Sie den Proxy aktualisieren müssen, haben Sie immer noch Ausfallzeiten.

@ ms1111 Nginx-Docker-Image-Start in wenigen Sekunden, und wenn dieser Dienst nur diesen Teil verwaltet, müssen Sie ihn nicht oft aktualisieren. IMHO ist der Nachteil nicht so wichtig, aber es könnte in Ihrem Fall anders sein

Was ist dein Problem mit der Problemumgehung?

In unserem Fall ist es die Kombination dieser Problemumgehung mit der Unfähigkeit, einen Host-exponierten Port an eine bestimmte IP-Adresse zu binden. Stattdessen wird der Port aller internen Dienste, die die IP des echten Besuchers benötigen und das PROXY-Protokoll unterstützen, auf 0.0.0.0 auf dem Host verfügbar gemacht, was nicht optimal ist.

Ein anderer ist der nicht zu vernachlässigende Leistungseinbruch, wenn Sie Hunderte von neuen Verbindungen pro Sekunde haben - alle exponierten Ports sind eigentlich DNAT-Regeln in iptables, die conntrack erfordern und andere Probleme haben (trifft auch k8s, aber Swarm hat dies .) zusätzliches Niveau von NATs, die es noch schlimmer machen).

An Docker,

Wach auf! Es gibt ein offensichtliches Problem, wenn man bedenkt, wie viele Personen an diesem Problem beteiligt sind (es gibt andere mit der gleichen Ursache). Alles, was wir bekommen, sind Leute, die immer wieder wiederholen, dass es eine Problemumgehung gibt, obwohl schon einige Male erklärt wurde, warum diese Problemumgehung keine Lösung ist. Das Wort "Workaround" weist darauf hin, dass es sich um eine vorübergehende Sache handelt, die später behoben wird. Es ist über 3 Jahre her, dass das Problem erstellt wurde und für die ganze Zeit lautet die Antwort "Es gibt eine Problemumgehung".

An alle Swarm-Benutzer,

Seien wir realistisch. Die traurige Wahrheit ist, dass sich niemand, einschließlich Docker, wirklich um Swarm kümmert. Alle sind zu k8s gewechselt und es gibt keine "richtigen" Investitionen in Swarm. Das Projekt ist lebenserhaltend und wartet auf den Tod. Erwarten Sie also nicht, dass dieses Problem behoben wird. Seien Sie schlau und wechseln Sie zu k8s.

Dieses Problem scheint viel zu lange ignoriert zu werden. Es scheint nie umgesetzt zu werden. Schneiden Sie einfach auf den Punkt und verwenden Sie k8s.

@leojonathanoh kannst du bitte erläutern, wie genau k8s dieses spezielle Problem löst :)?

Einfach: Proxy-Protokoll

@ajatkj Wie gesagt. Oder, wenn dies nicht möglich ist, einen externen Load Balancer und externalTrafficPolicy: Local auf der Ressource Service . Das ist alles, was ich hier sagen werde. Und ich melde mich vom Thread ab.

Warum erwarten die Leute, dass andere die Arbeit für sie erledigen?

Ich würde gerne der Held sein und mich darum kümmern, aber die Realität ist, dass ich an vielen anderen Dingen arbeite und das hat keine Auswirkungen auf meinen Alltag. Beeinflusst das Ihren Alltag? Wir würden uns über Hilfe bei der Lösung des Problems freuen!

Ich habe mir das auch mehrmals angesehen und es scheint wirklich keine Möglichkeit zu geben, dies mit IPVS NAT zum Laufen zu bringen, was das magische Schwarm-Routing verwendet.

Ich stimme zu, dass k8s hier viel flexibler ist. Wenn es Ihren Bedürfnissen besser entspricht, verwenden Sie es.
Sich zu beschweren, dass es nicht behoben ist und dann mit dem Wechsel auf k8s zu drohen, hat in unserem Issue-Tracker wirklich keinen Platz und ist im Allgemeinen nicht hilfreich.

Menschen helfen mit ihrem Wissen. Nicht alle haben die Fähigkeiten, den Code selbst zu ändern, daher erstellen sie Probleme wie diese, um einen Konsens über die erforderliche Änderung zu erzielen.

Niemand hier argumentiert, dass Sie die Änderungen speziell vornehmen müssen, aber selbst bei den von @sandys aufgeworfenen Problemen zum Proxy-Protokoll stimmte das Kernteam den Änderungen zu. Wie kann also jemand daran arbeiten, wenn er nicht weiß, ob die Änderung akzeptiert wird?

Der beste Weg ist, einen Vorschlag zu machen, dh. Wie soll die Architektur nach getaner Arbeit aussehen? Was bringt es? Was verlieren wir?

Der beste Weg ist, einen Vorschlag zu machen, dh. Wie soll die Architektur nach getaner Arbeit aussehen? Was bringt es? Was verlieren wir?

Hier schon fertig: #39465

versuche host-mode-networking

Bitte den ganzen Thread vor dem Kommentieren lesen

"Verwenden Sie das Proxy-Protokoll", obwohl es in der Tat interessant ist, legt nicht fest, was
Änderungen an der Codebasis müssen vorgenommen werden.

Vielleicht ist dies eine naive Frage, aber warum ist es notwendig, die Quell-IP neu zu schreiben? Würde der Verkehr nicht sowieso über das Standard-Gateway der Schnittstelle zurückgegeben werden? Selbst wenn es über den Schwarm-Load-Balancer kam, könnte das Gateway es einfach über den Load-Balancer zurückgeben, der bereits weiß, woher der Verkehr kam...

Vielleicht ist dies eine naive Frage, aber warum ist es notwendig, die Quell-IP neu zu schreiben? Würde der Verkehr nicht sowieso über das Standard-Gateway der Schnittstelle zurückgegeben werden? Selbst wenn es über den Schwarm-Load-Balancer kam, könnte das Gateway es einfach über den Load-Balancer zurückgeben, der bereits weiß, woher der Verkehr kam...

Es ist notwendig zu wissen, von welcher IP die Anfrage kommt. Vielleicht möchte ein bestimmter Benutzer die IP begrenzen, und Sie können dies nicht außerhalb des laufenden Dienstes tun, dh traefik kennt den Inhalt der Anfrage nicht, die möglicherweise angeben, welcher Benutzer sie stellt, daher kann er einige Benutzer nicht ausschließen und akzeptiert andere basieren nur auf IP (da die Richtlinie in diesem Beispiel IP + Request-Content => Allow/Disallow ist).

Oder, häufiger, nur zum Protokollieren der Verbindung. Ich muss dem Kunden meine Servicenutzung in Rechnung stellen und in tabellarischer Form angeben: Zeitpunkt der Anfrage, Ressourcenmenge, Quell-IP der Anfrage. Fast alle in Rechnung gestellten Dienste liefern diese Art von Bericht.

Ich glaube du hast meine Frage falsch verstanden. Ich verstehe, warum Dienste die wahre Quell-IP sehen möchten. Ich möchte wissen, warum Docker es ändert, bevor es in einen Container gelangt

Am 1. November 2019, 01:47 Uhr, um 01:47 Uhr schrieb Daniele Cruciani [email protected] :

Vielleicht ist das eine naive Frage, aber warum ist es notwendig, umzuschreiben?
die Quell-IP zu Beginn? Wäre der Verkehr nicht über die
Standard-Gateway der Schnittstelle sowieso? Auch wenn es über die Schwarmladung kam
Balancer, das Gateway könnte es einfach über den Load Balancer zurückgeben, der
weiß schon woher der Verkehr kam...

Es ist notwendig zu wissen, von welcher IP die Anfrage kommt. Vielleicht ein
Ein bestimmter Benutzer möchte die IP begrenzen, und Sie können dies nicht außerhalb der
Dienst läuft, dh traefik kennt den Inhalt der Anfrage nicht
das kann angeben, welcher Benutzer es erstellt, kann also einige nicht ausschließen
Benutzer und akzeptiert andere nur auf der Grundlage der IP (weil die Richtlinie in diesem
Beispiel ist ip + request-content => erlauben/verbieten).

Oder, häufiger, nur zum Protokollieren der Verbindung. Ich muss dem Kunden eine Rechnung stellen
für meine Servicenutzung, und ich muss in tabellarischer Form angeben: Zeitpunkt von
Anfrage, Ressourcenmenge, Quell-IP der Anfrage. Fast jeder Service
in Rechnung gestellt stellen diese Art von Bericht zur Verfügung.

--
Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an:
https://github.com/moby/moby/issues/25526#issuecomment -548711563

@kaysond Kein guter Ort, um zu fragen.

Sie stellen im Wesentlichen zwei Fragen,

  1. Wie IPVS technisch funktioniert und
  2. Warum libnetwork zu Beginn IPVS wählt

Beides ist schwer unterschiedlich zu beantworten.

Ich frage mich, wo diese Fragen am besten gestellt werden, weil ich jetzt sehr fasziniert bin, die Geschichte dieser Entscheidungen zu lesen und wie alles funktioniert, damit ich hier mehr Kontext erhalten kann.

@kaysond Kein guter Ort, um zu fragen.

Sie stellen im Wesentlichen zwei Fragen,

  1. Wie IPVS technisch funktioniert und
  2. Warum libnetwork zu Beginn IPVS wählt

Beides ist schwer unterschiedlich zu beantworten.

irgendein Update?

Ich verfolge diesen Thread jetzt schon eine Weile, weil ich über das gleiche Problem gestolpert bin, aber nachdem ich ein paar Whoami-Container im Schwarm hinter traefik aufgestellt hatte, sah ich, dass es funktionierte. Die Sache war, dass wir hinter Cloudflare standen und die CF-Header weiterleiten mussten. (ja, wir verwenden ipvs und unsere Dienste werden im Schwarm repliziert).

Habe es gerade nochmal probiert mit:

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.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

und die folgenden Docker komponieren:

version: "3.3"

services:

  traefik:
    image: "traefik:v2.0.0-rc3"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.swarmMode=true"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  whoami:
    image: "containous/whoami"
    container_name: "simple-service"
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.whoami.rule=HostRegexp(`{any:.*}`)"
        - "traefik.http.routers.whoami.entrypoints=web"
        - "traefik.http.services.whoami.loadbalancer.server.port=80"

Whoami-Ausgabe war:

Hostname: 085c373eb06d
IP: 127.0.0.1
IP: 10.0.1.10
IP: 172.19.0.4
RemoteAddr: 10.0.1.11:51888
GET / HTTP/1.1
Host: testserver.nub.local
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Dnt: 1
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 10.0.0.2
X-Forwarded-Host: testserver.nub.local
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: ad14e372f6e9
X-Real-Ip: 10.0.0.2

Also nein. es funktioniert immer noch nicht

Aus Neugier .... kann mir ein Entwickler den Code zeigen, der das Schwarmnetzwerk verwaltet?

Habe es gerade nochmal probiert mit:

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.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

und die folgenden Docker komponieren:

version: "3.3"

services:

  traefik:
    image: "traefik:v2.0.0-rc3"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.swarmMode=true"
      - "--providers.docker.endpoint=unix:///var/run/docker.sock"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  whoami:
    image: "containous/whoami"
    container_name: "simple-service"
    deploy:
      labels:
        - "traefik.enable=true"
        - "traefik.http.routers.whoami.rule=HostRegexp(`{any:.*}`)"
        - "traefik.http.routers.whoami.entrypoints=web"
        - "traefik.http.services.whoami.loadbalancer.server.port=80"

Whoami-Ausgabe war:

Hostname: 085c373eb06d
IP: 127.0.0.1
IP: 10.0.1.10
IP: 172.19.0.4
RemoteAddr: 10.0.1.11:51888
GET / HTTP/1.1
Host: testserver.nub.local
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.5
Dnt: 1
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 10.0.0.2
X-Forwarded-Host: testserver.nub.local
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Server: ad14e372f6e9
X-Real-Ip: 10.0.0.2

Also nein. es funktioniert immer noch nicht

Sie können traefik by host mode verwenden, um echte IP zu erhalten

ports:
      - target: 80
        published: 80
        mode: host
      - target: 443
        published: 443
        mode: host

noch geöffnet?
2020-05-08

noch geöffnet?
2020-05-08

Ja, noch geöffnet. In dem Thread werden architektonische Probleme erwähnt, die verdeutlichen, warum dies nicht so einfach gelöst werden kann, wie es oberflächlich erscheinen sollte. An diesem Punkt ist es wahrscheinlich, dass diese Probleme wahrscheinlich nicht gelöst werden können.

Wenn Sie eine echte Benutzer-IP benötigen, werden im Thread hier einige Alternativen gepostet, die möglicherweise geeignet sind. Der HOST-Modus für Dienste scheint der einfachste Ansatz zu sein, ist jedoch für einige nicht geeignet, die Skalierbarkeit auf einzelnen Knoten benötigen.

Wir hatten Erfolg mit dem PROXY-Protokoll mit DigitalOcean LB -> Traefik -> Apache-Container. Der Apache-Container konnte die echten IPs der Benutzer protokollieren, die auf den Dienst zugreifen. Theoretisch sollte es funktionieren, solange alle Proxy-Schichten das PROXY-Protokoll unterstützen.

https://docs.traefik.io/v1.7/configuration/entrypoints/#proxyprotocol

Der Traefik-Dienst befindet sich in einem Docker-Netzwerk namens 'ingress', der Apache-Dienst hat ein eigenes Stack-Netzwerk, ist aber auch als extern Teil des 'ingress'-Netzwerks.

https://autoize.com/logging-client-ip-addresses-behind-a-proxy-with-docker/

2020 und immer noch nicht behoben, was für ein Drag. scheint ein sehr wichtiges Feature zu sein

Dies ist sehr nötig. Setzen Sie einige Host-Modus ist nur ein Patch, manchmal ist es notwendig, NGINX hinter dem Netzwerk auszuführen (je nach Verwendung und Einrichtung). Bitte beheben Sie dies.

Ich denke, ein Workaround dafür und um einen Docker-Schwarm laufen zu lassen, ohne den Host einzustellen, besteht darin, die IP auf der Client-Seite zu erhalten. Ex. js für Web- und mobile Clients verwenden und nur von vertrauenswürdigen Quellen akzeptieren. Ex. js -> get ip, backend akzeptiert nur ips, die user-token oder etc. enthalten. ip kann im Header gesetzt und über https verschlüsselt werden. Allerdings weiß ich nichts über die Leistung

@Damidara16 genau das wollen wir nicht. Ist wirklich unsicher, das zu tun. Sie können es nach Belieben umgehen.

Schade, dass dies noch ein offenes Problem ist, leider ... es sieht nicht so aus, als ob es bald behoben wird

Schade, dass dies noch ein offenes Problem ist, leider ... es sieht nicht so aus, als ob es bald behoben wird

Ich denke, es wird bald vom Bot geschlossen. Seit github diese Funktion gestartet hat, können viele Fehler ignoriert werden.

Schade, dass dies noch ein offenes Problem ist, leider ... es sieht nicht so aus, als ob es bald behoben wird

Ich denke, es wird bald vom Bot geschlossen. Seit github diese Funktion gestartet hat, können viele Fehler ignoriert werden.

Dies ist die beste Funktion für aufgeblähte Teams von Unternehmen, um die Kontrolle über die Community zu erlangen.

Die Chance, dass dies jemals behoben wird, ist sehr gering. AFAIK hält jeder für sich, dass k8s das "Rennen" gewonnen haben und ein Schwarm nicht benötigt wird, aber ich würde sagen, dass beide nebeneinander existieren und je nach den Notwendigkeiten und Fähigkeiten des Teams, das diese verwendet, richtig verwendet werden können. RIP-Schwarm :)

Ich verwende ein verwaltetes HAIP, aber Sie könnten vor dem Schwarm etwas anderes verwenden, einen eigenständigen Nginx-Load-Balancer, der auf die IPs Ihres Schwarms verweist.
https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/

In Ihrem Schwarm benötigt der Reverse-Proxy dies:

server {
        listen 443 ssl proxy_protocol;
        location / {
        proxy_set_header   X-Real-IP $proxy_protocol_addr;  # this is the real IP address 

Wenn Sie einen Schwarm ausführen, benötigen Sie einen Load Balancer, um die Anfragen an Ihren Schwarm (oder Sticky usw.) zu übertragen.

Bisher mag diese Architekturentscheidung wie ein "fehlendes Stück" erscheinen, dies erhöht jedoch die Flexibilität, indem Optionen bereitgestellt werden und die Notwendigkeit beseitigt wird, integrierte Funktionen zu deaktivieren, um sie durch etwas Passenderes für die Anwendungsanforderungen zu ersetzen.

Ich glaube, ich habe möglicherweise eine Problemumgehung für dieses Problem gefunden, mit der _aktuellen_ Einschränkung, dass alle Dienstcontainerreplikate auf einem einzigen Knoten bereitgestellt werden müssen, zum Beispiel mit --constraint-add='node.hostname==mynode' oder mit a Gruppe von Schwärmen, die jeweils aus einem einzigen Knoten bestehen.

Das Problem

Das zugrunde liegende Problem wird durch die SNAT-Regel in der iptables-nat-Tabelle im ingress_sbox-Namespace verursacht, die bewirkt, dass alle eingehenden Anfragen von Containern gesehen werden, die die IP-Adresse des Knotens im Ingress-Netzwerk haben (zB 10.0.0.2, 10.0.0.3, . .., in der Standardkonfiguration des Ingress-Netzwerks), zB:

iptables -t nat -A POSTROUTING -d 10.0.0.0/24 -m ipvs --ipvs -j SNAT --to-source 10.0.0.2

Das Entfernen dieser SNAT-Regel bedeutet jedoch, dass, während Container weiterhin eingehende Pakete empfangen, die nun von der ursprünglichen Quell-IP stammen, ausgehende Pakete, die an die ursprüngliche Quell-IP zurückgesendet werden, über das Standard-Gateway des Containers gesendet werden, das sich nicht im selben Eingangsnetzwerk befindet, sondern auf das docker_gwbridge-Netzwerk (zB 172.31.0.1), und diese Pakete gehen dann verloren.

Die Problemumgehung

Die Problemumgehung umfasst also: 1. Entfernen (eigentlich Sperren) dieser SNAT-Regel im Namensraum ingress_sbox; und 2. Erstellen einer Richtlinien-Routing-Regel für Schwarmdienst-Container, die diese ausgehenden Pakete zurück zur IP-Adresse des Eingangsnetzwerks des Knotens zwingt, zu der sie zurückgegangen wäre (zB 10.0.0.2); 3. Automatisieren des Hinzufügens der Richtlinien-Routing-Regeln, so dass sie bei jedem neuen Service-Container sofort nach der Erstellung installiert werden.

  1. Um die SNAT-Regel zu unterbinden, erstellen wir weiter vorne in der Tabelle eine Regel, die verhindert, dass die übliche SNAT erreicht wird:
nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT

(Wir machen es auf diese Weise, anstatt nur die vorhandene SNAT-Regel zu löschen, da Docker die SNAT-Regel während der Erstellung eines Dienstes anscheinend mehrmals neu erstellt. Dieser Ansatz ersetzt diese Regel nur, was sie widerstandsfähiger macht).

  1. So erstellen Sie die Routingregel für die Containerrichtlinie:
docker inspect -f '{{.State.Pid}}' <container-id>
nsenter -n -t $NID bash -c "ip route add table 1 default via 10.0.0.2 && ip rule add from 10.0.0.0/24 lookup 1 priority 32761"
  1. Zusammen mit docker event automatisieren wir schließlich den Prozess der Änderung der SNAT-Regeln, der Suche nach neu gestarteten Containern und des Hinzufügens der Richtlinien-Routing-Regeln über dieses ingress-routing-daemon Skript:
#!/bin/bash

# Ingress Routing Daemon
# Copyright © 2020 Struan Bartlett
# --------------------------------------------------------------------
# Permission is hereby granted, free of charge, to any person 
# obtaining a copy of this software and associated documentation files 
# (the "Software"), to deal in the Software without restriction, 
# including without limitation the rights to use, copy, modify, merge, 
# publish, distribute, sublicense, and/or sell copies of the Software, 
# and to permit persons to whom the Software is furnished to do so, 
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be 
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
# SOFTWARE.
# --------------------------------------------------------------------
# Workaround for https://github.com/moby/moby/issues/25526

echo "Ingress Routing Daemon starting ..."

read INGRESS_SUBNET INGRESS_DEFAULT_GATEWAY \
  < <(docker inspect ingress --format '{{(index .IPAM.Config 0).Subnet}} {{index (split (index .Containers "ingress-sbox").IPv4Address "/") 0}}')

echo INGRESS_SUBNET=$INGRESS_SUBNET
echo INGRESS_DEFAULT_GATEWAY=$INGRESS_DEFAULT_GATEWAY

# Add a rule ahead of the ingress network SNAT rule, that will cause the SNAT rule to be skipped.
echo "Adding ingress_sbox iptables nat rule: iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT"
while nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -D POSTROUTING -d 10.0.0.0/24 -m ipvs --ipvs -j ACCEPT; do true; done 2>/dev/null
nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT

# Watch for container start events, and configure policy routing rules on each container
# to ensure return path traffic from incoming connections is routed back via the correct interface.
docker events \
  --format '{{.ID}} {{index .Actor.Attributes "com.docker.swarm.service.name"}}' \
  --filter 'event=start' \
  --filter 'type=container' | \
  while read ID SERVICE
  do
    if [ -n "$SERVICE" ]; then

      NID=$(docker inspect -f '{{.State.Pid}}' $ID)
      echo "Container ID=$ID, NID=$NID, SERVICE=$SERVICE started: applying policy route."
      nsenter -n -t $NID bash -c "ip route add table 1 default via $INGRESS_DEFAULT_GATEWAY && ip rule add from $INGRESS_SUBNET lookup 1 priority 32761"
    fi
  done

Wenn nun Anfragen an den veröffentlichten Ports für den einzelnen Knoten eintreffen, sehen dessen Container die ursprüngliche IP-Adresse der Maschine, die die Anfrage stellt.

Verwendungszweck

Führen Sie das obige ingress-routing-daemon als Root auf _jedem und jedem_ Ihrer Schwarmknoten aus, _bevor_ Sie Ihren Dienst erstellen. (Wenn Ihr Dienst bereits erstellt wurde, stellen Sie sicher, dass Sie ihn auf 0 skalieren, bevor Sie ihn auf eine positive Anzahl von Replikaten zurückskalieren.) Der Daemon initialisiert iptables, erkennt, wenn Docker neue Container erstellt, und wendet auf jeden neuen Container neue Routing-Regeln an.

Tests, Anwendungsfälle und Einschränkungen

Das Obige wurde mit mehreren Replikaten getestet, die auf einen einzelnen Knoten beschränkt sind, auf einem Dienst, der auf einem Schwarm mit mehreren Knoten ausgeführt wird.

Es wurde auch mit mehreren Knoten getestet, von denen jeder einen separaten Pro-Knoten-Dienst hat, der auf diesen Knoten beschränkt ist, aber dies ist mit der Einschränkung verbunden, dass für jeden Pro-Knoten-Dienst unterschiedliche veröffentlichte Ports verwendet werden müssen. Trotzdem könnte das für einige Anwendungsfälle funktionieren.

Die Methode sollte auch mit mehreren Knoten funktionieren, wenn jeder als einzelner Knoten in einem eigenen Schwarm konfiguriert wurde. Dies beinhaltet die Einschränkung, dass die Docker-Schwärme nicht mehr verwendet werden können, um Container auf Knoten zu verteilen, aber es könnten noch andere Verwaltungsvorteile der Verwendung von Docker-Diensten wie Containerreplikat und Lifecycle-Management geben.

Verbesserung der Problemumgehung, um weitere Anwendungsfälle zu adressieren

Mit der Weiterentwicklung sollte diese Methode in der Lage sein, auf mehrere Knoten zu skalieren, ohne separate Dienste pro Knoten zu benötigen oder den Schwarm aufzuteilen. Ich kann mir zwei mögliche Ansätze vorstellen: 1. Anordnen für Docker oder einen maßgeschneiderten Daemon, um alle nicht-lokalen IPs aus der ipvsadm-Tabelle jedes Knotens zu entfernen. 2. Erweitern der Richtlinien-Routingregeln, um das Zurückleiten von Ausgabepaketen an den richtigen Knoten zu ermöglichen.

Für 1 könnten wir ipvsadm -S -n abfragen, um nach neuen IPs zu suchen, die jedem Dienst hinzugefügt wurden, prüfen, ob jede lokal ist, und alle entfernen, die es nicht sind. Dies würde es jedem Knoten ermöglichen, als Load Balancer für seine eigenen Container innerhalb des Gesamtdienstes zu fungieren, jedoch ohne dass Anfragen, die einen Knoten erreichen, an einen anderen weitergeleitet werden können. Dies würde sicherlich meinen eigenen Anwendungsfall erfüllen, bei dem wir unseren eigenen IPVS-Load-Balancer vor einer Reihe von Servern haben, auf denen jeweils eine Webanwendung ausgeführt wird, die wir durch mehrere containerisierte Instanzen derselben Anwendung mit Load-Balancing ersetzen möchten , damit wir Updates ausrollen können, ohne einen ganzen Server zu verlieren.

Für 2 könnten wir iptables verwenden, um ein Pro-Knoten-TOS in der iptable ingress_sbox jedes Knotens zuzuweisen (zum Beispiel dem letzten Byte der Knoten-Eingangsnetzwerk-IP); Ordnen Sie dann im Container an, den TOS-Wert einer Verbindungsmarkierung und dann von einer Verbindungsmarkierung auf eine Firewallmarkierung für ausgehende Pakete zuzuordnen, und wählen Sie für jede Firewallmarkierung eine andere Routingtabelle aus, die die Pakete zurück zum Ursprungsknoten leitet. Die Regeln dafür werden etwas klobig sein, aber ich kann mir vorstellen, dass sie auf 2-16 Knoten gut skalieren sollten.

Ich hoffe, das obige ist nützlich. Ich werde auch (2) versuchen, und wenn ich Fortschritte mache, werde ich ein weiteres Update veröffentlichen.

Unten ist eine verbesserte Version des Ingress-Routing-Daemons, ingress-routing-daemon-v2 , der das Richtlinien-Routing-Regelmodell erweitert, sodass jeder Container seine Ausgabepakete ohne SNAT an den richtigen Knoten zurückleiten kann.

Das verbesserte Modell

Zusätzlich zur Sperrung der SNAT-Regel gemäß dem vorherigen Modell erfordert das neue Modell eine iptables-Regel im ingress_sbox-Namespace auf jedem Knoten, den Sie als IPVS-Load-Balancer-Endpunkt verwenden möchten (also normalerweise Ihre Manager-Knoten oder eine Teilmenge davon). Manager-Knoten), die allen Paketen, die für einen beliebigen Knoten im Eingangsnetzwerk bestimmt sind, einen TOS-Wert pro Knoten zuweist. (Wir verwenden das letzte Byte der Ingress-Netzwerk-IP des Knotens.)

Da der TOS-Wert innerhalb des Pakets gespeichert ist, kann er von dem Zielknoten gelesen werden, an den die eingehende Anforderung gerichtet wurde, und das Paket wurde gesendet.

Dann arrangieren wir im Container auf dem Zielknoten, den TOS-Wert aller eingehenden Pakete einer Verbindungsmarkierung zuzuordnen, wobei derselbe Wert verwendet wird.

Da ausgehende Pakete auf derselben Verbindung dieselbe Verbindungsmarkierung haben, ordnen wir die Verbindungsmarkierung aller ausgehenden Pakete einer Firewall-Markierung zu, wobei wiederum derselbe Wert verwendet wird.

Schließlich wählt ein Satz von Richtlinien-Routing-Regeln eine andere Routing-Tabelle aus, die die ausgehenden Pakete gemäß dem Firewall-Markierungswert zurück an den erforderlichen Lastenausgleichs-Endpunktknoten leitet.

Wenn Client-Anfragen nun an den veröffentlichten Ports für einen beliebigen Knoten im Schwarm eintreffen, sieht der Container (ob auf demselben und/oder anderen Knoten), an den die Anforderung gerichtet ist, die ursprüngliche IP-Adresse des Clients, der die Anforderung stellt, und in der Lage sein, die Antwort zurück zum Ursprungsknoten des Lastausgleichsmoduls zu leiten; die wiederum in der Lage sein wird, die Antwort an den Client zurückzuleiten.

Verwendungszweck

Einrichten

Generieren Sie einen für Ihren Schwarm spezifischen Wert für INGRESS_NODE_GATEWAY_IPS , indem Sie ingress-routing-daemon-v2 als Root auf jedem Knoten Ihres Schwarms ausführen, den Sie als Load-Balancer-Endpunkt verwenden möchten (normalerweise nur Ihr Manager Knoten oder eine Teilmenge Ihrer Manager-Knoten) und notieren Sie die Werte, die für INGRESS_DEFAULT_GATEWAY angezeigt werden. Sie müssen dies nur einmal tun oder jedes Mal, wenn Sie Knoten hinzufügen oder entfernen. Ihr INGRESS_NODE_GATEWAY_IPS sollte wie 10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.5 aussehen:

Ausführen des Daemons

Führen Sie INGRESS_NODE_GATEWAY_IPS="<Node Ingress IP List>" ingress-routing-daemon-v2 --install als Root auf _jedem einzelnen_ Knoten Ihres Schwarms (Manager und Arbeiter) aus, _bevor_ Sie Ihren Dienst erstellen. (Wenn Ihr Dienst bereits erstellt wurde, stellen Sie sicher, dass Sie ihn auf 0 skalieren, bevor Sie ihn auf eine positive Anzahl von Replikaten zurückskalieren.) Der Daemon initialisiert iptables, erkennt, wenn Docker neue Container erstellt, und wendet auf jeden neuen Container neue Routing-Regeln an.

Wenn Sie die Aktivitäten des Daemons auf einen bestimmten Dienst beschränken müssen, ändern Sie [ -n "$SERVICE" ] in [ "$SERVICE" = "myservice" ] .

Deinstallieren von iptables-Regeln

Führen Sie ingress-routing-daemon-v2 --uninstall auf jedem Knoten aus.

Testen

Das Skript ingress-routing-daemon-v2 wurde mit 8 Replikaten eines Webdienstes getestet, der in einem Schwarm mit vier Knoten bereitgestellt wird.

Curl-Anforderungen für den Dienst, die an eine der angegebenen Endpunktknoten-IPs mit Lastenausgleich gerichtet waren, gaben erfolgreiche Antworten zurück, und die Prüfung der Containerprotokolle ergab, dass die Anwendung die eingehenden Anforderungen als von der IP des Curl-Clients stammend erkannte.

Einschränkungen

Da der TOS-Wert eine 8-Bit-Zahl speichern kann, kann dieses Modell im Prinzip bis zu 256 Load-Balancer-Endpunktknoten unterstützen.

Da das Modell jedoch erfordert, dass jeder Container mit einer iptables-mangle-Regel + einer Richtlinien-Routingregel + einer Richtlinien-Routingtabelle pro Manager-Endpunktknoten installiert wird, kann es möglicherweise zu Leistungseinbußen kommen, wenn die Anzahl solcher Endpunktknoten zunimmt (obwohl die Erfahrung dies vermuten lässt) bei <= 16 Load-Balancer-Endpunktknoten auf moderner Hardware unwahrscheinlich).

Wenn Sie Ihrem Schwarm Load-Balancer-Endpunktknoten hinzufügen oder vorhandene Managerknoten als Load-Balancer-Endpunkte verwenden möchten, müssen Sie vorsichtig vorgehen, da vorhandene Container den Datenverkehr nicht zurück an die neuen Endpunktknoten weiterleiten können. Versuchen Sie, INGRESS_NODE_GATEWAY_IPS="<Node Ingress IP List>" ingress-routing-daemon-v2 mit dem aktualisierten Wert für INGRESS_NODE_GATEWAY_IPS neu zu starten, und führen Sie dann eine fortlaufende Aktualisierung aller Container durch, bevor Sie den neuen Load-Balancer-Endpunkt verwenden.

Spielraum für native Docker-Integration

Ich kenne die Docker-Codebasis nicht, kann aber nichts sehen, was ingress-routing-daemon-v2 tut, was nicht prinzipiell von Docker nativ implementiert werden könnte, aber das überlasse ich dem Docker-Team betrachten, oder als Übung für jemanden, der mit dem Docker-Code vertraut ist.

Das Ingress Routing Daemon v2-Skript

Hier ist das neue ingress-routing-daemon-v2 Skript.

#!/bin/bash

# Ingress Routing Daemon v2
# Copyright © 2020 Struan Bartlett
# ----------------------------------------------------------------------
# Permission is hereby granted, free of charge, to any person 
# obtaining a copy of this software and associated documentation files 
# (the "Software"), to deal in the Software without restriction, 
# including without limitation the rights to use, copy, modify, merge, 
# publish, distribute, sublicense, and/or sell copies of the Software, 
# and to permit persons to whom the Software is furnished to do so, 
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be 
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
# SOFTWARE.
# ----------------------------------------------------------------------
# Workaround for https://github.com/moby/moby/issues/25526

if [ "$1" = "--install" ]; then
  INSTALL=1
elif [ "$1" = "--uninstall" ]; then
  INSTALL=0
else
  echo "Usage: $0 [--install|--uninstall]"
fi

echo
echo "  Dumping key variables..."

if [ "$INSTALL" = "1" ] && [ -z "$INGRESS_NODE_GATEWAY_IPS" ]; then
  echo "!!! ----------------------------------------------------------------------"
  echo "!!! WARNING: Using default INGRESS_NODE_GATEWAY_IPS"
  echo "!!! Please generate a list by noting the values shown"
  echo "!!! for INGRESS_DEFAULT_GATEWAY on each of your swarm nodes."
  echo "!!!"
  echo "!!! You only have to do this once, or whenever you add or remove nodes."
  echo "!!!"
  echo "!!! Then relaunch using:"
  echo "!!! INGRESS_NODE_GATEWAY_IPS=\"<Node Ingress IP List>\" $0 -x"
  echo "!!! ----------------------------------------------------------------------"
fi

read INGRESS_SUBNET INGRESS_DEFAULT_GATEWAY \
  < <(docker inspect ingress --format '{{(index .IPAM.Config 0).Subnet}} {{index (split (index .Containers "ingress-sbox").IPv4Address "/") 0}}')

echo "  - INGRESS_SUBNET=$INGRESS_SUBNET"
echo "  - INGRESS_DEFAULT_GATEWAY=$INGRESS_DEFAULT_GATEWAY"

# We need the final bytes of the IP addresses on the ingress network of every node
# i.e. We need the final byte of $INGRESS_DEFAULT_GATEWAY for every node in the swarm
# This shouldn't change except when nodes are added or removed from the swarm, so should be reasonably stable.
# You should configure this yourself, but for now let's assume we have 8 nodes with IPs in the INGRESS_SUBNET numbered x.x.x.2 ... x.x.x.9
if [ -z "$INGRESS_NODE_GATEWAY_IPS" ]; then
  INGRESS_NET=$(echo $INGRESS_DEFAULT_GATEWAY | cut -d'.' -f1,2,3)
  INGRESS_NODE_GATEWAY_IPS="$INGRESS_NET.2 $INGRESS_NET.3 $INGRESS_NET.4 $INGRESS_NET.5 $INGRESS_NET.6 $INGRESS_NET.7 $INGRESS_NET.8 $INGRESS_NET.9"
fi

echo "  - INGRESS_NODE_GATEWAY_IPS=\"$INGRESS_NODE_GATEWAY_IPS\""

# Create node ID from INGRESS_DEFAULT_GATEWAY final byte
NODE_ID=$(echo $INGRESS_DEFAULT_GATEWAY | cut -d'.' -f4)
echo "  - NODE_ID=$NODE_ID"

if [ -z "$INSTALL" ]; then
  echo
  echo "Ingress Routing Daemon v2 exiting."
  exit 0
fi

# Add a rule ahead of the ingress network SNAT rule, that will cause the SNAT rule to be skipped.
[ "$INSTALL" = "1" ] && echo "Adding ingress_sbox iptables nat rule: iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT"
while nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -D POSTROUTING -d 10.0.0.0/24 -m ipvs --ipvs -j ACCEPT; do true; done 2>/dev/null
[ "$INSTALL" = "1" ] && nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t nat -I POSTROUTING -d $INGRESS_SUBNET -m ipvs --ipvs -j ACCEPT

# 1. Set TOS to NODE_ID in all outgoing packets to INGRESS_SUBNET
[ "$INSTALL" = "1" ] && echo "Adding ingress_sbox iptables mangle rule: iptables -t mangle -A POSTROUTING -d $INGRESS_SUBNET -j TOS --set-tos $NODE_ID/0xff"
while nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t mangle -D POSTROUTING -d $INGRESS_SUBNET -j TOS --set-tos $NODE_ID/0xff; do true; done 2>/dev/null
[ "$INSTALL" = "1" ] && nsenter --net=/var/run/docker/netns/ingress_sbox iptables -t mangle -A POSTROUTING -d $INGRESS_SUBNET -j TOS --set-tos $NODE_ID/0xff

if [ "$INSTALL" = "0" ]; then
  echo
  echo "Ingress Routing Daemon v2 iptables rules uninstalled, exiting."
  exit 0
fi

echo "Ingress Routing Daemon v2 starting ..."

# Watch for container start events, and configure policy routing rules on each container
# to ensure return path traffic for incoming connections is routed back via the correct interface
# and to the correct node from which the incoming connection was received.
docker events \
  --format '{{.ID}} {{index .Actor.Attributes "com.docker.swarm.service.name"}}' \
  --filter 'event=start' \
  --filter 'type=container' | \
  while read ID SERVICE
  do
    if [ -n "$SERVICE" ]; then

      NID=$(docker inspect -f '{{.State.Pid}}' $ID)
      echo "Container ID=$ID, NID=$NID, SERVICE=$SERVICE started: applying policy routes."

      # 3. Map any connection mark on outgoing traffic to a firewall mark on the individual packets.
      nsenter -n -t $NID iptables -t mangle -A OUTPUT -p tcp -j CONNMARK --restore-mark

      for NODE_IP in $INGRESS_NODE_GATEWAY_IPS
      do
        NODE_ID=$(echo $NODE_IP | cut -d'.' -f4)

    # 2. Map the TOS value on any incoming packets to a connection mark, using the same value.
        nsenter -n -t $NID iptables -t mangle -A PREROUTING -m tos --tos $NODE_ID/0xff -j CONNMARK --set-xmark $NODE_ID/0xffffffff

    # 4. Select the correct routing table to use, according to the firewall mark on the outgoing packet.
        nsenter -n -t $NID ip rule add from $INGRESS_SUBNET fwmark $NODE_ID lookup $NODE_ID prio 32700

    # 5. Route outgoing traffic to the correct node's ingress network IP, according to its firewall mark
    #    (which in turn came from its connection mark, its TOS value, and ultimately its IP).
        nsenter -n -t $NID ip route add table $NODE_ID default via $NODE_IP dev eth0

      done

    fi
  done

Hallo @struanb , ich verstehe nicht, wie der Deinstallationsabschnitt in Ihrem v2-Skript funktioniert.

Hallo @jrbecart. Ich hoffe nicht. Bevor iptables-Regeln installiert werden, sehen Sie, dass es zwei while-Schleifen gibt, die alle bereits vorhandenen Regeln mit iptables -D löschen. Dies ist eine Sicherheitsmaßnahme für den Fall, dass das Skript mehrmals hintereinander mit --install , ohne dass dazwischen ein Aufruf mit --uninstall .

Wenn das Skript mit --uninstall aufgerufen wird, werden diese Regeln beim Beenden des Skripts entfernt und neue Regeln noch nicht hinzugefügt.

Hoffe das beantwortet deine Frage.

Hallo zusammen, ich möchte Ihnen mitteilen, dass ich eine Lösung für dieses Problem gefunden habe, ohne nichts anderes zu installieren und zu konfigurieren, als die NGINX-Konfiguration gut zu definieren. Ich weiß, dass wir alle verschiedene Ansätze ausprobiert haben. Dieser wurde aus Versehen entdeckt. Ehrlich gesagt habe ich das längst aufgegeben. Naja, bis heute. Während ich ein Überwachungssystem implementierte, konnte ich die Quell-IP, die echte Quell-IP, mithilfe des NGINX-Protokolls ermitteln, also begann ich zu debuggen, wie das möglich war.

Hier ist ein Beispiel für diese Art von Log

10.0.0.2 - - [19/Nov/2020:04:56:31 +0000] "GET / HTTP/1.1" 200 58 "-" req_t=0.003 upstream_t=0.004 "<browser-info>" "<source-ip-1,source-ip2,....>"

Hinweis: Es gibt mehrere Quell-IPs, wenn Sie einen Proxy verwenden (zB Cloudfare und andere).

Die Info war da, meine echte IP war da. Dann habe ich das Logging-NGINX-Format überprüft, um zu wissen, wie die Magie möglich war, und ich fand Folgendes:

log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      'req_t=$request_time upstream_t=$upstream_response_time '
                      '"$http_user_agent" "$http_x_forwarded_for"';

Das heißt, die Magie ist hier -> $http_x_forwarded_for

Danach habe ich die Proxy-Header wie proxy_set_header X-Real-IP $http_x_forwarded_for; geändert.

Und schließlich der letzte Test, der diese Informationen zu einem NodeJS-Projekt innerhalb des produktionsähnlichen Systems verwendet, Docker Swarm mit einem Overlay-Netzwerk mit etwa 4 VMs verwendet, und raten Sie mal, es hat funktioniert! Endlich konnte ich die echte IP-Adresse bekommen.

Ich bin so glücklich, weil dieses Thema schon lange offen ist, aber ich denke, dies ist die Antwort. Die von mir verwendeten Versionen sind:

Docker version: 19.03.8
NGINX version: nginx/1.14.2

Ich werde auf Ihr Feedback warten. Ich hoffe, Sie können die gleichen Ergebnisse wie ich erzielen.

Danke schön!
Sebastian.

PS: Versuchen Sie dies mit einer anderen Netzwerkschnittstelle, also außerhalb von localhost, da Sie im Log ein "-" anstelle Ihrer echten IP-Adresse finden. Versuchen Sie es im Internet zu testen, komplett außerhalb Ihres Heimnetzwerks.

Bonus: Ich könnte die IP-Adresse auch mit einer Nachschlagetabelle einer Geolokalisierung zuordnen, sie zählen und auf eine Karte setzen, also ist die Antwort ja, das ist es, wonach wir gesucht haben :)

@sebastianfelipe das ist nach all den Jahren ein großer Anspruch. Sind Sie sicher, dass Sie in diesem Thread nicht den Hostmodus oder andere Problemumgehungen verwenden?

@sebastianfelipe das ist nach all den Jahren ein großer Anspruch. Sind Sie sicher, dass Sie in diesem Thread nicht den Hostmodus oder andere Problemumgehungen verwenden?

Ich bin sicher. Ich verwende den Netzwerkhost nicht für alle diese verbundenen Dienste. Ich habe gerade einen Stack mit einem Overlay-Netzwerk in einer produktionsähnlichen Umgebung bereitgestellt, einschließlich eines Digital Ocean-Load-Balancers, und es hat funktioniert. Ich meine, besser kann ich es nicht testen. Ist 100% echt.

@sebastianfelipe Ich anhängt . Dies ist eine bekannte Problemumgehung, die das Problem des Abrufens der IP des Benutzers im eigenständigen Docker Swarm-Modus nicht löst.

@beornf Ich habe versucht zu schlafen und dann habe ich deine Benachrichtigung gelesen, also musste ich aufwachen und einen Ansatz ohne Digital Ocean Load Balancer versuchen, und es ist fehlgeschlagen. Sie haben Recht, Digital Ocean fügt dort eine Magie hinzu, wenn ein Load Balancer hinzugefügt wird. Dies geschieht mit der Variablen $http_x_forwarded_for . Der Digital Ocean Load Balancer fügt Informationen zu einer anderen NGINX-Variablen hinzu, Informationen, die nicht direkt von Docker Swarm hinzugefügt werden. Vermutlich könnte dies zu einem "Dummy-ähnlichen" Ansatz führen, um für jeden Fall eine echte Lösung zu haben. Zumindest Kunden von Digital Ocean können sich freuen, wenn sie derzeit wissen, wie sie damit umgehen sollen.

@beornf @sebastianfelipe Als X-Forwarded-For und ist weitgehend kostenlos.

@beornf @sebastianfelipe Als X-Forwarded-For und ist weitgehend kostenlos.

Ich denke, das könnte für viele von uns funktionieren, die einen Ausweg brauchen, um die echte IP zu bekommen. Cloudfare kann als Proxy oder nur DNS eingestellt werden. Es passt perfekt für keine Digital Ocean-Kunden. Es ist bis jetzt der sauberere Workaround. Aber ich stimme @beornf zu , wir brauchen eine echte Lösung, ohne auf Digital Ocean oder Cloudfare angewiesen zu sein, um dies zu erreichen.

Vielen Dank!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen