Linux veth pair

veth 是虚拟以太网卡 ( Virtual Ethemet )的缩写。

veth 设备总是成对的,因此我们称之为 veth pair。 veth pair 常被用于 跨 network namespace 之间的通信,即分别将 veth pair 的两端放在不同的 namespace 里

仅有veth pair设备,容器是无法访问外部网络的。

从容器发出的数据包,实际上是直接进了 veth pair 设备的协议栈。

如果容器需要访问网络,则需要使用网桥等技术将 veth pair 设备接收的数据包转发出去。

sudo ip link add veth0 type veth peer name veth1

创建的 veth pair 在主机上表现为2块网卡,默认会创建在当前进程的命名空间内

这里的MTU默认是 1500,

可以看到默认的初始状态是 down,我们需要 设置它为 up 

lizhe@ubuntu:~$ sudo ip link set dev veth0 up
lizhe@ubuntu:~$ sudo ip link set dev veth1 up

配置ip

sudo ifconfig veth0 10.10.10.1/24

sudo ifconfig veth1 10.10.10.2/24 

如何查看某个 veth pair 两端的设备

veth0 10.10.10.1

veth1 10.10.10.2

这里他们都在一个网段上,如果你使用 ping 命令直接 ping 它们都可以ping通

但是 ping -I veth0 10.10.10.2 使用 veth0 ping veth1 是 ping不通的

我们尝试使用 tcpdump 来看看发生了什么

可以看到 veth1 没有相应 ARP 包,所以没有ping通

下面是cloud_dev上的解释

使用 root 用户修改内核中关于 ARP 的配置

# Linux IP 路由实现中有个限制,即任何从非 loopback 网卡进来的任何数据包的源地址不能是本机地址。因此要先取消该限制

echo 1 > /proc/sys/net/ipv4/conf/veth1/accept_local

echo 1 > /proc/sys/net/ipv4/conf/veth0/accept_local

# 假设一台主机从接口 A 收到一个包,其源地址为 <srcip> ,
# 若启用反向路径过滤功能,会以 <srcip> 作为目标 IP 去查找路由表,
# 如果得到的输出接口不为 A ,则认为反向路径过滤检查失败,内核就会丢弃该包。

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

再试一次

可以看到 ARP 通过了,我们的 IP 10.10.10.2 成功转换成了 52:e8:fe:e7:8b:05 ,但是仍然不通,

只有 ICMP echo request , 没有 reply , 根据上面的解释,reply应该通过 localback 接口返回

监听一下 localback 接口得到

可以看到确实有 ICMP 的 reply 从 veth1 返回给 veth0 , 但是为什么还是没 ping 通呢

字段说明
Destination目标网络或目标主机。Destination 为 default(0.0.0.0)时,表示这个是默认网关,所有数据都发到这个网关。
Gateway网关地址,0.0.0.0 表示当前记录对应的 Destination 跟本机在同一个网段,通信时不需要经过网关。如果没有就显示星号(*)。
GenmaskDestination 字段的网络掩码,Destination 是主机时需要设为 255.255.255.255,是默认路由时会设置为 0.0.0.0
Flags标记
● U 该路由可以使用。 
● H 该路由是到一个主机,也就是说,目的地址是一个完整的主机地址。如果没有设置该标志,说明该路由是到一个网络,而目的地址是一个网络地址:一个网络号,或者网络号与子网号的组合。 
● G 该路由是到一个网关(路由器)。如果没有设置该标志,说明目的地 是直接相连的。 
● R 恢复动态路由产生的表项。 
● D 该路由是由改变路由(redirect)报文创建的。 
● M 该路由已被改变路由报文修改。 
● ! 这个路由将不会被接受。
Metric路由距离,到达指定网络所需的中转数,是大型局域网和广域网设置所必需的。
Ref路由项引用次数 。
Use此路由项被路由软件查找的次数。
Iface网卡名字,例如 eth0。
Send a Message