基于LInux的Veth Peer虚拟网络设备详解

实验环境:VMware下创建的centos7.9虚拟机

Veth Peer介绍

Veth(Virtual Ethernet)Peer 是 Linux 内核中网络虚拟化的一种基础技术,它用于在两个网络命名空间之间建立通信通道。Veth 本质上是一对虚拟网络接口,它们成对出现,一个接口的发送操作会直接传递到它的对等接口,就像一根虚拟的以太网线。

Veth Peer的特点

  • 成对出现: Veth 设备总是以对的形式出现,例如 veth0 和 veth1。它们彼此互为对等接口(peer)。
  • 高效通信: 数据包在两端的接口之间直接传递,不会经过实际的网络设备,通信效率很高。
  • 网络命名空间隔离: 通常用于连接不同的 Linux 网络命名空间,将一端接口放入一个命名空间,另一端接口放入另一个命名空间。
  • 与桥接和路由配合使用: Veth 接口常与 Linux 桥接(Bridge)、路由(Routing)等技术结合,用于构建更复杂的网络拓扑,例如 Docker 容器和 Kubernetes Pod 的网络通信。

Veth Peer 的实现基于 Linux 内核中的网络设备驱动程序,工作原理主要包括以下部分:

  • 虚拟网卡的创建: 每个 Veth 设备在内核中被视为一个网络设备,其驱动程序负责处理数据包的接收与发送操作。Veth 的两个端口是对称的,一个端口的发送动作就是另一个端口的接收动作。
    设备 A 发送的帧会直接被设备 B 接收。
    在内核中,通过缓冲区(Buffer)共享数据包。
  • 数据包转发: Veth 并不涉及实际的网络硬件,所有的数据转发在内存中完成。它通过内核的 Netlink 子系统和 socket buffer(sk_buff)传递数据。
    具体流程如下:
    当应用程序通过 veth0 发出一个数据包时,内核驱动会将数据包放入 veth1 的接收队列中。
    反之亦然,从 veth1 发出的数据包会直接进入 veth0 的接收队列。
  • 与命名空间交互: Veth 接口的一大优势是支持网络命名空间。将 Veth 的一端(如 veth1)移动到一个网络命名空间后,该端口的配置、路由表和 ARP 表等都与所在命名空间的网络环境独立。

Veth Peer的优缺点

  • 优点:
    轻量化:无硬件依赖,消耗系统资源少。
    高效:传输直接在内存中完成,无需额外的协议处理。
    灵活:支持网络命名空间,可以模拟多种复杂的网络场景。
  • 缺点:
    仅限本机:Veth Peer 仅能在同一台主机上工作,不能跨主机通信。
    依赖内核:需要 Linux 内核支持,某些场景可能受到内核版本限制

基本命令

帮助文档

man ip link
man ip netns

创建veth接口

创建一对veth接口,一端命名为veth0,另一端命名为veth1

ip link add veth0 type veth peer name veth1

查看接口

查看接口的信息

[root@localhost ~]# ip link show veth0
5: veth0@veth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether e6:24:22:c8:35:14 brd ff:ff:ff:ff:ff:ff
[root@localhost ~]# ip link show veth1
4: veth1@veth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether fa:a2:c1:90:1e:e4 brd ff:ff:ff:ff:ff:ff
[root@localhost ~]#

或者在ip a中全部查看

[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:ec:a6:85 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.100/24 brd 192.168.200.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::39d3:e75e:a18b:b362/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:ec:a6:8f brd ff:ff:ff:ff:ff:ff
4: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether fa:a2:c1:90:1e:e4 brd ff:ff:ff:ff:ff:ff
5: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether e6:24:22:c8:35:14 brd ff:ff:ff:ff:ff:ff

配置veth接口

  • 启用接口;配置的接口默认是关闭的,需要手动启用
ip link set veth0 up
ip link set veth1 up
  • 设置IP地址:接口创建后需要手动设置IP地址
ip addr add 192.168.1.1/24 dev veth0
ip addr add 192.168.1.2/24 dev veth1
  • 查看接口信息已经有固定IP
[root@localhost ~]# ip a
---------------
4: veth1@veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether fa:a2:c1:90:1e:e4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.2/24 scope global veth1
       valid_lft forever preferred_lft forever
    inet6 fe80::f8a2:c1ff:fe90:1ee4/64 scope link
       valid_lft forever preferred_lft forever
5: veth0@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether e6:24:22:c8:35:14 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 scope global veth0
       valid_lft forever preferred_lft forever
    inet6 fe80::e424:22ff:fec8:3514/64 scope link
       valid_lft forever preferred_lft forever
  • 且地址可以进行通信
[root@localhost ~]# ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.047 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.062 ms
^C
--- 192.168.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.047/0.056/0.062/0.011 ms
[root@localhost ~]# ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.065 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.072 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.058 ms

跨命名空间通信

  • 创建网络命名空间
ip netns add ns1
ip netns add ns2
  • 该命名空间位于/var/run/netns/
[root@localhost ~]# ls /var/run/netns/
ns1  ns2
  • 将veth接口移动到对应的命名空间
ip link set veth0 netns ns1
ip link set veth1 netns ns2
  • 在命名空间中配置接口:注意这里需要再次启用接口,之前所配置的网络信息等都会清空
ip netns exec ns1 ip link set veth0 up
ip netns exec ns2 ip link set veth1 up
  • 设置命名空间中的IP地址
ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth0
ip netns exec ns2 ip addr add 192.168.1.2/24 dev veth1
  • 验证测试:从各自命名空间ping对端命名空间的网络设备
[root@localhost ~]# ip netns exec ns1 ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.132 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.038 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.043 ms
^C
--- 192.168.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.038/0.071/0.132/0.043 ms
[root@localhost ~]# ip netns exec ns2 ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.046 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.048 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.067 ms

删除Veth接口

  • 接口成对出现:如果删除其中一个接口会自动删除对端接口
ip link delete veth0
  • 该接口如果在命名空间中
ip netns exec ns1 ip link delete veth0

网桥(Bridge)

Linux 系统中的网桥(Bridge)是实现二层网络通信的重要工具,类似于硬件交换机的功能。它可以连接多个网络接口,使它们在同一个广播域内通信,广泛应用于虚拟化、容器和网络模拟中

网桥基本概念

  • 网桥作用:将多个网络接口桥接在一起,使它们能像处于同一个交换机下一样通信。
  • 工作层:网桥工作在 OSI 模型的第二层(数据链路层)。
  • 关键命令工具:ip 和 brctl。

创建网桥

  • 创建一个名为 br0 的网桥
ip link add name br0 type bridge
  • 启用网桥
ip link set dev br0 up

网桥添加接口

[root@localhost ~]# ip link add veth0 type veth peer name veth1
[root@localhost ~]# ip link set veth0 up
[root@localhost ~]# ip link set veth1 up
  • 将网络接口 veth0 添加到网桥 br0
ip link set dev veth0 master br0

网桥设置IP

ip addr add 192.168.1.254/24 dev br0

查看网桥信息

  • 如果网桥上没有接口,则什么也不显示
[root@localhost ~]# bridge link show
8: veth0 state UP @veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 2
  • 接口设置IP
ip addr add 192.168.1.1/24 dev veth0
ip addr add 192.168.1.2/24 dev veth1

此时可查看到网桥,以及对应的接口的IP信息

[root@localhost ~]# ip a
------
6: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether f2:00:e8:d0:9f:e0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.254/24 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::e0dc:6cff:febb:3090/64 scope link
       valid_lft forever preferred_lft forever
7: veth1@veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 0a:5d:06:8d:60:09 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.2/24 scope global veth1
       valid_lft forever preferred_lft forever
    inet6 fe80::85d:6ff:fe8d:6009/64 scope link
       valid_lft forever preferred_lft forever
8: veth0@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br0 state UP group default qlen 1000
    link/ether f2:00:e8:d0:9f:e0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 scope global veth0
       valid_lft forever preferred_lft forever
    inet6 fe80::f000:e8ff:fed0:9fe0/64 scope link
       valid_lft forever preferred_lft forever
  • 测试访问
[root@localhost ~]# ping 192.168.1.254
PING 192.168.1.254 (192.168.1.254) 56(84) bytes of data.
64 bytes from 192.168.1.254: icmp_seq=1 ttl=64 time=0.031 ms
64 bytes from 192.168.1.254: icmp_seq=2 ttl=64 time=0.065 ms
^C
--- 192.168.1.254 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.031/0.048/0.065/0.017 ms
[root@localhost ~]# ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.054 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.104 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.101 ms
^C
--- 192.168.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1999ms
rtt min/avg/max/mdev = 0.054/0.086/0.104/0.024 ms
[root@localhost ~]# ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.059 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.038 ms
64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.085 ms
^C

此时如果有其他的设备将网络接口(veth2)放入网桥中,则veth1可以访问到该设备(veth3),网络走向如下:

  • veth1—>veth0—>网桥br0---->veth2—>veth3

网桥移除接口

  • 从网桥中移除网络接口
ip link set dev eth0 nomaster

删除网桥

ip link delete dev br0
posted @ 2021-06-27 23:50  huhy  阅读(104)  评论(0)    收藏  举报  来源
--> --> /*文章评论*/