【NetDevOps】新一代网工需要了解的那点事儿(二)---veth-pari

2 虚拟网络设备veth-pair

  veth从名字上来看是 Virtual Ethernet 的缩写,veth是成对出现的一种虚拟网络设备。一端连接着协议栈,一端连接着彼此,数据从一端出,从另一端进,通常也称作veth-pair(如下图所示)。它的作用很简单,就是要把从一个 network namespace 发出的数据包转发到另一个 namespace中。正因为它的这个特性,常常被用来连接不同的虚拟网络组件,构建大规模的虚拟网络拓扑,比如连接Bridge、OVS、LXC、Docker容器等。很常见的案例就是它被用于Docker网络还有OpenStack Neutron,构建非常复杂的网络形态。

                                Veth Pair
               +--------------+            +--------------+
               |  Socket API  |            |  Socket API  |
               +-------+------+            +-------+------+
                       |                           |
 User Space            |                           |
+------------------------------------------------------------------+
 Kernel Space          +                           +
                 raw ethernet                 raw ethernet
                       +                           +
               +-------+-------+           +-------+-------+
               | Network Stack |           | Network Stack |
               +-------+-------+           +-------+-------+
                       |                           |
               +-------+-------+           +-------+-------+
               |      vethX    |           |     vethX     |
               +-------+-------+           +-------+-------+
                       |                           |
                       +---------------------------+

2.1 创建veth-pair

  我们通过"ip link"相关命令,创建一对虚拟网卡veth0和veth1。其中给veth0配置IP为12.1.1.1/24,veth1配置IP为12.1.1.2/24,并激活这一对虚拟网卡。"ip link"命令相关参数比较多,可以使用"ip link help"查看这里就不做过多解释。最后通过"ip link list"查看虚拟网卡相关状态,连接图及创建过程如下:

+--------------------------------------------------------------------------------------+
|             +-------------------------------------------------------------+          |
|             |                     Network Protocol Stack                  |          |
|             +------+------------------------+-----------------------+-----+          |
|                    ^                        ^                       ^                |
|                    |                        |                       |                |
+--------------------------------------------------------------------------------------+
|                    |                        |                       |                |
|                    v                        v                       v                |
|            +-------+------+           +-----+-----+           +-----+-----+          |
|            |     Eth0     |           |   Veth0   |           |   Veth1   |          |
|            +-------+------+           +-----+-----+           +------+----+          |
|                    ^                        ^                        ^               |
|      10.10.10.137  |             12.1.1.1/24|                        |12.1.1.2/24    |
|                    |                        +------------------------+               |
|                    |                                                                 |
+--------------------v-----------------------------------------------------------------+
|           Physical Network                                           By:[F0rGeEk]    |
+--------------------------------------------------------------------------------------+
  • 创建一对veth
[root@d1 ~]# ip link add veth0 type veth peer name veth1
# 查看是否创建成功
[root@d1 ~]# ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:97:0f:70 brd ff:ff:ff:ff:ff:ff
3: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 12:64:bd:95:4f:40 brd ff:ff:ff:ff:ff:ff
4: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 96:10:c9:07:77:d9 brd ff:ff:ff:ff:ff:ff
  • 为虚拟网卡配置IP
[root@d1 ~]# ip addr add 12.1.1.1/24 dev veth0
[root@d1 ~]# ip addr add 12.1.1.2/24 dev veth1
 # 查看是否配置成功
[root@d1 ~]# ip addr
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:97:0f:70 brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.137/24 brd 10.10.10.255 scope global noprefixroute dynamic ens33
       valid_lft 5444486sec preferred_lft 5444486sec
    inet6 fe80::d956:a6bf:6a6e:b6a7/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
3: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 12:64:bd:95:4f:40 brd ff:ff:ff:ff:ff:ff
    inet 12.1.1.2/24 scope global veth1
       valid_lft forever preferred_lft forever
4: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 96:10:c9:07:77:d9 brd ff:ff:ff:ff:ff:ff
    inet 12.1.1.1/24 scope global veth0
       valid_lft forever preferred_lft forever
  • 激活这一对虚拟网卡
[root@d1 ~]# ip link set veth0 up
[root@d1 ~]# ip link set veth1 up
 # 查看是否激活
[root@d1 ~]# ip link list
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
    link/ether 00:0c:29:97:0f:70 brd ff:ff:ff:ff:ff:ff
3: veth1@veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 12:64:bd:95:4f:40 brd ff:ff:ff:ff:ff:ff
4: veth0@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 96:10:c9:07:77:d9 brd ff:ff:ff:ff:ff:ff

2.2 veth-pair连通性

  接1.4.1步骤这一对虚拟网卡IP地址在同一段且均已激活,这里我们用veth0 ping veth1,查看网络是否可以连通。测试过程如下:

[root@d1 ~]# ping 12.1.1.2 -c 3 -I veth0
PING 12.1.1.2 (12.1.1.2) from 12.1.1.1 veth0: 56(84) bytes of data.

--- 12.1.1.2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 1999ms

  由上面步骤可以看出,实际上这一对虚拟网卡并不能互相通信。可是依据理论来讲,他们是可以互相通信的。这里我们通过抓包来分析一下原因,首先从veth0长pingveth1,然后分别抓veth0和veth1这两个虚拟网卡的包:

  • veth0
[root@d1 ~]# 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 12.1.1.2 tell 12.1.1.1, length 28
ARP, Request who-has 12.1.1.2 tell 12.1.1.1, length 28
ARP, Request who-has 12.1.1.2 tell 12.1.1.1, length 28
  • veth1
