在CentOS上模拟网络延迟和其他网络环境

在开始之前,请确保你的系统已经安装了iproute-tc和kernel-modules-extra包。这两个包分别提供了tc工具和额外的内核模块,包括网络调度器sch_netem,它是我们实现网络延迟模拟的关键。


yum -y install kernel-modules-extra iproute-tc

安装这些包后,理论上你应该可以使用sch_netem模块了。然而,有时候你可能会发现即使安装了必要的包,sch_netem模块也没有被自动加载到内核中。


发现问题(在Centos8情况下较多)

当尝试使用tc命令添加网络延迟时,比如想要在enp1s0f0网络接口上添加8毫秒的延迟:

tc qdisc add dev enp1s0f0 root netem delay 8ms

你可能会遇到一个错误,提示“RTNETLINK answers: No such file or directory”,这表明sch_netem模块未被加载。


使用find命令来搜索sch_netem模块是否存在于系统中:

find /lib/modules/$(uname -r) -type f -name 'sch_netem.ko.xz'

在Centos8的环境下有些时候可能不会在/lib/modules下,使用以下搜索命令

find / -type f -name *sch_netem*

如果找到了模块,输出类似于:

/usr/lib/modules/4.18.0-544.el8.x86_64/kernel/net/sched/sch_netem.ko.xz

这意味着模块确实存在,只是没有被加载。

手动加载模块

insmod /usr/lib/modules/$(uname -r)/kernel/net/sched/sch_netem.ko.xz

加载模块后,再次尝试添加网络延迟的tc命令

例如我们将服务器的所有延迟增大8ms

tc qdisc add dev enp1s0f0 root netem delay 8ms

关闭延迟模拟

tc qdisc del dev enp1s0f0 root netem


其他功能用法:

丢包

tc qdisc add dev enp1s0f0 root netem loss 1%

包乱序

tc qdisc add dev enp1s0f0 root netem delay 10ms reorder 25% 50%

包重复

tc qdisc add dev enp1s0f0 root netem duplicate 1%

组合模拟

tc qdisc add dev enp1s0f0 root netem delay 100ms loss 2% duplicate 1% reorder 25% 50%

此命令同时模拟了100ms的延迟、2%的丢包率、1%的包重复和25%的包乱序,其中50%的乱序包会立即发送。


移除所有的模拟规则

tc qdisc del dev enp1s0f0 root netem



如果需要针对特殊的网络协议进行延迟模拟(例如ICMP协议)

要专门针对ICMP流量模拟延迟,而不影响UDP和TCP流量,可以采用更精细的控制手段,因为tc工具本身作用于网络接口层面,而不区分不同类型的流量。要实现这一目的,你需要结合使用tc和iptables,后者能够根据流量类型(如ICMP)进行匹配,并将匹配到的流量标记出来。然后,你可以让tc仅对这些被标记的流量应用延迟。


以下是实现这个目标的大致步骤:


1. 使用iptables标记ICMP流量

首先,你需要创建一个新的iptables规则,用于标记所有的ICMP包。这里,我们假设使用1作为标记值(iptables的标记值可以是任何32位整数):

iptables -t mangle -A PREROUTING -p icmp -j MARK --set-mark 1

这个命令的含义是,在mangle表的PREROUTING链上添加一个规则,该规则匹配所有ICMP协议的包,并将它们标记为1。


2. 创建一个针对特定标记流量的过滤器

接下来,使用tc为网络接口创建一个队列规则,然后添加一个过滤器,只对标记为1的流量(即ICMP流量)应用延迟。

首先,为网络接口创建一个根队列规则:

tc qdisc add dev enp1s0f0 root handle 1: htb

然后,添加一个子队列规则,用于应用延迟:

tc qdisc add dev enp1s0f0 parent 1:1 handle 10: netem delay 8ms

最后,将标记为1的流量定向到这个子队列规则:

tc filter add dev enp1s0f0 protocol ip parent 1:0 prio 1 handle 1 fw flowid 1:1

如果需要清理上述的规则

iptables -t mangle -F PREROUTING
tc qdisc del dev enp1s0f0 root


关于tc qdisc能模拟的部分

tc命令(通过qdisc,即队列规则)能够模拟的网络条件不仅限于延迟。


通过上述方法,你可以实现只对ICMP流量模拟延迟,而不影响UDP和TCP流量。这种方法提供了一种灵活的方式,以针对性地测试和优化网络应用对特定类型流量的响应。需要注意的是,通过使用iptables和tc结合的方式,可以实现非常精细和灵活的网络流量控制策略,但同时也增加了配置的复杂度。



其他错误

遇到 "Error: Exclusivity flag on, cannot modify." 错误时,通常意味着你尝试在一个已经有qdisc设置的接口上添加新的qdisc,而没有先删除或更改现有的设置。这个错误阻止了对已存在的qdisc配置的修改,因为netem需要独占地控制接口的队列规则(qdisc)。

[root@qy ~]# tc qdisc add dev enp1s0f0 root netem delay 8ms
Error: Exclusivity flag on, cannot modify.
[root@qy ~]# tc qdisc show dev enp1s0f0
qdisc htb 1: root refcnt 65 r2q 10 default 0 direct_packets_stat 237471 direct_qlen 1000
[root@qy ~]# tc qdisc del dev enp1s0f0 root



iptables -t nat -A OUTPUT -p icmp -j DNAT --to-destination 127.0.0.1

将icmp进行回环,让所有的ping都变为0。


发表评论

必填

选填

选填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。