Heim  >  Artikel  >  Betrieb und Instandhaltung  >  Detaillierte Erläuterung des Veth-Pairs für virtuelle Linux-Netzwerkgeräte. Dieser Artikel ist sehr informativ

Detaillierte Erläuterung des Veth-Pairs für virtuelle Linux-Netzwerkgeräte. Dieser Artikel ist sehr informativ

若昕
若昕nach vorne
2019-04-01 13:03:505781Durchsuche

Dieser Artikel stellt Veth-Pair und seine Konnektivität sowie die Konnektivität zwischen zwei Namespaces vor.

01 Was ist Veth-Pair?

Wie der Name schon sagt veth-pair ist ein Paar virtueller Geräteschnittstellen. Im Gegensatz zu Tap/Tun-Geräten erscheinen sie alle paarweise. Ein Ende ist mit dem Protokollstapel verbunden und das andere Ende ist miteinander verbunden. Wie in der folgenden Abbildung dargestellt:

Detaillierte Erläuterung des Veth-Pairs für virtuelle Linux-Netzwerkgeräte. Dieser Artikel ist sehr informativ

Aufgrund dieser Funktion fungiert es häufig als Brücke zum Verbinden verschiedener virtueller Netzwerkgeräte. Ein typisches Beispiel ist „zwischen zwei Namespaces“. „Verbindung zwischen“, „Verbindung zwischen Bridge und OVS“, „Verbindung zwischen Docker-Containern“ usw., um eine sehr komplexe virtuelle Netzwerkstruktur wie OpenStack Neutron aufzubauen.

02 Veth-Pair-Konnektivität

Wir weisen veth0 und veth1 in der obigen Abbildung IPs zu: 10.1.1.2 bzw. 10.1.1.3 und pingen dann veth1 von veth0 an. Theoretisch befinden sie sich im selben Netzwerksegment und können erfolgreich angepingt werden, das Ergebnis ist jedoch, dass der Ping-Vorgang fehlschlägt.

Schnappen Sie sich das Paket und werfen Sie einen Blick darauf. 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

Da sich veth0 und veth1 im selben Netzwerksegment befinden und zum ersten Mal verbunden sind, werden ARP-Pakete angezeigt Aber veth1 hat nicht auf das ARP-Paket geantwortet.

Nach der Überprüfung liegt dies an einigen ARP-bezogenen Standardkonfigurationseinschränkungen im von mir verwendeten Ubuntu-Systemkernel. Ich muss die Konfigurationselemente ändern:

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

Nach Abschluss einfach pingen.

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

Wir sind mehr an diesem Kommunikationsprozess interessiert und können die Pakete erfassen, um einen Blick darauf zu werfen.

Für 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

Für 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

Seltsam, wir haben das ICMP-Paket echo reply nicht gesehen. Wie hat es also erfolgreich gepingt?

Tatsächlich wird hier echo reply der Localback-Port verwendet. Wenn Sie mir nicht glauben, schnappen Sie sich eine Tasche und schauen Sie nach:

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

Warum?

Wir werden es verstehen, wenn wir den gesamten Kommunikationsprozess betrachten.

  1. Zuerst erstellt das Ping-Programm ICMP echo request und sendet es über den Socket an den Protokollstapel.
  2. Da Ping den veth0-Port angibt, müssen Sie beim ersten Mal eine ARP-Anfrage senden, andernfalls übergibt der Protokollstapel das Datenpaket direkt an veth0.
  3. Da veth0 mit veth1 verbunden ist, wird die ICMP-Anfrage direkt an veth1 gesendet.
  4. Nach Erhalt der Anfrage übergibt veth1 sie an den Protokollstapel am anderen Ende.
  5. Der Protokollstapel hat festgestellt, dass es lokal eine IP-Adresse von 10.1.1.3 gibt, also hat er ein ICMP-Antwortpaket erstellt, die Routing-Tabelle überprüft und festgestellt, dass das Datenpaket an das Netzwerksegment 10.1.1.0 zurückgegeben werden sollte Gehen Sie über den Localback-Port, sodass das Antwortpaket an den lo-Port weitergeleitet wird (zuerst wird Tabelle 0 der Routing-Tabelle überprüft, ip route show table 0 zur Überprüfung).
  6. Nachdem er das Antwortpaket vom Protokollstapel erhalten hatte, tat er nichts, wechselte den Besitzer und gab es an den Protokollstapel zurück.
  7. Nach dem Empfang des Antwortpakets stellte der Protokollstapel fest, dass ein Socket auf das Paket wartete, und gab das Paket an den Socket weiter.
  8. Warten, bis das Ping-Programm im Benutzermodus feststellt, dass der Socket zurückkehrt, sodass das ICMP-Antwortpaket empfangen wird.

Der gesamte Prozess ist in der folgenden Abbildung dargestellt:

Detaillierte Erläuterung des Veth-Pairs für virtuelle Linux-Netzwerkgeräte. Dieser Artikel ist sehr informativ

03 Konnektivität zwischen zwei Namespaces

Namespace ist eine Funktion, die von der Linux-Kernelversion 2.6.x und höher unterstützt wird und hauptsächlich zur Ressourcenisolierung verwendet wird. Mit dem Namespace kann ein Linux-System mehrere Netzwerksubsysteme abstrahieren, ohne dass sich diese gegenseitig beeinflussen.

Was sollten wir tun, wenn wir zwischen Namespaces kommunizieren müssen? Die Antwort ist, veth-pair als Brücke zu verwenden.

Je nach Verbindungsmethode und -umfang kann es in „direkte Verbindung“, „Verbindung über Bridge“ und „Verbindung über OVS“ unterteilt werden.

3.1 Direkte Verbindung

Eine direkte Verbindung ist der einfachste Weg. Wie unten gezeigt, verbindet ein Veth-Paar zwei Namespaces direkt miteinander.

Detaillierte Erläuterung des Veth-Pairs für virtuelle Linux-Netzwerkgeräte. Dieser Artikel ist sehr informativ

IP für Veth-Pair konfigurieren und Konnektivität testen:

# 创建 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 Verbindung über Bridge

Linux Bridge entspricht einem Switch. kann den Datenverkehr zweier Namespaces übertragen. Mal sehen, welche Rolle veth-pair dabei spielt.

Wie unten gezeigt, verbinden zwei Veth-Paare zwei Namespaces mit der Bridge.

Detaillierte Erläuterung des Veth-Pairs für virtuelle Linux-Netzwerkgeräte. Dieser Artikel ist sehr informativ

Konfigurieren Sie auf ähnliche Weise die IP für Veth-Pair und testen Sie die Konnektivität:

# 首先创建 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 Verbindung über OVS

OVS ist eine Open-Source-Bridge eines Drittanbieters mit leistungsfähigeren Funktionen als Linux Bridge. Für das gleiche Experiment verwenden wir OVS, um den Effekt zu sehen.

Wie unten gezeigt:

Detaillierte Erläuterung des Veth-Pairs für virtuelle Linux-Netzwerkgeräte. Dieser Artikel ist sehr informativ

Testen Sie außerdem die Konnektivität zwischen den beiden Namespaces:

# 用 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

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Veth-Pairs für virtuelle Linux-Netzwerkgeräte. Dieser Artikel ist sehr informativ. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen