Tóm tắt: tc gắn qdisc vào interface. netem thêm delay/jitter/loss/duplicate/reorder/corrupt, tbf giới hạn băng thông. Qdisc chỉ tác động chiều ra (egress) của interface đó; muốn tác động chiều vào thì chuyển traffic sang interface ifb. Tất cả là runtime, mất sau reboot, gỡ bằng tc qdisc del dev <if> root.
Đặt netem lên interface đang SSH vào có thể làm mất phiên. Hẹn giờ tự gỡ trước khi thử: sudo systemd-run --on-active=5m /usr/sbin/tc qdisc del dev eth0 root.
Luồng hoạt động
flowchart LR A["App"] --> B["root qdisc eth0"] B --> C["netem: delay, loss"] C --> D["tbf: rate limit"] D --> E["NIC eth0 (egress)"] F["Traffic vào eth0"] --> G["ingress + mirred"] G --> H["ifb0: netem"] H --> I["Stack nhận"]
Lệnh
Xem và gỡ
tc qdisc show dev eth0
tc -s qdisc show dev eth0 # kèm counter: sent, dropped, overlimits
sudo tc qdisc del dev eth0 root # gỡ toàn bộ, về mặc định (fq_codel / mq)netem cơ bản
| Mục đích | Lệnh |
|---|---|
| Delay cố định 100 ms | tc qdisc add dev eth0 root netem delay 100ms |
| Delay 100 ms ± 20 ms jitter, phân bố normal | tc qdisc add dev eth0 root netem delay 100ms 20ms distribution normal |
| Mất 1% gói | tc qdisc add dev eth0 root netem loss 1% |
| Mất gói theo cụm (correlation 25%) | tc qdisc add dev eth0 root netem loss 1% 25% |
| Nhân đôi / hỏng / đảo thứ tự gói | tc qdisc add dev eth0 root netem delay 10ms duplicate 1% corrupt 0.1% reorder 5% 50% |
| Giới hạn tốc độ ngay trong netem | tc qdisc add dev eth0 root netem delay 50ms rate 10mbit |
| Đổi tham số không gỡ | tc qdisc change dev eth0 root netem delay 200ms loss 2% |
| Thêm hoặc thay (idempotent) | tc qdisc replace dev eth0 root netem delay 80ms |
Tất cả cần sudo. reorder chỉ có tác dụng khi có delay (gói "đảo" được gửi ngay, phần còn lại bị delay).
netem + tbf (delay và giới hạn băng thông)
sudo tc qdisc add dev eth0 root handle 1: netem delay 50ms loss 0.5%
sudo tc qdisc add dev eth0 parent 1: handle 2: tbf rate 10mbit burst 32kbit latency 400ms
tc -s qdisc show dev eth0tbf: rate là tốc độ, burst là bucket (quá nhỏ so với rate thì không đạt được rate), latency là thời gian tối đa gói nằm chờ (quá thì drop).
Chỉ áp cho một đích
Dùng prio để chia band, chỉ band 3 có netem, filter đẩy traffic tới đích vào band đó:
sudo tc qdisc add dev eth0 root handle 1: prio
sudo tc qdisc add dev eth0 parent 1:3 handle 30: netem delay 200ms loss 2%
sudo tc filter add dev eth0 parent 1:0 protocol ip prio 3 \
u32 match ip dst 203.0.113.0/24 flowid 1:3
tc filter show dev eth0Chiều vào (ingress) qua ifb
sudo modprobe ifb
sudo ip link add ifb0 type ifb
sudo ip link set ifb0 up
sudo tc qdisc add dev eth0 handle ffff: ingress
sudo tc filter add dev eth0 parent ffff: matchall action mirred egress redirect dev ifb0
sudo tc qdisc add dev ifb0 root netem delay 100ms
# Gỡ
sudo tc qdisc del dev eth0 ingress
sudo tc qdisc del dev ifb0 root
sudo ip link del ifb0Trong container / network namespace
Không cần đụng interface của host: chạy tc trong netns của container (veth phía container).
sudo ip netns exec ns1 tc qdisc add dev veth1 root netem delay 100ms
# Docker: nsenter vào netns của container
sudo nsenter -t "$(docker inspect -f '{{.State.Pid}}' app)" -n tc qdisc add dev eth0 root netem delay 100msĐo kết quả bằng ping, mtr, iperf3: xem Network testing cheatsheet.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách xử lý |
|---|---|---|
Error: Exclusivity flag on, cannot modify. |
Đã có qdisc root do bạn thêm | Dùng tc qdisc change / replace, hoặc del rồi add |
Error: Specified qdisc kind is unknown. |
Thiếu module sch_netem (một số kernel tối giản/cloud) |
sudo modprobe sch_netem; không có thì cài gói linux-modules-extra-$(uname -r) nếu tồn tại |
| Delay chỉ thấy một chiều | netem chỉ tác động egress | Áp cả hai đầu, hoặc dùng ifb cho chiều vào |
ping thấy delay gấp đôi |
Áp netem ở cả hai máy | Bình thường: RTT = tổng hai chiều |
| tbf không đạt rate đặt | burst quá nhỏ, hoặc offload (TSO/GSO) gửi gói lớn |
Tăng burst; thử ethtool -K eth0 tso off gso off khi test |
| Mất SSH ngay sau khi thêm | Loss/delay quá nặng trên interface quản lý | Gỡ từ console hoặc chờ job systemd-run tự gỡ |
| Sau test máy vẫn chậm | Quên gỡ qdisc | tc qdisc show trên mọi interface, del dev <if> root |
Tham khảo
man tc,man tc-netem,man tc-tbf- Linux Foundation wiki: netem
- Namespace và veth: Linux namespaces & cgroups