之前学习研究了下 linux 内核中的网络设备,工作之余总结了几篇关于网络设备的使用和内核中网络数据包的走向。今天来一起讨论下 vEth设备以及 vEth 设备和 linux network namespace 在 docker、虚拟化中的基本应用。本文主要讲的是 vEth 设备的基本走向,以及跨 network namespace 的使用。vEth 与 bridge(网桥)、network namespace 的使用将在今后的文章中继续讨论。文中有理解有误的地方,还望各位读者积极指出。
一.Linux 内核中的 vEth 设备
1. vEth 设备的特点
- 1.1 vEth 设备和其它的网络设备一样,一端连接的是内核协议栈,即从协议栈读取数据,
在 netdevice 子系统进行接口数据处理,然后通过 vEth 的驱动发送出去。 - 1.2 vEth 设备是在 linux 内核中是成对出现,两个设备彼此相连。
- 1.3 一个设备从协议栈读取数据后,会将数据发送到另一个设备上去。
- 1.4 我将给 vEth0 配置 1.1.1.1/24,给 vEth1 配置 1.1.1.2/24 的地址,如图 1-1-1 说明了
vEth 设备的特点:
图 1-1-1
二.实验验证(环境:Centos7,3.10 内核)
1. 只给 vEth0 配置 ip,vEth1 不配置 ip 实验(这里不给 vEth1 设备配置 IP 的原因 就是想看看在 vEth1 没有 IP 的情况下,vEth0 收到协议栈的数据后会不会转发给 vEth1)
- 1.1 如图 2-1-1,添加 veth 设备对:
图 2-1-1
- 1.2 如图 2-1-2,查看 vEth0 和 vEth1 设备的状态:
图 2-1-2
- 1.3 如图 2-1-3,给 vEth0 配置 ip:
图 2-1-3
- 1.4 如图 2-1-4,up vEth0 和 vEth1,查看设备信息,两接口已经 up:
图 2-1-4
- 1.5 ping 3 个包发送给 1.1.1.2,由于 vEth1 还没配置 IP,所以肯定不通:
- 1.5.1 发送的 3 个 icmp 报文,显示目标不可达,从经验上来讲应该是 arp 请求收到 arp 应答,如图 2-1-5:
图 2-1-5
-
- 1.5.2 在 vEth0 上抓包,如图 2-1-6:
图 2-1-6
-
- 1.5.3 在 vEth1 上抓包,如图 2-1-7:
图 2-1-7
-
- 1.5.4 在 vEth0 上抓包,如图 2-1-8:
图 2-1-8
-
- 1.5.5 在 vEth1 上抓包,如图 2-1-9:
-
图 2-1-9
- 1.5.6 结论:vEth1 没有配置 ip,但是收到了从 vEth0 上发出的 arp 请求报文,但是
由于没有配置 ip,协议栈没有这个 ip 信息,所以丢弃 arp 请求报文,没有发送 arp 响应 报文。
- 1.5.6 结论:vEth1 没有配置 ip,但是收到了从 vEth0 上发出的 arp 请求报文,但是
2.给 vEth0 和 vEth1 都配置 ip 进行实验
- 2.1 如图 2-1-1,给 vEth1 配置 ip:
图 2-1-1
- 2.2 重复 1.5.1-1.5.3 的步骤,会出现如图 2-2-1、2-2-2 的情况:
- 2.2.1 在 vEth0 上抓包,如图 2-2-1:
图 2-2-1
-
- 2.2.2 在 vEth1 上抓包,如图 2-2-2:
图 2-2-2
-
- 2.2.3 同 1.5.6,是 vEth0 接口没有收到 arp 应答(主要是因为内核中的一些ARP 相关配置导致 vEth1 不返回 ARP 应答包),如图 2-2-3:
图 2-2-3
-
- 2.2.4 我们编写一个简单脚本设置 arp 相关的内核参数,如图 2-2-4:
图 2-2-4
-
- 2.2.5 再次从 vEth0 ping 3 个包到 vEth1,如图 2-2-5。抓包结果如图 2-2-6、2-2-7 和 2-2-8:
图 2-2-5
图 2-2-6
图 2-2-7
图 2-2-8
-
- 2.2.6 现象分析:从 vEth0 口发出了 arp 请求,从 vEth1 口发出了 arp 响应,然后从vEth0 口发出了 3 个 icmp 请求报文,vEth1 口收到 icmp 请求报文后,封装好 icmp 响应 报文,在做路由的时候,发现 1.1.1.1 是本地接口地址,所以发给了 lo 接口(所以图 2- 2-7 中的 arp 请求只有对 1.1.1.2 的请求,而没有对 1.1.1.1 的请求)。
三.不同 vEth 设备在不同 network namespace 间的数据收发
1. namespace 的特点
- 1.1 network namespace 是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自的网络栈信息。不管是 vm 还是 docker,运行的时候仿佛自己就在独立的网络中。 这篇文章介绍 networknamespace 的基本概念和用法,networknamespace 是 linux 内核提 供的功能。
- 1.2 每个 network namespace 都有一个 lo 接口。
2. network namespace 之间通信实验
- 2.1 有了不同 networknamespace 之后,也就有了网络的隔离,但是如果它们之间没有
办法通信,也没有实际用处。要把两个网络连接起来,linux 提供了 veth 设备对, 可以把 veth 设备对当做是双向的 pipe(管道),从一个方向发送的网络数据,可以直接被另外一端接收到;或者也可以想象成两个 namespace 直接通过一个特殊的虚拟网卡连接起来,可以直接通信。 - 2.2 使用上面提到的方法,我们再创建另外一个 networknamespace,这里我们使用 net0
和 net1 两个名字。 - 2.3 我们将按照图 3-2-1 中的网络拓扑进行实验:
图 3-2-1
- 2.3.1 如图 3-2-2 添加 veth0 和 veth1 设备对:
图 3-2-2
- 2.3.2 如图 3-2-3 创建 net0 和 net1 两个 network namespace:
图 3-2-3
- 2.3.3 如图 3-2-4 把 veth0 加入到 net0,把 veth1 加入到 net1,如图 3-2-3:
图 3-2-4
- 2.3.4 如图 3-2-5 我们给这对 veth pair 配置上 ip 地址,并启用它们以及 lo 接口:
图 3-2-5
- 2.3.5 可以看到,最每个 namespace 中,在配置了 ip 之后,还自动生成了对应的
路由表信息,网络 10.0.1.0/24 数据报文都会通过 vethpair 进行传输。使用 ping 命令 可以验证它们的连通性,并在 veth0 和 veth1 上抓包,如图 3-2-6、3-2-7、3-2-8:
图 3-2-6
图 3-2-7
图 3-2-8
- 2.4 如 2.3 实验,namespace net0 中的 veth0 和 namespace net1 中的 veth1 收发数据成功
- 2.5 小结:在不同的 namespace 之间进行通信可以使用 veth 设备对来进行数据的转发。
四. 下次分享预告
1. Bridge 设备介绍。
2. 使用 bridge 设备连接不同的 namespace 进行数据转发。
3. OVS、OVS 代替 bridge 设备进行不同 namespace 之间数据转发简介。