Flannel基于UDP的网络实现

container-1的route表信息如下(b1):

default via 100.96.1.1 dev eth0
100.96.1.0/24 dev eth0 proto kernel scope link src 100.96.1.2
100.96.0.0/16 via 100.96.1.1 dev eth0

node1(10.168.0.2)的route表信息如下(b2):

default via 10.168.0.1 dev eth0
100.96.0.0/16 dev flannel0 proto kernel scope link src 100.96.1.0
100.96.1.0/24 dev docker0 proto kernel scope link src 100.96.1.1
10.168.0.0/24 dev eth0 proto kernel scope link src 10.168.0.2

说明

如果发生如下情况不应该质疑,先认为理论正确
1.容器中的eth0与挂在docker0网桥上的veth*虚拟网卡设备组成veth设备对,数据包从某一端流入,在另一端将直接收到。
2.挂在docker0网桥上的veth*虚拟网卡设备作为从设备,会被“剥夺”调用网络协议栈处理数据包的资格,从而“降级”成为网桥上的一个端口。而这个端口唯一的作用,就是接收流入的数据包。
3.TUN 设备(Tunnel 设备)是工作在第三层的虚拟网络设备,用于在操作系统内核和用户应用程序之间传递IP包,当操作系统将一个 IP 包发送给 flannel0 设备之后,flannel0 就会把这个 IP 包,交给创建这个设备的应用程序(Flannel进程)
4.docker0相当于二层交换机,其维护了 mac地址与interface的对应关系表,如目的mac地址为xx的应该发往veth*这个interface

过程

container-1(c1 100.96.1.2) -> container-2(c2 100.96.2.3) 数据包流转过程如上图(图源自极客实践):

1. c1发出数据包,根据c1的route表b1,因为目的地址为c2的ip100.96.2.3,匹配b1的第三条规则,既数据包将通过c1的eth0发出,根据说明1,数据包出现在docker0网桥的veth*一端并流入docker0处理。

2. docker0查询节点的route表,既b2,匹配第二条规则,数据包从docker0发至flannel0,根据说明3,ip数据包将会从flannel设备(内核中)到达flanneld进程(用户进程)。

3.ip数据包到达flanneld进程后,问题可转化为在宿主机node1和node2的flanneld之间的通信问题,node1上的进程发送的数据,匹配b1第四条规则,宿主机eth0网卡以UDP协议格式发送ip包,此时存在真实网络链路可通信。

4. 当node2的flanneld进程收到报文之后会交给flannel0设备,flannel0设备查询route表后把数据包交给docker0,docker0再根据目地容器的mac地址找到目的容器在docker0一端的veth*,数据发往veth*之后,容器端的eth0网卡即收到数据并处理之。

flannel的udp后端实现性能较差,如下图,在数据包最终从宿主机发出之前经过了3次的用户态和内核态之间的拷贝(进行系统级编程的时候,有一个非常重要的优化原则,就是要减少用户态到内核态的切换次数,并且把核心的处理逻辑都放在内核态进行)

问题

1. 当flanneld进程收到flannel0这个tun设备交上来的ip包之后,是怎么知道这个数据应该发往的目的宿主机的flanneld进程的?

flannel首先规划一个网段作为集群的容器ip分配的地址段如100.96.0.0/16,在这个基础上为每一个宿主机划分一个子网subnet,如node1的subnet为100.96.1.0/24,node2的subnet为100.96.2.0/24,每个宿主机上的容器在自己的subnet上为容器分配ip,这样就能保证各容器ip不冲突,反过来,根据目的容器ip如100.96.2.3就能知道其subnet为100.96.2.0/24,既对应宿主机node2,subnet与宿主机ip的对应关系存储在etcd中。

2. 为什么flanneld使用UDP协议来发送包而不是TCP,因为UDP简单高效,但UDP不是不可靠吗?

我的理解:因为flanneld进程的目的只是将tun设备交上来的数据包进行封装并发送给目的端,并不需要保证数据包正确到达,这个保证工作应该由发送方进程也就是容器中的进程使用的传输层tcp协议控制。

其实吧,所谓的可靠的tcp链接不过是发送方和接收方各自维护一个连接状态而已,包在网络中传输过程中该丢丢,只不过tcp协议会做一些重传等机制来做到最终数据的按序、完整到达。所以在flannel的udp实现中,容器之间已经在维护tcp状态了,节点间的flanneld再用

tcp协议传输包就没必要且低效了。

Flannel基于Vxlan的网络实现

最新文章

  1. 可以结合react的ui组件
  2. IOS第11天(2:UIPickerView自定义国旗选择)
  3. Oracle EBS Java Applet报错:找不到类
  4. NFS文件系统
  5. POJ-2152 Fire (树形DP)
  6. Path Sum的变体
  7. DISCUZ X2更换域名注意事项
  8. VS2010开发2dx无法解析的外部符号解决记录
  9. kafka.utils.Utils阅读
  10. Passbook教程中生成pass时遇到的“Couldn't find a passTypeIdentifier in the pass”
  11. Codeforces 437B The Child and Set
  12. #UnityTips# 2017.11.14
  13. 前端跨域(二):JSONP
  14. Spring中@Value注解使用——一种新的直接读取配置文件的方式
  15. Subtree Minimum Query CodeForces - 893F (线段树合并+线段树动态开点)
  16. iOS 可高度自定义的底部弹框
  17. Android ANR Waiting because no window has focus问题分析
  18. [LeetCode] 441. Arranging Coins_Easy tag: Math
  19. nagios监控oracle 表空间
  20. Bartender 使用 Excel xlsx 数据库时出现 0x800A0E7A

热门文章

  1. Git的使用(2) —— 本地版本库的操作
  2. ciscn2019华北赛区半决赛day1web5CyberPunk
  3. vue中样式被覆盖的问题
  4. https://suchprogramming.com/epoll-in-3-easy-steps/
  5. 写了一个具有future接口的rust测试代码
  6. js中const,var,let区别与用法(转)
  7. python3以post方式提交数据
  8. 线程或进程绑定到特定的cpu
  9. Spring cloud微服务安全实战-4-1章节概述
  10. 全面系统Python3入门+进阶-1-1 导学