已发表的技术专栏(订阅即可观看所有专栏)
0 grpc-go、protobuf、multus-cni 技术专栏 总入口
1 grpc-go 源码剖析与实战 文章目录
2 Protobuf介绍与实战 图文专栏 文章目录
3 multus-cni 文章目录(k8s多网络实现方案)
4 grpc、oauth2、openssl、双向认证、单向认证等专栏文章目录
1、tun、tap设备是什么 |
TUN与TAP是操作系统内核中的虚拟网络设备。
不同于硬件设备这些虚拟的网络设备全部用软件实现,但提供了与硬件设备完全相同的功能。
2、tun设备跟tap设备的区别? |
- TUN 设备
- 字符描述文件/dev/net/tun,收发的是 IP 层数据包,只能工作在 IP 层;
- 点对点的三层设备;
- 无法与物理网卡做 bridge,但是可以通过三层交换(如 ip_forward)与物理网卡连通。
- TAP 设备
- /dev/tapX 文件收发的是 MAC 层数据包(以太网帧);
- 拥有 MAC 层功能,可以与物理网卡做 bridge;
- 支持 MAC 层广播。
换一种形式:
对比项 | tun设备 | tap设备 |
---|---|---|
协议栈层次 | 三层设备 | 二层设备 |
处理数据包类型 | IP数据包 | 以太网数据包 |
是否有MAC地址 | 没有 | 有 |
是否是虚拟网卡 | 是 | 是 |
tap比tun更接近于物理网卡
3、tun、tap设备跟物理网卡设备的区别? |
3.1、区别? |
- tun、tap设备
- 纯软件实现的
- 一端链接网络协议栈,一端通过字符文件/dev/net/tun链接应用程序
- 物理网卡
- 一端链接网络协议栈,一端链接物理网线
- 非软件实现
3.2、注意点 |
tun设备和物理网卡eth0分别代表不同的网络,分别属于不同的网络段里。
比方说,
- tun设备所属的网络为10.244.1.0/24
- 物理网卡eth0所属的网络为10.211.55.0/24
要求是,业务应用希望通过tun所在的网络,跟其他宿主机上的tun所属于的网络进行数据的通信;
不同宿主机上tun设备所在的网络,默认情况下,是不能直接通信的,
因此,我们要解决的是如何让不同宿主机上tun设备所在的网络能够通信?
4、tun设备的使用场景 |
TUN设备最常用的场景是VPN,包括tunnel以及应用层的IPSec
比方说,flannel网络中的UDP模式
5、tun设备、tap设备收发数据包的方式 |
5.1、物理网卡收发数据包的方式 |
先看一下,物理网卡收发数据包的方式
用户空间中的应用程序如何跟外部网络进行通信呢?
直接通过物理网卡eth0进行的通信,通过eth0网卡将物理线路wire跟内核空间中的网络协议栈进行链接在一起。
通过eth0网卡,进行数据包的收发。
也没有转发到其他设备。
好,我们看下虚拟网络设备tun、tap是如何收发数据包的?
5.2、虚拟网络设备tun、tap是如何收发数据包的? |
5.2.1、业务应用程序APP接收tun设备发送数据包方式? |
从上面的图,可以看出来:
虚拟网络设备tun跟物理网卡有一个很大的区别,tun设备的一端并没有链接物理网线,而是链接了一个文件描述符/dev/net/tun;
/dev/net/tun就是一个文件,如下图所示:(centos7.5上)
假设我们以flannel为例
- 用户空间的flannel服务向文件描述符/dev/net/tun发送数据;
- 注意,给/dev/net/tun发送数据时,必须遵循一定的格式,
- 比方说,发送一个icmp数据包(ping xx.xx.xx.xx),必须添加上IP报文头
- 因为,tun设备,只能处理IP层的数据包
- 可以认为,只要/dev/net/tun文件收到数据后,就会自动的转发给tun设备,即转发了给虚拟网卡flannel0设备;(背后的原理,不再深究,这相当于基础条件,类似于1+1必须等于2)
- 当虚拟网络设备flannel0收到数据包后,可能会经过路由表,IP防火墙规则,网络协议栈等,最终发送给了用户空间的业务应用
- 注意一点,虚拟网络设备flannel0收到/dev/net/tun转发的数据包后,会解析IP头
- 将剩下的数据,扔给业务应用APP
接下来,看下面的图:
5.2.2、业务应用程序APP给tun设备发送数据包的方式? |
此图跟上面的图,数据包的流向刚好相反
- 假设某个应用的APP产生一个ICMP类型的数据包,此数据包会经过网络协议栈,路由表,防火墙,最终进入到了tun设备里(flannel0)
- 当虚拟网络设备flannel0接收到icmp类型的数据包,会自动给这个数据包添加一个IP层的报文头,
- 此时,新的数据包就会自动的转发到/dev/net/tun文件描述符里
- 而flannel服务在不断的从/dev/net/tun文件描述符里读取数据,这样的话,flannel服务就读取到了业务应用发送的ICMP数据包了
- 注意一点,flannel服务收到的数据包是IP类型的数据包
- 需要flannel服务,解析IP数据包,去掉20个字节的IP报文头,获取剩下的数据内容
5.2.3、业务应用程序APP如何利用tun设备跟外部进行通信呢? |
接下来,我们分析一下,业务应用程序APP如何利用tun设备跟外部进行通信呢?
上图中的网络协议栈-1,网络协议栈-2 就是宿主机上的同一个网络协议栈,为了更好理解,画了两个。
- 假设用户空间的APP应用执行ping命令,产生ICMP数据包,此数据包经过了路由表,防火墙,网络协议栈,最终到达tun设备(flannel0)
- flannel0设备接收到数据包后,会自动的添加上IP报文头,20个字节,产生的新的数据包,
- 新的数据包会自动的转发到文件描述符/dev/net/tun里
- 用户空间的flannel服务,会不断的监听/dev/net/tun文件描述符,从此文件里读取数据包
- 本地宿主机上,会建立一个socket链接,如udp链接;
- 用户空间的flannel服务会将从/dev/net/tun文件描述符里接收的数据包通过udp连接发送出去
通过这种形式,业务应用就将数据包传输出去了
5.2.4、如何利用tun设备实现不同宿主机上的tun网络通信?跨主机通信 |
如何利用tun设备实现不同宿主机上的应用通信呢?
如下图所示:
假设,上面的图是宿主机1,下面的图是宿主机2;
宿主机-1对应的物理网卡eth0的IP地址10.211.55.161,
宿主机-2对应的物理网卡eth0的IP地址10.211.55.162,
宿主机-1上flannel0虚拟网卡的IP网络是10.244.1.1/24
宿主机-2上flannel0虚拟网卡的IP网络是10.244.2.1/24
宿主机-1上的业务应用APP-1使用的网络是flannel0网络10.244.1.1/24
宿主机-2上的业务应用APP-2使用的网络是flannel0网络10.244.2.1/24
现在的需求是,希望宿主机-1上的业务应用APP-1能够ping通宿主机-2上的业务应用APP-2
在宿主机-1上
- 业务应用APP-1使用ping命令创建icmp数据包
- 经过路由表,防火墙,网络协议栈,最终达到了tun设备,如flannel0
- 虚拟网络设备flannel0接收到ICMP包后,会自动的给ICMP包添加一个IP报文头,20个字节(如,报文协议,源地址10.244.1.1,目的IP地址10.244.2.1)
- 虚拟网络设备flannel0产生的新的数据包,会自动的转发到文件描述符/dev/net/tun里
- 网络相关服务,如flannel服务,会从/dev/net/tun里读取到虚拟网络设备flannel0产生的数据包,
- flannel服务将接收到的数据包通过udp连接,发送出去
在宿主机-2上
- flannel服务通过UDP连接,读取到宿主机-1上发送过来的数据包
- flannel服务,会将接收到的数据包写到文件描述符/dev/net/tun里
- 虚拟网络设备flannel0从文件描述符/dev/net/tun里读取到了数据包
- 虚拟网络设备flannel0会自动的分析数据包的IP报文头,即分析前20个字节,
- 虚拟网络设备去掉前20个字节后,会将剩下的数据包发送出去
- 离开虚拟网络设备flannel0的数据包,会经过路由表,防火墙,网络协议栈后,最终到达业务应用APP-2里
= 业务应用APP-2接收到数据包后,会进行响应的处理
其实具体是TUN或者是TAP,都不是在open打开设备的文件节点时就确定的。文件节点只是内核提供给用户的接口而已,应用程序需要ioctl设置自己的虚拟网络设备的工作模式,是TUN还是TAP。