wake-up-neo.com

Wie ist die Beziehung zwischen docker0 und eth0?

Ich weiß, dass Docker standardmäßig eine virtuelle Brücke docker0 erstellt und alle Containernetzwerke mit docker0 verknüpft sind.

Wie oben dargestellt:

  • container eth0 ist mit vethXXX gepaart
  • vethXXX ist mit docker0 verknüpft, genau wie eine Maschine, die mit dem Switch verbunden ist

Aber wie ist die Beziehung zwischen docker0 und Host eth0? Genauer:

  1. Wenn ein Paket vom Container zum Docker0 fließt, woher weiß es, dass es an eth0 und dann an die Außenwelt weitergeleitet wird?
  2. Wenn ein externes Paket bei eth0 ankommt, warum wird es dann an docker0 und container weitergeleitet? anstatt es zu verarbeiten oder fallen zu lassen?

Frage 2 kann etwas verwirrend sein, ich werde es dort belassen und ein wenig mehr erklären:

  • Es handelt sich um ein vom Container initialisiertes Rückgabepaket (in Frage 1): Da das externe Containernetzwerk nicht bekannt ist, wird das Paket an Host eth0 gesendet. Wie wird es zum Container weitergeleitet? Ich meine, es muss einen Ort geben, an dem die Informationen gespeichert werden können. Wie kann ich sie überprüfen?

Danke im Voraus!


Nachdem ich die Antwort und die offiziellen Netzwerkartikel gelesen habe, finde ich das folgende Diagramm genauer, dass docker0 und eth0 keine direkte Verknüpfung haben, sondern Pakete weiterleiten können:

http://dockerone.com/uploads/article/20150527/e84946a8e9df0ac6d109c35786ac4833.png

16
cizixs

Es gibt keine direkte Verbindung zwischen der Standardbrücke docker0 und den Ethernet-Geräten des Hosts. Wenn Sie die --net=Host-Option für einen Container verwenden, werden der Hoststapel und der Container-Netzwerkstapel verknüpft.

Wenn ein Paket vom Container zum Docker0 fließt, woher weiß es dann, dass es an eth0 und dann an die Außenwelt weitergeleitet wird?

Der docker0-Brücke ist die .1-Adresse des Docker-Netzwerks zugewiesen. Dies ist normalerweise etwas um 172.17 oder 172.18.

$ ip address show dev docker0
8: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:03:47:33:c1 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
       valid_lft forever preferred_lft forever

Containern wird eine veth-Schnittstelle zugewiesen, die an die docker0-Brücke angeschlossen ist.

$ bridge link
10: vethcece7e5 state UP @(null): <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master docker0 state forwarding priority 32 cost 2

Container, die im Standard-Docker-Netzwerk erstellt wurden, erhalten die .1-Adresse als Standardroute. 

$ docker run busybox ip route show
default via 172.17.0.1 dev eth0 
172.17.0.0/16 dev eth0  src 172.17.0.3 

Docker verwendet NAT MASQUERADE für ausgehenden Datenverkehr von dort aus und folgt dem Standard-Routing für ausgehende Daten auf dem Host, das standardmäßig eth0 verwendet werden kann.

$ iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0  

iptables wickelt die Verbindungsverfolgung und den Rückkehrverkehr ab. 

Wenn ein externes Paket bei eth0 eintrifft, warum wird es dann an den docker0-Container weitergeleitet? anstatt es zu bearbeiten oder fallen zu lassen?

Wenn Sie nach zurückgehendem ausgehenden Datenverkehr fragen, lesen Sie die obigen Informationen zu iptables. 

Wenn Sie neuen eingehenden Datenverkehr meinen, werden Pakete standardmäßig nicht in einen Container weitergeleitet. Die Standardmethode, dies zu erreichen, ist das Einrichten von einer Portzuordnung . Docker startet einen Daemon, der auf dem Host an Port X abhört und an den Container an Port Y weiterleitet. 

Ich bin nicht sicher, warum NAT auch nicht für eingehenden Datenverkehr verwendet wurde. Ich bin auf einige Probleme gestoßen, als ich versuche, eine große Anzahl von Ports in Containern abzubilden, was dazu führte, dass reale Schnittstellen abgebildet werden vollständig in Containern. 

17
Matt

Sie können die Beziehung über die Netzwerkschnittstelle iflink aus einem Container und ifindex auf dem Host-Computer erkennen. 

iflink aus einem Container holen:

$ docker exec ID cat /sys/class/net/eth0/iflink

17253

Dann finden Sie diese ifindex unter den Schnittstellen auf dem Host-Rechner:

$ grep -l 17253 /sys/class/net/veth*/ifindex

/sys/class/net/veth02455a1/ifindex
0
chingis