最简单的openvswitch转发过程内核代码级实现
笔者写这篇文章出于好奇,对namespace和openvswitch如何工作在内核协议栈中的好奇,也出于对openvswitch了解的渴望,因此这篇文章仅仅是开端,后续会有更多文章揭秘openvswitch具体工作过程,不啰嗦了,下面步入正题。
这篇文章是基于两个namespace经过openvswitch之间进行通信的场景,分析寻找该通信底层发生的事情;所以该篇文章会涉及namespace协议栈处理和openvswitch通信过程两大部分;不过后续文章书写部分并没有按照这个书写逻辑;后文是根据笔者具体实践步骤书写的,这两部分内容会蕴含其中,具体请看后文。
最简单的环境
1 | br0 |
数据包如何从物理网卡到达云主机的应用程序?
笔者工作后从事的行业是linux2.6内核态的负载均衡研发,但是当时采用的mips CPU且整个架构重构了;对于通用的服务器的网络数据包运行流程,有了解,但是缺少大规模的总结和深刻的认识
因为笔者在之前工作中解决了云主机tap口丢包问题,就借此机会详细阐述下数据包处理流程吧,一为总结,二为兴趣,笔者不太喜欢看黑盒的东西。
如上图示,数据包从物理HOST外侧,经过物理网卡,发给ovs bridge,最后经过linux 安全组交给guest云主机1,最后交给guest1云主机应用程序;后文就从接近代码级别阐述此过程的详细步骤;笔者讲述的这个过程只能算是通用流程,可以用来参考,因为不同物理网卡会存在差异性。希望你通过这篇文章了解整个数据包转发流程,更深入了解底层网络实现。
云主机tap口丢包问题
背景
某一用户在云平台上,在同一个VPC建立3台云主机,2台centos6.3(16vcpu,8G内存)和一台windows2008 sever(4 vcpu,4G内存)云主机;
我们编号为A,B,C ,其中A代表压力客户端云主机, B代表应用后台服务器云主机, C代表存储服务器云主机
通过A持续压力B,发现网络流量只有50Mb情况下,在外部ping服务器B出现大幅动的延迟波动,在15ms以上,有时候甚至50ms;而无压力情况下ping 浮动ip延迟在5ms以下;
且此时查看云主机接口发现连接云主机B的tap口丢包很严重,约丢1000个左右。
linux服务端程序tunning过程简要总结
如何定位性能瓶颈问题?
步骤1:网络丢包的原因定位
ethtool -S eth0
rx_dropped代表丢包发生在linux 内核缓冲区,丢包发生在docker的虚拟网卡上
cat /proc/net/softnet_stat
1 | root@xnet-controller1:~# cat /proc/net/softnet_stat |
第一列:中断处理程序接收的帧数
第二列:由于超过cpu队列 netdev_max_backlog 1000 丢弃帧数
第三列:net_rx_action 函数中处理数据包超过300 netdev_budget 或者 运行时间超过2个时间片
内核为每个cpu都存储一个softnet_data对象,如果所有中断都由一个cpu核处理,如果接受数据包量非常大,超过中断处理速度,就会导致超过netdev_max_backlog而丢包
网卡rx dropped问题
问题
有一些设备出现rx dropped,如下图示,或者通过ifconfig 查看
详细定位error分布
我遇到了物理网卡的dropped丢包问题,详细查找丢包原因可以通过ethtool -S ens2f0 查看具体丢包分布,如上图,所有的丢包点在rx_missed_errors,
那么rx_missed_errors 代表什么? 我又能做些什么?rx_fifo_errors,rx_over_errors丢包参数含义是什么?后文主要围绕这三点进行说明
rx_missed_errors 代表什么?
物理网卡接受数据buffer已经满了,无法接收数据计数
rx_missed_errors代表着DMA传送完成数据,发送硬件中断前,网卡的FIFO缓冲已经满了,导致数据丢掉的个数
Counts the number of missed packets. Packets are missed when the receive FIFO has insufficient space
to store the incoming packet. This can be caused because of too few buffers allocated, or because there
is insufficient bandwidth on the PCI bus. Events setting this counter causes ICR.Rx Miss, the Receiver
Overrun Interrupt, to be set. This register does not increment if receives are not enabled.
These packets are also counted in the Total Packets Received register as well as in Total Octets
Received.
rx_no_buffer
网卡通过DMA将设备FIFO中的数据传送给ring buffer时候,已经无内存可以放数据了,也就是说ringbuffer不足了,往往是系统处理数据较慢导致
rx_over_errors
系统ring buffer 满了,数据放不进去了,物理网卡无法通过DMA传送数据,该数据包被丢弃,尝尝发生在系统无法及时处理流量时候。
总结:
其实上面计数信息,不同网卡计数信息含义不同,在此不做解释了,具体遇到问题,再查找具体含义吧
不管怎么说出现rx_missed_errors代表还有有流量突发,导致网卡fifo满了,个人认为应该观察rx_missed_errors 后续增长情况,如果长时间不增长,可以不用做调整
如果持续增长,你就要看看你的网卡是不是次品了;如果很少切少量的增长,其实最难定位,像我遇到的这种情况,只有rx_missed_errors 没有rx_fifo_errors和rx_over_errors计数,网卡可以通过DMA将数据送给
系统内存中,这就很奇怪了,所以我怀疑,有两种可能性导致该问题:
可能性较大:在机器刚上线时候,网卡速率和交换机速率没有调整好导致,该计数后续不会增长了
可能性较小:网卡异常
二层广播和三层广播
广播只有2层的。跨网段访问是寻址。
三层交换机等同于路由器。也就是说源ip和目的ip在数据包里一直不变(不经过nat的情况),mac地址将时刻改变。广播只存在二层。三层情况下是路由寻址。
二层广播:全F的二层广播帧(交换机一般所发送的广播帧)
三层广播:192.168.1.255&255.255.255.255(区别是一个网段内的广播&全网络广播,一般是路由传播。但默认情况下路由器不转发广播包)
广播地址是一种特殊的IP地址形式,一种是直接广播地址,一种是有限广播地址。 直接广播地址包含一个有效的网络号和一个全”1”的主机号,如你说的202.163.30.255,255就是一个主机号,202则是C类的IP地址,C类IP地址就是我们常接触到的。 受限广播地址是32位全1的IP地址(255.255.255.255)。该地址用于主机配置过程中IP数据报的目的地址,此时,主机可能还不知道它所在网络的网络掩码,甚至连它的IP地址也不知道。在任何情况下,路由器都不转发目的地址为受限的广播地址的数据报,这样的数据报仅出现在本地网络中。
受限广播可以用在计算机不知道自己IP地址的时候,比如向DHCP服务器索要地址时、PPPOE拨号时等.
直接广播可用于本地网络,也可以跨网段广播,比如主机192.168.1.1/30可以发送广播包到192.168.1.7,使主机192.168.1.5/30也可以接收到该数据包,前提是之间的路由器要开启定向广播功能.
另外,无论是何种广播,它第二层目的MAC地址都是FF-FF-FF-FF-FF-FF,这样交换机也就可以往外flood广播包.区别于多播的MAC帧头是01005A+subnetid
eg:
因为访问的目的地址是直接广播地址,所以云主机并没有学习其arp,而是广播发出,如果不是广播地址,云主机会首先发arp学习其目的mac,然后将目的mac填入icmp数据包,将icmp数据包发出去
DHCP 请求目的地址是255.255.255.255三层受限广播,且目的MAC是全F
openstack and Dragonflow DNS
为什么会有这篇文章,这篇文章总结了openstack和dragonflow有关DNS的技术点,search 和 domain 经常出现在dns配置当中,于是就借此机会来个大总结。详细见后文
默认情况下的三层云主机的DNS
云主机内部的DNS配置,如下图所示
针对于linux系统DNS配置位于/etc/resolv.conf
默认openstack配置建立的云主机DNS指向DHCP服务器的地址,云主机内所有DNS请求流量会发给网络节点的DHCP namespace,该DHCP namespace中含有一个53端口dnsmsq服务,接收到该DNS请求后
会向已经配置的DNS服务器转发DNS请求,如果配置的外网DNS服务器不可达则,该53端口的DNS代理服务向云主机回复refused,告知云主机无法获取DNS
Dragonflow安全组实现三(详细)
流量从其它云主机发起,然后该云主机被动回复的流量场景下,此情况的安全组工作情况
入方向安全组
入方向安全组是指控制数据流量进入云主机的安全组,下文是针对于这种安全组的详细分析。分析方式有多种,下文是按照流量时刻进行分析的,流量时刻包含未放通入方向安全组、放通安全组第一个数据包、放通安全组建立会话后;根据这些流量时刻可以观察安全组起作用的整个过程,方便理解。
openvswitch bridge br-ex三层转发
ovs bridge br-ex三层转发概念
openvswitch bridge三层转发,和linux bridge三层转发类似,只有给br-ex桥配置上ip地址后才存在三层转发的概念。
三层转发的概念和传统的三层转发有一定差异性,给bridge配置地址这种模式是,赋予bridge一种能力,该能力能让访问bridge地址的数据流进入协议栈中的具体应用中;eg:配置bridge一个地址后
我们可以ssh连接这个地址控制这台服务器;这种能把流量送给上层应用的能力叫做三层转发能力。当然这种能力只有给ovs bridge配置地址且开启主机的forward功能后才具备。