Maison  >  Article  >  Opération et maintenance  >  Explication détaillée de la paire veth du périphérique réseau virtuel Linux, cet article est très informatif

Explication détaillée de la paire veth du périphérique réseau virtuel Linux, cet article est très informatif

若昕
若昕avant
2019-04-01 13:03:505778parcourir

Cet article présente veth-pair et sa connectivité, ainsi que la connectivité entre deux espaces de noms.

01 Qu'est-ce que veth-pair

Comme son nom l'indique , veth-pair est une paire d'interfaces de périphériques virtuels. Différentes des périphériques tap/tun, elles apparaissent toutes par paires. Une extrémité est connectée à la pile de protocoles et l'autre extrémité est connectée l'une à l'autre. Comme le montre la figure ci-dessous :

Explication détaillée de la paire veth du périphérique réseau virtuel Linux, cet article est très informatif

En raison de cette fonctionnalité, il agit souvent comme un pont pour connecter divers périphériques réseau virtuels. Un exemple typique est comme "entre deux espaces de noms". "Connexion entre", "Connexion entre Bridge et OVS", "Connexion entre conteneurs Docker", etc., pour construire une structure de réseau virtuel très complexe, comme OpenStack Neutron.

Connectivité 02 veth-pair

Nous attribuons des adresses IP à veth0 et veth1 dans la figure ci-dessus : 10.1.1.2 et 10.1.1.3 respectivement, puis pingons veth1 depuis veth0. Théoriquement, ils se trouvent sur le même segment de réseau et peuvent être pingés avec succès, mais le résultat est que le ping échoue.

Prenez le paquet et jetez un œil tcpdump -nnt -i veth0

root@ubuntu:~# tcpdump -nnt -i veth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
ARP, Request who-has 10.1.1.3 tell 10.1.1.2, length 28
ARP, Request who-has 10.1.1.3 tell 10.1.1.2, length 28

Vous pouvez voir que puisque veth0 et veth1 sont sur le même segment de réseau et sont connectés pour la première fois, ARP le fera. être envoyé à l'avance, mais veth1 n'a pas répondu au paquet ARP.

Après vérification, cela est dû à certaines restrictions de configuration par défaut liées à ARP dans le noyau du système Ubuntu que j'utilise. Je dois modifier les éléments de configuration :

echo 1 > /proc/sys/net/ipv4/conf/veth1/accept_local
echo 1 > /proc/sys/net/ipv4/conf/veth0/accept_local
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/veth0/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/veth1/rp_filter

Il suffit de faire un nouveau ping après. que. .

root@ubuntu:~# ping -I veth0 10.1.1.3 -c 2
PING 10.1.1.3 (10.1.1.3) from 10.1.1.2 veth0: 56(84) bytes of data.
64 bytes from 10.1.1.3: icmp_seq=1 ttl=64 time=0.047 ms
64 bytes from 10.1.1.3: icmp_seq=2 ttl=64 time=0.064 ms

--- 10.1.1.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 3008ms
rtt min/avg/max/mdev = 0.047/0.072/0.113/0.025 ms

Nous sommes plus intéressés par ce processus de communication et pouvons capturer les paquets pour y jeter un œil.

Pour le port veth0 :

root@ubuntu:~# tcpdump -nnt -i veth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
ARP, Request who-has 10.1.1.3 tell 10.1.1.2, length 28
ARP, Reply 10.1.1.3 is-at 5a:07:76:8e:fb:cd, length 28
IP 10.1.1.2 > 10.1.1.3: ICMP echo request, id 2189, seq 1, length 64
IP 10.1.1.2 > 10.1.1.3: ICMP echo request, id 2189, seq 2, length 64
IP 10.1.1.2 > 10.1.1.3: ICMP echo request, id 2189, seq 3, length 64
IP 10.1.1.2 > 10.1.1.3: ICMP echo request, id 2244, seq 1, length 64

Pour le port veth1 :

root@ubuntu:~# tcpdump -nnt -i veth1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on veth1, link-type EN10MB (Ethernet), capture size 262144 bytes
ARP, Request who-has 10.1.1.3 tell 10.1.1.2, length 28
ARP, Reply 10.1.1.3 is-at 5a:07:76:8e:fb:cd, length 28
IP 10.1.1.2 > 10.1.1.3: ICMP echo request, id 2189, seq 1, length 64
IP 10.1.1.2 > 10.1.1.3: ICMP echo request, id 2189, seq 2, length 64
IP 10.1.1.2 > 10.1.1.3: ICMP echo request, id 2189, seq 3, length 64
IP 10.1.1.2 > 10.1.1.3: ICMP echo request, id 2244, seq 1, length 64

