Kubernetes: Verwenden Sie iptables für Proxying anstelle von Userspace

Erstellt am 23. Jan. 2015  ·  187Kommentare  ·  Quelle: kubernetes/kubernetes

Ich habe gestern mit iptables gespielt und ein Prototyp erstellt (nun, kopiert von Google-Treffern und mutiert) eine Reihe von iptables-Regeln, die im Wesentlichen das gesamte Proxying für uns ohne Hilfe vom Userspace erledigen. Es ist nicht dringend, aber ich möchte meine Notizen ablegen, bevor ich sie verliere.

Dies hat den zusätzlichen netten Nebeneffekt (soweit ich das beurteilen kann), die Quell-IP beizubehalten und eine große Netzvereinfachung zu sein. Jetzt müsste kube-proxy nur Dienste -> iptables synchronisieren. Dies hat den Nachteil, dass es nicht mit älteren iptables und Kerneln kompatibel ist. Wir hatten schon früher ein Problem damit - irgendwann müssen wir entscheiden, wie weit in der Zeit wir uns interessieren.

Dies kann wahrscheinlich weiter optimiert werden, aber in grundlegenden Tests sehe ich, dass Sticky Sessions funktionieren, und wenn ich diesen Teil auskommentiere, sehe ich ~ gleiche Wahrscheinlichkeit, jedes Backend zu treffen. Ich war nicht in der Lage, deterministisches Round-Robin richtig zum Laufen zu bringen (mit --nth statt --probability), aber wir könnten darauf zurückkommen, wenn wir wollen.

Dadurch wird ein Serviceportal mit den unten aufgeführten Backends eingerichtet

iptables -t nat -N TESTSVC
iptables -t nat -F TESTSVC
iptables -t nat -N TESTSVC_A
iptables -t nat -F TESTSVC_A
iptables -t nat -N TESTSVC_B
iptables -t nat -F TESTSVC_B
iptables -t nat -N TESTSVC_C
iptables -t nat -F TESTSVC_C
iptables -t nat -A TESTSVC -m recent --name hostA --rcheck --seconds 1 --reap -j TESTSVC_A
iptables -t nat -A TESTSVC -m recent --name hostB --rcheck --seconds 1 --reap -j TESTSVC_B
iptables -t nat -A TESTSVC -m recent --name hostC --rcheck --seconds 1 --reap -j TESTSVC_C
iptables -t nat -A TESTSVC -m statistic --mode random --probability 0.333 -j TESTSVC_A
iptables -t nat -A TESTSVC -m statistic --mode random --probability 0.500 -j TESTSVC_B
iptables -t nat -A TESTSVC -m statistic --mode random --probability 1.000 -j TESTSVC_C

iptables -t nat -A TESTSVC_A -m recent --name hostA --set -j DNAT -p tcp --to-destination 10.244.4.6:9376
iptables -t nat -A TESTSVC_B -m recent --name hostB --set -j DNAT -p tcp --to-destination 10.244.1.15:9376
iptables -t nat -A TESTSVC_C -m recent --name hostC --set -j DNAT -p tcp --to-destination 10.244.4.7:9376

iptables -t nat -F KUBE-PORTALS-HOST
iptables -t nat -A KUBE-PORTALS-HOST -d 10.0.0.93/32 -m state --state NEW -p tcp -m tcp --dport 80 -j TESTSVC
iptables -t nat -F KUBE-PORTALS-CONTAINER
iptables -t nat -A KUBE-PORTALS-CONTAINER -d 10.0.0.93/32 -m state --state NEW -p tcp -m tcp --dport 80 -j TESTSVC
prioritawaiting-more-evidence release-note sinetwork siscalability

Alle 187 Kommentare

Cool! Ich denke, wir sollten dies auf jeden Fall einbinden. In einer separaten Anmerkung habe ich gesehen, dass der Proxy unter hoher Last ~ 30% eines Kerns verbraucht. Ich muss glauben, dass iptables uns eine bessere Leistung bieten wird.

Wir müssen dies priorisieren - es ist fast eine komplette Neufassung von kube-proxy und
alle Tests davon. Es hat auch Probleme mit der Rückenkompatibilität (funktioniert nicht bei .)
ältere Kernel oder ältere iptables-Binärdateien).

Am Montag, 26. Januar 2015 um 11:06 Uhr, Brendan Burns [email protected]
schrieb:

Cool! Ich denke, wir sollten das auf jeden Fall zusammenführen.
Ich habe gesehen, wie der Proxy unter hoher Last ~30% eines Kerns frisst, ich muss
glauben, dass iptables uns eine bessere Leistung bietet.

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71517501
.

Vielleicht ist es sinnvoll, es als parallele Option zu implementieren und langsam zu migrieren?

Am Montag, 26. Januar 2015 um 12:01 Uhr, Tim Hockin [email protected]
schrieb:

Wir müssen dies priorisieren - es ist fast eine komplette Neufassung von kube-proxy und
alle Tests davon. Es hat auch Probleme mit der Rückenkompatibilität (funktioniert nicht bei .)
ältere Kernel oder ältere iptables-Binärdateien).

Am Montag, 26. Januar 2015 um 11:06 Uhr, Brendan Burns [email protected]
schrieb:

Cool! Ich denke, wir sollten das auf jeden Fall zusammenführen. Auf einer separaten Seite
Hinweis,
Ich habe gesehen, wie der Proxy unter hoher Last ~30% eines Kerns frisst, ich muss
glauben, dass iptables uns eine bessere Leistung bietet.

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71517501

.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71527216
.

Ich versuche, jemand anderen, der diesen Code nicht gut kennt, dazu zu überreden, ihn zu lernen
und nimm es an. Ich _will_ es wirklich anpacken, aber es wäre besser, wenn
jemand anderes hat diesen Raum gelernt (nicht du! :)

Abgesehen davon haben Sie auch (gute) E-Mails über die riesige P1-Liste gesendet - und ich
glaube nicht, dass dies noch auf dieser Liste steht.

Am Montag, 26. Januar 2015 um 13:06 Uhr, Brendan Burns [email protected]
schrieb:

Vielleicht als parallele Option implementieren und langsam migrieren macht
Sinn?

Am Montag, 26. Januar 2015 um 12:01 Uhr, Tim Hockin [email protected]
schrieb:

Wir müssen dies priorisieren – es ist fast eine komplette Neufassung von kube-proxy
und
alle Tests davon. Es hat auch Probleme mit der Rückenkompatibilität (funktioniert nicht)
An
ältere Kernel oder ältere iptables-Binärdateien).

Am Mo, 26. Januar 2015 um 11:06 Uhr, Brendan Burns <
[email protected]>
schrieb:

Cool! Ich denke, wir sollten das auf jeden Fall zusammenführen. Auf einer separaten Seite
Hinweis,
Ich habe gesehen, wie der Proxy unter hoher Last ~30% eines Kerns frisst, ich muss
glauben, dass iptables uns eine bessere Leistung bietet.

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
<

https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71517501

.

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment-71527216>

.

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -71538256
.

Ist das ein P2? Könnte es sich lohnen, es vorerst zu einem P3 zu machen?

Ich hoffe, dass es funktioniert, aber wir können es noch degradieren

Am Mittwoch, 11. Februar 2015 um 14:49 Uhr, Satnam Singh [email protected]
schrieb:

Ist das ein P2? Könnte es sich lohnen, es vorerst zu einem P3 zu machen?

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -73982161
.

Entspricht "Hoffnung" nicht einem P3, das wir erreichen werden, wenn wir können?

Aus Diskussion mit @thockin : Dies ist eine Voraussetzung, um Service-Port-Bereiche zu unterstützen, die für 1.0 nicht erforderlich sind, aber wir möchten sie irgendwann unterstützen.

@thockin "Dies hat den Nachteil, dass es nicht mit älteren iptables und Kerneln kompatibel ist." Wie "neu" müsste der Kernel sein?

Nicht ZU neu, aber wir haben einige Benutzer, die WIRKLICH iptables von 2012 bis wollen
Arbeit.

Am Mo, 23. Februar 2015 um 14:44 Uhr, Sidharta Seethana < [email protected]

schrieb:

@tockin https://github.com/tockin "Das hat den Nachteil, nicht zu sein
kompatibel mit älteren iptables und Kerneln." Wie 'neu' wäre der Kernel?
muss sein?

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -75654187
.

@thockin danke. Wir verwenden/testen zum Beispiel mit RHEL/CentOS 6 - es wäre also schön, wenn wir keine starke Abhängigkeit von aktuellen 3.x-Kernels hätten.

@pweil- wir haben das neulich besprochen
Am Montag, 23. Februar 2015 um 23:40 Uhr Sidharta Seethana [email protected]
schrieb:

@thockin https://github.com/thockin danke. Wir verwenden/testen mit
RHEL/CentOS 6 zum Beispiel - es wäre also schön, wenn wir keine harte
Abhängigkeit von aktuellen 3.x-Kernels.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -75698480
.

Nun, Sie brauchen Docker, um ausgeführt zu werden, und irgendwann müssen wir es abschneiden.
Die Unterstützung von Back-Rev iptables wird mich nicht davon abhalten, (eventuell) zu machen
diese Veränderung, und es wird für einige Leute stechen.

Am Mo, 23. Februar 2015 um 20:40 Uhr, Sidharta Seethana < [email protected]

schrieb:

@thockin https://github.com/thockin danke. Wir verwenden/testen mit
RHEL/CentOS 6 zum Beispiel - es wäre also schön, wenn wir keine harte
Abhängigkeit von aktuellen 3.x-Kernels.

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -75698480
.

Mit der Hilfe von @thockin haben wir das gleiche mit udp versucht.

Wir haben einen GCE-Kubernetes-Cluster mit 3 sky-dns-Replikationscontrollern erstellt.
Auf dem kubernetes-master setzen wir in iptables folgendes:
Die DNS-Dienst-IP war 10.0.0.10 und die Pod-Endpunkte, auf denen DNS ausgeführt wurde, waren 10.244.0.5:53, 10.244.3.6:53, 10.244.0.6:53

iptables -t nat -N TESTSVC
iptables -t nat -F TESTSVC
iptables -t nat -N TESTSVC_A
iptables -t nat -F TESTSVC_A
iptables -t nat -N TESTSVC_B
iptables -t nat -F TESTSVC_B
iptables -t nat -N TESTSVC_C
iptables -t nat -F TESTSVC_C
iptables -t nat -N KUBE-PORTALS-HOST
iptables -t nat -F KUBE-PORTALS-HOST

iptables -t nat -A TESTSVC -m aktuell --name hostA --rcheck --seconds 1 --reap -j TESTSVC_A
iptables -t nat -A TESTSVC -m aktuell --name hostB --rcheck --seconds 1 --reap -j TESTSVC_B
iptables -t nat -A TESTSVC -m aktuell --name hostC --rcheck --seconds 1 --reap -j TESTSVC_C

iptables -t nat -A TESTSVC -m Statistik --mode random --probability 0.333 -j TESTSVC_A
iptables -t nat -A TESTSVC -m Statistik --mode random --probability 0.5 -j TESTSVC_B
iptables -t nat -A TESTSVC -m Statistik --mode random --probability 1.000 -j TESTSVC_C

iptables -t nat -A TESTSVC_A -m aktuell --name hostA --set -j DNAT -p udp --to-destination 10.244.0.5:53
iptables -t nat -A TESTSVC_B -m aktuell --name hostB --set -j DNAT -p udp --to-destination 10.244.3.6:53
iptables -t nat -A TESTSVC_C -m aktuell --name hostC --set -j DNAT -p udp --to-destination 10.244.0.6:53
iptables -t nat -A KUBE-PORTALS-HOST -d 10.0.0.10/32 -p udp -m udp --dport 53 -j TESTSVC
iptables -t nat -A AUSGABE -j KUBE-PORTALS-HOST


kubernetes-master>nslookup kubernetes.default.kuberenetes.local 10.0.0.10

Wir bekommen eine Antwort zurück!

Tolles Zeug! Nur zur Info (Bestätigung durch unser persönliches Gespräch), es ist im Allgemeinen nicht sicher, mehrere gleichzeitige iptables-Befehle auszuführen (verschiedene Ketten scheinen in Ordnung zu sein). iptables ist ein Wrapper um libiptc, und siehe den Kommentar zu iptc_commit: http://www.tldp.org/HOWTO/Querying-libiptc-HOWTO/mfunction.html

Dies wurde anscheinend 2013 behoben, aber vielleicht nur, wenn Sie --wait (?) bestehen: http://git.netfilter.org/iptables/commit/?id=93587a04d0f2511e108bbc4d87a8b9d28a5c5dd8

Der Grund dafür ist, dass iptables effektiv iptables-save / iptables-restore aufruft (zumindest pro Kette); Ich habe viel Code gesehen, der nur iptables-save & iptables-restore aufruft, anstatt Dinge durch Hinzufügen und Löschen zu tun. Vielleicht habe ich sogar etwas Code zu tun, den ich ausgraben könnte, wenn das hilfreich ist.

Es verwundert mich, dass es keine Möglichkeit gibt, CAS- oder LL/SC-Operationen durchzuführen.

Wir sollten Unterstützung für --wait hinzufügen, obwohl es erst kürzlich genug ist, dass GCE's
debian-backports hat es nicht.

Vielleicht sollten wir unseren Code selbst sperren, um uns zumindest daran zu hindern
davon, auf uns selbst zu treten.

Am Do, 26. Februar 2015 um 13:56 Uhr, Justin Santa Barbara <
[email protected]> schrieb:

Tolles Zeug! Nur zur Info (Bestätigung aus unserem persönlichen Gespräch),
Es ist im Allgemeinen nicht sicher, mehrere gleichzeitige iptables-Befehle auszuführen
(verschiedene Ketten klingt, als ob es in Ordnung sein könnte). iptables ist ein Wrapper um
libiptc und sehen Sie sich den Kommentar zu iptc_commit an:
http://www.tldp.org/HOWTO/Querying-libiptc-HOWTO/mfunction.html

Dies wurde anscheinend 2013 behoben, aber vielleicht nur, wenn Sie --wait (?) bestehen:
http://git.netfilter.org/iptables/commit/?id=93587a04d0f2511e108bbc4d87a8b9d28a5c5dd8

Die Ursache dafür ist, dass iptables effektiv iptables-save / aufruft.
iptables-restore (zumindest pro Kette); Ich habe viel Code gesehen, der nur
ruft daher iptables-save & iptables-restore auf, anstatt Dinge zu tun
durch Hinzufügen und Löschen. Vielleicht habe ich sogar einen Code zu tun, den ich ausgraben könnte
auf, wenn das hilfreich ist.

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -76282629
.

Was passiert, wenn beim Erstellen einer Reihe von Regeln Fehler auftreten?

Faire Frage - wir sollten wahrscheinlich wirklich gründlich darüber nachdenken, was es bedeutet,
mittendrin auf einen Fehler stoßen

Am Donnerstag, 26. Februar 2015 um 20:47 Uhr, Brian Grant [email protected]
schrieb:

Was passiert bei Fehlern mitten in der Erstellung eines Haufens von
Regeln?

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -76331174
.

@thockin Von irc heute:

Das net.ipv4.conf.all.route_localnet erlaubt 127.0.0.1, das Ziel von DNAT Regeln zu sein. Aus den Dokumenten :

route_localnet - BOOLEAN

Betrachten Sie Loopback-Adressen nicht als Marsquelle oder -ziel
beim Routing. Dies ermöglicht die Verwendung von 127/8 für lokale Routing-Zwecke.
Standard FALSE

Würden wir dies in Kubelet integrieren oder in einem separaten Daemon aufbewahren? Kubelet überwacht bereits Dienste, um env vars zu füllen.

Ich möchte es als separate Binärdatei behalten. Es gibt Gründe, warum Sie
Vielleicht möchten Sie dies auf anderen Maschinen (z. B. Haustier-VMs) außerhalb eines k8s ausführen
Cluster, um Zugang zu k8s-Diensten zu erhalten.

--brendan

Am Freitag, 13. März 2015 um 11:37 Uhr, Brian Grant [email protected]
schrieb:

Würden wir dies in Kubelet integrieren oder in einem separaten Daemon aufbewahren?
Kubelet überwacht bereits Dienste, um env vars zu füllen.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79230747
.

Aufholen. In Bezug auf das, was bei Fehlern passiert (von denen es viele geben wird, glauben Sie mir), bin ich ein großer Fan des Anti-Entropie-Ansatzes - den gewünschten Zustand irgendwo speichern und periodisch den gewünschten und den tatsächlichen Zustand in Einklang bringen (durch Mutieren des Ist-Zustands). ). In diesem Fall vielleicht so einfach wie:

während (wahr) {
aktueller Zustand = iptablesSave()
if currentState != wishState { iptablesRestore(desiredState))
sleep_a_while()
}

Stimmen Sie zu 100% zu, dass dies der richtige Weg ist, um mit Fehlern beim Schreiben von iptables umzugehen
Regeln.

Am Freitag, 13. März 2015 um 13:16 Uhr, Quinton Hoole [email protected]
schrieb:

Aufholen. Was passiert bei Ausfällen (davon
es wird viele geben, glaub mir), ich bin ein großer Fan des Anti-Entropie-Ansatzes

  • gewünschten Zustand irgendwo speichern und periodisch gewünschten und abgleichen
    Ist-Zustand (durch Mutation des Ist-Zustands). In diesem Fall vielleicht so einfach wie:

während (wahr) {
aktueller Zustand = iptablesSave()
if currentState != wishState { iptablesRestore(desiredState))
sleep_a_while()
}


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79336296
.

Das passiert jetzt mehr oder weniger, oder? Für jede erwartete Regel gilt
Überprüfen Sie, ob es existiert und wenn nicht, erstellen Sie es.

Am Freitag, 13. März 2015 um 14:02 Uhr, Brendan Burns [email protected]
schrieb:

Stimmen Sie zu 100% zu, dass dies der richtige Weg ist, um mit Fehlern beim Schreiben von iptables umzugehen
Regeln.

Am Freitag, 13. März 2015 um 13:16 Uhr, Quinton Hoole [email protected]
schrieb:

Aufholen. Was passiert bei Ausfällen (davon
es wird viele geben, glaub mir), ich bin ein großer Fan der Anti-Entropie
sich nähern

  • gewünschten Zustand irgendwo speichern und periodisch gewünschten und abgleichen
    Ist-Zustand (durch Mutation des Ist-Zustands). In diesem Fall vielleicht so einfach
    wie:

während (wahr) {
aktueller Zustand = iptablesSave()
if currentState != wishState { iptablesRestore(desiredState))
sleep_a_while()
}


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79336296

.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79392626
.

Ich stimme zu, dass es ein Dienstprogramm in einer separaten Binärdatei gibt, aber vielleicht verknüpfen wir es damit
kubelet (auf die gleiche Weise wie cAdvisor) und machen Sie es zu einem eigenständigen
gleiche Zeit.

Am Freitag, 13. März 2015 um 12:03 Uhr, Brendan Burns [email protected]
schrieb:

Ich möchte es als separate Binärdatei behalten. Es gibt Gründe, warum Sie
Vielleicht möchten Sie dies auf anderen Maschinen (z. B. Haustier-VMs) außerhalb eines k8s ausführen
Cluster, um Zugang zu k8s-Diensten zu erhalten.

--brendan

Am Freitag, 13. März 2015 um 11:37 Uhr, Brian Grant [email protected]
schrieb:

Würden wir dies in Kubelet integrieren oder in einem separaten Daemon aufbewahren?
Kubelet überwacht bereits Dienste, um env vars zu füllen.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
<
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79230747

.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -79257059
.

Mich würde interessieren, was die Leute von Kubernetes-Mesos dazu sagen, ob Knotenkomponenten stärker integriert oder modularer sein sollten. @jdef?

[[BEARBEITET]] Ich mag die Modularität der k8s-Komponenten sehr, zum Beispiel das Ausführen eines Proxy-Prozesses getrennt von einem Kubelet-Prozess. Wenn der Proxy aus irgendeinem Grund fehlschlägt, wird das Kubelet nicht heruntergefahren. Das ist ziemlich großartig, da Mesos-Executoren derzeit kein sehr elegantes Failover-Modell haben – und der Executor des kubernetes-mesos-Frameworks ein Kubelet/Executor-Hybrid ist. Mit diesem Modell kann ich auch einen Proxy-Dienst auf einem Mesos-Master ausführen und ihn als Round-Robin-Balancer für externe Clients verwenden (wie in dem von uns eingereichten Leitfaden für die ersten Schritte).

In Bezug auf das Packen/Versenden von Binärdateien halte ich es für ziemlich nützlich, die Funktionen wie in Hyperkube zusammenzupacken. Ich habe auch darüber nachgedacht, wie man die kubernetes-mesos-Framework-Komponenten in minimale Docker-Container packt. Iptables hat Abhängigkeiten von externen Bibliotheken und das verkompliziert die Dinge. Ein netter Kompromiss könnte also darin bestehen, das k8sm-Framework als Docker auszuliefern, das das einzelne Hyperkube-Image enthält. Executor oder Proxy - und jeder Prozess kann direkt auf dem Host ausgeführt werden. Dies führt im Grunde zu einem Endlauf um das Abhängigkeitsproblem von iptables-{binaries,libraries}-in-Docker.

+1 für modulare Funktionalität, +1 für einzelnes Binärbild

@thockin re: Anti-Entropie: Ah ja. Ich sehe, dass proxier.SyncLoop() das tut. In welchem ​​Fall ist die Antwort auf die Frage von @ bgrant0607 vom 26. Februar nicht, dass Fehler ignoriert werden können und bei der nächsten Iteration von SyncLoop() (derzeit 1 Minute) repariert werden? Oder übersehe ich vielleicht etwas?

@thockin

  1. Machen wir uns Sorgen über den Netzwerkverkehr, der durch schwarze Löcher verursacht wird, oder muss sich der Dienst-/Pod-Autor darum kümmern?

Mit Userspace-Proxy
Angenommen, die virtuelle IP 10.0.0.11 hat 3 Endpunkte, sagen wir, 10.240.1.1, 10.240.1.2, 10.240.1.3
Wenn bei einem User-Space-Proxy ein Endpunkt beispielsweise 10.240.1.1 nicht funktionierte, würde der Proxy feststellen, dass die TCP-Verbindung mit 10.240.1.1 nicht hergestellt wurde, und er könnte auf einen der anderen beiden Endpunkte zurückgreifen.

Mit iptables
Wenn wir iptables verwenden, gibt es keinen Fallback-Mechanismus, da Kubernetes nicht erkennt, ob der Endpunkt funktioniert hat oder nicht.
Wir könnten dies abmildern, wenn wir eine Art Zustandsprüfung für die Endpunkte durchführen würden, die nicht reagierende Endpunkte entfernen würde.

Oder liegt es vielleicht nicht in der Verantwortung des Kubernetes-Systems, sich über nicht reagierende Endpunkte Sorgen zu machen, sondern in die Verantwortung des Pod-Autors?

Der Benutzer kann Bereitschaftstests einrichten, die von Kubelet durchgeführt werden. Bei einem Probefehler wird ein Endpunkt vom Endpunkt-Controller aus der Endpunktliste entfernt. Der Dienstproxy sollte dann den Endpunkt aus dem Zielsatz entfernen.

Ich habe dies für GSoC untersucht und frage mich:

Idealerweise würden wir also feststellen, ob iptables ausreichend neu genug ist, um kube-proxy zu verwenden, und ansonsten weiterhin verwenden?

Von https://github.com/GoogleCloudPlatform/kubernetes/issues/5419 klingt es so, als wäre dies der ideale Ansatz; wobei kubelet bestimmt, ob ip-tables verwendet oder kube-proxy gestartet wird.

Ich bin auch etwas spät zu GSoC (war in den Frühlingsferien....), daher frage ich mich auch, ob ich morgen/später heute noch einen GSoC-Vorschlag dafür einreichen kann (außer natürlich der 27 das ist noch offen)?

@BenTheElder Ja, Sie haben bis Freitag Zeit, um einen Vorschlag einzureichen. Es gibt eine weitere Person, die möglicherweise an diesem Thema interessiert ist, aber noch keinen konkreten Vorschlag dafür.

Ich mache mir keine Sorgen um Kernel, die älter als 2012 sind, so sehr wie über Betriebssysteme ohne iptables, obwohl diese bereits zu einem gewissen Grad kaputt sind.

@bgrant0607 danke!
Ich denke, ich kann dieses Thema dann auswählen. Es sieht interessant aus.

Die Bereitschaftsprüfung funktioniert gut für den Anwendungsstart, aber ich bin mir nicht sicher, ob die Bereitschaft zur Minderung von Anwendungsfehlern geeignet ist. Bei einem Pod-Fehler muss das Signal von Anwendung -> Kubelet -> Apiserver -> Endpoints_Controller -> Apiserver -> Kube-Proxy übergeben werden. Ich wäre daran interessiert, die Latenz zwischen einem Anwendungsfehler und dem Entfernen eines Endpunkts aus der Kube-Proxy-Rotation zu verstehen. Während dieses Zeitraums werden Anfragen an einen nicht reagierenden Endpunkt weitergeleitet.

Wiederholen bei Verbindungsfehlern ist eine gängige Strategie und eine recht nützliche Funktion vieler beliebter Load Balancer (z. B. haproxy, AWS ELB) und wird von der aktuellen Implementierung von kube-proxy gehandhabt. Soll diese Verantwortung auf die externe LB übertragen werden? Was ist mit dem Intra-Cluster-Traffic?

Ein weiterer Gedanke, bei iptables werden wir wahrscheinlich auf Probleme stoßen, die bei einer Neukonfiguration im Vergleich zu einem tatsächlichen LB ordnungsgemäß abfließen.

Mike bringt gute Punkte.

Am Montag, 23. März 2015 um 23:00 Uhr, Mike Danese [email protected]
schrieb:

Ein weiterer Gedanke, wir werden wahrscheinlich auf Probleme mit einer eleganten Verbindung stoßen
Ablassen bei Neukonfiguration im Vergleich zu einem tatsächlichen LB.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -85354865
.

Ich habe den Quellcode für kube-proxy und das Proxy-Paket durchgelesen; wird iptables nicht bereits in der aktuellen Revision verwendet?

Was genau ist hier zu tun? Aus der aktuellen Master-Quelle sieht es so aus, als ob iptables bereits ziemlich umfangreich im Proxy verwendet wird.

@mikedanese @thockin Readiness ist am nützlichsten für geplante Ausfälle. Ungeplante Ausfälle führen immer zu beobachtbaren Fehlern. Das Polling-Intervall sollte im Allgemeinen relativ zur Update-Latenz lang sein, aber wir könnten auch Re-Forwarding-Regeln auf dem Zielknoten über die direkte Kommunikation zwischen Kubelet und kube-proxy einrichten, wenn die Latenz über apiserver und etcd zu lang ist und/oder das Pfad ist nicht zuverlässig genug.

@BenTheElder Die vorhandenen Regeln

@bgrant0607 Danke, das macht jetzt absolut Sinn. Ein weiteres Lesen der Quelle und der Designdokumente und ich bin fast fertig mit dem Schreiben eines Vorschlagsentwurfs.

Entwurf des GSoC-Vorschlags: https://gist.github.com/BenTheElder/ac61900595a7ea9ea9b5

Ich würde mich besonders über Feedback zum Zeitplanabschnitt freuen. Da bin ich mir nicht ganz sicher.
Sollte ich früher fertig werden, würde ich gerne an einigen anderen (kleineren?) nicht bearbeiteten GSoC-Problemen arbeiten wie:
https://github.com/GoogleCloudPlatform/kubernetes/issues/1651.

Nochmals vielen Dank, Kubernetes nimmt den Kuchen für die freundlichste Gruppe.

Ich möchte nur sagen, dass ich sehr glücklich bin, sagen zu können, dass mein Vorschlag angenommen wurde und dass ich im Sommer daran arbeiten werde. :smiley:

Ich bin sehr aufgeregt. Leider stecke ich gerade mitten in meinem Finale, aber irgendwann dieses Wochenende sollte ich noch viel mehr machen und daran arbeiten, höchstwahrscheinlich beginnend mit https://github.com/GoogleCloudPlatform/kubernetes/pull/7032 fertig.

@thockin @brendanburns Kann jemand

Es sieht so aus, als ob wir bereits iptables >= 1.4.11 (veröffentlicht am 26. Mai 2011) bevorzugen.

// Executes the rule check without using the "-C" flag, instead parsing iptables-save.
// Present for compatibility with <1.4.11 versions of iptables.  This is full
// of hack and half-measures.  We should nix this ASAP.
func (runner *runner) checkRuleWithoutCheck(table Table, chain Chain, args ...string) (bool, error) {

Quelle: https://github.com/GoogleCloudPlatform/kubernetes/blob/aec41967416cf3463b188d72c97e71465e00719d/pkg/util/iptables/iptables.go#L206

Sehen wir tatsächlich ältere Gastgeber?

Ein Ansatz wäre offensichtlich, zur Laufzeit zu erkennen, welche Version von iptables wir ausführen, und das "Beste" zu tun, was wir der Version geben können, z.

if (alte Version) {
Proxy-Modul für den Benutzerbereich laden
}
anders {
iptables-Proxy-Modul laden
}

Ich warne davor, zu viele Verzweigungen in der obigen if-Anweisung (idealerweise nur 2) zu haben, und vermeiden Sie so weit wie möglich, diese Art von if-Anweisung an mehr als einer Stelle im Code zu haben.

Ich habe den Code nicht im Detail durchgesehen, um herauszufinden, wie machbar der obige Ansatz ist.

Müssen alle Knoten dieselbe Strategie implementieren (Benutzerbereich vs. iptables-Proxying) oder kann jeder unabhängig entscheiden?

Wenn jeder Knoten unabhängig entscheidet, erhöhen wir möglicherweise die Testoberfläche proportional zum Quadrat der Anzahl der Verzweigungen in der obigen if-Anweisung (dh source_mode x dest_mode), aber wenn wir die Anzahl der Modi auf 2 halten können, denke ich, dass das in Ordnung ist .

Q

Oh, und die Antwort auf Ihre Frage, ob wir alte Knoten sehen, ist leider "ja".

Es gibt viele Diskussionen über das oben Genannte in einer separaten Ausgabe. Ich werde versuchen, es für Sie auszugraben.

@quinton-hoole Danke!

Außerdem bin ich mir ziemlich sicher, dass wir den Benutzerbereich auf einem Knoten und iptables auf einem anderen ausführen können.

Die Anzahl der Modi sollte nur 2 betragen, mit Ausnahme dieses Hacks, wenn wir kein -C haben, aber die Knoten mit -C sollten in der Lage sein, die reine iptables-Version auszuführen (glaube ich).

Ah ja, #7528 behandelt Kernelversionen und dergleichen.

Vielen Dank.
Das habe ich nicht gesehen, als ich nach Anforderungen für Kubernetes suchte. Die einzigen Anforderungen, die ich gefunden habe, waren in den Netzwerkdokumenten, in denen diskutiert wird, wie wir von eindeutigen IPs ausgehen.

Wir sollten wahrscheinlich eine Dokumentation für Anforderungen schreiben lassen, sobald wir eine bessere Vorstellung davon haben, was sie sind.

Ich habe hier angefangen zu hacken: https://github.com/BenTheElder/kubernetes/tree/iptables_proxy

Konkret habe ich die User-Space-Implementierung hier hinter eine Schnittstelle verschoben:
https://github.com/BenTheElder/kubernetes/commit/4e5d24bb74aca43b0dd37cf5cfee8a34f8eff2bf

Ich bin mir jetzt jedoch nicht sicher, ob die Implementierungsauswahl in cmd/kube-proxy oder in pkg/proxy sein sollte, also kann ich dies entfernen und die Implementierung stattdessen von kube-proxy auswählen lassen.

Edit: Ich denke im Nachhinein, dass es wahrscheinlich sinnvoller ist, die Implementierung von kube-proxy auszuwählen.

@BenTheElder Ich habe Tims Regeln mit Calico getestet und sie funktionieren gut. Wir erledigen unsere ganze Arbeit in der Filtertabelle, daher haben die DNAT-Regeln hier die entsprechende src-IP zu diesem Zeitpunkt festgelegt.

Generell wäre es gut, eine Diskussion darüber zu führen, wie Netzwerk-Plugins iptables sicher ändern können, wenn Kubernetes dort auch Regeln einfügt. Ich möchte nicht, dass Kubernetes-Regeln mit Füßen getreten werden (oder von ihnen niedergetrampelt werden), wenn sie sich im Laufe der Zeit ändern.

@Symmetrisch Ja. Ich bin mir beim Plugin-Teil noch nicht sicher, aber das scheint ziemlich wichtig zu sein.

Ich werde dieses Wochenende wahrscheinlich etwas beschäftigt sein, aber am Montag sollte ich anfangen, an diesem Vollzeitjob für GSoC zu arbeiten, um die erste Iteration zu implementieren.
Ich würde dies gerne im Hinterkopf behalten, aber nachdem ich mir die API der Netzwerk-Plugins angeschaut habe, bin ich mir nicht wirklich sicher, was der sauberste Weg ist, damit umzugehen.

Haben Sie eine Idee, wie das aussehen soll / wie es funktionieren soll?

FWIW, ich habe etwas gemacht, das für uns funktioniert, weil der Kube-Proxy fast nicht mehr reagierte. Es ist hier: https://github.com/MikaelCluseau/kubernetes-iptables-proxy/blob/master/iptables-routing.rb.

Ich habe diesen Thread noch nicht gesehen, aber am Ende habe ich etwas in der Nähe, außer dass ich einen Fehler mit meinen zufälligen Statistik-Matchgewichten gemacht habe :-)

Ich möchte auch mitteilen, dass wir den nf_conntrack_max schnell erreicht haben. Es sollte wohl erhöht werden.

# cat /etc/sysctl.d/nf_conntrack.conf 
net.netfilter.nf_conntrack_max = 1000000
net.nf_conntrack_max           = 1000000

Ich habe vielleicht nicht die ganze Notwendigkeit von iptables , aber warum nicht stattdessen IPVS verwenden?
Es scheint für das Proxing relevanter zu sein als für iptables ...
Hier ist eine einfache Go-Implementierung: https://github.com/noxiouz/go-ipvs
Und um #561 abzuschließen, gibt es noch das Projekt ktcpvs .

IPVS scheint auch eine Abstraktion von Netfilter zu sein (wie iptables). Wir können einige Funktionen mit dem vorhandenen Code teilen, indem wir iptables verwenden; und iptables scheint die flexiblere/allgemeinere Lösung für die Verwaltung von Netfilter zu sein.

Was #561 und ktcpvs angeht: ktcpvs scheint seit 2004 nicht mehr weiterentwickelt worden zu sein und scheint keine Funktionen zu haben, die Benutzer wie das URL-Rewriting wünschen würden. Unabhängig davon sucht #561 nach einer generischen Lösung, die mit steckbaren Balancern verwendet werden kann.

Randnotiz: Dieses go-Projekt scheint keine Lizenz zu haben.

iptables wird "eines Tages" zugunsten von nftables ( nft cli) verworfen.
Auch die Verwendung von iptables CLI zum Erstellen von Regeln scheint nicht ganz robust zu sein ...

Eine schnelle Suche findet mich dieses andere MIT-Projekt: https://github.com/vieux/go-libipvs
Aber es scheint wirklich ziemlich einfach zu sein, ein einfaches funktionierendes zu erstellen, da die gesamte Komplexität bereits im Kernel-Code kugelsicher ist.

Ich bezweifle, dass iptables in naher Zukunft aus einer der großen Distributionen entfernt wird, und die iptables-CLI ist speziell zum Erstellen und Verwalten von Regeln für Netfilter ... ?

Ein unvollständiger cgo-Wrapper wie der verlinkte scheint viel weniger sicher zu sein, als iptables und iptables-restore berappen und wir brauchen bereits iptables für andere Regeln (zB Nodeports) und mit iptables-restore wir können Bulk-Updates mit einer gewissen Atomarität durchführen.

IPVS scheint ferner darauf ausgelegt zu sein, auf einer Lastausgleichs-Hostmaschine getrennt von den "echten" Servern verwendet zu werden.
Dies deutet darauf hin, dass dies die einzige unterstützte Verwendung ist:

2.2. Fallstricke: Sie benötigen einen externen Client (der Direktor und die Realserver können nicht auf den virtuellen Dienst zugreifen)

Um LVS einzurichten und zu testen/auszuführen, benötigen Sie mindestens 3 Maschinen: Client, Director, Realserver(s).

Von außen betrachtet fungiert der LVS als eine Maschine. Der Client kann keine der Maschinen im LVS sein (der Director oder Realserver). Sie benötigen einen externen Client. Wenn Sie versuchen, von einer der Maschinen im LVS aus auf einen von LVS kontrollierten Dienst (zB http, smtp, telnet) zuzugreifen; Der Zugriff vom Director bleibt hängen, der Zugriff von einem Realserver verbindet sich lokal mit dem Dienst, wobei das LVS umgangen wird.

Es sieht auch so

+1 für den iptables-Ansatz. Wir verwenden iptables ausgiebig in Calico und sie haben sich als robust erwiesen und sie funktionieren und skalieren gut (vorausgesetzt, Sie haben Ihre Regeln gut entworfen). @BenTheElder , sollten Sie Hilfe bei der Arbeit von iptables benötigen,

+1 für iptables und iptables-restore, es ist viel weniger umständlich
als IPVS/LVS und diktiert weniger Systemanforderungen (Heartbeating Daemon,
etc.)

Am Samstag, 13. Juni 2015 um 11:27 Uhr, Alex Pollitt [email protected]
schrieb:

+1 für den iptables-Ansatz. Wir verwenden iptables ausgiebig in Calico und
Sie haben sich als robust erwiesen und funktionieren gut und skalieren gut (vorausgesetzt, Sie
Gestalten Sie Ihre Regeln gut). @BenTheElder https://github.com/BenTheElder ,
Sollten Sie Hilfe bei der Arbeit von iptables benötigen, dann lassen Sie es bitte
wissen wir, denn wir packen gerne mit an.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -111719474
.

Danke Alex, ich melde mich wenn ich es tue.

Ich könnte etwas Feedback/Input zur aktuellen Implementierung (https://github.com/GoogleCloudPlatform/kubernetes/pull/9210) gebrauchen, wenn jemand Zeit hat.

Es ist größtenteils vollständig und aktuell mit dem Upstream-Master auf dem neuesten Stand. Ich muss den Code schreiben, der die generierten Regeln mit iptables-save und die Zähler usw. wiederherstellt, aber die Regeln werden generiert und (meistens) funktionieren. im Wesentlichen den hier im OP beschriebenen Regeln folgen, wobei die größte Änderung nur die Kettennamen sind, die für die automatische Generierung von Namen erforderlich waren, die iptables akzeptieren wird.

Hier wird ein Grenzfall gemeldet: https://github.com/BenTheElder/kubernetes/issues/3 , der möglicherweise eine Änderung für die Handhabung von Pods erfordert, die sich mit sich selbst verbinden.

Ich hatte einige ausgezeichnete Rückmeldungen und Diskussionen mit @MikaelCluseau und @Symmetric, insbesondere über einige Redesigns, um dies und andere Dinge zu handhaben (nochmals

Der PR selbst ist ziemlich groß, aber die relevante Regelgenerierung befindet sich in pkg/proxy/proxieriptables.go syncProxyRules() unter: https://github.com/BenTheElder/kubernetes/blob/iptables_proxy/pkg/proxy/proxieriptables. geh#L286

Die bestehende Diskussion ist (natürlich hier) sowie in den PR-Kommentaren und unter https://github.com/BenTheElder/kubernetes/issues/3 sowie ein bisschen mehr unter https://github.com/ zu sehen. BenTheElder/kubernetes/issues/4.

Ein weiteres Problem, das Eingaben erfordert:

Im aktuellen Code ist der kube-proxy noch enthalten, um NUR den Fall nodePort zu behandeln. Ich denke, wir können auch in diesem Fall auf kube-proxy verzichten und haben dazu einige einfache iptables-Regeln für Bens PR vorgeschlagen .

Diese Regeln verschleiern jedoch immer noch die Quell-IP jedes externen LB, sodass sie nicht ideal sind. Das Problem ist, dass das Antwortpaket von einem anderen Knoten kommen könnte, wenn wir nur DNAT-Datenverkehr vom LB ausgeben, wenn er einen Knoten trifft. Daher glaube ich nicht, dass der LB die Antwort mit der ursprünglichen TCP-Sitzung korrelieren kann . Ist diese Sorge berechtigt? Die Implementierung wäre einfacher, wenn wir uns nicht darum kümmern müssten.

Ich vermute, wir können etwas zaubern, um HTTP-Proxys glücklich zu machen, aber ich sehe keine Möglichkeit, dies bei L4 allgemein zu machen.

Ich versuche es mit der schwarzen Magie Ihrer PR, aber es generiert nichts für mich, es scheint, dass die Regeln mit Aufrufen von iptables generiert wurden, dann wird eine iptables-restore-Datei erstellt.

Es gibt einen Fehler im Header-Teil der erzeugten Datei, normalerweise diejenigen, die mit dem iptables-Aufruf gefüllt wurden. Es gibt den relevanten Teil des Protokolls:

I0807 11:41:24.560063 8369 iptables.go:327] iptables ausführen -N [KUBE-PORTALS-CONTAINER -t nat]
I0807 11:41:24.562361 8369 iptables.go:327] Ausführen von iptables -C [PREROUTING -t nat -m Kommentar --comment Handle ClusterIPs; HINWEIS: Dies muss vor den NodePort-Regeln sein -j KUBE-PORTALS-CONTAINER]
I0807 11:41:24.563469 8369 iptables.go:327] iptables ausführen -N [KUBE-PORTALS-HOST -t nat]
I0807 11:41:24.565452 8369 iptables.go:327] Ausführen von iptables -C [AUSGABE -t nat -m Kommentar --comment Handle ClusterIPs; HINWEIS: Dies muss vor den NodePort-Regeln sein -j KUBE-PORTALS-HOST]
I0807 11:41:24.566552 8369 iptables.go:327] iptables ausführen -N [KUBE-NODEPORT-CONTAINER -t nat]
I0807 11:41:24.568363 8369 iptables.go:327] Ausführen von iptables -C [PREROUTING -t nat -m addrtype --dst-type LOCAL -m Kommentar --comment handle service NodePorts; HINWEIS: Dies muss die letzte Regel in der Kette sein -j KUBE-NODEPORT-CONTAINER]
I0807 11:41:24.569564 8369 iptables.go:327] Ausführen von iptables -N [KUBE-NODEPORT-HOST -t nat]
I0807 11:41:24.571458 8369 iptables.go:327] Ausführen von iptables -C [AUSGABE -t nat -m addrtype --dst-type LOCAL -m Kommentar --comment handle service NodePorts; HINWEIS: Dies muss die letzte Regel in der Kette sein -j KUBE-NODEPORT-HOST]
I0807 11:41:24.573392 8369 iptables.go:327] Ausführen von iptables -C [POSTROUTING -t nat -m Kommentar --comment Handle Pod Verbindung mit self -s 10.240.240.78/32 -d 10.240.240.78/32 -j MASQUERADE ]
I0807 11:41:24.574447 8369 proxier.go:349] iptables-Regeln synchronisieren.
I0807 11:41:24.575592 8369 proxier.go:399] Kette: PREROUTING, Regel: :PREROUTING ACCEPT [0:0]
I0807 11:41:24.575615 8369 proxier.go:401] Regel: -A PREROUTING -m Kommentar --comment "Handle ClusterIPs; HINWEIS: Dies muss vor den NodePort-Regeln stehen" -j KUBE-PORTALS-CONTAINER
I0807 11:41:24.575625 8369 proxier.go:401] Regel: -A PREROUTING -m addrtype --dst-type LOCAL -m Kommentar --comment "handle service NodePorts; HINWEIS: Dies muss die letzte Regel in der Kette sein" -j KUBE-NODEPORT-CONTAINER
I0807 11:41:24.575633 8369 proxier.go:399] Kette: INPUT, Regel: :INPUT ACCEPT [0:0]
I0807 11:41:24.575646 8369 proxier.go:399] Kette: OUTPUT, Regel: :OUTPUT ACCEPT [0:0]
I0807 11:41:24.575658 8369 proxier.go:401] Regel: -A OUTPUT -m Kommentar --comment "Handle ClusterIPs; HINWEIS: Dies muss vor den NodePort-Regeln sein" -j KUBE-PORTALS-HOST
I0807 11:41:24.575670 8369 proxier.go:401] Regel: -A OUTPUT -m addrtype --dst-type LOCAL -m Kommentar --comment "handle service NodePorts; HINWEIS: Dies muss die letzte Regel in der Kette sein" -j KUBE-NODEPORT-HOST
I0807 11:41:24.575683 8369 proxier.go:399] Kette: POSTROUTING, Regel: :POSTROUTING AKZEPTIEREN [0:0]
I0807 11:41:24.575691 8369 proxier.go:401] Regel: -A POSTROUTING ! -d 10.0.0.0/8 -o eth0 -j MASQUERADE
I0807 11:41:24.575699 8369 proxier.go:401] Regel: -A POSTROUTING -s 10.240.240.78/32 -d 10.240.240.78/32 -m Kommentar --comment "handle pod connect to self" -j MASQUERADE
I0807 11:41:24.575709 8369 proxier.go:399] Kette: KUBE-NODEPORT-CONTAINER, Regel: :KUBE-NODEPORT-CONTAINER - [0:0]
I0807 11:41:24.575720 8369 proxier.go:399] Kette: KUBE-NODEPORT-HOST, Regel: :KUBE-NODEPORT-HOST - [0:0]
I0807 11:41:24.575729 8369 proxier.go:399] Kette: KUBE-PORTALS-CONTAINER, Regel: :KUBE-PORTALS-CONTAINER - [0:0]
I0807 11:41:24.575740 8369 proxier.go:399] Kette: KUBE-PORTALS-HOST, Regel: :KUBE-PORTALS-HOST - [0:0]
I0807 11:41:24.581897 8369 proxier.go:603] Synchronisierungsregel: :KUBE-PORTALS-HOST - [0:0]
:KUBE-PORTALS-CONTAINER - [0:0]
:KUBE-NODEPORT-HOST - [0:0]
:KUBE-NODEPORT-CONTAINER - [0:0]
:KUBE-SVC-VO8JL93ZeRSf8cnsLpl - [0:0]
:KUBE-SVC-L26cB3JYuxdW5TF84ct - [0:0]
:KUBE-SVC-j2SF8q3nUajS8vOx2qL - [0:0]
:KUBE-SVC-shln2urO8W1aBiB2bWJ - [0:0]
:KUBE-SVC-8jQ3IvijvhJ4ppFj3Ui - [0:0]
[... SCHNIP...]

