![Kubernetes网络权威指南:基础、原理与实践](https://wfqqreader-1252317822.image.myqcloud.com/cover/281/27741281/b_27741281.jpg)
1.2 千呼万唤始出来:veth pair
介绍namespace时,我们多次提到veth pair。本节将详细介绍这对“孪生兄弟”。
部署过Docker或Kubernetes的读者肯定有这样的经历:在主机上输入ifconfig或ip addr命令查询网卡信息的时候,总会出来一大堆vethxxxx之类的网卡名,这些是Docker/Kubernetes为容器而创建的虚拟网卡。
veth是虚拟以太网卡(Virtual Ethernet)的缩写。veth设备总是成对的,因此我们称之为veth pair。veth pair一端发送的数据会在另外一端接收,非常像Linux的双向管道。根据这一特性,veth pair常被用于跨network namespace之间的通信,即分别将veth pair的两端放在不同的namespace里,如图1-2所示。
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_29.jpg?sign=1739298854-EgxnS4kXWdgv9jsiaCk9c8lDNjwSjxip-0-a4e72f7962cd37be1a502654fe0cfabb)
图1-2 veth pair示意图
前文已经提到,仅有veth pair设备,容器是无法访问外部网络的。为什么呢?因为从容器发出的数据包,实际上是直接进了veth pair设备的协议栈。如果容器需要访问网络,则需要使用网桥等技术将veth pair设备接收的数据包通过某种方式转发出去。
注:虽然我们在容器化的场景里经常看到veth网卡,但veth pair在传统的虚拟化技术(比如KVM等)中的应用也非常广泛。
下面,我们将演示veth pair的创建和使用:
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_30.jpg?sign=1739298854-kgnKDldvQNyYmErrY4j24inmsbdqwolY-0-6decaabebdc662bbb00a0a079461d91d)
创建的veth pair在主机上表现为两块网卡,我们可以通过ip link命令查看:
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_31.jpg?sign=1739298854-nssekQ8ra5Iv88yS4YrEHDBvjtVl7rni-0-6f0a345720a57d4a3501b568b3cc810f)
如上所示,新创建的veth pair设备的默认mtu是1500,设备初始状态是DOWN。我们同样可以使用ip link命令将这两块网卡的状态设置为UP。
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_32.jpg?sign=1739298854-qlvsfUR2y9gtIE0u31sFmYmn6Fd3cAhh-0-a53602d822f7ccc97a6ce3d717ad10ba)
veth pair设备同样可以配置IP地址,命令如下:
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_33.jpg?sign=1739298854-WfgUUlVB8qyW0eNyQEYHXXRYsAGYSzO9-0-968f4bc23c97f3aac3f31b4bc440a580)
可以将veth pair设备放到namespace中。让我们来温习命令的使用:
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_34.jpg?sign=1739298854-ECCbcYG99Zk7e9Phi4V13K8tLMxwjyhr-0-808f1b21046ccd8974ea5e95144136aa)
veth pair设备的原理较简单,就是向veth pair设备的一端输入数据,数据通过内核协议栈后从veth pair的另一端出来。veth pair的基本工作原理如图1-3所示。
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_35.jpg?sign=1739298854-M9bfDM6teRY0qCaatuodYAHrP08ofVy8-0-fc96f50b523c2bf2fc6e29f533ff501d)
图1-3 veth pair的基本工作原理图
1.2.1 veth pair内核实现
veth pair内核实现的源代码如下:
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_37.jpg?sign=1739298854-YY2gzgZjAXefwHj87TFSripnOR1XE5BD-0-dac29239b6e99d6f5b4815590a46bdd1)
上述代码块想表达的意思是:在veth pair设备上,任意一端(RX)接收的数据都会在另一端(TX)发送出去,veth pair在转发过程中不会篡改数据包的内容。
1.2.2 容器与host veth pair的关系
我们要学习的经典容器组网模型就是veth pair+bridge的模式。容器中的eth0实际上和外面host上的某个veth是成对的(pair)关系,那么,有没有办法知道host上的vethxxx和哪个container eth0是成对的关系呢?
方法1
首先,在目标容器里查看:
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_38.jpg?sign=1739298854-pqc3GA6Rss8YctDB5e7Z85WbMADJI8w7-0-88988fc97fba1580d42453243912202b)
然后,在主机上遍历/sys/claas/net下面的全部目录,查看子目录ifindex的值和容器里查出来的iflink值相当的veth名字,这样就找到了容器和主机的veth pair关系。例如,下面的例子中主机上veth63a89a3的ifindex刚好是5,意味着是目标容器veth pair的另一端。
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_39.jpg?sign=1739298854-WJZpnVKSEwOXRfmL2pKBn3mVx19rZZDm-0-1f7f2932a8a8c52f50b75f8c07611b34)
方法2
在目标容器里执行以下命令:
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_40.jpg?sign=1739298854-QiPT6TUZqrWO1135iqD1un1HJ1YWOwd9-0-0b8472fa700e458ae5698b0148d5f411)
从上面的命令输出可以看到116:eth0@if117,其中116是eth0接口的index,117是和它成对的veth的index。
当host执行下面的命令时,可以看到对应117的veth网卡是哪一个,这样就得到了容器和veth pair的关系。
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_41.jpg?sign=1739298854-9pW1cIx6dkGA08QZCF0QyudHhYa9zSnK-0-74d3471db9d9fafb40ea279cf7e3dd6e)
方法3
可以通过ethtool-S命令列出veth pair对端的网卡index,例如:
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_42.jpg?sign=1739298854-YzIroGrogpRQCD0wf7y9UrhXwAw3oj5O-0-a613f8353bd73c292f7eece037e69ee1)
而主机上index为6的网卡为:
![](https://epubservercos.yuewen.com/D7598A/15937388804515906/epubprivate/OEBPS/Images/txt001_43.jpg?sign=1739298854-ZUGHjsTA3GT5d8KQetDZRwqUNczLgg5b-0-48c76e828f08fcdbe8034cacdc43fd3a)
1.2.3 小结
更多关于容器的介绍请参考后面的章节,这里仅仅是抛砖引玉,让读者对容器与veth pair的关系有个大概的了解。
那么,veth pair的实际用途是什么?1.3节将介绍Linux bridge,当Linux bridge和veth设备相结合时,就能组建一个最简单的容器网络。