Linux Veth Pair 介绍

发布时间: 更新时间: 总字数:1422 阅读时间:3m 作者: IP上海 分享 网址

VETH (virtual Ethernet) 设备是本地虚拟以太网隧道,成对出现。veth-pair 就是一对的虚拟设备接口,和 tap/tun 设备不同的是,它都是成对出现的。功能类似于网线。本文结合bridgeOpenvSwitchnetns说明 veth pair 的作用。

介绍

veth-pair 一端连着协议栈,一端彼此相连着,如下图:

正因为有这个特性,它常常充当着一个桥梁,连接着各种虚拟网络设备,典型的例子像:

使用veth-pair也可以构建出复杂的虚拟网络结构,比如 OpenStack Neutron。一个设备(Linux Device)只能位于一个namespace中,不同namespace中的设备可以利用veth pair进行桥接。

bridge 示例

创建一个veth-pair,并与两个 netns 互联

# 1. 创建 veth-pair
$ ip link add veth1 type veth peer name veth2
$ ip link
21: veth2@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether c2:43:ac:c0:53:10 brd ff:ff:ff:ff:ff:ff
22: veth1@veth2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether 26:91:22:3c:63:29 brd ff:ff:ff:ff:ff:ff

# 2. 创建 netns
$ ip netns add ns1
$ ip netns add ns2

# 3. 把两个tap设备分别分配到 netns 中
$ ip link set veth1 netns ns1
$ ip link set veth2 netns ns2

# 4. 为 netns 中的tap设备分配 ip 地址,并启用 tap 设备
$ ip netns exec ns1 ip addr add local 172.20.1.1/24 dev veth1
$ ip netns exec ns2 ip addr add local 172.20.1.2/24 dev veth2
$ ip netns exec ns1 ip link set veth1 up
$ ip netns exec ns2 ip link set veth2 up

# 5. 连通性验证
$ ip netns exec ns1 ping -c 1 172.20.1.2
PING 172.20.1.2 (172.20.1.2) 56(84) bytes of data.
64 bytes from 172.20.1.2: icmp_seq=1 ttl=64 time=0.064 ms

--- 172.20.1.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.064/0.064/0.064/0.000 ms

OpenvSwitch 示例

OVSLinux Bridge 功能更强大,针对上述示例,采用 OVS 配置如下:

# 1. 创建 br0
$ ovs-vsctl show
2e6ffc1e-472a-48f5-9d19-84e4bf0bb7a5
    ovs_version: "2.11.7"
$ ovs-vsctl add-br br0
$ ovs-vsctl show
2e6ffc1e-472a-48f5-9d19-84e4bf0bb7a5
    Bridge "br0"
        Port "br0"
            Interface "br0"
                type: internal
    ovs_version: "2.11.7"

# 2. 创建两组 veth-pair
$ ip link add nveth1 type veth peer name oveth1
$ ip link add nveth2 type veth peer name oveth2
$ ip link set nveth1 up
$ ip link set oveth1 up
$ ip link set nveth2 up
$ ip link

# 3. 创建两个 netns
$ ip netns add ns1
$ ip netns add ns2
$ ip netns ls
ns2
ns1

# 4. 连接
$ ip link set nveth1 netns ns1
$ ovs-vsctl add-port br0 oveth1
$ ip link set nveth2 netns ns2
$ ovs-vsctl add-port br0 oveth2

# 5. 为 netns 中的 veth 配置 ip 地址
$ ip netns exec ns1 ip addr add 172.20.0.1/24 dev nveth1
$ ip netns exec ns2 ip addr add 172.20.0.2/24 dev nveth2

# 6. 配置查看
$ ovs-vsctl show
2e6ffc1e-472a-48f5-9d19-84e4bf0bb7a5
    Bridge "br0"
        Port "oveth1"
            Interface "oveth1"
        Port "br0"
            Interface "br0"
                type: internal
        Port "oveth2"
            Interface "oveth2"
    ovs_version: "2.11.7"
$ ip netns exec ns1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
7: nveth1@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 66:6d:72:6b:e1:71 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.20.0.1/24 scope global nveth1
       valid_lft forever preferred_lft forever
    inet6 fe80::646d:72ff:fe6b:e171/64 scope link
       valid_lft forever preferred_lft forever