Étrange, nous n'avons pas vu le paquet echo reply d'ICMP, alors comment est-ce possible tu cingles ?

En fait, ici echo reply utilise le port localback Si vous ne me croyez pas, prenez un sac et jetez un œil :

root@ubuntu:~# tcpdump -nnt -i lo
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
IP 10.1.1.3 > 10.1.1.2: ICMP echo reply, id 2244, seq 1, length 64
IP 10.1.1.3 > 10.1.1.2: ICMP echo reply, id 2244, seq 2, length 64
IP 10.1.1.3 > 10.1.1.2: ICMP echo reply, id 2244, seq 3, length 64
IP 10.1.1.3 > 10.1.1.2: ICMP echo reply, id 2244, seq 4, length 64

Pourquoi ?

Nous comprendrons si nous regardons l’ensemble du processus de communication.

  1. Tout d'abord, le programme ping construit ICMP echo request et l'envoie à la pile de protocoles via socket.
  2. Puisque ping spécifie le port veth0, si c'est la première fois, vous devez envoyer une requête ARP, sinon la pile de protocoles remettra directement le paquet de données à veth0.
  3. Puisque veth0 est connecté à veth1, la requête ICMP est envoyée directement à veth1.
  4. Après avoir reçu la demande, veth1 la remet à la pile de protocoles à l'autre extrémité.
  5. La pile de protocoles a constaté qu'il existe une adresse IP de 10.1.1.3 localement. Elle a donc construit un paquet de réponse ICMP, vérifié la table de routage et constaté que le paquet de données renvoyé au segment de réseau 10.1.1.0 devait passer par le port localback, il a donc transmis le paquet de réponse au port lo (il vérifiera d'abord la table 0 de la table de routage, ip route show table 0 pour vérifier).
  6. Après avoir reçu le paquet de réponse de la pile de protocoles, Lo n'a rien fait, a changé de mains et l'a renvoyé à la pile de protocoles.
  7. Après avoir reçu le paquet de réponse, la pile de protocoles a découvert qu'il y avait un socket en attente du paquet, elle a donc donné le paquet au socket.
  8. Attente que le programme ping en mode utilisateur constate que le socket revient, donc le paquet de réponse ICMP est reçu.

L'ensemble du processus est illustré dans la figure ci-dessous :

Explication détaillée de la paire veth du périphérique réseau virtuel Linux, cet article est très informatif

03 Connectivité entre deux espaces de noms

namespace est une fonctionnalité prise en charge par la version du noyau Linux 2.6.x et versions ultérieures, principalement utilisée pour l'isolation des ressources. Avec l'espace de noms, un système Linux peut abstraire plusieurs sous-systèmes réseau. Chaque sous-système possède son propre équipement réseau, sa pile de protocoles, etc., sans s'influencer mutuellement.

Que devons-nous faire si nous avons besoin de communiquer entre les espaces de noms ? La réponse est d'utiliser veth-pair comme pont ?

Selon la méthode et l'échelle de connexion, elle peut être divisée en « connexion directe », « connexion via Bridge » et « connexion via OVS ».

3.1 Connexion directe

La connexion directe est le moyen le plus simple, comme indiqué ci-dessous, une paire de veth-pair connecte directement deux espaces de noms ensemble.

Explication détaillée de la paire veth du périphérique réseau virtuel Linux, cet article est très informatif

Configurer l'IP pour la paire veth et tester la connectivité :

# 创建 namespace
ip netns a ns1
ip netns a ns2

# 创建一对 veth-pair veth0 veth1
ip l a veth0 type veth peer name veth1

# 将 veth0 veth1 分别加入两个 ns
ip l s veth0 netns ns1
ip l s veth1 netns ns2

# 给两个 veth0 veth1 配上 IP 并启用
ip netns exec ns1 ip a a 10.1.1.2/24 dev veth0
ip netns exec ns1 ip l s veth0 up
ip netns exec ns2 ip a a 10.1.1.3/24 dev veth1
ip netns exec ns2 ip l s veth1 up

