运维过程中,最复杂的问题,莫过于网络的问题,而网络问题最烦的就是无法复现,这篇介绍一个强大的网络模拟工具Netem。
Netem是从linux 2.6以上内核版本开始提供的一个网络模拟功能模块,它主要用来在性能良好的网络环境中,模拟出复杂的网络传输性能,比如低带宽、传输延迟、丢包等各种常见的网络故障的情况。
而Netem是由命令行工具tc控制,tc我们应该比较熟悉,tc是iproute2工具包的一部分,它的全称是traffic control(流量控制),最常用的莫过于通过nc监听进行反弹shell。
tc主要用于linux内核的流量控制,主要是通过在是输出端口处建立一个队列来实现流量控制,接收包从输入接口进来后,经过流量限制,丢弃不符合规定的数据包,由输入多路分配器进行判断选择,如果接收包的目的是本主机,那么将该包送给上层处理,否则需要进行转发,将接收包交到转发块处理,转发块同时也接收本机上层(TCP、UDP等)产生的包。转发块通过查看路由表,决定所处理包的下一跳,然后对包进行排列以便将他们传送到输出接口,一般我们只能限制网卡发送的数据包,不太好限制网卡接收的数据包,所以我们可以通过改变发送次序来控制传输速率,linux流量控制主要是在输出接口排列时进行处理和实现的。
关于linux内部网络包转发,在公众号之前发过的文章《nfstable比iptables强在哪里》里面有较详细的介绍,这里就不罗嗦了,有兴趣的可以点进去看下。
回到正题,我们主要通过tc工具加Netem模块进行网络状况的模拟,看下netem模块的强大功能
网络状况不好的情况通常就是以下几个表现:延迟、丢包、乱序、重复、错误等,我们就通过netem来模拟以上这几种情况,建议不要生产环境测试,熟练掌握后再使用
在tc配置netem的操作中,主要有4个控制参数,分别是add(表示为指定网卡添加Netem配置),change(表示修改已经存在的Netem配置),replace(表示替换已经存在的Netem配置的值),del(表示删除网卡上的Netem配置),好了,接着开始测试几种情况。
模拟延迟传输
- tc qdisc add dev eth0 root netem daly 100ms
模拟网络,所有的报文延迟100ms发送
上面的命令中qdisc是排队规则,没有添加规则之前,因为是内网,所以ping延迟在1ms,添加延迟后,增加到100ms
在真实的网络环境中,我们通常很难看到非常稳定的时延,别杠内网,所以netem也考虑到这一点,模拟延迟参数中提供了控制延迟的时间分布的可选参数,完整的参数列表如下:
可以看到,除了TIME外,还有三个可选参数:
- JITTTER:网络抖动,增加一个随机事件长度,让延迟事件出现在某个范围
- CORRELATION:相关系数,下一个报文延迟事件和上一个报文的相关系数
- distribution:延迟分布,可以选择的值有uniform、normal、pareto和paretonormal
先来看下JITTER,如果设置为10ms,那么报文延迟事件会在100ms± 10ms之间随机选择,看下效果
CORRELATION是指包和包之间的相关性,因为网络状况是平滑变化的,短时间里相邻报文的延迟应该是近似的,而不是完全随机的,这个值是个百分比,如果为100%,就是固定延迟的情况,如果是0%则是随机延迟的情况,接着刚才的配置继续看下效果
而distribution则是通过正态分布的方式来模拟更符合真实网络情况,它的几个参数就是几种延迟分布方法,有兴趣的可以试一下
模拟丢包率
丢包在网络中是最常见的一种情况,丢包会导致重传,重传会增加网络链路的流量和延迟,Netem提供了loss参数,可以模拟丢包率
- tc qdisc add dev eth0 root netem loss 50%
看下效果
和延迟类似,丢包率也有相关系数的参数可以设置,表示后一个报文丢包率和它前一个报文的相关性
- tc qdisc add dev eth0 root netem loss 50% 25%
上面这个命令表示,丢包率是50%,并且当前报文丢弃的可能性和前一个报文相关性为25%
模拟包重复
模拟报文重复,用duplicate参数,报文重复和丢包的参数类似,就是重复率和相关性两个参数,比如随机产生50%重复的包
- tc qdisc add dev eth0 root netem duplicate 50%
看下效果
相关性和其他参数一样,有兴趣可以测试
模拟包损坏
模拟报文损坏用参数corrupt,报文损坏和报文重复的参数也类似,比如随机产生30%损坏的报文
- tc qdisc add dev eth0 root netem corrupt 30%
查看效果
可以从icmp_seq看到,损坏的报文,导致严重的丢包
模拟包乱序
我们知道TCP为了保证可靠传输,会在报文中添加序列号,确保被拆分的包能够到达后进行重组,那么最好的情况就是包能按序传输,减少重新排序的次数,虽然包乱序造成的影响没有上面几种严重,但是仍然是会经常遇到,netem同样提供了模拟包乱序的方法
模拟报文乱序和前面的参数不太一样,上面的操作都是针对单个报文的,而乱序则牵扯到多个报文重组的问题,所以Netem这里有两种方法来模拟乱序
第一种是固定的每隔一定数量的报文乱序一次
- tc qdisc add dev eth0 root netem reorder 50% gap 3 delay 100ms
上面这个是每隔3个数据包正常发送,其他的数据包延迟100ms发送
第二种方法是更接近显示情况的,就是随机的,用概率来选择乱序的报文
- tc qdisc change dev eth0 root netem reorder 50% 15% delay 300ms
看效果
上面这个就是50%的报文正常发送,其他报文延迟300ms发送
查看已配置过滤条件
测试的过程中,肯定需要查看当前配置了那些条件,通过tc的show指令可以进行查看
对于模拟弱网环境,排查问题,这个工具必不可少,赶紧收藏!