同样我们来看看节点 A 是如何接受数据:
文章插图
当节点A 通过物理网卡 eth0 接受到数据后会将写入内核网络协议栈,因为目标端口号是OpenVPN程序所监听的,所以网络协议栈会将数据交给 OpenVPN ;
OpenVPN 程序得到数据之后,发现目标IP是tun0设备的,于是将数据从用户空间写入到字符设备文件中,然后 tun0 设备会将数据写入到协议栈中,网络协议栈最终将数据转发给应用进程 。
从上面我们知道使用 tun/tap 设备传输数据需要经过两次协议栈,不可避免地会有一定的性能损耗,如果条件允许,容器对容器的直接通信并不会把 tun/tap 作为首选方案,一般是基于稍后介绍的 veth 来实现的 。但是 tun/tap 没有 veth 那样要求设备成对出现、数据要原样传输的限制,数据包到用户态程序后,程序员就有完全掌控的权力,要进行哪些修改,要发送到什么地方,都可以编写代码去实现,因此 tun/tap 方案比起 veth 方案有更广泛的适用范围 。
flannel UDP 模式使用 tun 设备收发数据早期 flannel 利用 tun 设备实现了 UDP 模式下的跨主网络相互访问,实际上原理和上面的 OpenVPN 是差不多的 。
在 flannel 中 flannel0 是一个三层的 tun 设备,用作在操作系统内核和用户应用程序之间传递 IP 包 。当操作系统将一个 IP 包发送给 flannel0 设备之后,flannel0 就会把这个 IP 包,交给创建这个设备的应用程序,也就是 flanneld 进程,flanneld 进程是一个 UDP 进程,负责处理 flannel0 发送过来的数据包:
文章插图
flanneld 进程会根据目的 IP 的地址匹配到对应的子网,从 Etcd 中找到这个子网对应的宿主机 Node2 的 IP 地址,然后将这个数据包直接封装在 UDP 包里面,然后发送给 Node 2 。由于每台宿主机上的 flanneld 都监听着一个 8285 端口,所以 Node2 机器上 flanneld 进程会从 8285 端口获取到传过来的数据,解析出封装在里面的发给 ContainerA 的 IP 地址 。
flanneld 会直接把这个 IP 包发送给它所管理的 TUN 设备,即 flannel0 设备 。然后网络栈会将这个数据包根据路由发送到 docker0 网桥,docker0 网桥会扮演二层交换机的角色,将数据包发送给正确的端口,进而通过 veth pair 设备进入到 containerA 的 Network Namespace 里 。
上面所讲的 Flannel UDP 模式现在已经废弃,原因就是因为它经过三次用户态与内核态之间的数据拷贝 。容器发送数据包经过 docker0 网桥进入内核态一次;数据包由 flannel0 设备进入到 flanneld 进程又一次;第三次是 flanneld 进行 UDP 封包之后重新进入内核态,将 UDP 包通过宿主机的 eth0 发出去 。
tap 设备作为虚拟机网卡上面我们也说了,tap 设备是一个二层链路层设备,通常用作实现虚拟网卡 。以 qemu-kvm 为例,它利用 tap 设备和 Bridge 配合使用拥有极大的灵活性,可以实现各种各样的网络拓扑 。
文章插图
在 qume-kvm 开启 tap 模式之后,在启动的时候会向内核注册了一个tap类型虚拟网卡 tapx,x 代表依次递增的数字; 这个虚拟网卡 tapx 是绑定在 Bridge 上面的,是它上面的一个接口,最终数据会通过 Bridge 来进行转发 。
qume-kvm 会通过其网卡 eth0 向外发送数据,从 Host 角度看就是用户层程序 qume-kvm 进程将字符设备写入数据;然后 tapx 设备会收到数据后由 Bridge 决定数据包如何转发 。如果 qume-kvm 要和外界通信,那么数据包会被发送到物理网卡,最终实现与外部通信 。
从上面的图也可以看出 qume-kvm 发出的数据包通过 tap 设备先到达 Bridge,然后到物理网络中,数据包不需要经过主机的的协议栈,这样效率也比较高 。
经验总结扩展阅读
- 电视剧燕云台演员表介绍?
- 通常云计算服务应该具备哪些特征
- 八云紫是哪个动漫
- 云南雪山玉龙雪山冷不冷
- 制造业数字化转型,本土云ERP系统如何卡位?
- 马云发红包是真的吗
- frp服务利用云主机实现Windows远程连接
- frp服务利用云主机docker服务实现Windows远程连接
- 云淡风轻类似的词语
- 云顶之弈S3虚空斗法怎么玩