$ ip netns exec ns2 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
9: nveth2@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether de:f5:0d:10:1f:27 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.20.0.2/24 scope global nveth2
       valid_lft forever preferred_lft forever
    inet6 fe80::dcf5:dff:fe10:1f27/64 scope link
       valid_lft forever preferred_lft forever

$ 7. ping验证
$ ip netns exec ns1 ping -c 1 172.20.0.2
PING 172.20.0.2 (172.20.0.2) 56(84) bytes of data.
64 bytes from 172.20.0.2: icmp_seq=1 ttl=64 time=0.046 ms

--- 172.20.0.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.046/0.046/0.046/0.000 ms

# 8. 抓包
$ ip netns exec ns1 tcpdump -i nveth1 -vv -nnt
tcpdump: listening on nveth1, link-type EN10MB (Ethernet), capture size 262144 bytes
IP (tos 0x0, ttl 64, id 8833, offset 0, flags [DF], proto ICMP (1), length 84)
    172.20.0.1 > 172.20.0.2: ICMP echo request, id 2095, seq 318, length 64
IP (tos 0x0, ttl 64, id 51286, offset 0, flags [none], proto ICMP (1), length 84)
    172.20.0.2 > 172.20.0.1: ICMP echo reply, id 2095, seq 318, length 64
$ tcpdump -i oveth1 -vv -nnt
tcpdump: listening on oveth1, link-type EN10MB (Ethernet), capture size 262144 bytes
IP (tos 0x0, ttl 64, id 24617, offset 0, flags [DF], proto ICMP (1), length 84)
    172.20.0.1 > 172.20.0.2: ICMP echo request, id 2095, seq 92, length 64
IP (tos 0x0, ttl 64, id 8326, offset 0, flags [none], proto ICMP (1), length 84)
    172.20.0.2 > 172.20.0.1: ICMP echo reply, id 2095, seq 92, length 64
$ tcpdump -i oveth2 -vv -nnt
tcpdump: listening on oveth2, link-type EN10MB (Ethernet), capture size 262144 bytes
IP (tos 0x0, ttl 64, id 33852, offset 0, flags [DF], proto ICMP (1), length 84)
    172.20.0.1 > 172.20.0.2: ICMP echo request, id 2095, seq 109, length 64
IP (tos 0x0, ttl 64, id 16049, offset 0, flags [none], proto ICMP (1), length 84)
    172.20.0.2 > 172.20.0.1: ICMP echo reply, id 2095, seq 109, length 64
$ ip netns exec ns2 tcpdump -i nveth2 -vv -nnt
tcpdump: listening on nveth2, link-type EN10MB (Ethernet), capture size 262144 bytes
IP (tos 0x0, ttl 64, id 12050, offset 0, flags [DF], proto ICMP (1), length 84)
    172.20.0.1 > 172.20.0.2: ICMP echo request, id 2095, seq 190, length 64
IP (tos 0x0, ttl 64, id 54949, offset 0, flags [none], proto ICMP (1), length 84)
    172.20.0.2 > 172.20.0.1: ICMP echo reply, id 2095, seq 190, length 64

容器和宿主机 veth pair 对应关系

  • 容器
[root@2105d89721a8 /]# ip link show eth0
23: eth0@if24: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0

23: eth0@if24: 23 为该 veth-pair peerindex24为该 veth-pairindex

  • 宿主机
$ ip link show
24: veth05ae645@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
    link/ether 76:7a:e0:31:a9:56 brd ff:ff:ff:ff:ff:ff link-netnsid 4

可以看到宿主机上 24: veth05ae645@if2323/24 的释义和容器内正好相反

  • 容器
[root@2105d89721a8 /]# cat /sys/class/net/eth0/iflink
24
  • 宿主机
$ cat /sys/class/net/veth05ae645/iflink
23

ethtool

  • 宿主机
$ ip link show
24: veth05ae645@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
    link/ether 76:7a:e0:31:a9:56 brd ff:ff:ff:ff:ff:ff link-netnsid 4
  • 容器
$ ethtool -S veth05ae645
NIC statistics:
peer_ifindex: 23
Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数