[root@d1 ~]# 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 12.1.1.2 tell 12.1.1.1, length 28
ARP, Request who-has 12.1.1.2 tell 12.1.1.1, length 28
ARP, Request who-has 12.1.1.2 tell 12.1.1.1, length 28

  通过以上抓包分析:veth0和veth1处于同一网段12.1.1.0/24,由于是第一次通信会通过ARP来确定MAC。可是在两个网卡的抓包情况来看,只有veth0发出的Request包并没有veth1回应的Raply包。有一定传统网络Trouble Shooting功底的您,看到这种现象肯定会想这肯定是防火墙策略阻止了吧😷您的猜测完全正确,经过查阅相关文档得知:大部分发行版Linux在默认情况下,内核中关于ARP是有一定限制的。所以为了使这一对虚拟网卡在根NS能直接互通,必须要修改默认的策略:

 # 修改IP路由默认策略及默认ARP策略
[root@d1 ~]# echo 1 > /proc/sys/net/ipv4/conf/veth1/accept_local
[root@d1 ~]# echo 1 > /proc/sys/net/ipv4/conf/veth0/accept_local
[root@d1 ~]# echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
[root@d1 ~]# echo 0 > /proc/sys/net/ipv4/conf/veth0/rp_filter
[root@d1 ~]# echo 0 > /proc/sys/net/ipv4/conf/veth1/rp_filter
 # 接下来再测试连通性
[root@d1 ~]# ping 12.1.1.2 -c 3 -I veth0
PING 12.1.1.2 (12.1.1.2) from 12.1.1.1 veth0: 56(84) bytes of data.
64 bytes from 12.1.1.2: icmp_seq=1 ttl=64 time=0.037 ms
64 bytes from 12.1.1.2: icmp_seq=2 ttl=64 time=0.051 ms
64 bytes from 12.1.1.2: icmp_seq=3 ttl=64 time=0.045 ms

--- 12.1.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2034ms
rtt min/avg/max/mdev = 0.037/0.044/0.051/0.005 ms

注:至于为什么修改上述策略才能通信,过两天还是单独写一篇文章来解释吧。

2.3 在NS中的连通性

  接下来我们将veth1关联到1.3章节中创建的NS,然后看看和veth0通信的过程。

[root@d1 ~]# ip link set veth1 netns forgeek
[root@d1 ~]# ip netns exec forgeek ifconfig veth1 12.1.1.2/24
[root@d1 ~]# ip netns exec forgeek ip link set dev veth1 up
[root@d1 ~]# ping 12.1.1.2 -c 3 -I veth0
PING 12.1.1.2 (12.1.1.2) from 12.1.1.1 veth0: 56(84) bytes of data.
64 bytes from 12.1.1.2: icmp_seq=1 ttl=64 time=0.115 ms
64 bytes from 12.1.1.2: icmp_seq=2 ttl=64 time=0.066 ms
64 bytes from 12.1.1.2: icmp_seq=3 ttl=64 time=0.072 ms

--- 12.1.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.066/0.084/0.115/0.023 ms

2.4 NS之间的连通性

  之前我们说veth-pair主要是用来解决不同NS之间通信的,那么接下来我们来创建两个NS:ns1,ns2。然后将veth0
加入到ns1中,veth1加入到ns2中,分别给veth0和veth1配置IP地址如下图所示:

+------------------------------------------------------------------+
|                                                                  |
| +-----------------+                          +-----------------+ |
| |      NS1        |                          |       NS2       | |
| |              +--+         Veth pair        +--+              | |
| |              |  +--------------------------+  |              | |
| |              +--+veth0                veth1+--+              | |
| |   Name Space    |12.1.1.1          12.1.1.2|    Name Space   | |
| +-----------------+                          +-----------------+ |
|                                                                  |
|                             Linux Server                         |
|                                                     By:[F0rGeEk] |
+------------------------------------------------------------------|

操作过程如下:

[root@d1 ~]# ip netns add ns1
[root@d1 ~]# ip netns add ns2
[root@d1 ~]# ip link set veth0 netns ns1
[root@d1 ~]# ip link set veth1 netns ns2
 # 验证网卡是否加入对应的NS中
[root@d1 ~]# ip netns exec ns1 ip link ls
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
6: veth0@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 02:77:ea:e8:3a:30 brd ff:ff:ff:ff:ff:ff link-netnsid 0
[root@d1 ~]# ip netns exec ns2 ip link ls
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
7: veth1@if8: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether ce:47:33:1f:90:fe brd ff:ff:ff:ff:ff:ff link-netnsid 0
 # 激活相应的网卡
[root@d1 ~]# ip netns exec ns1 ip link set dev veth0 up
[root@d1 ~]# ip netns exec ns2 ip link set dev veth1 up
 # 为网卡配置IP地址
[root@d1 ~]# ip netns exec ns1 ifconfig veth0 12.1.1.1/24
[root@d1 ~]# ip netns exec ns2 ifconfig veth1 12.1.1.2/24
 # 测试连通性
[root@d1 ~]# ip netns exec ns1 ping 12.1.1.2 -c 3 -I veth0
PING 12.1.1.2 (12.1.1.2) from 12.1.1.1 veth0: 56(84) bytes of data.
64 bytes from 12.1.1.2: icmp_seq=1 ttl=64 time=0.051 ms
64 bytes from 12.1.1.2: icmp_seq=2 ttl=64 time=0.057 ms
64 bytes from 12.1.1.2: icmp_seq=3 ttl=64 time=0.052 ms

--- 12.1.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.051/0.053/0.057/0.006 ms
posted @ 2020-04-01 10:27  为极客而生  阅读(321)  评论(0编辑  收藏  举报