web-dev-qa-db-fra.com

Quelle est la relation entre docker0 et eth0?

Je sais que, par défaut, docker crée un pont virtuel docker0 et que tous les réseaux de conteneurs sont liés à docker0.

Comme illustré ci-dessus:

  • le conteneur eth0 est associé à vethXXX
  • vethXXX est lié à docker0 identique à une machine liée à un commutateur

Mais quelle est la relation entre docker0 et l'hôte eth0? Plus précisément:

  1. Lorsqu'un paquet passe d'un conteneur à docker0, comment peut-il savoir qu'il sera transmis à eth0 puis au monde extérieur?
  2. Lorsqu'un paquet externe arrive sur eth0, pourquoi est-il transmis à docker0 puis conteneur? au lieu de le traiter ou de le laisser tomber?

La question 2 peut être un peu déroutante, je vais la garder là et expliquer un peu plus:

  • Il s’agit d’un paquet de retour initialisé par conteneur (question 1): comme l’extérieur ne connaît pas le réseau de conteneurs, le paquet est envoyé à l’hôte eth0. Comment est-il transmis au conteneur? Je veux dire, il doit y avoir un endroit où stocker les informations, comment puis-je les vérifier?

Merci d'avance!


Après avoir lu la réponse et les articles officiels du réseau, je trouve le diagramme suivant plus précis que docker0 et eth0 n’ont pas de lien direct, mais qu’ils peuvent transférer des paquets:

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

16
cizixs

Il n'y a pas de lien direct entre le pont docker0 par défaut et les périphériques Ethernet hôtes. Si vous utilisez l'option --net=Host pour un conteneur, la pile réseau de l'hôte et des conteneurs sera liée.

Lorsqu'un paquet passe d'un conteneur à un autre, comment sait-il qu'il sera transmis à eth0, puis au monde extérieur?

Le pont docker0 a l’adresse .1 du réseau Docker qui lui est attribuée. Il s’agit généralement d’un chiffre 172.17 ou 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

Les conteneurs se voient attribuer une interface veth attachée au pont docker0.

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

Les conteneurs créés sur le réseau Docker par défaut reçoivent l'adresse .1 comme itinéraire par défaut. 

$ 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 utilise NAT MASQUERADE pour le trafic sortant à partir de là. Il suivra le routage sortant standard sur l'hôte, qui peut ou non adopter par défaut 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 gère le suivi de la connexion et le trafic de retour. 

Lorsqu'un paquet externe arrive sur eth0, pourquoi est-il transmis à docker0 puis conteneur? au lieu de le traiter ou de le laisser tomber?

Si vous vous interrogez sur le trafic de retour, consultez iptables ci-dessus. 

Si vous voulez dire nouveau trafic entrant, les paquets ne sont pas transférés dans un conteneur par défaut. La méthode standard pour y parvenir consiste à configurer un mappage de port . Docker lance un démon qui écoute sur l'hôte sur le port X et le transmet au conteneur sur le port Y. 

Je ne suis pas sûr de savoir pourquoi NAT n'a pas été utilisé non plus pour le trafic entrant. J'ai rencontré des problèmes en essayant de mapper un grand nombre de ports dans des conteneurs, ce qui a conduit à mapper des interfaces du monde réel complètement dans des conteneurs. 

17
Matt

Vous pouvez détecter la relation par l'interface réseau iflink à partir d'un conteneur et ifindex sur la machine hôte. 

Obtenez iflink à partir d'un conteneur:

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

17253

Trouvez ensuite cette ifindex parmi les interfaces de la machine hôte:

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

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