# 从 veth0 ping veth1
[root@localhost ~]# ip netns exec ns1 ping 10.1.1.3
PING 10.1.1.3 (10.1.1.3) 56(84) bytes of data.
64 bytes from 10.1.1.3: icmp_seq=1 ttl=64 time=0.073 ms
64 bytes from 10.1.1.3: icmp_seq=2 ttl=64 time=0.068 ms

--- 10.1.1.3 ping statistics ---
15 packets transmitted, 15 received, 0% packet loss, time 14000ms
rtt min/avg/max/mdev = 0.068/0.084/0.201/0.032 ms

3.2 Se connecter via un pont

Le pont Linux est équivalent à un Un commutateur peut transférer le trafic de deux espaces de noms. Voyons quel rôle y joue veth-pair.

Comme indiqué ci-dessous, deux paires de paires veth connectent deux espaces de noms au Bridge.

Explication détaillée de la paire veth du périphérique réseau virtuel Linux, cet article est très informatif

Configurez de la même manière l'IP pour la paire veth et testez sa connectivité :

# 首先创建 bridge br0
ip l a br0 type bridge
ip l s br0 up 

# 然后创建两对 veth-pair
ip l a veth0 type veth peer name br-veth0
ip l a veth1 type veth peer name br-veth1

# 分别将两对 veth-pair 加入两个 ns 和 br0
ip l s veth0 netns ns1
ip l s br-veth0 master br0
ip l s br-veth0 up

ip l s veth1 netns ns2
ip l s br-veth1 master br0
ip l s br-veth1 up

# 给两个 ns 中的 veth 配置 IP 并启用
ip netns exec ns1 ip a a 10.1.1.2/24 dev veth0
ip netns exec ns1 ip l s veth0 up

ip netns exec ns2 ip a a 10.1.1.3/24 dev veth1
ip netns exec ns2 ip l s veth1 up

# veth0 ping veth1
[root@localhost ~]# ip netns exec ns1 ping 10.1.1.3
PING 10.1.1.3 (10.1.1.3) 56(84) bytes of data.
64 bytes from 10.1.1.3: icmp_seq=1 ttl=64 time=0.060 ms
64 bytes from 10.1.1.3: icmp_seq=2 ttl=64 time=0.105 ms

--- 10.1.1.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.060/0.082/0.105/0.024 ms

3.3 Connectez-vous via OVS

OVS est un Bridge open source tiers avec des fonctions plus puissantes que Linux Bridge Pour la même expérience, nous utilisons OVS pour voir quel est l'effet.

Comme indiqué ci-dessous :

Explication détaillée de la paire veth du périphérique réseau virtuel Linux, cet article est très informatif

Testez également la connectivité entre les deux espaces de noms :

# 用 ovs 提供的命令创建一个 ovs bridge
ovs-vsctl add-br ovs-br

# 创建两对 veth-pair
ip l a veth0 type veth peer name ovs-veth0
ip l a veth1 type veth peer name ovs-veth1

# 将 veth-pair 两端分别加入到 ns 和 ovs bridge 中
ip l s veth0 netns ns1
ovs-vsctl add-port ovs-br ovs-veth0
ip l s ovs-veth0 up

ip l s veth1 netns ns2
ovs-vsctl add-port ovs-br ovs-veth1
ip l s ovs-veth1 up

# 给 ns 中的 veth 配置 IP 并启用
ip netns exec ns1 ip a a 10.1.1.2/24 dev veth0
ip netns exec ns1 ip l s veth0 up

ip netns exec ns2 ip a a 10.1.1.3/24 dev veth1
ip netns exec ns2 ip l s veth1 up

# veth0 ping veth1
[root@localhost ~]# ip netns exec ns1 ping 10.1.1.3
PING 10.1.1.3 (10.1.1.3) 56(84) bytes of data.
64 bytes from 10.1.1.3: icmp_seq=1 ttl=64 time=0.311 ms
64 bytes from 10.1.1.3: icmp_seq=2 ttl=64 time=0.087 ms
^C
--- 10.1.1.3 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.087/0.199/0.311/0.112 ms

相关课程推荐:Linux视频教程

总结

veth-pair 在虚拟网络中充当着桥梁的角色,连接多种网络设备构成复杂的网络。

veth-pair 的三个经典实验,直接相连、通过 Bridge 相连和通过 OVS 相连。

参考

http://www.opencloudblog.com/?p=66

https://segmentfault.com/a/1190000009251098

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer