Ubuntu 22.04服务器如何预留固定网络带宽(上传/下载各200Mb/s)
Ubuntu 22.04服务器如何预留固定网络带宽(上传/下载各200Mb/s)
嘿,这个需求太实用了——要给服务器锁死200Mb/s的保底上下行带宽,不让其他设备把带宽抢光对吧?在Ubuntu 22.04上,咱们用内核原生的tc(Traffic Control)工具就能搞定,不用装额外的第三方软件,稳定性拉满。
核心原理
我们用HTB(Hierarchical Token Bucket)队列规则,给服务器的网卡划分优先级:
- 给服务器单独分配一个“保底带宽类”,固定200Mb/s的上传和下载
- 剩下的带宽其他设备可以自由使用,但服务器的保底配额绝对不会被占用,甚至在空闲时还能用更多带宽
第一步:确认你的网卡名称
先搞清楚服务器的物理网卡名,执行命令:
ip link show
输出里类似eth0、enp0s3的就是你的网卡名,下面的例子里我用eth0代替,记得替换成你自己的。另外,假设服务器的IP是192.168.1.100,也请替换成实际IP。
第二步:配置上传(出站)带宽预留
出站流量(服务器往外发的数据包)可以直接用tc处理:
- 先清空网卡上的旧规则(如果有的话):
tc qdisc del dev eth0 root 2>/dev/null
- 给网卡添加HTB根队列:
tc qdisc add dev eth0 root handle 1: htb default 10
- 创建主类,这里假设你的网络总带宽是10G(如果知道实际上限比如500Mb/s,就改成
500mbit):
tc class add dev eth0 parent 1: classid 1:1 htb rate 10000mbit ceil 10000mbit
- 创建服务器的上传保底类,固定200Mb/s,空闲时可以用满总带宽:
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 200mbit ceil 10000mbit
- 把服务器的所有出站流量导向这个保底类:
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip src 192.168.1.100 flowid 1:10
第三步:配置下载(入站)带宽预留
tc默认只能处理出站流量,入站流量需要用IFB虚拟网卡转一下:
- 加载IFB内核模块:
modprobe ifb numifbs=1
- 启动虚拟网卡
ifb0:
ip link set dev ifb0 up
- 把网卡
eth0的入站流量转发到ifb0:
tc qdisc add dev eth0 ingress handle ffff: tc filter add dev eth0 parent ffff: protocol ip u32 match ip dst 192.168.1.100 action mirred egress redirect dev ifb0
- 给
ifb0配置HTB根队列:
tc qdisc add dev ifb0 root handle 1: htb default 10
- 创建
ifb0的主类:
tc class add dev ifb0 parent 1: classid 1:1 htb rate 10000mbit ceil 10000mbit
- 创建服务器的下载保底类:
tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 200mbit ceil 10000mbit
- 把转发过来的入站流量导向保底类:
tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.1.100 flowid 1:10
验证配置是否生效
执行以下命令查看队列状态,确认规则已经加载:
tc -s qdisc show dev eth0 tc -s qdisc show dev ifb0
也可以用iperf3做实际带宽测试:在另一台机器上启动iperf3 -s,服务器上运行iperf3 -c 目标IP,同时让其他设备跑满带宽,看看服务器的上下行是不是稳定在200Mb/s以上(空闲时会更高)。
让配置开机自启
刚才的命令重启后会失效,我们把它做成systemd服务:
- 创建脚本文件
/usr/local/bin/reserve-bandwidth.sh,内容如下(记得替换网卡名和IP):
#!/bin/bash # 替换成你的网卡名 NIC="eth0" # 替换成你的服务器IP SERVER_IP="192.168.1.100" # 替换成你的网络总带宽(比如500mbit) TOTAL_BW="10000mbit" # 预留带宽 RESERVE_BW="200mbit" # 清空旧规则 tc qdisc del dev $NIC root 2>/dev/null tc qdisc del dev $NIC ingress 2>/dev/null tc qdisc del dev ifb0 root 2>/dev/null # 配置上传带宽 tc qdisc add dev $NIC root handle 1: htb default 10 tc class add dev $NIC parent 1: classid 1:1 htb rate $TOTAL_BW ceil $TOTAL_BW tc class add dev $NIC parent 1:1 classid 1:10 htb rate $RESERVE_BW ceil $TOTAL_BW tc filter add dev $NIC protocol ip parent 1:0 prio 1 u32 match ip src $SERVER_IP flowid 1:10 # 配置下载带宽 modprobe ifb numifbs=1 ip link set dev ifb0 up tc qdisc add dev $NIC ingress handle ffff: tc filter add dev $NIC parent ffff: protocol ip u32 match ip dst $SERVER_IP action mirred egress redirect dev ifb0 tc qdisc add dev ifb0 root handle 1: htb default 10 tc class add dev ifb0 parent 1: classid 1:1 htb rate $TOTAL_BW ceil $TOTAL_BW tc class add dev ifb0 parent 1:1 classid 1:10 htb rate $RESERVE_BW ceil $TOTAL_BW tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 match ip dst $SERVER_IP flowid 1:10
- 给脚本加执行权限:
chmod +x /usr/local/bin/reserve-bandwidth.sh
- 创建systemd服务文件
/etc/systemd/system/reserve-bandwidth.service:
[Unit] Description=Reserve fixed bandwidth for server After=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/reserve-bandwidth.sh RemainAfterExit=yes [Install] WantedBy=multi-user.target
- 启用并启动服务:
systemctl enable --now reserve-bandwidth.service
小提醒
- 如果配置后规则不生效,先清空所有规则再重新执行脚本:
tc qdisc del dev eth0 root; tc qdisc del dev eth0 ingress; tc qdisc del dev ifb0 root - 总带宽
TOTAL_BW尽量设成你的实际网络上限,这样服务器空闲时能用到全部带宽 - 如果服务器有多个IP,需要把所有IP都加到filter规则里,或者用子网匹配
备注:内容来源于stack exchange,提问作者Kamiszewskyy
相关产品推荐
相关产品推荐