Das Zusammenführen eines iptable-save mit dem im ausführlichen Modus erzeugten Ergebnis kann importiert werden und gute Dinge tun.

@bnprss danke für den Bericht, es gab vor kurzem eine Reihe von ungetesteten Änderungen, einschließlich der Verwendung einer temporären Datei und der Verwendung des Flags "-T table" für iptables-restore während einiger Überarbeitungen für den Überprüfungsprozess. Ich werde eine Korrektur vornehmen, sobald ich weiß, was die Regression(en) verursacht hat.

@bnprss Wie Sie sagten, fehlt der Tabellenkopf ("*nat" sollte die erste Zeile sein), er wurde fälschlicherweise entfernt und nachdem er wieder eingefügt wurde, scheint alles wieder einwandfrei zu funktionieren, scheinbar ohne andere Fehler (außer: https:/ /github.com/BenTheElder/kubernetes/issues/3). Danke nochmal, tut mir leid. Ich habe den Fix verschoben.

Gute Arbeit, Regeln werden geladen und scheinen von innen zu funktionieren, aber kein Glück mit externalloadbalancer keine Kommunikation von außen gibt Antwort.

Hm. Könnten Sie zum PR übergehen und weitere Details angeben? Bisher
es hat gut funktioniert, aber ich setze mich nicht über lokale Tests hinaus ein und ich
glaube nicht, dass einer der anderen Tester einen externen Load Balancer verwendet hat.
Am 7. August 2015, 13:29 Uhr, schrieb "bnprss" [email protected] :

Schöne Arbeit, Regeln werden geladen und scheinen von innen zu funktionieren, aber kein Glück
bei externalloadbalancer keine kommunikation von aussen antwortet.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128772763
.

Ja, für die Details werde ich weitere Nachforschungen anstellen und einige Protokolle oder Hinweise zu PR erstellen, aber nicht vor morgen, ich möchte einen guten Backup-Job ausführen, bevor möglicherweise etwas kaputt geht.

Können Sie das Token der Regeln ohne Trennzeichen "-_" berechnen?

@bnprss ,
Die generierten Regelketten für Dienste sind ein Hash des Dienstports / Endpunkts und dann base64-URL-kodiert und abgeschnitten. KUBE-SVC-. Der Code ist hier: https://github.com/GoogleCloudPlatform/kubernetes/pull/9210/files#diff -d51765b83fe795b469e8a86276b12dc9R321
Wir haben dies gewählt, um gültige Kettennamen zu generieren, die die Zeichenbeschränkung in iptables erfüllen und dennoch deterministisch sind.
Es sollte also möglich sein, extern zu replizieren.
Wenn Sie meinen, können wir aufhören, Trennzeichen zu verwenden, könnten wir es wahrscheinlich tun, aber das "_" kommt von einigen codierten Hashs und das "-" folgt alle nur den Mustern in den Regelnamen des vorhandenen Userspace-Proxys.
Wir könnten wahrscheinlich ohne großen Aufwand etwas anderes verwenden, wenn es nötig war.

Ich bin damit einverstanden, und das ist wirklich kosmetisch! :)
Aber das unterscheidet sich von den Dingen, die ich vorher gesehen habe:
gce lb Regeln: a07f76b3b2ec311e59e2642010af0479
gce fw-Regeln: k8s-fw-a7ecad94f3ba511e59e2642010af0479
gce-Routingregeln: default-route-6973e029b504a0e8
gce-Routing zum Knoten: obfuscated_cluster_node-43506797-2eb2-11e5-9e26-42010af04793

dieser ist schön:
KUBE-SVC-6ADi2TVfn7mFPvBjC56
die sind lustig:
KUBE-SVC-zU6ParcQ-UfW_LdRDUc
KUBE-SVC-y--z1xTUpHPT6sgAUCC

Ja, ich bin auch nicht gerade ein Fan davon, wir könnten vielleicht das Haschisch ändern
Codierung.

Am Freitag, den 7. August 2015 um 14:16 Uhr schrieb bnprss [email protected] :

Ich bin damit einverstanden, und das ist wirklich kosmetisch! :)
Aber das unterscheidet sich von den Dingen, die ich vorher gesehen habe:
gce lb Regeln: a07f76b3b2ec311e59e2642010af0479
gce fw-Regeln: k8s-fw-a7ecad94f3ba511e59e2642010af0479
gce-Routingregeln: default-route-6973e029b504a0e8
gce-Routing zum Knoten:
obfuscated_cluster_node-43506797-2eb2-11e5-9e26-42010af04793

dieser ist schön:
KUBE-SVC-6ADi2TVfn7mFPvBjC56
die sind lustig:
KUBE-SVC-zU6ParcQ-UfW_LdRDUc
KUBE-SVC-y--z1xTUpHPT6sgAUCC


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128785914
.

Ja, es kann möglich sein, nur den abgeschnittenen Teil von SHA zu verwenden, git ist damit in Ordnung, Docker auch und scheint die Art und Weise zu sein, wie die anderen Verweise auf kube-Entitäten gemacht werden. Im Falle einer Kollision im generierten Hash hilft base64 nicht. ;)
Ich denke, @thockin könnte zu diesem Punkt Ratschläge geben.

Ich war mehr besorgt über gültige Zeichen in iptables, für die ich Schwierigkeiten hatte, eine gute Referenz zu finden. Ich werde das in Kürze weiter untersuchen.

Am Freitag, den 7. August 2015 um 14:29 Uhr schrieb bnprss [email protected] :

Ja, es kann möglich sein, nur den abgeschnittenen Teil von SHA zu verwenden, git ist damit ok
das, Docker auch, und scheint übrigens der andere Hinweis auf kube zu sein
Entitäten gemacht werden. Im Falle einer Kollision im generierten Hash wird base64 nicht
Hilfe. ;)
Ich denke, @tockin https://github.com/tockin könnte zu diesem Punkt beraten.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128788454
.

@bnprss zu Ihrer Information, der PR ist ziemlich instabil und wird per tockin überarbeitet. Wir kürzen NodePort usw. vorerst ab und konzentrieren uns darauf, eine einfachere, sauberere Version mit Unterstützung für Portale zu erhalten, und arbeiten dann wieder auf volle Parität.

Ich würde _nicht_ versuchen, dies jetzt zu starten, aber es wird hoffentlich bald wiederkommen. Den PR in einige kleinere verwandte aufteilen und dann einen sauberen mit dem iptables-proxy-Zeug vorantreiben.

Für diejenigen von euch, die zu Hause spielen, bin ich zuversichtlich, dass wir es voll machen können
Parität, aber es wird viel einfacher sein, in Etappen zu überprüfen :)

Am Freitag, 7. August 2015 um 21:35 Uhr, Benjamin Elder [email protected]
schrieb:

Meine Antwort auf den obigen Kommentar, die auch bald weggequetscht wird:

Im IRC diskutiert:

  • muss immer noch mit Zählern umgehen, möchte aber weiterhin parsen von
    Zustand im Paket util/iptables.
  • benötigen noch Hashing oder ähnliches, um die Kettenlängenbeschränkungen zu handhaben

Scheint ansonsten eine sehr saubere Vereinfachung zu sein, wird nachher umgesetzt
noch eine Diskussion.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/GoogleCloudPlatform/kubernetes/issues/3760#issuecomment -128912169
.

Status: Die "Haupt"-Logik ist eingecheckt und mit Flag-Gate versehen.

Ich arbeite jetzt an Knotenports. Es gibt viele seltsame Fälle, die eine besondere Behandlung erfordern. Meine Notizen bisher:

# Basic node ports:
iptables -t nat -N KUBE-NODEPORTS
iptables -t nat -A PREROUTING -j KUBE-NODEPORTS
iptables -t nat -A OUTPUT -j KUBE-NODEPORTS
iptables -t nat -A KUBE-NODEPORTS -p tcp -m comment --comment "TEST: default/nodeport:p" -m tcp --dport 30241 -j KUBE-SVC-EQKU6GMUKRXBR6NWW53

# To get traffic from node to localhost:nodeport to the service:
echo 1 > /proc/sys/net/ipv4/conf/all/route_localnet
# Mark packets that are destined for services from localhost, then masquerade those
iptables -t nat -I KUBE-SVC-EQKU6GMUKRXBR6NWW53 -s 127.0.0.0/16 -j MARK --set-mark 0x4b000001;
iptables -t nat -A POSTROUTING -m mark --mark 0x4b000001 -j MASQUERADE

# To get traffic from a pod to itself via a service:
for intf in $(ip link list | grep veth | cut -f2 -d:); do brctl hairpin cbr0 $intf on; done
# Mark packets that are destined for each endpoint from the same endpoint, then masquerade those.
# This is hacky, but I don't really know which pods are "local" and I don't really want to right now. (but I will eventually)
iptables -t nat -I KUBE-SEP-HHNEQBOLY57T5MQCFIY -s 10.244.1.6 -j MARK --set-mark 0x4b000001

Arbeite an einem Contrib-Tool zum Testen.
Bisher denke ich, dass ich einen Server auf einem Knoten hochfahren werde, Zeitlatenz von
Anfragen an ihn, siehe Abrufen der kube-proxy-Ressourcenlast und Dump der
Daten in CSV zur grafischen Darstellung usw.
Hoffentlich vor Freitag fertig, um sich jetzt mit kubectl vertraut zu machen.

Am Mittwoch, 12. August 2015 um 20:48 Uhr, Tim Hockin [email protected]
schrieb:

Status: Die "Haupt"-Logik ist eingecheckt und mit Flag-Gate versehen.

Ich arbeite jetzt an Knotenports. Es gibt viele verrückte Fälle, die brauchen
besondere Behandlung. Meine Notizen bisher:

Grundlegende Knotenports:

iptables -t nat -N KUBE-NODEPORTS
iptables -t nat -A PREROUTING -j KUBE-NODEPORTS
iptables -t nat -A AUSGABE -j KUBE-NODEPORTS
iptables -t nat -A KUBE-NODEPORTS -p tcp -m Kommentar --comment "TEST: default/ nodeport:p " -m tcp --dport 30241 -j KUBE-SVC-EQKU6GMUKRXBR6NWW53

So rufen Sie Datenverkehr vom Knoten zu

echo 1 > /proc/sys/net/ipv4/conf/all/route_localnet

Markieren Sie Pakete, die für Dienste von localhost bestimmt sind, und maskieren Sie diese dann

iptables -t nat -I KUBE-SVC-EQKU6GMUKRXBR6NWW53 -s 127.0.0.0/16 -j MARK --set-mark 0x4b000001;
iptables -t nat -A POSTROUTING -m mark --mark 0x4b000001 -j MASQUERADE

So leiten Sie über einen Dienst Datenverkehr von einem Pod zu sich selbst ab:

für intf in $(IP-Linkliste | grep veth | cut -f2 -d:); do brctl haarnadel cbr0 $intf on; getan

Markieren Sie Pakete, die für jeden Endpunkt vom gleichen Endpunkt bestimmt sind, und maskieren Sie diese dann.

Das ist hackig, aber ich weiß nicht wirklich, welche Pods "lokal" sind, und ich möchte es im Moment auch nicht wirklich. (aber ich werde irgendwann)

iptables -t nat -I KUBE-SEP-HHNEQBOLY57T5MQCFIY -s 10.244.1.6 -j MARK --set-mark 0x4b000001


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130492394
.

@BenTheElder Ich habe gerade einige einigermaßen detaillierte Netzwerk-Perf-Messungen auf GCE durchgeführt - ich empfehle, einen Blick auf netperf zu werfen (qperf gibt auch Latenzmessungen an).

netperf ist ein Client/Server-Perf-Tool, ich habe sowohl den Client als auch den Server in den Docker-Container paultiplady/ netserver:ubuntu.2 gepackt. Es gibt viele Optionen auf netperf, aber so etwas wie zwei Netserver-Pods hochfahren und ausführen

kubectl exec  -t $netserver-pod-1 -- netperf –l 30 -i 10 -I 99,1 -c -j -H $netserver-pod-2-ip -t OMNI --  -T tcp -D -O THROUGHPUT,THROUGHPUT_UNITS,MEAN_LATENCY,MIN_LATENCY,MAX_LATENCY,P50_LATENCY,P90_LATENCY,P99_LATENCY,STDDEV_LATENCY,LOCAL_CPU_UTIL

sollte Ihnen eine anständige Verteilung von Statistiken einschließlich Latenz und Durchsatz geben. Sie können den Netserver-Container auch mit docker run --net=host ausführen, um auch node->pod-Tests durchzuführen.

Das Dockerfile für diesen Container ist ziemlich einfach, ich kann es abfeuern, wenn Sie es in etwas schlankeres erweitern möchten (zB einen alpinelinux-basierten Container zum schnelleren Ziehen).

Danke das werde ich mir anschauen.

Aus diesem Kommentar geht jedoch hervor, dass wir eine Art Serviceanfrage-Latenzzeit erreichen möchten. Im Moment versuche ich, den Standard-nginx-Container als Knoten X zu verwenden, und arbeite daran, einen Test-Pod wiederholt zu treffen, damit wir einen Graphen auf Knoten Y erstellen können.

Ich werde mir jedoch netperf/qperf ansehen, und wir können immer mehrere Tests durchführen.
Ich möchte dieses Diagramm zuerst erstellen, obwohl es in der vorherigen Diskussion mit @tockin

Am Do, 13. August 2015 um 00:02 Uhr, Paul Tiplady [email protected]
schrieb:

@BenTheElder https://github.com/BenTheElder Ich habe gerade etwas vernünftiges gemacht
detaillierte Netzwerkleistungsmessungen auf GCE -- ich empfehle einen Blick auf
netperf (qperf liefert auch Latenzmessungen).

netperf ist ein Client/Server-Perf-Tool, ich habe sowohl den Client als auch gepackt
der Server im Docker-Container paultiplady/ netserver:ubuntu.2. Dort
Es gibt viele Optionen auf netperf, aber so etwas wie das Drehen von zwei
Netserver-Pods und läuft

kubectl exec -t $netserver-pod-1 -- netperf –l 30 -i 10 -I 99,1 -c -j -H $netserver-pod-2-ip -t OMNI -- -T tcp -D -O THROUGHPUT,THROUGHPUT_UNITS,MEAN_LATENCY,MIN_LATENCY,MAX_LATENCY,P50_LATENCY,P90_LATENCY,P99_LATENCY,STDDEV_LATENCY,LOCAL_CPU_UTIL

sollte Ihnen eine anständige Verteilung von Statistiken einschließlich Latenz und Durchsatz geben.
Sie können den Netserver-Container mit docker run --net=host to do ausführen
Knoten->Pod-Tests auch.

Das Dockerfile für diesen Container ist ziemlich einfach, ich kann es abfeuern, wenn
Sie es zu etwas schlankeren erweitern möchten (z. B. ein alpinelinux-basiertes
Behälter zum schnelleren Ziehen).


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130524576
.

zu Knotenports: In #9210 brachte @Symmetric diesen Fall:

Wenn der Verkehr fließt:
LB -> node1:nodePort
Und der Service-Pod befindet sich auf node2, dann ist der vollständige Ablauf:
LB -> node1:nodePort -> node2 -> pod:svcPort
Die srcIP wird immer noch die LB sein, also wird die Antwort gehen
pod -> node2 -> LB
Da node2 direkt zum LB routen kann.

Jetzt verlieren wir die Gelegenheit, die DNAT aufzuheben, um die richtige Quell-IP für das Rückpaket wiederherzustellen (das kann nur auf Knoten 1 passieren).

Ich habe das Problem reproduziert. ACK, dass es ein echtes Problem ist. tcpdump zeigt an, dass die Pakete mit DNAT an den (außerhalb der Maschine befindlichen) Pod IP:port mit intaktem src gesendet werden, aber tcpdump auf der Zielmaschine zeigt nichts an. Ich bin mir nicht sicher, was ich erwarten würde, selbst wenn die Pakete dort ankommen würden.

Ich denke, die einzige Lösung ist SNAT. Die am wenigsten wirkungsvolle Lösung wäre, _nur_ SNAT-Pakete von der LB, die für Off-Node bestimmt sind, zu verwenden, aber a) ich habe diese Informationen nicht in kube-proxy (könnte sie auf Kosten von Code erhalten) und b) da alle Politik muss den SNAT-Fall sowieso berücksichtigen, kann ich vereinfachen, indem ich immer externe LB-Pakete SNATing. Wie schlimm ist das für Policy Engines?

Schließlich werden LBs intelligent genug sein, um nur Hosts mit Pods anzusprechen, und der Verkehr bleibt lokal, und dann wird dies strittig sein.

Es wird jedoch komplizierter. Wir haben das Feld "deprecatedPublicIPs", das wir wahrscheinlich mit einigen Verhaltensänderungen aufheben werden. Ich denke, wir müssen das Gleiche für die tun. Aber es wird noch komplizierter - ich kenne nicht alle öffentlichen IPs (zB hat die VM eine 1-zu-1-NAT-externe IP). Einfache Antwort - immer SNAT-Knoten-Port-Pakete. Was denken?

Ich teste morgen mehr.

@BenTheElder Sie könnten den Netserver-Pod zu einem Dienst machen, damit der Verkehr von perf <->
Server geht über den Service VIP. So musst du das nicht machen
Sampling-/Latenzberechnungen selbst...

Am Mittwoch, den 12. August 2015 um 21:20 Uhr, Benjamin Elder [email protected]
schrieb:

Danke das werde ich mir anschauen.

Aus diesem Kommentar
obwohl ich denke, dass wir eine Art Service-Request-Latenzzeit machen wollen. Rechts
Jetzt habe ich versucht, den Standard-Nginx-Container als Knoten X zu verwenden und daran zu arbeiten
eine Test-Pod-Zeit haben, um sie wiederholt zu treffen, damit wir ein Diagramm erstellen können
Knoten Y.

Ich werde mir jedoch netperf/qperf ansehen, und wir können immer mehrere Tests durchführen.
Ich möchte dieses Diagramm zuerst erstellen, obwohl es in der vorherigen Diskussion mit
@thockin

Am Do, 13. August 2015 um 00:02 Uhr, Paul Tiplady [email protected]
schrieb:

@BenTheElder https://github.com/BenTheElder Ich habe gerade etwas vernünftiges gemacht
detaillierte Netzwerkleistungsmessungen auf GCE -- ich empfehle einen Blick auf
netperf (qperf liefert auch Latenzmessungen).

netperf ist ein Client/Server-Perf-Tool, ich habe sowohl den Client als auch gepackt
der Server im Docker-Container paultiplady/ netserver:ubuntu.2. Dort
Es gibt viele Optionen auf netperf, aber so etwas wie das Drehen von zwei
Netserver-Pods und läuft

kubectl exec -t $netserver-pod-1 -- netperf –l 30 -i 10 -I 99,1 -c -j -H
$netserver-pod-2-ip -t OMNI -- -T tcp -D -O
THROUGHPUT,THROUGHPUT_UNITS,MEAN_LATENCY,MIN_LATENCY,MAX_LATENCY,P50_LATENCY,P90_LATENCY,P99_LATENCY,STDDEV_LATENCY,LOCAL_CPU_UTIL

sollte Ihnen eine anständige Verteilung von Statistiken einschließlich Latenz und
Durchsatz.
Sie können den Netserver-Container mit docker run --net=host to do ausführen
Knoten->Pod-Tests auch.

Das Dockerfile für diesen Container ist ziemlich einfach, ich kann es abfeuern, wenn
Sie es zu etwas schlankeren erweitern möchten (z. B. ein alpinelinux-basiertes
Behälter zum schnelleren Ziehen).


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
<
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130524576

.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130527558
.

Wahr. Ich denke, @tockin hat erwähnt, dass er schließlich einen e2e-Latenztest als
Gut. Wenn es die Zeit erlaubt, wird es eine Reihe verschiedener Tests geben und wir werden
muss wahrscheinlich gce vs AWS usw. berücksichtigen.
Am 13. August 2015 um 13:47 Uhr schrieb "Paul Tiplady" [email protected] :

Sie könnten den Netserver-Pod zu einem Dienst machen, damit der Verkehr von perf <->
Server geht über den Service VIP. So musst du das nicht machen
Sampling-/Latenzberechnungen selbst...

Am Mittwoch, den 12. August 2015 um 21:20 Uhr, Benjamin Elder [email protected]
schrieb:

Danke das werde ich mir anschauen.

Von [diesem Kommentar](

https://github.com/kubernetes/kubernetes/pull/9210#issuecomment-130154261)
obwohl ich denke, dass wir eine Art Service-Request-Latenzzeit machen wollen. Rechts
Jetzt habe ich versucht, den Standard-Nginx-Container als Knoten X zu verwenden und zu arbeiten
An
eine Test-Pod-Zeit haben, um sie wiederholt zu treffen, damit wir ein Diagramm erstellen können
Knoten Y.

Ich werde mir jedoch netperf/qperf ansehen, und wir können immer mehrere Tests durchführen.
Ich möchte dieses Diagramm zuerst erstellen, obwohl es in der vorherigen Diskussion mit
@thockin

Am Do, 13. August 2015 um 00:02 Uhr, Paul Tiplady < [email protected]

schrieb:

@BenTheElder https://github.com/BenTheElder Ich habe gerade etwas gemacht
vernünftig
detaillierte Netzwerk-Perf-Messungen auf GCE -- ich empfehle einen Blick
bei
netperf (qperf liefert auch Latenzmessungen).

netperf ist ein Client/Server-Perf-Tool, ich habe sowohl den Client gepackt
und
der Server im Docker-Container paultiplady/ netserver:ubuntu.2.
Dort
Es gibt viele Optionen auf netperf, aber so etwas wie das Drehen von zwei
Netserver-Pods und läuft

kubectl exec -t $netserver-pod-1 -- netperf –l 30 -i 10 -I 99,1 -c -j
-H
$netserver-pod-2-ip -t OMNI -- -T tcp -D -O

THROUGHPUT,THROUGHPUT_UNITS,MEAN_LATENCY,MIN_LATENCY,MAX_LATENCY,P50_LATENCY,P90_LATENCY,P99_LATENCY,STDDEV_LATENCY,LOCAL_CPU_UTIL

sollte Ihnen eine anständige Verteilung von Statistiken einschließlich Latenz und
Durchsatz.
Sie können den Netserver-Container mit docker run --net=host to do ausführen
Knoten->Pod-Tests auch.

Das Dockerfile für diesen Container ist ziemlich einfach, ich kann es überfeuern
wenn
Sie es zu etwas schlankeren erweitern möchten (z. B. ein alpinelinux-basiertes
Behälter zum schnelleren Ziehen).


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
<

https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130524576

.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
<
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130527558

.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130776866
.

@Symmetric Die Netperf-Tests funktionieren gut. Danke für den Vorschlag :-)

Ich würde den Test für eine "echte" Last wie einen Webdienst später möglicherweise wiederholen, aber nachdem ich die Argumente richtig verstanden habe, liefert er bisher sehr schöne Daten. Ich werde die Ergebnisse später posten, wenn ich mit dem Aufräumen fertig bin.

Freut mich zu hören, dass das bei dir funktioniert – es gibt eine verwirrende Anzahl von
Optionen für dieses Tool, aber es hat sich für meine Profilerstellung als sehr nützlich erwiesen.
Definitiv besser als iperf...

Am Do, 13. August 2015 um 14:32 Uhr, Benjamin Elder [email protected]
schrieb:

@Symmetric https://github.com/Symmetric die Netperf-Tests funktionieren
schön. Danke für den Vorschlag :-)

Ich möchte den Test für eine "echte" Last wie einen Webservice später wiederholen
möglicherweise, aber nachdem man die Argumente richtig gemacht hat, gibt es sehr schöne Daten, also
weit. Ich werde die Ergebnisse später posten, wenn ich mit dem Aufräumen fertig bin.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -130850398
.

@thockin Ich denke, wir können mit SNAT für LB-Verkehr leben. Meine derzeitige Meinung ist, dass Sie die Zugriffsrichtlinie eines Pods als eine der folgenden angeben müssen:

  • Standard ist 'allow from [my namespace]', in diesem Fall werden LB-Pakete verworfen
  • 'allow from [list of namespaces]' oder 'allow from [all namespaces in the cluster]', auch hier werden LB-Pakete immer verworfen
  • 'von allen zulassen', in diesem Fall ist es uns egal, ob es von einem LB, einem anderen Knoten oder wo auch immer ist

Der Verlust der Quell-IP für LBs kostet uns also nicht viel.

Wenn wir garantieren können, dass der LB den richtigen Knoten für den Service-Pod erreicht, wäre das großartig – in diesem Fall brauchen wir kein SNAT und können ein strafferes Schiff betreiben, indem wir LB-IPs auf die Whitelist setzen, wenn sie auf einem bereitgestellt werden Dienst, und den Verkehr sonst fallenlassen.

In Bezug auf publicIPs denke ich, dass sie die gleichen Überlegungen wie nodePort haben, und daher müssen wir sie SNATieren, bis LBs die richtigen Hosts erreichen können. Was nach dem oben genannten in Ordnung ist, es sei denn, ich übersehe irgendwie, dass sie böser sind als nodePort ...

Aus Sicherheitsgründen könnte es sehr nützlich sein, tatsächlich ein Flag zum Proxy einzufügen, um alles zu MASQUERADE (das sich sehr nahe an einem Userspace-Proxy verhält). Ich denke, es ist nicht sehr schwer zu tun und eine sehr gute Möglichkeit, im Falle eines Problems zu diagnostizieren oder sogar zurückzugreifen (ich denke an vxlan-Fälle).

-------- Herkunftsnachricht --------
De : Paul Tiplady [email protected]
Datum : 14.08.2015 12:50 (GMT+11:00)
: kubernetes/kubernetes [email protected]
Cc : Mikaël Cluseau [email protected]
Objet : Re: [kubernetes] verwende iptables für Proxying anstelle von Userspace
(#3760)

@thockin Ich denke, wir können mit SNAT für LB-Verkehr leben. Meine derzeitige Meinung ist, dass Sie die Zugriffsrichtlinie eines Pods als eine der folgenden angeben müssen:

Standard ist 'allow from [my namespace]', in diesem Fall werden LB-Pakete verworfen
'allow from [list of namespaces]' oder 'allow from [all namespaces in the cluster]', auch hier werden LB-Pakete immer verworfen
'von allen zulassen', in diesem Fall ist es uns egal, ob es von einem LB, einem anderen Knoten oder wo auch immer ist

Der Verlust der Quell-IP für LBs kostet uns also nicht viel.

Wenn wir garantieren können, dass der LB den richtigen Knoten für den Service-Pod erreicht, wäre das großartig – in diesem Fall brauchen wir kein SNAT und können ein strafferes Schiff betreiben, indem wir LB-IPs auf die Whitelist setzen, wenn sie auf einem bereitgestellt werden Dienst, und den Verkehr sonst fallenlassen.

In Bezug auf publicIPs denke ich, dass sie die gleichen Überlegungen wie nodePort haben, und daher müssen wir sie SNATieren, bis LBs die richtigen Hosts erreichen können. Was nach dem oben genannten in Ordnung ist, es sei denn, ich übersehe irgendwie, dass sie böser sind als nodePort ...


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an.

@MikaelCluseau das ist keine schlechte Idee - kannst du bitte speziell dazu ein neues Thema eröffnen, damit ich nicht den Überblick verliere?

Noch TODO: Haarnadel reparieren, e2e, standardmäßig aktivieren

Hi Tim, tut mir leid, dass ich nicht zu dir zurückkomme, aber wir hatten hier einiges zu besorgen... Ich werde die feste Haarnadelkurve nächsten Samstag wählen, denke ich.

Dies war eine Anmerkung für mich selbst - planten Sie, einiges davon in Angriff zu nehmen? :)

Ja, sicher, wie ich schon sagte, als wir über e2e-Tests sprachen. Ich werde helfen, Kubernetes ist eine große Hilfe für mich, also beherrsche ich es besser so gut es geht, und was ist besser, als Bugs zu nehmen? :-) Fühlen Sie sich frei, etwas mit höherer Priorität vorzuschlagen, aber ich denke, Haarnadelkurven sind für den Anfang ziemlich gut. Es sollte im Kubelet stattfinden und ein Flag zum Aktivieren haben (vorerst standardmäßig deaktiviert). Ich werde versuchen, 0,5 bis 1 Tag pro Woche zu arbeiten.

AFAIK der einzige Teil, der noch zu tun ist, ist, es zum Standard zu machen, was einige Zeit nach v1.1 passieren kann (vorausgesetzt, keine Blow-ups) und dies hat einige Meilen auf sich.

Huhu!

Am Do, 24. September 2015 um 11:21 Uhr, Tim Hockin [email protected]
schrieb:

AFAIK der einzige Teil, der noch zu tun ist, ist, es zum Standard zu machen, der kann
passieren (vorausgesetzt keine Explosionen) einige Zeit nach v1.1 und dies hat einige Meilen
darauf.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -142960614
.

einige Zeit nach v1.1 und das hat einige Meilen drauf.

Autsch. Wir haben am 1.1 wirklich damit gerechnet....
https://github.com/kubernetes/kubernetes/blob/master/docs/roadmap.md

@bgrieder Sie können es immer noch über Parameter aktivieren.

Es ist IN, aber standardmäßig nicht aktiviert. Sie können sich mit einer einzigen Anmerkung per anmelden
Knoten (und ein Kube-Proxy-Neustart)

Am Do, 24. September 2015 um 8:27 Uhr schrieb Bruno G. [email protected] :

einige Zeit nach v1.1 und das hat einige Meilen drauf.

Autsch. Wir haben am 1.1 wirklich damit gerechnet....
https://github.com/kubernetes/kubernetes/blob/master/docs/roadmap.md


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -142962932
.

@thockin @bnprss ok, aber wir erwarten, dass Version 1.1 nach der Veröffentlichung auf der Google Container Engine ausgeführt wird. Ich frage mich, welche Flexibilität wir haben werden, um „mit einer einzigen Anmerkung pro Knoten“ zuzustimmen. Könnten Sie uns bitte einige Details zum Ablauf mitteilen oder uns auf eine Dokumentation hinweisen ?

Nach dem Upgrade auf 1.1:

$ for node in $(kubectl get nodes -o name); do kubectl annotate $node net.beta.kubernetes.io/proxy-mode=iptables; done

Dann SSH zu jedem Knoten und starten Sie kube-proxy neu (oder starten Sie jeden Knoten neu).

Wenn Sie vorsichtiger sein möchten, machen Sie ein oder zwei Nodes und probieren Sie es dann aus :)

Ich habe dieses Problem als "Versionshinweis" markiert, damit wir nicht vergessen, diese magische Schleife in unsere 1.1-Dokumentation aufzunehmen.

@RichieEscarez

(Ich wollte nur vorbeischauen und sagen, dass wir das iptables-Proxying jetzt seit einer Woche verwenden und es scheint alles in Ordnung zu sein!)

@thockin Sollte dies geschlossen oder aus dem 1.1-Meilenstein entfernt werden?

Ich werde es nur für die Standardaktivierung auf 1.2 verschieben.

Entschuldigung für eine möglicherweise dumme Frage, aber in Bezug auf die Erhaltung der Client-IPs:

@tockin Ich habe in einer anderen Ausgabe vom 2. September gesehen, dass "nur der Intra-Cluster-Datenverkehr die Client-IP behält" - gilt dies immer noch für das 1.2-Alpha?

Wir haben einen neuen 1.2-Cluster gestartet, die Node-Annotation angewendet, neu gestartet und sehen immer noch 10.244.0.1 als Quelladresse für alle Anfragen an einen Pod, auf dem HAProxy ausgeführt wird.

An dieser Stelle versuche ich nur herauszufinden, ob wir eine Einstellung übersehen haben oder nicht, oder ich versuche, etwas zu erreichen, was noch nicht möglich ist - das heißt, die öffentliche IP-Adresse des tatsächlichen Clients zu sehen, von dem die Anfrage gestellt wird außerhalb des Clusters.

Die Standardeinstellung verwendet weiterhin den Userspace-Modus. Sie müssen eine Anmerkung aktivieren
den Knoten (net.beta.kubernetes.io/proxy-mode=iptables) und starten Sie den
Stellvertreter. Dadurch werden jedoch keine externen Client-IPs verfügbar gemacht, sondern nur innerhalb des Clusters
IPs.
Am 23. Oktober 2015, 17:09 Uhr, schrieb "Ben Hundley" [email protected] :

Entschuldigung für eine möglicherweise dumme Frage, aber in Bezug auf die Konservierung
der Client-IPs:

@tockin https://github.com/tockin Ich habe es in einer anderen Ausgabe vom 2. September gesehen
dass "nur der Intra-Cluster-Datenverkehr die Client-IP behält" -- ist das immer noch?
stimmt das für den 1.2 alpha?

Wir haben einen neuen 1.2-Cluster gestartet, die Knotenanmerkung angewendet, neu gestartet,
und sehen Sie immer noch 10.244.0.1 als Quelladresse für alle Anfragen an a
Pod, auf dem HAProxy ausgeführt wird.

An dieser Stelle versuche ich nur herauszufinden, ob wir eine verpasst haben oder nicht
Einstellung oder ich versuche etwas zu erreichen, was noch nicht möglich ist -- das
sieht die öffentliche IP-Adresse des tatsächlichen Clients, der die Anfrage stellt
von außerhalb des Clusters.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150725513
.

Ich kann die externe Client-IP beibehalten, indem ich externen Datenverkehr mit DNAT + Routing über einen Kube-Proxy leitet. Wenn Ihr Dienstnetzwerk beispielsweise 10.42.0.0/16 ist und Sie einen hochverfügbaren Kube-Proxy auf der IP 10.10.1.1 haben, können Sie die folgende iptable-Regel verwenden:

-A PREROUTING -i public -p tcp -m tcp --dport 25 -j DNAT --to-destination 10.42.12.34

und folgende Strecke:

10.42.0.0/16 via 10.10.1.1 dev edge 

Der Pod dahinter sieht dann die echte IP:

Oct 24 02:41:39 email-0yr7n mail.info postfix/smtpd[469]: connect from zed.yyy.ru.[94.102.51.96]

Sie müssen natürlich das Recht auf den Rückweg des Pakets haben.

Ja, wenn dieser DNAT zu einem Off-Machine-Backend führt, bilden Sie ein Dreieck ohne
SNAT. Dies ist das grundlegende Problem.

Am Freitag, 23. Oktober 2015 um 20:12 Uhr, Mikaël Cluseau [email protected]
schrieb:

Ich kann die externe Client-IP behalten, indem ich externen Datenverkehr mit DNAT +
Routing über einen Kube-Proxy. Wenn Ihr Servicenetzwerk beispielsweise
10.42.0.0/16 und Sie haben einen hochverfügbaren Kube-Proxy auf der IP
10.10.1.1 können Sie die folgende iptable-Regel haben:

-A PREROUTING -i public -p tcp -m tcp --dport 25 -j DNAT --to-destination 10.42.12.34

und folgende Strecke:

10.42.0.0/16 über 10.10.1.1 Entwicklungskante

Der Pod dahinter sieht dann die echte IP:

24. Okt 02:41:39 email-0yr7n mail.info postfix/smtpd[469]: Verbindung von zed.yyy.ru.[94.102.51.96]

Sie müssen natürlich das Recht auf den Rückweg des Pakets haben.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150747217
.

Klingt interessant, ein Link? :-) Ich versuche, einen Weg zu finden, um sicherzustellen, dass das Paket die richtige Conntrack-Regel durchläuft. Ich dachte darüber nach, den Conntrack-Zustand über den Cluster zu replizieren.

Ich bin ein bisschen verloren mit dem, was Sie erreichen wollen.

Der aktuelle iptables-Proxy soll so funktionieren, dass ein Paket
an einem Knoten ankommt, erkennen wir, dass er nicht lokal generiert wurde, markieren ihn für
SNAT, Backend auswählen, mit SNAT zum Backend weiterleiten, Backend antwortet
zu uns, wir un-SNAT, un-DNAT und antworten auf externe Benutzer.

Am Freitag, 23. Oktober 2015 um 21:32 Uhr, Mikaël Cluseau [email protected]
schrieb:

Klingt interessant, ein Link? :-) Ich versuche einen Weg zu finden, um sicher zu sein
Paket durchläuft die richtige Conntrack-Regel. ich dachte an
Replizieren des Conntrack-Zustands durch den Cluster.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150753147
.

Oh, tut mir leid, wenn ich nicht klar bin. Ich sprach über den Fall ohne SNAT. Wenn jeder Kube-Proxy die gleiche Conntrack-Liste hat, sollte jeder von ihnen in der Lage sein, die DNAT korrekt aufzuheben, wenn der Container dem Kunden antwortet.

Ich konnte kein Was ohne Replikation sehen, das keine HA beinhaltet, um eine linienförmige Struktur wie diese beizubehalten:

[client] ----- [proxy in HA] ------ [node1]
                           `------- [node2]

Aber wenn ein dreieckiges Ding funktionieren kann, sollte es mehr Möglichkeiten eröffnen.

[client] ----- [proxy1] ------ [node1]
       `------ [proxy2] ------ [node2]

Das wäre süß, scheint aber verrückt kompliziert zu sein

Am So, 25.10.2015 um 23:20 Uhr, Mikaël Cluseau [email protected]
schrieb:

Oh, tut mir leid, wenn ich nicht klar bin. Ich sprach über den Fall ohne SNAT. Wenn
Jeder Kube-Proxy hat die gleiche Conntrack-Liste, jeder von ihnen sollte in der Lage sein
un-DNAT korrekt, wenn der Container dem Kunden antwortet.

Ich konnte kein Was ohne Replikation sehen, die keine HA beinhaltet, um ein zu behalten
linienförmige Struktur wie folgt:

[Client] ----- [Proxy in HA] ------ [node1]
`------- [Knoten2]

Aber wenn ein dreieckiges Ding funktionieren kann, sollte es mehr Möglichkeiten eröffnen.

[Client] ----- [Proxy1] ------ [Knoten1]
`------ [Proxy2] ------ [Knoten2]


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -151037663
.

Der Weg, den ich erkunden muss (ich habe und frage nicht gerne, bevor ich richtig recherchiere, aber da das Subjet jetzt offen ist ...) ist das "Asymmetrische Multi-Path-Routing", das Sie hier sehen können: http:// conntrack-tools.netfilter.org/manual.html#sync-aa . Und ja, das wäre wirklich sehr schön :-)

Das einfachste was funktionieren könnte...

  1. proxy1 erhält eine neue Verbindung über einen iptables-Hook (ich glaube, das habe ich irgendwo gesehen), und sein LB weist ihn dem Knoten des proxy2 zu.
  2. proxy1 sendet eine Anfrage wie "setup a conntrack entry for {src-ip}:{src-port} -> {pod-ip}:{pod-port}"
  3. proxy2 empfängt die Anfrage, richtet den conntrack-Eintrag ein und bestätigt ihn an proxy1
  4. proxy1 lässt das Paket die DNAT-Regel durchlaufen (die auch einen conntrack-Eintrag in proxy1 setzt).
  5. Wenn der Pod antwortet, deDNATs vom Host des Proxy2 entsprechend.
  6. Wenn der Client ein weiteres Paket in diesem Fluss über Proxy1 sendet, führt der Conntrack-Eintrag auch die richtige DNAT durch.

Auf diese Weise beträgt der Overhead 2 Pakete pro neuer Verbindung und wird schnell zurückgezahlt, indem Un-SNAT + zusätzliches Routing vermieden wird (da das Paket sonst über Proxy1 zurückgeschickt werden muss).

Ich bin kein Netzwerk-Typ, daher kann ich zu viel annehmen, aber das scheint vernünftig.

In meinem Fall wollte ich Firewallregeln pro NodePort-Dienst einrichten.

Es sieht so aus, als ob ich einfache ALLOW IP / DROP-Regeln für alle anderen Regeln in der INPUT-Kette hinzufügen kann, wie folgt:

iptables -A INPUT -s $WHITELISTED_IP -p tcp --dport $CONTAINER_PORT -j ACCEPT
iptables -A INPUT -p tcp --dport $CONTAINER_PORT -j DROP

Um diese Regeln anzuwenden, stellte ich mir die Verwendung von Anmerkungen zu den NodePort-Diensten vor. Die Anmerkungen würden IPs auf der Whitelist enthalten.

Da ich etwas warten kann, bis diese Regeln gelten, habe ich mir eine minutiöse Cron-Aufgabe für jeden Diener vorgestellt, der durchkommt und die INPUT-Kette des Dieners aus allen Service-Anmerkungen aktualisiert.

Gibt es hier etwas, was zu Problemen führen könnte? Bin ich verrückt?

@thockin habe eine bessere Sicht als ich, aber ich würde dafür keine Anmerkung verwenden. Ich denke, Sicherheit ist orthogonal und sollte in einem System beiseite gelegt werden, oder vielleicht in einem Netzwerk-/Proxy-Plugin. Wenn Sie Kubernetes haben, haben Sie etcd, also könnten Sie einfach einen Regelsatz in einem Schlüssel speichern und mit etcdctl watch/exec aktualisieren:

# while true; do etcdctl watch "/iptables/$(hostname)" && etcdctl get /iptables/$(hostname) |iptables-restore --noflush; done &
# iptables -F my-filter
# iptables -nvL my-filter
Chain my-filter (0 references)
 pkts bytes target     prot opt in     out     source               destination      
# ~nwrk/go/bin/etcdctl set /iptables/$(hostname) >/dev/null <<EOF
*filter
:my-filter -
-A my-filter -j ACCEPT -s 1.2.3.4 -p tcp --dport 80
-A my-filter -j DROP -p tcp --dport 80
COMMIT
EOF
# iptables -nvL my-filter
Chain my-filter (0 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp  --  *      *       1.2.3.4              0.0.0.0/0            tcp dpt:80
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80

Ich glaube, du willst #14505

Am Montag, 26. Oktober 2015 um 8:53 Uhr, Ben Hundley [email protected]
schrieb:

In meinem Fall wollte ich Firewallregeln pro NodePort-Dienst einrichten.

Es sieht so aus, als könnte ich einfache ALLOW IP / DROP hinzufügen, alles andere Regeln in
die INPUT-Kette, wie folgt:

iptables -A INPUT -s $WHITELISTED_IP -p tcp --dport $CONTAINER_PORT -j ACCEPT
iptables -A INPUT -p tcp --dport $CONTAINER_PORT -j DROP

Um diese Regeln anzuwenden, stellte ich mir die Verwendung von Anmerkungen auf den
NodePort-Dienste. Die Anmerkungen würden IPs auf der Whitelist enthalten.

Da ich noch ein bisschen warten kann, bis diese Regeln gelten, habe ich mir minutiös vorgestellt
Cron-Aufgabe für jeden Diener, der durchkommt und die INPUT des Dieners aktualisiert
Kette aus allen Service-Anmerkungen.

Gibt es hier etwas, was zu Problemen führen könnte? Bin ich verrückt?


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -151181267
.

Dies war der ursprüngliche Ansatz, bei dem Sicherheitsgruppen an Load Balancer angehängt wurden. Ich habe gerade das Limit für Listener pro Netzwerkschnittstelle auf AWS ziemlich schnell erreicht und bin auf eine haarige Logik gestoßen, als ich versuchte, Firewall-Regeln auf mehrere SGs und mehrere ELBs für einen einzelnen Kube-Cluster zu verteilen.

Glücklicherweise haben wir eine bessere Lösung gefunden, bei der es nicht darum geht, mit iptables herumzuschrauben.

Wenn Sie gerade erst beigetreten sind, erlauben Sie mir, es zusammenzufassen. Alle Probleme bezüglich der Unfähigkeit, die Client-IP zu erhalten, wurden in diesem Problem zusammengeführt, aber die vorgeschlagene (und implementierte) Lösung löst es nicht. Sie haben derzeit keine Möglichkeit, auf die IP des Clients zuzugreifen. Ha.

@shaylevi2 Es gibt derzeit einfach keine gute Möglichkeit, die Client-IP zu erhalten, während Sie durch einen Cloud-LB und auf einen NodePort springen. Sobald Cloud LB's aufgeholt hat, werde ich direkt darauf springen. Aber dies bewahrt die Client-IP innerhalb des Clusters

Aber dies bewahrt die Client-IP innerhalb des Clusters

Das hängt davon ab, wie das Cluster-Networking genau eingerichtet ist; zB funktioniert es in OpenShift im Moment nicht richtig, weil iptables-Regeln nicht auf OVS-internem Verkehr ausgeführt werden. Die Pakete werden also mit DNAT in den Service-Endpunkt geleitet, aber da die Quell-IP clusterintern ist, bleibt die Antwort innerhalb von OVS, sodass sie nicht erneut auf iptables trifft, sodass die DNAT nicht rückgängig gemacht wird. Daher erkennt der Client-Pod die Pakete nicht. Im Moment ist die einfachste Problemumgehung dafür, die Pakete, die in den Endpunkt gehen, vollständig zu maskieren und sie zu zwingen, auf dem Weg nach draußen wieder aus OVS gesprungen zu werden. (Ich arbeite daran, das irgendwie zu umgehen.)

Hat OVS intern einen VIP-Begriff? Du könntest einfach loswerden
kube-proxy (siehe opencontrail)

Am Freitag, den 20. November 2015 um 7:09 Uhr, Dan Winship [email protected]
schrieb:

Aber dies bewahrt die Client-IP innerhalb des Clusters

Das hängt davon ab, wie das Cluster-Networking genau eingerichtet ist; zB nicht
arbeiten im Moment direkt in OpenShift, da iptables-Regeln nicht ausgeführt werden
auf OVS-internen Datenverkehr. Also werden die Pakete DNAT'ed, die in den Dienst gehen
Endpunkt, aber da die Quell-IP clusterintern ist, wird die Antwort
bleib innerhalb von OVS, damit es nicht wieder iptables trifft, also das DNAT'ing nicht
werden umgekehrt, sodass der Client-Pod die Pakete nicht erkennt. Bei der
Momentan besteht die einfachste Problemumgehung darin, die Pakete vollständig zu maskieren
in den Endpunkt gehen und sie zwingen, wieder aus OVS gesprungen zu werden
der Weg hinaus. (Ich arbeite daran, das irgendwie zu umgehen.)


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -158426296
.

Wir hatten darüber gesprochen, im Wesentlichen das Äquivalent des pure-iptables-Proxying vollständig innerhalb von OVS durchzuführen, aber das erfordert OVS conntrack-Unterstützung, die einen sehr aktuellen Kernel erfordert, auf den wir uns noch nicht verlassen wollen. Das ist aber wahrscheinlich der langfristige Plan.

(Im Moment sieht es so aus, als könnten wir es zum Laufen bringen, indem wir für Pakete mit einer Quell-IP + Port, die einem bekannten Dienstendpunkt entsprechen und von einer Containerschnittstelle kommen, einen unentgeltlichen zusätzlichen Hop aus OVS hinzufügen , und senden Sie es dann zurück in OVS, wo es korrekt an den Client-Pod zurückgesendet werden kann.)

Ich hoffe, ein Dokument über die Service-VIP-Abstraktion schreiben und es schaffen zu können
klar, dass es sich um eine Abstraktion handelt, die ersetzt werden kann (und in einigen sein sollte)
Fälle).

Am Montag, 23. November 2015 um 6:54 Uhr, Dan Winship [email protected]
schrieb:

Wir hatten darüber gesprochen, im Wesentlichen das Äquivalent der
pure-iptables-proxying vollständig innerhalb von OVS, aber dafür ist OVS conntrack erforderlich
Unterstützung, die einen sehr aktuellen Kernel erfordert, von dem wir nicht abhängig sind
noch auf. Das ist aber wahrscheinlich der langfristige Plan.

(Im Moment sieht es so aus, als könnten wir es zum Laufen bringen, indem wir ein kostenloses Extra hinzufügen
Hop aus OVS für Pakete mit einer Quell-IP+Port, die einem bekannten Dienst entsprechen
Endpunkte, die von einer Containerschnittstelle stammen; der Knoten wird dann
möglicherweise un-DNAT und dann zurück in OVS, wo es bekommen kann
korrekt an den Client-Pod zurückgeliefert.)


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -158959014
.

Obwohl iptables/nftables sowohl die Anwendungsfälle des TCP- als auch des UDP-Lastenausgleichs lösen würde, denke ich persönlich, dass IPVS https://github.com/kubernetes/kubernetes/issues/17470 viel besser passt, da es speziell für den Lastausgleich entwickelt wurde (sprich: weniger laufende Änderungen / Wartung für das k8s-Team), bietet einen reichhaltigeren Satz an Lastausgleichsalgorithmen, hat sich bei nahezu leitungsgebundenen Geschwindigkeiten als stabil erwiesen, amd hat auch Golang-Bibliotheken, die bereit sind, Regeln zu manipulieren.

@tockin , andere, gemäß https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150743158 habe ich die Anmerkung gemacht, aber wie richtig erwähnt, wird die externe Client-IP immer noch nicht von der App in einem Container gesehen .

Wie kann man dies erreichen, dh die externe Client-IP erhalten? In meinem Setup gibt es keinen externen LB, der Dienst wird als Nodeport bereitgestellt und der Client stellt eine reine TCP-Verbindung (nicht http/Websocket) zu meiner containerisierten Anwendung her.

@ashishvyas welche Version von kube-proxy verwendest du?

Ich verwende v1.1.3

Folgen Sie den Anweisungen in https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -143280584 und https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150743158, aber verwenden Sie anstelle der Anmerkung namens net.beta.kubernetes.io/proxy-mode , verwenden Sie die Anmerkung mit dem Namen net.experimental.kubernetes.io/proxy-mode .

for node in $(kubectl get nodes -o name); do
  kubectl annotate $node net.experimental.kubernetes.io/proxy-mode=iptables;
done

Sie sollten am Anfang des Kube-Proxy-Starts Protokollanweisungen wie "Found experimentelle Annotation" und "Annotation allow iptables proxy" sehen.

Die erste Version, in die https://github.com/kubernetes/kubernetes/commit/da9a9a94d804c5bfdf3cc86ee76a2bc1a2742d16 es geschafft hat, war 1.1.4, also funktioniert net.beta.kubernetes.io/proxy-mode für viele Leute nicht. Sie sind nicht der Erste, der darauf stößt.

Aufgrund der Funktionsweise des Proxys verlieren wir die Client-IP, wenn sie durchkommt
ein Knotenport. Ich weiß, das ist nicht großartig. Es ist sehr in meinem Kopf, wie es geht
beheben Sie dies richtig, aber es kommt hauptsächlich auf die Fähigkeiten des
Load-Balancer (oder die anderen Wege, auf denen Datenverkehr an einem Knoten ankommt, z
als DNS-RR)

Am Mittwoch, den 13. Januar 2016 um 10:25 Uhr, Mike Danese [email protected]
schrieb:

Folgen Sie den Anweisungen in #3760 (Kommentar)
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -143280584
und #3760 (Kommentar)
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -150743158
aber anstatt die Annotation mit dem Namen zu verwenden
net.beta.kubernetes.io/proxy-mode, verwenden Sie die Anmerkung namens
net.experimental.kubernetes.io/proxy-mode.

für Knoten in $(kubectl get Knoten -o Name); tun
kubectl kommentiert $node net.experimental.kubernetes.io/proxy-mode=iptables;
getan

Sie sollten Protokollanweisungen am Anfang des Kube-Proxy-Starts sehen
wie 'Experimentelle Anmerkung gefunden' und 'Annotation erlaubt iptables proxy'

Die erste Veröffentlichung, die da9a9a9
https://github.com/kubernetes/kubernetes/commit/da9a9a94d804c5bfdf3cc86ee76a2bc1a2742d16
es in war 1.1.4. Sie sind nicht der Erste, der darauf stößt.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171387997
.

@thockin , ist Problemumgehung möglich , um dies vorübergehend zu

Nein, derzeit gibt es keinen wirklichen Workaround. Das Problem liegt an der
Tatsache, dass jeder Kube-Proxy ein Back-End auf einem anderen Knoten auswählen kann.
Das Weiterleiten des Datenverkehrs mit der ursprünglichen Client-IP würde den anderen Knoten haben
direkt antworten, was offensichtlich nicht funktioniert.

Der "Fix" besteht darin, _nur_ Verkehr für Service S an Knoten zu senden, die at . haben
Mindestens 1 Back-End für S _and_, um Traffic proportional zu wie viele zu senden
Back-Ends, die jeder Knoten hat. Kube-Proxy könnte dann lokale Back-Ends auswählen
ausschließlich.

Betrachten Sie 2 Knoten und 3 Back-Ends. Ein Knoten endet zwangsläufig mit 2
Backends. Was auch immer den Verkehr leitet, muss 2x so viel an einen Knoten senden wie er
zu einem anderen Knoten macht. Wir haben dieses Problem nur noch nicht angegangen - keines davon
die Cloud-Load-Balancer unterstützen dies, also ist es irgendwie spekulativ und
Daher ist es sehr riskant, mit der Arbeit zu beginnen.

Am Mittwoch, 13. Januar 2016 um 12:17 Uhr, Ashish Vyas [email protected]
schrieb:

@tockin https://github.com/tockin , vorübergehende Problemumgehung
Adresse ist das jetzt möglich? Wenn ja, würde ich die Bereitstellung empfehlen
detaillierte Schritte für mich und andere in diesem Thread würden helfen.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171420567
.

@mikedanese , ich scheine 1.1.4 auf gcr.io nicht finden zu können:

$ sudo docker pull gcr.io/google_containers/ hyperkube:v1.1.4
Pull-Repository gcr.io/google_containers/hyperkube
Tag v1.1.4 nicht im Repository gcr.io/google_containers/hyperkube gefunden
$ sudo docker pull gcr.io/google_containers/ hyperkube:v1.1.3
v1.1.3: Ziehen von google_containers/hyperkube
Zusammenfassung: sha256:004dde049951a4004d99e12846e1fc7274fdc5855752d50288e3be4748778ca2
Status: Image ist aktuell für gcr.io/google_containers/ hyperkube:v1.1.3

@thockin Entschuldigung für die lange Antwort, ich wollte beide Methoden behandeln, mit denen wir versucht haben, das

Als Hintergrundwissen ist unsere Hauptanwendung eine sehr leistungsstarke Smart-DNS-Plattform (dh sie benötigt UDP und muss mindestens 100.000 Anfragen/Sek. pro Pod ausführen) und ihre unterstützende Anwendung in einem SNI-Proxy, der die Clients real sehen muss IP-Adresse (dies ist ein Showstopper für uns). Wir wollten nicht unterschiedliche Netzwerkansätze für verschiedene Anwendungen verwenden, also haben wir uns entschieden, auf eine einzige Netzwerkmethode für alle zu standardisieren, und wir haben uns aus den oben genannten Gründen für IPVS entschieden (Leistung / Stabilität / Flexibilität / Zweckbau-SLB). , aber Sie könnten wahrscheinlich auch etwas zusammenhacken, indem Sie nur iptables in der gleichen Richtung verwenden. Wir verwenden vxlan (schnell, einfach, funktioniert zwischen Standorten), aber beide Methoden sollten auch mit GRE/VXLAN mit OVS oder auch mit Standard-Layer-2-Hostnetzwerken funktionieren (vorausgesetzt, Ihre Hosts befinden sich alle im selben L2-Netzwerk).

Wir verteilen eingehenden Endbenutzerverkehr mit einer Mischung aus Anycast und DNS, abhängig von den Anforderungen an die Failover-Geschwindigkeit oder was auch immer für den jeweiligen Diensttyp am besten funktioniert, sodass wir eine ziemlich gleichmäßige Verteilung des Endbenutzerverkehrs haben, der in unsere Knoten eindringt, aber die Problem, wie Sie bereits erwähnt haben, besteht darin, dass der Datenverkehr unabhängig vom Standort des Pods gleichmäßig auf die Pods verteilt wird. Das andere Problem besteht darin, sicherzustellen, dass Dienste, die mit anderen Diensten kommunizieren, einen effektiven Lastenausgleich durchführen.

Wir haben zwei Modelle versucht, um dies zu beheben:

Die erste Methode, die wir ausprobiert haben, waren zwei VIP-Schichten. Externe VIPs (1 pro Dienst), die den Datenverkehr auf die Knoten verteilen (basierend auf der Pod-Anzahl für diesen Dienst auf dem Knoten) und dann interne VIPs (die auf dem Knoten mit den Pods ausgeführt werden), die die Last innerhalb der Knoten verteilen (normalerweise gleichmäßig über die Schoten). Die Einschränkung dieses Modells bestand darin, dass Knoten, auf denen externe VIPs ausgeführt wurden, zwei verschiedene Netzwerk-Namespaces oder ihre eigenen physischen Knoten ausführen mussten. Das Schöne an IPVS im DSR-Modus (Direct Server Return) ist, dass es den Rückverkehr nicht sehen muss, der Verkehr geht:

Consumer >> (over L3) >> External VIP node >> (1) >> Internal VIP node >> (2) >> Container >> (any which way you want) >> Consumer

(1) IPVS (im DSR-Modus) auf dem Host mit einem externen VIP wählt einen _Knoten_ zum Senden von Verkehr (ein "echter Server" in IPVS-Begriffen) und ändert nur die DST-MAC-Adresse des Pakets (dh das IP-Paket kommt unverändert an bei k8s-Knoten). Es verteilt Lasten auf die Knoten basierend auf der Anzahl der Pods, die diesen Dienst auf dem Knoten ausführen.
(2) IPVS (auch im DSR-Modus) auf dem k8s-Knoten verteilt den Verkehr über die Pods hinweg (über die veths zum Knoten). Antworten von Containern (TCP und UDP) gehen direkt an den Verbraucher des Dienstes zurück.

Der Vorteil dieses Modells ist, dass es wirklich einfach zu starten war und das Regelwerk sehr einfach zu verwalten war. Der Nachteil dieses Modells besteht darin, dass es alle unsere Serviceanfragen (aber nicht die Antworten) über eine Reihe von Knoten konzentriert, die die externen VIPs ausführen. Wir mögen "shared-nothing", also geben Sie Version 2 ein:

Das zweite Modell, das jetzt unterhaltsam ist, ist eine einzelne Ebene von VIPs mit intelligenterer IPVS- und iptables-Konfiguration.

Consumer >> Any node/local node >> (1) >> Container >> (any which way you want) >> Consumer
oder es könnte zu einem anderen Knoten gehen:
Consumer >> Any node/local node >> (1) >> Remote Node >> (2) >> Container >> (any which way you want) >> Consumer

(1) Datenverkehr trifft auf primären VIP, der Datenverkehr wird auf alle Pods im Cluster verteilt.
(2) Datenverkehr trifft sekundäre VIP, Datenverkehr wird nur über alle lokalen Pods verteilt. Diese sekundäre VIP wird nur für Datenverkehr verwendet, der von anderen Hosts im Netzwerk eingeht (es handelt sich um einen FWMARK VIP). Wir markieren Verkehr, der an einer externen Schnittstelle ankommt, mit FWMARK=1234, und das zwingt den Verkehr, zu einem anderen Regelsatz zu gehen, der Schleifen zwischen Knoten verhindert.

Die primäre VIP verfügt über eine Liste lokaler Pods und Remote-Hosts mit Pods (mit einer Gewichtung von 100 für jeden lokalen Pod und 100 * Anzahl von Pods für Remote-Knoten). Wenn also zum Beispiel 3 Pods lokal auf nodeA laufen und zwei Pods auf nodeB laufen, würde der Regelsatz auf nodeA so aussehen:

Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP service.ip.address:0 rr persistent 360
-> pod1.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> interfaceip.of.nodeB:80 Route 200 0 0
FWM 1234 rr
-> pod1.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> pod3.on.nodeA.ip:80 Route 100 0 0

Auf NodeB würde die IPVS-Konfiguration jedoch etwas anders aussehen, da sie nur zwei lokale Pods und drei Remote-Pods auf NodeA hat:

Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP service.ip.address:0 rr persistent 360
-> pod1.on.nodeB.ip:80 Route 100 0 0
-> pod2.on.nodeB.ip:80 Route 100 0 0
-> interfaceip.of.nodeA:80 Route 300 0 0
FWM 1234 rr
-> pod1.on.nodeB.ip:80 Route 100 0 0
-> pod2.on.nodeB.ip:80 Route 100 0 0

Eine andere Möglichkeit wäre, die FWMARKs umzuschalten und iptables zu verwenden, um alles in veth+-Schnittstellen zu FWMARKEN (Wildcard-Match) und den FWMARK-Match nur für den lokalen Lastausgleich zu verwenden.

Da hier keine NAT beteiligt ist, müssen Sie beim Starten jedes Pods die SVC_XXX_YYY-IPs in der Umgebung zu einer Loopback- oder Dummy-Schnittstelle hinzufügen, aber Sie könnten wahrscheinlich auch die IPVS-VIPs ändern, um auch DNAT auszuführen, sehe ich nicht warum das nicht gehen würde.

Das Endergebnis ist die direkteste Vernetzung, ohne dass die Anforderungsverarbeitung/das Routing zentralisiert werden muss, sodass sie viel besser skaliert werden kann. Der Nachteil sind einige zusätzliche Klugheiten beim Erstellen der IPVS-Regeln. Wir verwenden einen kleinen (Golang-)Daemon, um all dies zu tun, aber ich würde in Betracht ziehen, dafür ein k8s-Modul zu schreiben, wenn ich die Zeit hätte und genügend Interesse vorhanden wäre.

Ich tauche spät in dieses Problem ein und habe den vollständigen Trail wahrscheinlich nicht ausführlich genug gelesen, aber nur für den Fall, dass es hilft: Wenn ich den obigen Beitrag von habe , möchten sie VIPs und keine Knotenports verwenden . Eine der weiter oben im Thread geäußerten Bedenken war, dass die Quell-IP bei der Verwendung des iptables-kubeproxy nicht beibehalten wird. Es wird jedoch beibehalten, wenn Sie den Service-VIP und nicht die Knotenportfunktion verwenden, glaube ich. (Wie auch immer, wie gesagt, ich habe nicht wirklich den ganzen Trail gelesen, also wenn diese Kommentare offensichtlich oder nicht hilfreich sind, dann ignoriere sie bitte! Ich werde versuchen, nächste Woche Zeit zu finden, sie ausführlich zu lesen, wenn ich zurück bin aus dem Urlaub.)

@lxpollitt Richtig, die Quell-IP wird bei der Verwendung von IPVS beibehalten, aber bedenken Sie, dass wir bei dieser Methode so ziemlich das gesamte Netzwerk selbst machen mussten, da die Konfiguration von IPVS von kube-proxy nicht unterstützt wird. Sie können die Quell-IP auch mit iptables beibehalten, benötigen jedoch zwei Schichten IPtables-DNAT, damit Sie den Verkehr auf dem Rückweg "un-nat" können

Auf meiner Seite, mit Flanell (im vxlan-Modus), das mein Container-Netzwerk verwaltet, verwende ich kube-proxy (im iptables-Modus und nicht maskierend) + Flanell in einem Namespace auf meinen Routing-Knoten. Die externen Anfragen werden an Service-IPs DNATed und dann mit dem kube-proxy über den Namespace weitergeleitet. Ich habe keine Aktiv/Aktiv-Router-Cluster-Tests durchgeführt, aber dieses Setup ermöglicht es mir, die externe IP beizubehalten. Ich erwähne es FWIW, aber ich verstehe, dass es nicht die "direkteste Vernetzung" ist.

Ich verstehe, dass es schön wäre, wenn kube-proxy dies verwalten könnte, aber angesichts Ihrer spezifischen Bedürfnisse und insbesondere der Tatsache, dass das Load-Balancing bereits außerhalb von kube-proxy liegt, wäre es nicht sinnvoll, einen iptables-rules-Manager eines Kunden zu programmieren? den Zustand des Kubernetes-Clusters beobachten und die Regeln für DNAT-VIPs nur für die Pods des laufenden Hosts einrichten? Dies könnte jedoch auch ein Modus für kube-proxy sein, wie... nun... ich bin nicht gut in Namen... --proxy-mode=iptables-to-node-pods-only.

Danke für die ausführliche Beschreibung. Ihre Lösung ist interessant, und ich habe ausgegeben
heute viel Zeit zum Nachdenken. Leider hast du
in ein sehr spezifisches Territorium überquert, das im allgemeinen nicht funktioniert.
Clouds wie GCE können den IPVS-Gatewaying-Modus aufgrund des Routings nicht verwenden
Netzwerk. Selbst wenn das Gatewaying funktioniert hat, wird die Port-Neuzuordnung nicht unterstützt.
was Kubernetes tut, gilt also nur, wenn der Dienstport == Ziel
Hafen.

Die Herausforderung mit dem Kern von Kubernetes besteht darin, Wege zu finden, mit Ihren
eine Art von Situation generisch oder um Ihnen aus dem Weg zu gehen und Sie zu befähigen,
stellen Sie es selbst ein. Vielleicht könnten wir etwas mit dem ipvs-encap-Modus machen,
aber ich kenne die Perf-Implikationen davon nicht.

Am Do, 14. Januar 2016 um 3:37 Uhr schrieb qoke [email protected] :

@tockin https://github.com/tockin Entschuldigung für die lange Antwort, ich
wollte beide Methoden behandeln, mit denen wir versucht haben, dies zu lösen, damit andere dies tun können
verstehen die Herausforderungen, mit denen wir uns konfrontiert sahen.

Als Hintergrund ist unsere Hauptanwendung eine sehr hohe Leistung
Smart DNS-Plattform (dh sie benötigt UDP und muss mindestens 100.000+ tun
Anfragen/Sek. pro Pod) und seine unterstützende Anwendung in einem SNI-Proxy
die die echte IP-Adresse des Clients sehen müssen (dies ist ein Showstopper für
uns). Wir wollten nicht unterschiedliche Vernetzungsansätze für unterschiedliche nutzen
Anwendungen, daher haben wir uns entschieden, auf eine einzige Netzwerkmethode für
alle, und wir haben uns aus den oben genannten Gründen für IPVS entschieden
(Leistung/Stabilität/Flexibilität/zweckgerichteter SLB), aber Sie könnten
hacke wahrscheinlich etwas zusammen, indem du nur iptables in der gleichen Richtung verwendest
auch. Wir verwenden vxlan (schnell, einfach, funktioniert zwischen Sites), aber beides
Methoden sollten auch mit GRE/VXLAN mit OVS oder mit Standard Layer 2 funktionieren
Host-Netzwerk auch (vorausgesetzt, Ihre Hosts befinden sich alle im selben L2-Netzwerk).

Wir verteilen eingehenden Endbenutzerverkehr mit einer Mischung aus Anycast und
DNS, je nach Failover-Geschwindigkeitsanforderungen oder was auch immer am besten funktioniert
die jeweilige Art des Dienstes, daher haben wir eine ziemlich gleichmäßige Verteilung von
Endbenutzerverkehr, der in unsere Knoten eindringt, aber das Problem, wie Sie darauf hingewiesen haben,
erhält dann eine gleichmäßige Verteilung des Datenverkehrs auf die Pods, unabhängig davon
Pod-Standort. Das andere Problem besteht darin, sicherzustellen, dass Dienste mit anderen kommunizieren
Dienste wird effektiv Load-Balancing durchgeführt.

Wir haben zwei Modelle versucht, um dies zu beheben:

Die erste Methode, die wir ausprobiert haben, waren zwei VIP-Schichten. Externe VIPs (1 pro
service), die den Datenverkehr auf die Knoten verteilen (basierend auf der Pod-Anzahl für
dieser Dienst auf dem Knoten) und dann interne VIPs (die auf dem Knoten ausgeführt werden)
mit den Pods), die die Last innerhalb der Knoten verteilen (normalerweise gleichmäßig
über Schoten). Die Einschränkung dieses Modells bestand darin, dass Knoten extern ausgeführt wurden
VIPs mussten zwei verschiedene Netzwerk-Namespaces ausführen oder ihre eigenen ausführen
physische Knoten. Das Schöne an IPVS im DSR-Modus (direkter Server-Return)
Modus ist, dass es den Rückverkehr nicht sehen muss, der Verkehr geht:

Verbraucher >> (über L3) >> Externer VIP-Knoten >> (1) >> Interner VIP-Knoten >>
(2) >> Container >> (beliebig) >> Verbraucher

(1) IPVS (im DSR-Modus) auf dem Host mit einem externen VIP wählt einen _Knoten_ an
Senden Sie Datenverkehr an (einen "echten Server" in IPVS-Begriffen) und ändert nur DST MAC
Adresse des Pakets (dh das IP-Paket kommt unverändert am k8s-Knoten an). Es lädt
wird auf die Knoten basierend auf der Anzahl der Pods ausgeglichen, auf denen dieser Dienst ausgeführt wird
der Knoten.
(2) IPVS (auch im DSR-Modus) auf dem k8s-Knoten verteilt den Verkehr über
Pods (über die Veths zum Knoten). Antworten von Containern (TCP und UDP) go
direkt an den Verbraucher des Dienstes zurück.

Der Vorteil dieses Modells ist, dass es wirklich einfach zu starten war und die
Regelsatz war sehr einfach zu verwalten. Der Nachteil dieses Modells ist, dass es
bündelt alle unsere Serviceanfragen (aber nicht die Antworten) durch a
Anzahl der Knoten, auf denen die externen VIPs ausgeführt werden. Wir mögen "gemeinsames Nichts", also
Geben Sie Version 2 ein:

Das zweite Modell, das jetzt unterhaltsam ist, ist eine einzige Schicht von VIPs mit
intelligentere IPVS- und iptables-Konfiguration.

Consumer >> Beliebiger Knoten/lokaler Knoten >> (1) >> Container >>
wollen) >> Verbraucher
oder es könnte zu einem anderen Knoten gehen:
Consumer >> Beliebiger Knoten/lokaler Knoten >> (1) >> Remote-Knoten >> (2) >> Container

(wie immer Sie wollen) >> Verbraucher

(1) Traffic trifft auf primären VIP, Traffic wird auf alle Pods verteilt in
der Cluster.
(2) Traffic trifft sekundäre VIP, Traffic wird nur über alle verteilt
lokale Schoten. Dieser sekundäre VIP wird nur für Traffic verwendet, der von kommt
andere Hosts im Netzwerk (es ist ein FWMARK VIP). Wir markieren eingehenden Verkehr
jede externe Schnittstelle mit FWMARK=1234, und das zwingt den Verkehr zu gehen
zu einem anderen Regelsatz, der Schleifen zwischen Knoten verhindert.

Der primäre VIP verfügt über eine Liste lokaler Pods und Remote-Hosts mit Pods (mit
das Gewicht beträgt 100 für jede lokale Kapsel und 100 * Anzahl der Kapseln für
entfernte Knoten). Wenn also zum Beispiel 3 Pods lokal auf nodeA laufen, und
Auf NodeB laufen zwei Pods, der Regelsatz auf NodeA würde so aussehen
Dies:

Prot LocalAddress:Port-Scheduler-Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP service.ip.address:0 rr persistent 360
-> pod1.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> interfaceip.of.nodeB:80 Route 200 0 0
FWM 1234 rr
-> pod1.on.nodeA.ip:80 Route 100 0 0
-> pod2.on.nodeA.ip:80 Route 100 0 0
-> pod3.on.nodeA.ip:80 Route 100 0 0

Auf nodeB würde die IPVS-Konfiguration jedoch etwas anders aussehen, weil sie
hat nur zwei lokale Pods und drei Remote-Pods auf nodeA:

Prot LocalAddress:Port-Scheduler-Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP service.ip.address:0 rr persistent 360
-> pod1.on.nodeB.ip:80 Route 100 0 0
-> pod2.on.nodeB.ip:80 Route 100 0 0
-> interfaceip.of.nodeA:80 Route 300 0 0
FWM 1234 rr
-> pod1.on.nodeB.ip:80 Route 100 0 0
-> pod2.on.nodeB.ip:80 Route 100 0 0

Eine andere Möglichkeit wäre, die FWMARKs umzuschalten und iptables zu verwenden, um
FWMARK alles in veth+ Interfaces (Wildcard Match) und habe den FWMARK
match wird nur für den lokalen Lastenausgleich verwendet.

Das Endergebnis ist die direkteste Vernetzung, ohne dass eine Zentralisierung erforderlich ist
Anfrageverarbeitung/Routing skaliert also viel besser. Der Nachteil ist etwas
zusätzliche Intelligenz beim Erstellen der IPVS-Regeln.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171619663
.

Ich denke, es wäre interessant, einen iptables-to-node-pods-only Modus auszuprobieren,
aber es hat eine Menge Wellen. Das Potenzial für ein Ungleichgewicht ist sehr real und
zumindest müsste der Service-Controller wissen, wie man das programmiert
externe Load-Balancer.

Am Do, 14. Januar 2016 um 15:59 Uhr, Mikaël Cluseau [email protected]
schrieb:

Auf meiner Seite, mit Flanell (im vxlan-Modus), das mein Containernetzwerk verwaltet, bin ich
Verwenden Sie kube-proxy (im iptables-Modus und nicht maskierend) + Flanell in a
Namespace auf meinen Routingknoten. Die externen Anfragen sind DNATed to service
IPs und dann mit dem kube-proxy über den Namespace weitergeleitet. ich nicht
Aktive/aktive Router-Cluster-Tests durchgeführt, aber dieses Setup ermöglicht es mir, beizubehalten
die externe IP. Ich erwähne es FWIW, aber ich verstehe, dass es nicht das "meiste" ist
direkte Vernetzung".

Ich verstehe, dass es schön wäre, wenn Kube-Proxy das schaffen könnte, aber
Ihren spezifischen Bedürfnissen und vor allem der Tatsache, dass der Lastausgleich
ist bereits außerhalb von kube-proxy, wäre es nicht sinnvoll, einen Kunden zu codieren?
iptables-rules-Manager überwacht den Zustand des Kubernetes-Clusters und richtet ihn ein
die Regeln für DNAT-VIPs nur für die Pods des laufenden Hosts? Das könnte
aber auch ein Modus für Kube-Proxy sein, wie... nun... ich bin nicht gut darin
Namen... --proxy-mode=iptables-to-node-pods-only.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -171821603
.

@thockin Sie meinen, wenn sich beispielsweise 2 Replikate auf demselben Knoten befinden? Ich denke, wir könnten den Fall "Programmieren der externen Load-Balancer" außerhalb des Geltungsbereichs des Kube-Proxys platzieren, da er mehrere Instanzen hat und ein externer LB-Programmierer wahrscheinlich in einem "Single-Master"-Modus sein sollte. Daher ist das Zulassen des Kube-Proxy-Modus "iptables-to-node-pods-only" nur der erste von zwei Schritten.

Ich denke, ich könnte morgen versuchen, so etwas zu implementieren: "iptables-to-node-pods-only"-Modus in kube-proxy, plus ein contrib/ip-route-elb, das eine Linux-Routing-Tabelle mit einer Route pro Dienst verwaltet , mit der richtigen Gewichtung für jeden Knoten basierend darauf, wie viele Endpunkte der Knoten für einen bestimmten Dienst hat.

@tockin Sie meinen, dass sich beispielsweise 2 Replikate auf demselben Knoten befinden? Ich denke, wir könnten den Fall "programmieren"
externe Load-Balancer" außerhalb des Bereichs des Kube-Proxy, da dieser über mehrere Instanzen und einen externen LB verfügt
Programmierer sollte sich wahrscheinlich in einem "Single Master"-Modus befinden. Wenn Sie also den Kube-Proxy-Modus "iptables-to-node-
pods-only" ist nur der erste von zwei Schritten.

"Nur Proxy für lokale Pods" muss Schritt 2 des Prozesses sein. Schritt 1
muss den Service Controller ändern, um nur Load-Balancer zu senden
an Knoten, die ein oder mehrere Back-Ends für einen bestimmten Dienst haben. Dieser Schritt
allein ist WAHRSCHEINLICH vernünftig, erfordert aber viele Tests, um
stellen Sie sicher, dass wir es richtig machen. Ich denke, wir wollen dies irgendwann tun,
ohnehin.

Sobald dies erledigt ist, können wir darüber sprechen, dass Node-Ports lokal bevorzugt werden
Backends wenn möglich, aber dieser Schritt erfordert viel mehr Sorgfalt
dachte.. Bedeutet das _immer_ (dh wähle niemals eine Fernbedienung?
Backend, wenn ein lokales verfügbar ist) oder probabilistisch? Sollten wir tun
dass über den gleichen Knotenport (verschiedene Knoten werden sehr
unterschiedliche Verhaltensweisen) oder weisen wir einen anderen Port zu, der verwendet wird?
wenn und nur, wenn dieser Knoten 1 oder mehrere Back-Ends hat? Wie gehen wir mit der
Ungleichgewichtsproblem?

Ich denke, ich könnte versuchen, morgen so etwas zu implementieren: "iptables-to-node-pods-only"-Modus in kube-proxy,
plus ein contrib/ip-route-elb, das eine Linux-Routing-Tabelle mit einer Route pro Dienst mit der richtigen Gewichtung verwaltet
für jeden Knoten basierend darauf, wie viele Endpunkte der Knoten für einen bestimmten Dienst hat.

Wenn ELB Gewichte unterstützt, funktioniert es in mancher Hinsicht besser als
GCE, was nicht der Fall ist. Das ist in Ordnung, ich dachte nur, dass es nicht unterstützt wird
Gewichte. Ich glaube nicht, dass es dazu beitragen kann - es ist ein hübsches
grundlegender Bestandteil des Systems.

Am 16.01.2016 05:19 schrieb Tim Hockin:

"Nur Proxy für lokale Pods" muss Schritt 2 des Prozesses sein. Schritt 1
muss den Service Controller ändern, um nur Load-Balancer zu senden
an Knoten, die ein oder mehrere Back-Ends für einen bestimmten Dienst haben. Dieser Schritt
allein ist WAHRSCHEINLICH vernünftig, erfordert aber viele Tests, um
stellen Sie sicher, dass wir es richtig machen. Ich denke, wir wollen dies irgendwann tun,
ohnehin.

Das macht Sinn.

Sobald das erledigt ist, [...]

Mal sehen, wenn das erledigt ist :-)

Wenn ELB Gewichte unterstützt, funktioniert es in mancher Hinsicht besser als
GCE, was nicht der Fall ist. Das ist in Ordnung, ich dachte nur, dass es nicht unterstützt wird
Gewichte.

Da ist es aus dem Handbuch und du hast wahrscheinlich mehr als 10x my
Erfahrung in dieser Art der Vernetzung muss ich einen Haken ganz ignorieren.
Die man ip-route sagt dies:

           nexthop NEXTHOP
                  the nexthop of a multipath route.  NEXTHOP is a 

komplexer Wert mit eigener Syntax ähnlich den Top-Level-Argumentlisten:

                          via [ FAMILY ] ADDRESS - is the nexthop 

Router.

                          dev NAME - is the output device.

                          weight NUMBER - is a weight for this 

Element einer Mehrwegeroute, das seine relative Bandbreite oder Qualität widerspiegelt.

Ich glaube nicht, dass es dazu beitragen kann - es ist ein hübsches
grundlegender Bestandteil des Systems.

Da das "E" für "extern" steht, hatte ich das Gefühl, dass es dort beginnen könnte,
zumindest um etwas Code zu bekommen, um Ideen zu unterstützen.

Am Fr, 15.01.2016 um 14:55 Uhr, Mikaël Cluseau
[email protected] schrieb:

Am 16.01.2016 05:19 schrieb Tim Hockin:

"Nur Proxy für lokale Pods" muss Schritt 2 des Prozesses sein. Schritt 1
muss den Service Controller ändern, um nur Load-Balancer zu senden
an Knoten, die ein oder mehrere Back-Ends für einen bestimmten Dienst haben. Dieser Schritt
allein ist WAHRSCHEINLICH vernünftig, erfordert aber viele Tests, um
stellen Sie sicher, dass wir es richtig machen. Ich denke, wir wollen dies irgendwann tun,
ohnehin.

Das macht Sinn.

Ich habe heute mehr darüber nachgedacht, ich glaube nicht, dass es sehr schwer wird.
Nur mittelhart.

Sobald das erledigt ist, [...]

Mal sehen, wenn das erledigt ist :-)

fair genug, ich möchte nur wissen, wohin eine Reihe von Änderungen führt :)

Wenn ELB Gewichte unterstützt, funktioniert es in mancher Hinsicht besser als
GCE, was nicht der Fall ist. Das ist in Ordnung, ich dachte nur, dass es nicht unterstützt wird
Gewichte.

Da ist es aus dem Handbuch und du hast wahrscheinlich mehr als 10x my
Erfahrung in dieser Art der Vernetzung muss ich einen Haken ganz ignorieren.
Die man ip-route sagt dies:

nexthop NEXTHOP
der nächste Hop einer Mehrwegeroute. NEXTHOP ist ein
komplexer Wert mit eigener Syntax ähnlich den Top-Level-Argumentlisten:

über [ FAMILIE ] ADRESSE - ist der nexthop
Router.

dev NAME - ist das Ausgabegerät.

Gewicht NUMMER - ist ein Gewicht dafür
Element einer Mehrwegeroute, das seine relative Bandbreite oder Qualität widerspiegelt.

Wir verwenden jedoch nicht wirklich das Konzept von Linux zum IP-Routing. Keine von
LB-Implementierungen, die ich kenne, verwenden es sowieso. GCE nutzt die Cloud von Google
Balancer, der keine Gewichte hat. Ich weiß nicht, ist Amazon ELB
tut.

Ich glaube nicht, dass es dazu beitragen kann - es ist ein hübsches
grundlegender Bestandteil des Systems.

Da das "E" für "extern" steht, hatte ich das Gefühl, dass es dort beginnen könnte,
zumindest um etwas Code zu bekommen, um Ideen zu unterstützen.

Klar, wir können in contrib STARTEN :)

Wenn Sie dies verfolgen möchten, sollten Sie 2 Fehler öffnen, etwa:

1) Load-Balancer für einen Dienst sollten nur Knoten ansprechen, die tatsächlich
ein Backend für diesen Dienst haben

2) Um die Client-IP über Load-Balancer hinweg beizubehalten, sollte kube-proxy
Bevorzuge immer lokales Backend, falls vorhanden (xref #1)

und dann die Absicht und Richtung erklären

Am Freitag, den 15. Januar 2016 um 17:11 Uhr schrieb Tim Hockin [email protected] :

Am Fr, 15.01.2016 um 14:55 Uhr, Mikaël Cluseau
[email protected] schrieb:

Am 16.01.2016 05:19 schrieb Tim Hockin:

"Nur Proxy für lokale Pods" muss Schritt 2 des Prozesses sein. Schritt 1
muss den Service Controller ändern, um nur Load-Balancer zu senden
an Knoten, die ein oder mehrere Back-Ends für einen bestimmten Dienst haben. Dieser Schritt
allein ist WAHRSCHEINLICH vernünftig, erfordert aber viele Tests, um
stellen Sie sicher, dass wir es richtig machen. Ich denke, wir wollen dies irgendwann tun,
ohnehin.

Das macht Sinn.

Ich habe heute mehr darüber nachgedacht, ich glaube nicht, dass es sehr schwer wird.
Nur mittelhart.

Sobald das erledigt ist, [...]

Mal sehen, wenn das erledigt ist :-)

fair genug, ich möchte nur wissen, wohin eine Reihe von Änderungen führt :)

Wenn ELB Gewichte unterstützt, funktioniert es in mancher Hinsicht besser als
GCE, was nicht der Fall ist. Das ist in Ordnung, ich dachte nur, dass es nicht unterstützt wird
Gewichte.

Da ist es aus dem Handbuch und du hast wahrscheinlich mehr als 10x my
Erfahrung in dieser Art der Vernetzung muss ich einen Haken ganz ignorieren.
Die man ip-route sagt dies:

nexthop NEXTHOP
der nächste Hop einer Mehrwegeroute. NEXTHOP ist ein
komplexer Wert mit eigener Syntax ähnlich den Top-Level-Argumentlisten:

über [ FAMILIE ] ADRESSE - ist der nexthop
Router.

dev NAME - ist das Ausgabegerät.

Gewicht NUMMER - ist ein Gewicht dafür
Element einer Mehrwegeroute, das seine relative Bandbreite oder Qualität widerspiegelt.

Wir verwenden jedoch nicht wirklich das Konzept von Linux zum IP-Routing. Keine von
LB-Implementierungen, die ich kenne, verwenden es sowieso. GCE nutzt die Cloud von Google
Balancer, der keine Gewichte hat. Ich weiß nicht, ist Amazon ELB
tut.

Ich glaube nicht, dass es dazu beitragen kann - es ist ein hübsches
grundlegender Bestandteil des Systems.

Da das "E" für "extern" steht, hatte ich das Gefühl, dass es dort beginnen könnte,
zumindest um etwas Code zu bekommen, um Ideen zu unterstützen.

Klar, wir können in contrib STARTEN :)

Das Risiko einer PR ohne Dokumente besteht darin, dass sie in die falsche Richtung geht. es ist
viel einfacher, etwas als Vorschlag zu überprüfen. ich werde mir deine anschauen
PR bei Gelegenheit, hoffentlich bald.
Am 15. Januar 2016, 19:02 Uhr, schrieb "Mikaël Cluseau" [email protected] :

Ist es in Ordnung, einen Pull-Request für (1) direkt mit diesem Namen und einigen zu öffnen?
Erklärungen?


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172149777
.

Leider haben Sie ein sehr spezifisches Gebiet betreten, das im allgemeinen nicht funktioniert.
Clouds wie GCE können aufgrund des gerouteten Netzwerks den IPVS-Gatewaying-Modus nicht verwenden. Selbst wenn das Gatewaying funktioniert, unterstützt es keine Port-Neuzuordnung, was Kubernetes tut, also gilt es nur, wenn der Dienstport == Zielport ist.

Auf der Gateway-Seite funktioniert dies gut über ein Layer-3-Netzwerk (wir verwenden ein Overlay), und obwohl wir ohne ein Overlay-Netzwerk hätten auskommen können, haben wir es so aufgebaut, weil wir wollten, dass der Ansatz, den wir verwenden, portabel ist und funktioniert in Clouds von Drittanbietern (wie GCE).

Korrigieren Sie die Einschränkung im DSR-Modus, dass der Dienstport == Zielport ist, aber das ist nicht wirklich ein Problem, es sei denn, Sie haben zwei Anwendungen _im selben Container_, die auf demselben Port ausgeführt werden müssen (wir haben viel Zeit damit verbracht, darüber nachzudenken und unter der Annahme der Richtlinie "1 Anwendung pro Container" konnten wir dafür keinen einzigen Anwendungsfall finden). Wir haben viele Container, die alle auf denselben Knoten mit darin enthaltenen Diensten auf denselben Ports ausgeführt werden, und alle haben einen guten Lastenausgleich. Wenn Sie Ports _wirklich_ neu zuordnen müssen (ich möchte jedoch die wahren Gründe dafür verstehen), können Sie den IPVS-NAT-Modus anstelle des "ROUTE"-Modus verwenden.

Die Herausforderung beim Kern von Kubernetes besteht darin, Wege zu finden, Ihre Art von Situation generisch zu behandeln oder Ihnen aus dem Weg zu gehen und Sie zu befähigen, sie selbst einzurichten. Vielleicht könnten wir etwas mit dem ipvs-encap-Modus machen, aber ich kenne die Auswirkungen auf die Perf nicht.

Was wir getan haben, ist so allgemein wie möglich (funktioniert hier, funktioniert in Amazon, und ich bin sicher, es wird in GCE funktionieren, wenn wir erweitern müssen), mit der einzigen Einschränkung bei DSR, dass die Anwendung Die Ausführung im Pod/Container muss auf demselben Port wie der Dienst ausgeführt werden, was nach vielen internen Diskussionen niemand in der Lage war, ein Szenario zu finden, in dem dies aus Sicht des E2E-Anwendungsstapels einschränkend wäre.

Wenn Sie jedoch DSR (IPVS-Route-Modus) aus der Gleichung entfernen und stattdessen den "NAT-Modus" von IPVS verwenden, können die Ports neu zugeordnet werden und Sie profitieren immer noch von den IPVS-Funktionen / -Leistung / usw. Der einzige Nachteil ist, dass NAT etwas Leistungssteuer hinzufügt, aber (a) es unterstützt UDP und (b) es ist immer noch blitzschnell im Vergleich zu einer User-Space-Lösung.

@brendandburns @thockin Zuvor im Thread haben Sie nach einigen Leistungszahlen gefragt. Ich würde dies nicht als den umfassendsten Satz von Tests bezeichnen, aber ich gehe davon aus, dass HTTP eine der häufigsten Workloads in Containern ist, daher hier einige Apache-Bench-Nummern als Ausgangspunkt:

https://docs.google.com/presentation/d/1vv5Zszt4HDGbuyVlvOe76unHskxPuZQseQnarNbhQVc

DNAT wurde auf IPVS für einen fairen Vergleich mit den beiden anderen Lösungen aktiviert (dies bedeutet auch, dass sich der Service-Port vom Ziel-Service-Port unterscheiden kann). Unsere Workloads mögen einigen etwas ungewöhnlich erscheinen, aber unsere Leistungsziele sind wahrscheinlich denen anderer nicht unähnlich (dh die Hardware so weit wie möglich zusammenzupressen).

Vielen Dank!

Ich bin mir nicht sicher, woher die Idee kommt, dass Kube-Proxy kein UDP macht - es
absolut, wenn auch vielleicht nicht perfekt (ohne Verbindung kommt es)
bis hin zu Zeitüberschreitungen).

Es lohnt sich auch, die iptables (neu) kube-proxy vs. den Userspace zu klären
(Legacy-)Modus.

Am Samstag, 16. Januar 2016 um 21:45 Uhr schrieb qoke [email protected] :

@tockin https://github.com/tockin Weiter oben im Thread, nach dem du gefragt hast
einige Leistungszahlen. Ich würde das nicht als das umfangreichste Set bezeichnen
von Tests, aber ich gehe davon aus, dass HTTP eine der häufigsten Workloads in
Container, daher hier einige Apache-Bench-Nummern als Ausgangspunkt:

https://docs.google.com/presentation/d/1vv5Zszt4HDGbuyVlvOe76unHskxPuZQseQnarNbhQVc

DNAT wurde auf IPVS für einen fairen Vergleich mit den beiden anderen Lösungen aktiviert
(dies bedeutet auch, dass sich der Service-Port vom Ziel-Service-Port unterscheiden kann). Unsere
Workloads mögen manchen etwas ungewöhnlich erscheinen, aber unsere Leistungsziele
sind wahrscheinlich anderen nicht unähnlich (dh quetschen die Hardware für alle)
du kannst bekommen).


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172293881
.

Guter Aufruf zum neuen vs. Legacy-Modus - notiert und aktualisiert.

Auch auf der UDP-Seite danke ich für die Klarstellung; Mir war bisher nicht bewusst, dass UDP in kube-proxy vollständig unterstützt wird. Als wir Kube-Proxy zum ersten Mal mit UDP ausprobierten, hatten wir viele, viele Hänger. Ich bin mir nicht sicher, warum, aber wir haben die Timeouts erhöht und hatten immer noch Probleme. Wir mussten schnell eine Lösung finden, also arbeiteten wir am Ende mit IPVS, anstatt es zu debuggen. Zu dieser Zeit funktionierte es nur für relativ geringe Paket-pro-Sekunde-Workloads (unter 1.000 pps), aber wir haben es in letzter Zeit nicht erneut getestet.

Das Hauptproblem bei iptables und jedem UDP-Dienst mit hoher Rate ist, dass sich die Netfilter-Conntrack-Tabellen füllen. Selbst wenn Sie die Conntrack-Größe auf 1 Million erhöhen, werden Sie von einigen Malware-infizierten Endbenutzer-DDoS oder versucht, Sie für einen DNS-Amplification-Angriff zu verwenden, und dann füllt sich Ihre Conntrack-Tabelle einfach wieder. Im Allgemeinen besteht die beste Vorgehensweise für DNS-Server (oder andere UDP-Dienste mit hoher Rate) darin, conntrack zu deaktivieren (mit -j NOTRACK in der Rohtabelle) .

Abgesehen vom GIT-Repository, wo wäre der beste Ort, um zu suchen, bevor Sie versuchen, ein Modul/Paket "k8s.io/kubernetes/pkg/proxy/ipvs" zu erstellen? oder ist das am besten jemandem zu überlassen, der die Codebasis besser kennt?

Wenn Sie spezielle Benchmarks ausführen möchten, lassen Sie es mich wissen und ich werde sehen, was ich tun kann.

Am 17.01.2016 um 20:50 Uhr schrieb qoke:

Abgesehen vom GIT-Repo, wo könnte man vorher am besten nachschauen?
Versuchen Sie, ein Modul/Paket "k8s.io/kubernetes/pkg/proxy/ipvs" zu erstellen?

Ich glaube, man kann auch mit Contrib anfangen.

FWIW ... Ich habe Listenuhren und Undelta-Läden verwendet, um eine unabhängige zu machen
binay reagiert auf den Zustand des Clusters in
https://github.com/kubernetes/kubernetes/pull/19755. Wenn die Informationen
in
https://github.com/kubernetes/kubernetes/pull/19755/files#diff -0becc97ac222c3f2838fbfe8446d5375R26
reicht, Sie sollten den Anruf nur wenige Zeilen weiter unten ändern müssen
(https://github.com/kubernetes/kubernetes/pull/19755/files#diff-0becc97ac222c3f2838fbfe8446d5375R44).

Bitte beachten Sie, dass ich in diesem PoC nur ClusterIP-Dienste unterstütze.

Leider haben Sie ein sehr spezifisches Gebiet betreten, das im allgemeinen nicht funktioniert.
Clouds wie GCE können aufgrund des gerouteten Netzwerks den IPVS-Gatewaying-Modus nicht verwenden. Selbst wenn Gatewaying funktioniert hat, funktioniert es nicht
unterstützt die Port-Neuzuordnung, die Kubernetes tut, daher gilt dies nur, wenn der Dienstport == Zielport ist.

Auf der Gateway-Seite funktioniert dies über ein Layer-3-Netzwerk (wir verwenden ein Overlay) und obwohl wir hätten entkommen können
Ohne Overlay-Netzwerk haben wir es so aufgebaut, weil wir wollten, dass der Ansatz, den wir verwenden, portabel ist und in Drittanbietern funktioniert
Wolken (wie GCE).

Ich bin mir nicht sicher, wie es funktionieren kann. Statische Routen auf Maschinenebene funktionieren nicht
in GCE. Vielleicht fehlt mir eine Technik, die Sie angewendet haben. ich
gebe frei zu, dass ich KEIN Experte dafür bin :)

Korrigieren Sie die Einschränkung, dass der Dienstport == Zielport ist, aber dies ist nicht wirklich ein Problem, es sei denn, Sie haben zwei Anwendungen im
derselbe Container, der auf demselben Port ausgeführt werden muss (wir haben viel darüber nachgedacht und die "1 Anwendung" angenommen
pro Container"-Richtlinie konnten wir keinen einzigen Anwendungsfall dafür finden. Wir haben viele Container, die alle auf denselben Knoten laufen
mit Diensten in ihnen alle auf den gleichen Ports, und alle Lasten ausgeglichen. Kurz gesagt, der Ansatz, den wir verwenden, hält Sie nicht davon ab
von der Ausführung mehrerer Dienste auf denselben Ports auf demselben Knoten.

Dies gilt auch, wenn Sie Backends haben, die Versionen ändern (z
Übergang zwischen etcd1 und etcd2) oder jede andere Situation, in der
der Backend-Port muss nur anders sein. Das Problem ist, dass
Kubernetes ermöglicht es, es auszudrücken, also müssen wir sicherstellen, dass die Leute
kann es tatsächlich verwenden (oder es veralten und die Funktion EOL machen, die
scheint unwahrscheinlich).

Die Herausforderung beim Kern von Kubernetes besteht darin, Wege zu finden, mit Ihrer Art von Situation generisch umzugehen oder Ihnen aus dem Weg zu gehen
und befähigen Sie, es selbst einzurichten. Vielleicht könnten wir etwas mit dem ipvs-encap-Modus machen, aber ich kenne die Perf
Folgen davon.

Was wir gemacht haben, ist so allgemein wie möglich (funktioniert hier, funktioniert in Amazon, und ich bin mir sicher, dass es funktionieren wird .)
GCE, wenn wir erweitern müssen), mit der einzigen Einschränkung, dass die im Pod/Container ausgeführte Anwendung > auf demselben Port wie der Dienst laufen muss, den nach vielen internen Diskussionen niemand finden konnte Szenario wo
Dies wäre aus Sicht des E2E-Anwendungsstapels einschränkend.

Ich möchte wirklich verstehen, wie. Hast du etwas mehr Schritt für Schritt?

Auch auf der UDP-Seite danke ich für die Klarstellung; Mir war bisher nicht bewusst, dass UDP in kube-proxy vollständig unterstützt wird.
Als wir Kube-Proxy zum ersten Mal mit UDP ausprobierten, hatten wir viele, viele Hänger. Ich weiß nicht warum, aber wir haben die Timeouts erhöht und
hatte noch Probleme. Wir mussten schnell eine Lösung finden, also arbeiteten wir am Ende mit IPVS, anstatt es zu debuggen. Bei der
Zeitweise funktionierte es nur für relativ niedrige Paket-pro-Sekunde-Workloads (unter 1.000 pps), aber wir haben es in letzter Zeit nicht erneut getestet.

Das Hauptproblem bei iptables und jedem UDP-Dienst mit hoher Rate ist, dass sich die Netfilter-Conntrack-Tabellen füllen. Auch wenn Sie die erhöhen
conntrack-Größe auf 1 Million, dann werden Sie von einem Malware-infizierten Endbenutzer-DDoS oder versucht, Sie für eine DNS-Verstärkung zu verwenden
Angriff und dann füllt sich Ihr Conntrack-Tisch einfach wieder. Im Allgemeinen gilt die bewährte Methode für DNS-Server (oder andere hochfrequente
UDP-Dienste) besteht darin, conntrack zu deaktivieren (mit -j NOTRACK in der Rohtabelle) , und wenn Sie conntrack deaktivieren, iptables NAT und
Zustandsbehaftetes Zeug (-m Zustand) bricht ab.

Ja, NAT für UDP ist wirklich schade. Suche nach einem Non-Conntrack
Lösung wäre toll, muss aber entweder für alle gelten
Umgebungen oder nach Plattform parametrisiert werden (was an sich schon schwierig ist
Weg).

Abgesehen vom GIT-Repository, wo wäre der beste Ort, um zu suchen, bevor Sie versuchen, ein
"k8s.io/kubernetes/pkg/proxy/ipvs" Modul/Paket? oder ist das am besten jemandem zu überlassen, der die Codebasis besser kennt?

Ich habe ein Github-Problem zu IPVS geöffnet, aber ich habe Maskerade (NAT) verwendet.
Modus, weil ich es ohne GCE nicht zum Laufen bringen konnte (und wegen
die Port-Neuzuordnungsfunktion). Wenn die Port-Neuzuordnung ein weniger Ideales ausgelöst hat
Balancing-Modus, damit könnte ich wohl leben und es einfach dokumentieren
als solche.

Wir sollten diese Konvoi dorthin verlegen - sie wird hier verloren gehen.

Am 18.01.2016 12:34 schrieb Tim Hockin:

Ja, NAT für UDP ist wirklich schade. Suche nach einem Non-Conntrack
Lösung wäre toll, muss aber entweder für alle gelten
Umgebungen oder nach Plattform parametrisiert werden (was an sich schon schwierig ist
Weg).

könnte zustandsloses NAT für den Fall funktionieren, in dem ein (Pod, Port)-Paar at . hat
die meisten ein Service (viele Pods zu einem Service)?

Das würde so aussehen:

{from: clientIP:clientPort, to: externalIP:externalPort} ---[Proxy wählt einen zufälligen Pod] ---> {from: clientIP:clientPort, to: podIP:targetPort} ---> [durch den richtigen Host geleitet ...]

Auf dem Rückweg hat die Firewall eine Regel, die besagt, dass ein Paket {von:
podIP:targetPort , to: any} sollte an {from:
externalIP:externalPort , an: unverändert}.

Um es im iptables-Dialekt anzugeben:

iptables -t nat -N stateless-svc-in

iptables -t nat -N stateless-svc-out

iptables -t nat -A stateless-svc-in  -j DNAT -s 1.2.3.4  -p udp --dport 53 --to-destination 10.1.0.1 -m statistic --mode random --probability 0.3333

iptables -t nat -A stateless-svc-in  -j DNAT -s 1.2.3.4  -p udp --dport 53 --to-destination 10.2.0.1 -m statistic --mode random --probability 0.5

iptables -t nat -A stateless-svc-in  -j DNAT -s 1.2.3.4  -p udp --dport 53 --to-destination 10.2.0.2 -m statistic --mode random --probability 1

iptables -t nat -A stateless-svc-out -j SNAT -s 10.1.0.1 -p udp --sport 53 --to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.1 -p udp --sport 53 --to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.2 -p udp --sport 53 --to-source 1.2.3.4

Ich sehe nicht, wo das nicht funktioniert, wenn das Paket von außen kommt
der Cluster.

Die Art und Weise, wie Dienste in Kubernetes ausgedrückt werden, ermöglicht es, einen einzelnen Pod zu
mit einer beliebigen Anzahl von Diensten konfrontiert, also bricht das zusammen - wir wissen nicht was
zu SNAT zu.

Am So, 17. Januar 2016 um 18:13 Uhr, Mikaël Cluseau [email protected]
schrieb:

Am 18.01.2016 12:34 schrieb Tim Hockin:

Ja, NAT für UDP ist wirklich schade. Suche nach einem Non-Conntrack
Lösung wäre toll, muss aber entweder für alle gelten
Umgebungen oder nach Plattform parametrisiert werden (was an sich schon schwierig ist
Weg).

könnte zustandsloses NAT für den Fall funktionieren, in dem ein (Pod, Port)-Paar at . hat
die meisten ein Service (viele Pods zu einem Service)?

Das würde so aussehen:

{from: clientIP:clientPort, to: externalIP:externalPort} ---[Proxy wählt
ein zufälliger Pod]---> {from: clientIP:clientPort, to: podIP:targetPort} --->
[durch den richtigen Host geleitet...]

Auf dem Rückweg hat die Firewall eine Regel, die besagt, dass ein Paket {von:
podIP:targetPort , to: any} sollte an {from:
externalIP:externalPort , an: unverändert}.

Um es im iptables-Dialekt anzugeben:

iptables -t nat -N stateless-svc-in

iptables -t nat -N stateless-svc-out

iptables -t nat -A stateless-svc-in -j DNAT -s 1.2.3.4 -p udp --dport 53
--to-destination 10.1.0.1 -m statistic --mode random --probability 0.3333

iptables -t nat -A stateless-svc-in -j DNAT -s 1.2.3.4 -p udp --dport 53
--to-destination 10.2.0.1 -m statistic --mode random --probability 0.5

iptables -t nat -A stateless-svc-in -j DNAT -s 1.2.3.4 -p udp --dport 53
--to-destination 10.2.0.2 -m statistic --mode random --probability 1

iptables -t nat -A stateless-svc-out -j SNAT -s 10.1.0.1 -p udp --sport 53
--to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.1 -p udp --sport 53
--to-source 1.2.3.4

iptables -t nat -A stateless-svc-out -j SNAT -s 10.2.0.2 -p udp --sport 53
--to-source 1.2.3.4

Ich sehe nicht, wo das nicht funktioniert, wenn das Paket von außen kommt
der Cluster.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172408290
.

Am 18.01.2016 15:31 schrieb Tim Hockin:

Die Art und Weise, wie Dienste in Kubernetes ausgedrückt werden, ermöglicht einen einzelnen Pod
zu sein
mit einer beliebigen Anzahl von Diensten konfrontiert, also bricht dies zusammen - wir wissen es nicht
was
zu SNAT zu.

Deshalb habe ich den Fall auf ein Many-to-One beschränkt (mein erster Satz :-)).
Ich versuche nur, eine Grenze zu ziehen, was getan werden kann oder nicht.

Klar, ich habe nur die unglückliche Aufgabe, darauf hinzuweisen, warum es nicht so ist
allgemeine genug lösung :(

Am So, 17. Januar 2016 um 20:34 Uhr, Mikaël Cluseau [email protected]
schrieb:

Am 18.01.2016 15:31 schrieb Tim Hockin:

Die Art und Weise, wie Dienste in Kubernetes ausgedrückt werden, ermöglicht einen einzelnen Pod
zu sein
mit einer beliebigen Anzahl von Diensten konfrontiert, also bricht dies zusammen - wir wissen es nicht
was
zu SNAT zu.

Deshalb habe ich den Fall auf ein Many-to-One beschränkt (mein erster Satz :-)).
Ich versuche nur, eine Grenze zu ziehen, was getan werden kann oder nicht.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172421828
.

Am 18.01.2016 15:46 schrieb Tim Hockin:

Klar, ich habe nur die unglückliche Aufgabe, darauf hinzuweisen, warum es nicht so ist
allgemeine genug lösung :(

Ja... aber es ist eine FAQ. Wir könnten auch irgendwo "if len(services)
== 1 { implementiere zustandslos } else { implementiere zustandsbehaftet }". Aber das kann
sieht für die Neulinge wie ein Durcheinander aus. Ich könnte auch ein Beitrag/Elben/etwas sein...

Es ist nicht einmal etwas, das wir derzeit verfolgen (die Anzahl der Dienste, die
vor einem bestimmten Pod). Wir könnten, nehme ich an. Ich bin nicht dagegen (auch wenn es
scheint Nische). Es hört sich nach einer wesentlichen Änderung an, um so zu haben
viele Vorbehalte. Ich würde gerne noch über bessere Antworten nachdenken.

Am So, 17. Januar 2016 um 20:51 Uhr, Mikaël Cluseau [email protected]
schrieb:

Am 18.01.2016 15:46 schrieb Tim Hockin:

Klar, ich habe nur die unglückliche Aufgabe, darauf hinzuweisen, warum es nicht so ist
allgemeine genug lösung :(

Ja... aber es ist eine FAQ. Wir könnten auch irgendwo "if len(services)
== 1 { implementiere zustandslos } else { implementiere zustandsbehaftet }". Aber das kann
sieht für die Neulinge wie ein Durcheinander aus. ich könnte auch ein sein
Beitrag/Elben/etwas...


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172425404
.

Am 18.01.2016 16:07 schrieb Tim Hockin:

Es ist nicht einmal etwas, das wir derzeit verfolgen (die Anzahl der Dienste, die
vor einem bestimmten Pod). Wir könnten, nehme ich an. Ich bin nicht dagegen (auch wenn es
scheint Nische). Es hört sich nach einer wesentlichen Änderung an, um so zu haben
viele Vorbehalte. Ich würde gerne noch über bessere Antworten nachdenken.

Ich stimme zu, habe aber im Moment keine bessere Idee :-(

Sogar ein speziell entwickeltes SDN müsste etwas verfolgen, nehme ich an. Vielleicht
etikettenbasierte Lösungen wie MPLS..?

Am 18.01.2016 16:18 schrieb Mikaël Cluseau:

Sogar ein speziell entwickeltes SDN müsste etwas verfolgen, nehme ich an.
Vielleicht Label-basierte Lösungen wie MPLS..?

In der Idee, Dinge zu kennzeichnen ... wenn wir eine IP pro Dienst + eine zuweisen
IP pro Endpunkt (Service+Pod-Paar) und fügen Sie diese Endpunkt-IPs zu den
Pods sollte es vollständig zustandslos funktionieren:

``````

  • External to host:{from: clientIP:clientPort, to: externalIP:servicePort} -----[ELB
    wählt einen Endpunkt]--------> {von: clientIP:clientPort, an:
    endpointServiceIP:podPort} --> Route zum Host
  • Host to pod:{from: clientIP:clientPort, to: endpointServiceIP:podPort} --[standard
    Routing zu Containern]--> {from: clientIP:clientPort , to:
    Endpunkt ServiceIP:podPort }

  • Pod zum Host:{from: endpointServiceIP:podPort, to: clientIP:clientPort}
    --------[Standardrouting zu Routern]-----> {von:
    endpointServiceIP:podPort, an: clientIP:clientPort} - Host an extern:{von: endpointServiceIP:podPort, an: clientIP:clientPort} --------[ELB
    SNATs zurück]------------------> {von: clientIP:clientPort , an:
    externalIP:servicePort } ```

Wir denken, dass wir dies auch für ClusterIPs zum Laufen bringen können.
``````

Ich kann dies auf GCE nicht zum Laufen bringen und bin mir bei AWS nicht sicher - es gibt ein
begrenzte Anzahl von statischen Routen verfügbar.

Ich frage mich, ob ich es schaffen könnte, indem ich 2 IP-Bereiche in einem Huckepack zusammenstecke
Route. Es ist eine Menge IPs auszugeben, aber ich denke, es spielt nur für UDP eine Rolle.
Ich muss es ausprobieren.

Edit: Ich habe es ausprobiert und konnte es nicht zum Laufen bringen, aber mir fehlt etwas.
Wir müssen als Reaktion auf die kommenden Dienste IPs in Containern hinzufügen/entfernen
und gehen, aber ich konnte keine "zusätzlichen" IPs in einem Container zum Laufen bringen (es könnte
ping, aber nicht TCP oder UDP, ich weiß nicht warum).

Ich muss es irgendwann nochmal versuchen.

Am So, 17. Januar 2016 um 22:22 Uhr, Mikaël Cluseau [email protected]
schrieb:

Am 18.01.2016 16:18 schrieb Mikaël Cluseau:

Sogar ein speziell entwickeltes SDN müsste etwas verfolgen, nehme ich an.
Vielleicht Label-basierte Lösungen wie MPLS..?

In der Idee, Dinge zu kennzeichnen ... wenn wir eine IP pro Dienst + eine zuweisen
IP pro Endpunkt (Service+Pod-Paar) und fügen Sie diese Endpunkt-IPs zu den
Pods sollte es vollständig zustandslos funktionieren:

``````

  • Extern zum Host:{from: clientIP:clientPort, to: externalIP:servicePort}
    -----[ELB
    wählt einen Endpunkt]--------> {von: clientIP:clientPort, an:
    endpointServiceIP:podPort} --> Route zum Host
  • Host zum Pod:{von: clientIP:clientPort, an: endpointServiceIP:podPort}
    --[Standard
    Routing zu Containern]--> {from: clientIP:clientPort , to:
    Endpunkt ServiceIP:podPort }

  • Pod zum Host:{from: endpointServiceIP:podPort, to: clientIP:clientPort}
    --------[Standardrouting zu Routern]-----> {von:
    endpointServiceIP:podPort, an: clientIP:clientPort} - Host an
    external:{from: endpointServiceIP:podPort, to: clientIP:clientPort}
    --------[ELB
    SNATs zurück]------------------> {von: clientIP:clientPort , an:
    externalIP:servicePort } ```

Wir denken, dass wir dies auch für ClusterIPs zum Laufen bringen können.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment-172438133
.

``````

Ich versuche auf meiner Seite etwas zu bekommen (mit reinen Netns auf meinem lokalen Host)
zur Zeit).

Ich versuche einen Ansatz, bei dem ich Dienst-IP-Bereiche für Hosts beeinflusse
Reduzieren Sie die Anzahl der Routing-Einträge:

cli -- elb -- h1 -- c1

| `--- c2

`--- h2 -- c2

h1_ep_ip_ranges=( 10.1.1.0/24 10.1.2.0/24 )
h2_ep_ip_ranges=( 10.1.3.0/24 )

Kein Ping-Geldautomat (Pakete gehen nicht durch die PREROUTING-Kette...), und
muss schlafen. Morgen mehr dazu ;)

Am 18.01.2016 18:28 schrieb Tim Hockin:

Ich kann dies auf GCE nicht zum Laufen bringen und bin mir bei AWS nicht sicher - es gibt ein
begrenzte Anzahl von statischen Routen verfügbar.

Ich frage mich, ob ich es schaffen könnte, indem ich 2 IP-Bereiche in einem Huckepack zusammenstecke
Route. Es ist eine Menge IPs auszugeben, aber ich denke, es spielt nur für UDP eine Rolle.
Ich muss es ausprobieren.

Edit: Ich habe es ausprobiert und konnte es nicht zum Laufen bringen, aber mir fehlt etwas.
Wir müssen als Reaktion auf die kommenden Dienste IPs in Containern hinzufügen/entfernen
und gehen, aber ich konnte keine "zusätzlichen" IPs in einem Container zum Laufen bringen (es könnte
ping, aber nicht TCP oder UDP, ich weiß nicht warum).

Ich muss es irgendwann nochmal versuchen.

Ich kam ein bisschen weiter, aber etwas, das ich hätte voraussagen müssen, passierte.

Ich habe einen Pod mit 10.244.2.8/25 als Hauptschnittstelle und 10.244.2.250/25 . eingerichtet
als seine "in-a-service"-Schnittstelle. Ich hatte gehofft, dass ich UDP senden könnte an
.250 und erkennt Antworten, um sie zu SNAT. Aber natürlich, wenn der Kunde es ist
nicht in der gleichen /25 (was nicht sein kann) tritt die Standardroute ein, die
kommt von der .8-Adresse. tcpdump bestätigt, dass Antworten von .8 . kommen
bei Verwendung von UDP.

Ich bin wieder an einem Ort, an dem ich nicht sicher bin, wie es funktioniert. werde denken
mehr dazu.

Am Montag, 18. Januar 2016 um 2:59 Uhr, Mikaël Cluseau [email protected]
schrieb:

Ich versuche auf meiner Seite etwas zu bekommen (mit reinen Netns auf meinem lokalen Host)
zur Zeit).

Ich versuche einen Ansatz, bei dem ich Dienst-IP-Bereiche für Hosts beeinflusse
Reduzieren Sie die Anzahl der Routing-Einträge:

cli -- elb -- h1 -- c1

| `--- c2

`--- h2 -- c2

h1_ep_ip_ranges=( 10.1.1.0/24 10.1.2.0/24 )
h2_ep_ip_ranges=( 10.1.3.0/24 )

Kein Ping-Geldautomat (Pakete gehen nicht durch die PREROUTING-Kette...), und
muss schlafen. Morgen mehr dazu ;)

Am 18.01.2016 18:28 schrieb Tim Hockin:

Ich kann dies auf GCE nicht zum Laufen bringen und bin mir bei AWS nicht sicher - es gibt ein
begrenzte Anzahl von statischen Routen verfügbar.

Ich frage mich, ob ich es schaffen könnte, indem ich 2 IP-Bereiche in einem Huckepack zusammenstecke
Einzel
Route. Es ist eine Menge IPs auszugeben, aber ich denke, es spielt nur für UDP eine Rolle.
Ich muss es ausprobieren.

Edit: Ich habe es ausprobiert und konnte es nicht zum Laufen bringen, aber ich vermisse es
etwas.
Wir müssen als Reaktion auf die kommenden Dienste IPs in Containern hinzufügen/entfernen
und gehen, aber ich konnte keine "zusätzlichen" IPs in einem Container zum Laufen bringen (es könnte
ping, aber nicht TCP oder UDP, ich weiß nicht warum).

Ich muss es irgendwann nochmal versuchen.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172497456
.

Es dämmert mir (via Abhishek), dass wir, selbst wenn das funktioniert, NOCH Müssen müssen
Track fließt irgendwo hin, ist also am Ende sowieso nicht zustandslos.

Am Montag, den 18. Januar 2016 um 21:50 Uhr schrieb Tim Hockin [email protected] :

Ich kam ein bisschen weiter, aber etwas, das ich hätte voraussagen müssen, passierte.

Ich habe einen Pod mit 10.244.2.8/25 als Hauptschnittstelle eingerichtet und
10.244.2.250/25 als seine "in-a-service"-Schnittstelle. Ich hatte gehofft, dass ich
könnte UDP an .250 senden und Antworten erkennen, um sie zu SNAT. Aber natürlich,
wenn der Client nicht im selben /25 ist (was es nicht sein kann) der Standardwert
route tritt ein, die von der .8-Adresse kommt. tcpdump bestätigt das
Antworten kommen von .8, wenn UDP verwendet wird.

Ich bin wieder an einem Ort, an dem ich nicht sicher bin, wie es funktioniert. werde denken
mehr dazu.

Am Montag, 18. Januar 2016 um 2:59 Uhr, Mikaël Cluseau [email protected]
schrieb:

Ich versuche auf meiner Seite etwas zu bekommen (mit reinen Netns auf meinem lokalen Host)
zur Zeit).

Ich versuche einen Ansatz, bei dem ich Dienst-IP-Bereiche für Hosts beeinflusse
Reduzieren Sie die Anzahl der Routing-Einträge:

cli -- elb -- h1 -- c1

| `--- c2

`--- h2 -- c2

h1_ep_ip_ranges=( 10.1.1.0/24 10.1.2.0/24 )
h2_ep_ip_ranges=( 10.1.3.0/24 )

Kein Ping-Geldautomat (Pakete gehen nicht durch die PREROUTING-Kette...), und
muss schlafen. Morgen mehr dazu ;)

Am 18.01.2016 18:28 schrieb Tim Hockin:

Ich kann dies auf GCE nicht zum Laufen bringen und bin mir bei AWS nicht sicher - es gibt ein
begrenzte Anzahl von statischen Routen verfügbar.

Ich frage mich, ob ich es schaffen könnte, indem ich 2 IP-Bereiche in einem Huckepack zusammenstecke
Einzel
Route. Es ist eine Menge IPs auszugeben, aber ich denke, es spielt nur für UDP eine Rolle.
Ich muss es ausprobieren.

Edit: Ich habe es ausprobiert und konnte es nicht zum Laufen bringen, aber ich vermisse es
etwas.
Wir müssen als Reaktion auf Dienste IPs in Containern hinzufügen/entfernen
Kommen
und gehen, aber ich konnte keine "zusätzlichen" IPs in einem Container zum Laufen bringen (es
könnten
ping, aber nicht TCP oder UDP, ich weiß nicht warum).

Ich muss es irgendwann nochmal versuchen.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -172497456
.

Das ist schade :-( weiß übrigens nicht warum. Ich probiere dann mal was mit MPLS, ich will es sowieso lernen.

Wenn Sie 2 Back-Ends für Service haben und mehr als ein einzelnes senden möchten
Paket, Sie müssen Flüsse in irgendeiner Weise verfolgen, nicht wahr? Oder bist du
Angenommen, es ist sicher, Pakete auf verschiedene Backends zu sprühen?

Am Mittwoch, 20. Januar 2016 um 12:24 Uhr, Mikaël Cluseau [email protected]
schrieb:

Das ist schade :-( weiß übrigens nicht warum. Ich probiere mal was mit
MPLS also, ich will es trotzdem lernen.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an
https://github.com/kubernetes/kubernetes/issues/3760#issuecomment -173348973
.

Ich bin irgendwie davon ausgegangen, dass für UDP-Workloads ja. Es kann auch optional sein, selbst für UDP zustandslos zu werden. @qoke einen Kommentar dazu?

Außerdem könnten wir Dinge wie Client-IP-Hashing verwenden, um den Fluss stabiler zu machen, während er noch ausgeglichen ist (ich weiß nicht, ob wir das "eine Art von Tracking" nennen können :-)).

@MikaelCluseau wir verwenden das Standard-IPVS-Verhalten, das eine sehr leichte UDP-"Klebrigkeit" bewirkt ...

Zum Planen von UDP-Datagrammen zeichnet der IPVS-Load-Balancer die UDP-Datagramm-Planung mit konfigurierbarem Timeout auf, und das standardmäßige UDP-Timeout beträgt 300 Sekunden. Vor UDP-Verbindungs-Timeouts werden alle UDP-Datagramme von demselben Socket (Protokoll, IP-Adresse und Port) an denselben Server geleitet.

-- Zitiert von http://kb.linuxvirtualserver.org/wiki/IPVS

Dies funktioniert natürlich nur, wenn Sie viele Clients haben, die mit einem einzelnen Dienst kommunizieren, oder ein einzelner Client mit unterschiedlichen Quellports. Wenn Sie einen einzelnen Client mit hohem Volumen haben, der gesamte Datenverkehr von demselben Quellport sendet, und Sie dies über mehrere Back-Ends verteilen möchten, bevorzugen Sie möglicherweise einen zustandslosen/Spray-and-Pray-Ansatz.

Wir laden viel DNS- und RADIUS-Datenverkehr aus – DNS fällt normalerweise in die erste Kategorie (viele Clients oder Clients mit vielen Quellports) und RADIUS fällt normalerweise in die letztere Kategorie (wenige Clients, viele Pakete alle von gleiche IP/Port). Anstatt einen zustandslosen Hash für RADIUS zu verwenden, haben wir uns stattdessen entschieden, die Quellports zufällig zu verteilen, um eine gleichmäßige Verteilung zu erzielen.

Nachdem ich den ganzen Thread gelesen habe, kann ich immer noch nicht herausfinden, ob die Aktivierung des iptables-Modus für kube-proxy das Problem des Versteckens externer IPs (#10921) beheben sollte oder nicht. Wir haben den iptables-Modus mit v1.1 aktiviert, wie hier vorgeschlagen, aber wir sehen immer noch die IPs vom Cluster, nicht die echten von den Benutzern.

Unser Cluster befindet sich in GCE und wir benötigen nur einen Load Balancer mit HTTPS-Unterstützung, bevor wir live gehen. Da GCE v.1.2 Alpha nicht unterstützt, können wir den neuen Ingress (der AFAIK HTTPS Load Balancer unterstützt) nicht verwenden, daher ist der Network Load Balancer unsere einzige Option. Aber natürlich können wir nicht live gehen, ohne echte IPs von unseren Benutzern protokollieren zu können.

Etwas Klarstellung für neue Benutzer hierzu wäre wünschenswert. Die Unterstützung von HTTPS ist für viele von uns obligatorisch. Vielen Dank!

Ich benutze den iptables-Proxy seit geraumer Zeit ein und aus und kann bestätigen, dass die externen IPs von Clients immer noch versteckte/zeige Cluster-IPs sind.

Wir haben dies bisher umgangen, indem wir unseren Frontend-HTTP/HTTPS-Proxy im Host-Netzwerkmodus ausgeführt haben, damit er die Quell-IP-Adresse sieht.

@maclof danke für das Feedback. Könnten Sie weitere Informationen zu Ihrer Problemumgehung teilen? Was meinen Sie damit, dass Ihr HTTP/HTTPS im Host-Netzwerk läuft?

@javiercr wir verwenden eine Pod-Spezifikation wie diese: http://pastie.org/private/zpdelblsob654zif7xus5g

Die Verwendung des Hostnetzwerks bedeutet, dass der Pod im Hostcomputernetzwerk ausgeführt wird, anstatt eine Cluster-IP zugewiesen zu bekommen.

Das heißt, wenn sich unser nginx-Server an Port 80/443 bindet, wird er auf einer Host-IP lauschen und die Quell-IP-Adressen sehen.

Ich verwende Kubernetes 1.1, /opt/bin/kube-proxy ... --proxy-mode=iptables --masquerade-all=false und leite das Cluster-IP-Netzwerk über einen Host mit einem Kube-Proxy. In diesem Setup sehen meine Dienste die externe IP. Ich verwende einen hochverfügbaren Netzwerk-Namespace, der eine externe IP und eine Route zu den Hosts hat:

I0221 01:20:32.695440       1 main.go:224] <A6GSXEKN> Connection from 202.22.xxx.yyy:51954 closed.

Ich habe viel gelernt beim Lesen dieses Threads!

Als FYI besagt dieses Dokument, dass AWS ELB Round-Robin für TCP-Verbindungen und die geringsten Verbindungen für http/https verwendet: http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/how-elb-works.html# Anfrage -Routing

Ich stimme zu, dass es der beste Weg ist, sich darauf zu konzentrieren, Anfragen nur an Knoten zu senden, die Pods ausführen, und zu versuchen, lokale Pods zu bedienen. Der nette Nebenvorteil davon ist, dass es weniger Knoten-zu-Knoten-Verkehr innerhalb des Clusters gibt und ich vermute, dass eine Latenzverbesserung durch immer lokale Anfragen vom Dienst zum Pod erfolgt (was meiner Meinung nach noch vorteilhafter ist, wenn Sie Knoten in mehrere Availability Zones im selben Cluster).

In Bezug auf die Arbeit mit einem Load Balancer, der keine Gewichtung unterstützt, können Sie dies mit Ihrem Replikationscontroller lösen, indem Sie versuchen, immer die gleiche Anzahl von Pods auf einem Knoten zu halten (wenn mehr als 1 pro Knoten vorhanden sind) und dann gleichmäßig auf die anderen zu verteilen auch wenn dies bedeutet, dass in bestimmten Situationen Pods von einem Knoten entfernt werden müssen und nur bestimmte Replikatzahlen zugelassen werden. B. für einen 4-Knoten-Cluster mit einem Dienst, der mit einem Load Balancer verbunden ist, wäre die einzige zulässige Anzahl von Pod-Replikaten 1,2,3,4,6,8,9,12,16,20 usw.

Wir suchen auch nach einer Lösung für Traffic, der nur an lokale Pods weitergeleitet wird. Es wäre in Ordnung, wenn der Nodeport auf einem Node zu Zeiten verschwindet, wenn keine Pods lokal für einen Dienst vorhanden sind. Auf diese Weise würde eine einfache TCP-Zustandsprüfung des Load-Balancers verhindern, dass Anforderungen an diese Knoten gesendet werden. Ich denke, wenn wir zumindest den iptables\kube-proxy-Teil davon lösen können, werden wir herausfinden, was die Auswirkungen auf den Lastausgleich sind, wenn die Pods nicht über den Cluster verteilt sind. Ich denke, es gibt Möglichkeiten, das bei Load Balancern zu lösen, ohne für jeden Knoten eine Gewichtung mit einem API-Aufruf festlegen zu müssen.

Load Balancer lösen dies bereits mit anderen dynamischen Methoden. Je nachdem, was der von Ihnen ausgeführte Dienst tatsächlich für jeden API-Aufruf in diesem Container tut, kann er möglicherweise nicht das Doppelte des Datenverkehrs unterstützen, wenn sich sowieso 2 Pods auf einem Knoten befinden. Wenn Kubernetes-Limits festgelegt sind und die maximale Nutzung auf einem Podnode erreicht wird, könnte dies ebenfalls eine Rolle spielen, was die Suche nach der richtigen Gewichtungseinstellung auf dem externen Load Balancer noch komplizierter macht.

Ich würde sagen, halten Sie sich von dieser Komplexität fern und versuchen Sie nicht, das Gewicht des Load-Balancers von Kubernetes festzulegen.

@yoshiwaan Kann ich vorschlagen, ein neues Problem für den Vorschlag für den Verkehr zwischen Knoten zu öffnen, da dieses Problem jetzt geschlossen ist. Persönlich denke ich, dass ein guter erster Schritt darin besteht, sicherzustellen, dass _wenn_ ein Pod auf dem lokalen Knoten läuft, dass wir zum lokalen Pod routen. Ich vermute, dass dies ausreichen wird, da Sie dann Ihren RC so skalieren können, dass sich auf jedem Knoten Pods befinden.

@justinsb +1, außerdem

Das könnte viel zu naiv sein, aber ich habe mich gefragt, was der Unterschied zwischen dem Userspace-Modus und iptables ist. Das kann ich aus der Benutzerdokumentation nicht wirklich sagen.

Userland-Modus bedeutet, dass kube-proxy die Verbindungen selbst handhabt, indem er die Verbindungsanfrage vom Client empfängt und einen Socket zum Server öffnet, was (1) viel mehr CPU und Speicher verbraucht und (2) auf die Anzahl von Ports beschränkt ist, die ein einzelner Benutzer kann offen (<65k). Der iptables-Modus arbeitet auf einer niedrigeren Ebene im Kernel und verwendet stattdessen Verbindungsverfolgung, ist also viel einfacher und verarbeitet viel mehr Verbindungen*.

(Bearbeiten) (*) Solange Sie keine SNAT-Pakete durchlaufen lassen, was wiederum eine Einrichtung erfordert, bei der Sie sicher sind, dass Pakete die damit verbundenen Verbindungsverfolgungsregeln überschreiten. Wenn Sie beispielsweise ein Design mit geroutetem Zugriff verwenden, können Sie SNAT vermeiden, was bedeutet, dass der Endpunkt des Dienstes die IP des echten Clients sieht.

@MikaelCluseau
Das heißt, kube-proxy ist nur für das Einrichten und Verwalten von iptables-Regeln verantwortlich und wir erhalten im iptables-Modus nicht mehr einen zufälligen lokalen Port für jeden Dienst, oder?

Am 19.04.2016 22:51 Uhr schrieb Emma Er:

Das heißt, kube-proxy ist nur für die Einrichtung und Wartung verantwortlich
iptables und wir erhalten nicht mehr einen zufälligen lokalen Port für jeden Dienst in
iptables-Modus, oder?

Jawohl.

Sorry, aber das habe ich vorhin absolut übersehen.

(Bearbeiten) (*) Solange Sie keine SNAT-Pakete durchlaufen lassen, was wiederum eine Einrichtung erfordert, bei der Sie sicher sind, dass Pakete die damit verbundenen Verbindungsverfolgungsregeln überschreiten. Wenn Sie beispielsweise ein Design mit geroutetem Zugriff verwenden, können Sie SNAT vermeiden, was bedeutet, dass der Endpunkt des Dienstes die IP des echten Clients sieht.

@MikaelCluseau Ich dachte, iptables übernimmt SNAT und DNAT, was Ihrer Meinung nach nicht der Fall ist. Könnten Sie das bitte für mich klären?

Am 20.04.2016 13:59 Uhr schrieb Emma Er:

@MikaelCluseau https://github.com/MikaelCluseau dachte ich
iptables übernimmt SNAT und DNAT, was Ihrer Meinung nach nicht der Fall ist.
Könnten Sie das bitte für mich klären?

Es ist der schwierige Teil.

(1) Die Verwendung von Dienst-/externen IPs erfordert DNAT.
(2) Wenn Sie sicher sind, dass Antwortpakete denselben Conntrack durchlaufen werden
Regel (d. h. der gleiche Netzwerk-Stack oder eine replizierte conntrack-Tabelle), Sie
kann den SNAT-Teil überspringen (dh MASQUERADE-Regeln).

Die Bedingung von (2) ist in Netzwerkdesigns mit geroutetem Zugang normalerweise in Ordnung
(das ist das einfachste Design, das ich mir vorstellen kann).

Zum Beispiel gegeben

  • ein Kunde 1.0.1.1,
  • ein Dienst 1.0.2.1,
  • ein Pod, das den Dienst 1.0.3.1 implementiert.

Dann,

  1. Ihr Router/Firewall/Loadbalancer/Host/was auch immer ein Paket empfängt
    für den Dienst sieht er also ein Paket "1.0.1.1 -> 1.0.2.1";
  2. Es DNATs an den Endpunkt (Pod), sodass das Paket "1.0.1.1 -> ." ist
    1.0.3.1" im Cluster-Netzwerk;
  3. Der Pod antwortet mit einem Paket "1.0.3.1 -> 1.0.1.1";
  4. Das Paket geht durch einen Router/Firewall/Loadbalancer/Host/was auch immer
    Mit der Conntrack-Regel schreibt das Conntrack-System das Paket neu
    auf "1.0.2.1 -> 1.0.1.1", bevor Sie es an den Client zurücksenden.

Wenn die Bedingung von (2) nicht erfüllt werden kann, müssen Sie SNAT/MASQUERADING verwenden
um sicherzustellen, dass das Paket durch die
Router/Firewall/Loadbalancer/Host/was auch immer Conntrack ist.

@MikaelCluseau -
etwas für dich

Am Di, 19. April 2016 um 20:20 Uhr, Mikaël Cluseau [email protected]
schrieb:

Am 20.04.2016 13:59 Uhr schrieb Emma Er:

@MikaelCluseau https://github.com/MikaelCluseau dachte ich
iptables übernimmt SNAT und DNAT, was Ihrer Meinung nach nicht der Fall ist.
Könnten Sie das bitte für mich klären?

Es ist der schwierige Teil.

(1) Die Verwendung von Dienst-/externen IPs erfordert DNAT.
(2) Wenn Sie sicher sind, dass Antwortpakete denselben Conntrack durchlaufen werden
Regel (d. h. der gleiche Netzwerk-Stack oder eine replizierte conntrack-Tabelle), Sie
kann den SNAT-Teil überspringen (dh MASQUERADE-Regeln).

Die Bedingung von (2) ist in Netzwerkdesigns mit geroutetem Zugang normalerweise in Ordnung
(das ist das einfachste Design, das ich mir vorstellen kann).

Zum Beispiel gegeben

  • ein Kunde 1.0.1.1,
  • ein Dienst 1.0.2.1,
  • ein Pod, das den Dienst 1.0.3.1 implementiert.

Dann,

  1. Ihr Router/Firewall/Loadbalancer/Host/was auch immer ein Paket empfängt
    für den Dienst sieht er also ein Paket "1.0.1.1 -> 1.0.2.1";
  2. Es DNATs an den Endpunkt (Pod), sodass das Paket "1.0.1.1 -> ." ist
    1.0.3.1" im Cluster-Netzwerk;
  3. Der Pod antwortet mit einem Paket "1.0.3.1 -> 1.0.1.1";
  4. Das Paket geht durch einen Router/Firewall/Loadbalancer/Host/was auch immer
    Mit der Conntrack-Regel schreibt das Conntrack-System das Paket neu
    auf "1.0.2.1 -> 1.0.1.1", bevor Sie es an den Client zurücksenden.

Wenn die Bedingung von (2) nicht erfüllt werden kann, müssen Sie SNAT/MASQUERADING verwenden
um sicherzustellen, dass das Paket durch die
Router/Firewall/Loadbalancer/Host/was auch immer Conntrack ist.


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/kubernetes/kubernetes/issues/3760#issuecomment 212230959

@justinsb @yoshiwaan hat jemand jemals ein Problem dafür erstellt? Meine Suchfunktion versagt bei mir, und ich habe ein ähnliches Bedürfnis.

Kann ich vorschlagen, ein neues Problem für den Vorschlag für den Verkehr zwischen Knoten zu öffnen, da dieses Problem jetzt geschlossen ist. Persönlich denke ich, dass ein guter erster Schritt darin besteht, sicherzustellen, dass wir, wenn ein Pod auf dem lokalen Knoten ausgeführt wird, zum lokalen Pod routen. Ich vermute, dass dies ausreichen wird, da Sie dann Ihren RC so skalieren können, dass sich auf jedem Knoten Pods befinden.

Ich habe es nicht selbst großgezogen

Ahhhhh, ich glaube, ich habe es gefunden, dies scheint das Feature/Fix zu sein: https://github.com/kubernetes/features/issues/27

Scheint Beta von 1.5.x zu sein.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen