Veth Pair

Veth pair介绍

Veth是虚拟以太网(Virtual Ethernet)的缩写。

Veth pair一端发送的数据会在另一端接受。根据这一特性,veth pair常被用于跨network namespace之间的通信,即分别将veth pair的两端放在不同的namespace中。

Veth pair配置命令

1
2
3
4
5
6
7
8
9
10
11
# 创建一对虚拟以太网卡
ip link add veth0 type veth peer name veth1

# 将veth pair的一端设置为up状态
ip link set dev veth0 up

# 为veth pair的一端绑定ip,并设置成up状态
ifconfig veth0 10.1.1.2/24 up

# 将veth pair的一端放到namespace中(重置状态)
ip link set veth1 netns newns

查询容器与主机的veth pair

1
2
3
4
5
6
7
8
9
10
11
12
13
# 查看iflink和ifindex文件对
cat /sys/class/net/eth0/iflink
cat /sys/class/net/veth8080528/ifindex

# 使用ip link查询
ip link show eth0
ip link show | grep if3

# 通过ethtool -S查询
ethtool -S eth0
ip addr

# 注:第一条命令运行在容器环境,第二条运行在主机环境

Linux bridge ≈ 虚拟的网络交换机:除了跨机连接网络设备,任意的真实物理设备(如eth0)和虚拟设备(如veth pair和tap设备)都能连接到Linux bridge上。

  • Linux网桥:多个端口,数据可以从如何端口进来,再通过MAC地址决定出口
  • Linux其它网络设备:只有两端,从一端进来的数据会从另一端出去(外网 -> 物理网卡 -> 内核协议栈)

Linux bridge配置命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 新建网桥
ip link add name br0 type bridge
# or
brctl addbr br0

# 将网桥设置为up状态
ip link set br0 up

# 将veth0连接到br0上
ip link set dev veth0 master br0
# or
brctl addif br0 veth0

# 查看当前网桥上的网络设备
bridge link
# or
brctl show

Br0和veth0相连后:

Br0和veth0之间为双向的通道

协议栈和veth0之间变成了单通道,协议栈能发送数据给veth0,但veth0从外面收到的数据不会转发给协议栈

Br0的MAC地址变成了veth0的MAC地址

在veth0连接到网桥后,veth0的IP将变得没有意义(单向通道)。因此,需要将veth0的IP地址赋给Linux Bridge,之后将veth0视为一根网线。

1
2
3
4
# 删除veth0的IP
ip addr del 1.2.3.101/24 dev veth0
# 将veth0的IP配置给br0
ip addr add 1.2.3.101/24 dev br0

其他命令

1
2
3
4
5
6
7
8
9
10
11
# 将物理网卡添加到Linux bridge
ip addr set dev eth0 master br0

# 查看ip地址
ip add

# 查看路由表
route -v

# 添加默认网关
ip route add default via 192.168.0.1

注:以上实验需要打开veth0网卡的混杂模式。

混杂模式(Promiscuous mode):一个网卡会把它接收的所有网络流量都交给CPU,而不是只把它向转交的部分给CPU。

在非混杂模式下,网卡只会接收目的MAC地址是它自己的单播帧,以及多播帧和广播帧。

在混杂模式下,网卡会接收经过它的所有帧。

混杂模式命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 启动网卡的混杂模式
ifconfig eth0 promisc

# 退出网卡的混杂模式
ifconfig eth0 -promisc

# 查看网卡是否开启了混杂模式
ifconfig
# or
netstat -i

# 网络设备加入网桥后,会自动进入混杂模式,且无法退出
brctl addif br0 veth0

# 网络设备离开Linux bridge,会自动退出混杂模式
brctl delif br0 veth0

# 查看是否进入混杂模式
dmesg | grep promiscuous

附代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
[root@488dacbfe771 /]# ip netns add newns
[root@488dacbfe771 /]# ip netns exec newns ip link set dev lo up
[root@488dacbfe771 /]# ip link add veth0 type veth peer name veth1
[root@488dacbfe771 /]# ip link set veth1 netns newns
[root@488dacbfe771 /]# ip netns exec newns ifconfig veth1 10.1.1.1/24 up
[root@488dacbfe771 /]# ifconfig veth0 10.1.1.2/24 up
[root@488dacbfe771 /]# ping -c 1 -I veth0 10.1.1.1
PING 10.1.1.1 (10.1.1.1) from 10.1.1.2 veth0: 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=0.035 ms

--- 10.1.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.035/0.035/0.035/0.000 ms
[root@488dacbfe771 /]#
[root@488dacbfe771 /]# ip link add name br0 type bridge
[root@488dacbfe771 /]# ip link set br0 up
[root@488dacbfe771 /]# ip link set dev veth0 master br0
[root@488dacbfe771 /]#
[root@488dacbfe771 /]# ping -c 1 -I veth0 10.1.1.1
PING 10.1.1.1 (10.1.1.1) from 10.1.1.2 veth0: 56(84) bytes of data.
^C
--- 10.1.1.1 ping statistics ---
1 packets transmitted, 0 received, 100% packet loss, time 0ms

[root@488dacbfe771 /]# ip addr del 10.1.1.2/24 dev veth0
[root@488dacbfe771 /]# ip addr add 10.1.1.2/24 dev br0
[root@488dacbfe771 /]# ping -c 1 -I br0 10.1.1.1
PING 10.1.1.1 (10.1.1.1) from 10.1.1.2 br0: 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=0.040 ms

--- 10.1.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
[root@488dacbfe771 /]#
[root@488dacbfe771 /]# ip link set dev eth0 master br0
[root@488dacbfe771 /]# ifconfig eth0 promisc
[root@488dacbfe771 /]# ping -c 1 -I br0 1.2.3.102
PING 1.2.3.102 (1.2.3.102) from 1.2.3.101 br0: 56(84) bytes of data.
64 bytes from 1.2.3.102: icmp_seq=1 ttl=64 time=0.024 ms

--- 1.2.3.102 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.024/0.024/0.024/0.000 ms
[root@488dacbfe771 /]#

参考

《Kubernetes网络权威指南》