2016-05-31 20 views
6

So che per impostazione predefinita la finestra mobile crea un bridge virtuale docker0 e tutta la rete del contenitore è collegata a docker0.Qual è la relazione tra docker0 e eth0?

Come illustrato sopra:

  • contenitore eth0 è accoppiato con vethXXX
  • vethXXX è legata docker0 stessa come una macchina collegato a commutare

Ma che relazione tra docker0 e host eth0? In particolare:

  1. Quando un pacchetto scorre dal contenitore per docker0, come fa a sapere che sarà trasmessa al eth0, e quindi al mondo esterno?
  2. Quando un pacchetto esterno arriva a eth0, perché viene inoltrato a docker0 quindi contenitore? invece di elaborarlo o rilasciarlo?

Domanda 2 può essere fuorviante, terrò lì e spiegato un po 'più:

  • È un pacchetto di ritorno che siglata dal contenitore (domanda 1): dal lato esterno non conosce la rete container, il pacchetto viene inviato all'host eth0. Come viene inoltrato al contenitore? Voglio dire, ci deve essere un posto dove archiviare le informazioni, come posso verificarlo?

Grazie in anticipo!


Dopo aver letto la risposta e articoli rete ufficiale, trovo il seguente schema più accurato che docker0 e eth0 non ha collegamento diretto, invece possono inoltrare i pacchetti:

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

risposta

8

Non c'è collegamento diretto tra il bridge docker0 predefinito e i dispositivi Ethernet host. Se si utilizza l'opzione --net=host per un container, lo stack di rete host e contenitori verrà collegato.

Quando un pacchetto scorre da contenitore a docker0, come fa a sapere che verrà inoltrato a eth0 e quindi al mondo esterno?

Il ponteha l'indirizzo .1 assegnato.

$ 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 

contenitori sono assegnati un'interfaccia VETH, attaccato docker0.

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

Contenitori in rete predefinita ricevono l'indirizzo .1 come il loro percorso di default.

$ 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 utilizza NAT TRAVESTIMENTO per il traffico in uscita da lì e seguirà il percorso in uscita standard sul host, che può o non può default eth0.

$ 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 gestisce il tracciamento della connessione e il traffico di ritorno.

Quando un pacchetto esterno arriva a eth0, perché viene inoltrato a docker0 quindi contenitore? invece di elaborarlo o rilasciarlo?

Se si parla di traffico in uscita di ritorno, vedere iptables sopra.

Se si intende il nuovo traffico in entrata, i pacchetti non vengono inoltrati in un contenitore per impostazione predefinita. Il modo standard per farlo è impostare a port mapping. Docker avvia un demone che ascolta l'host sulla porta X e inoltra al contenitore sulla porta Y.

Non sono sicuro del motivo per cui NAT non è stato utilizzato anche per il traffico in entrata. Ho riscontrato alcuni problemi nel tentativo di mappare un numero elevato di porte in contenitori che portavano a mapping real world interfaces completamente in contenitori.

+0

Grazie per la spiegazione. Posso metterlo in questo modo: quando un pacchetto arriva a 'docker0' dal contenitore, non sa né preoccuparsi di' eth0'. Invece il kernel prende il sopravvento e decide cosa fare con esso. Di default il kernel controlla la tabella di routing, di solito sarà inviata a 'eth0', quindi a SNAT, quindi al mondo esterno? – cizixs

+0

Sì, routing standard Linux e NAT. – Matt

0

È possibile rilevare la relazione tramite l'interfaccia di rete iflink da un contenitore e ifindex sul computer host.

Ottenere iflink da un contenitore:

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

17253 

poi trovare questo ifindex tra interfacce sulla macchina host:

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

/sys/class/net/veth02455a1/ifindex 
Problemi correlati