目录
1. Linux 网络架构概览
1.1 网络栈分层模型
Linux 网络栈遵循经典的分层架构:
┌─────────────────────────────────────────────────────────────┐│ 用户空间层 ││ Application (curl/nginx/browser) │└─────────────────────────────────────────────────────────────┘ ↓┌─────────────────────────────────────────────────────────────┐│ Socket API ││ 系统调用:socket/bind/listen/accept/send/recv │└─────────────────────────────────────────────────────────────┘ ↓┌─────────────────────────────────────────────────────────────┐│ 传输层 ││ TCP (可靠传输) / UDP (无连接) / SCTP / QUIC │└─────────────────────────────────────────────────────────────┘ ↓┌─────────────────────────────────────────────────────────────┐│ 网络层 ││ IP (IPv4/IPv6) / ICMP / ARP / NDP │└─────────────────────────────────────────────────────────────┘ ↓┌─────────────────────────────────────────────────────────────┐│ 数据链路层 ││ Ethernet / VLAN / Bridge / MAC │└─────────────────────────────────────────────────────────────┘ ↓┌─────────────────────────────────────────────────────────────┐│ 物理层 ││ Network Interface Card (NIC) │└─────────────────────────────────────────────────────────────┘
1.2 数据包处理流程
发送路径:应用程序 → Socket → TCP/UDP → IP → Netfilter(POST_ROUTING) → 网卡驱动 → 硬件接收路径:硬件 → 网卡驱动 → Netfilter(PRE_ROUTING) → IP → TCP/UDP → Socket → 应用程序
内核关键数据结构:
// Socket 结构体(核心)structsocket { socket_state state; // 连接状态structsock *sk;// 协议特定结构conststructproto_ops *ops;// 操作函数表};// TCP Socket(struct sock 的 TCP 扩展)structtcp_sock {structsocksk; u32 snd_nxt; // 下一个发送序列号 u32 rcv_nxt; // 下一个接收序列号 u32 snd_cwnd; // 拥塞窗口 u32 snd_ssthresh; // 慢启动阈值// ... 更多字段};
1.3 网络命名空间
网络命名空间(Network Namespace)是 Linux 容器的基础:
# 创建网络命名空间ip netns add test-ns# 在命名空间中执行命令ip netns exec test-ns ip addr# 创建 veth 对(虚拟以太网设备)ip link add veth0 type veth peer name veth1# 将 veth1 移入命名空间ip linkset veth1 netns test-ns# 配置 IPip addr add 192.168.100.1/24 dev veth0ip netns exec test-ns ip addr add 192.168.100.2/24 dev veth1# 启动设备ip linkset veth0 upip netns exec test-ns ip linkset veth1 up# 测试连通性ping 192.168.100.2# 删除命名空间ip netns delete test-ns
2. TCP/IP 协议栈实现
2.1 TCP 三次握手与四次挥手
连接建立(三次握手):
客户端 服务器 │ SYN(seq=x) │ │ ────────────────────> │ │ │ │ SYN(seq=y,ACK=x+1) │ │ <──────────────────── │ │ │ │ ACK(y+1) │ │ ────────────────────> │ │ │ [ ESTABLISHED ]
连接关闭(四次挥手):
客户端 服务器 │ FIN(seq=u) │ │ ────────────────────> │ │ ACK(u+1) │ │ <──────────────────── │ │ │ │ FIN(seq=w) │ │ <──────────────────── │ │ ACK(w+1) │ │ ────────────────────> │ │ │ [ TIME_WAIT (2MSL) ]
内核参数调优:
# /etc/sysctl.conf# SYN 队列长度(应对 SYN Flood)net.ipv4.tcp_max_syn_backlog = 65535# 启用 SYN Cookiesnet.ipv4.tcp_syncookies = 1# TIME_WAIT 优化net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 0 # Linux 4.12+ 已废弃net.ipv4.tcp_fin_timeout = 10net.ipv4.tcp_max_tw_buckets = 2000000# 应用配置sysctl -p
2.2 TCP 拥塞控制算法
Linux 支持多种拥塞控制算法:
# 查看可用算法cat /sys/module/tcp_cubic/parameters/available_congestion_control# cubic reno bbr illinois westwood# 查看当前算法sysctl net.ipv4.tcp_congestion_control# net.ipv4.tcp_congestion_control = cubic# 临时切换为 BBRsysctl -w net.ipv4.tcp_congestion_control=bbr# 永久配置echo"net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.confsysctl -p
算法对比:
BBR 算法原理:
传统算法(Cubic/Reno):- 基于丢包判断拥塞- 高丢包率导致吞吐量下降BBR 算法:- 测量瓶颈带宽(BtlBw)- 测量最小 RTT- 发送速率 = BtlBw × (RTT / 2)- 不受丢包影响(除非丢包率 > 10%)
2.3 TCP 缓冲区优化
# /etc/sysctl.conf# 核心缓冲区net.core.rmem_default = 262144net.core.wmem_default = 262144net.core.rmem_max = 33554432net.core.wmem_max = 33554432# TCP 缓冲区(min default max,单位字节)net.ipv4.tcp_rmem = 4096 87380 33554432net.ipv4.tcp_wmem = 4096 65536 33554432# TCP 总内存限制(页数)net.ipv4.tcp_mem = 786432 1048576 1572864# 窗口缩放(高带宽延迟积网络)net.ipv4.tcp_window_scaling = 1# 启用 SACK(选择性确认)net.ipv4.tcp_sack = 1# 启用 FACK(快速确认)net.ipv4.tcp_fack = 1
缓冲区计算:
带宽延迟积(BDP)= 带宽 × RTT例如:- 带宽:1Gbps = 125MB/s- RTT:100ms = 0.1s- BDP = 125MB/s × 0.1s = 12.5MB因此 TCP 缓冲区至少需要 12.5MB
2.4 连接追踪(Conntrack)
Netfilter 的连接追踪机制:
# 查看连接追踪表cat /proc/net/nf_conntrack | head -20# 查看统计cat /proc/sys/net/netfilter/nf_conntrack_countcat /proc/sys/net/netfilter/nf_conntrack_max# 调整最大连接数echo 2000000 > /proc/sys/net/netfilter/nf_conntrack_max# 优化超时时间echo 600 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_establishedecho 30 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_time_wait# 查看哈希表使用情况cat /proc/sys/net/netfilter/nf_conntrack_bucketscat /sys/module/nf_conntrack/parameters/hashsize
3. Netfilter 与防火墙
3.1 Netfilter 框架与 Hooks
Netfilter 是 Linux 内核的包过滤框架:
数据包流程: ┌─────────────────┐ │ PREROUTING │ ← DNAT、路由前处理 └────────┬────────┘ ↓ ┌─────────────────┐ │ Routing Decision│ └────────┬────────┘ ↓ ┌─────────────────┐ │ FORWARD │ ← 转发包处理 └────────┬────────┘ ↓ ┌─────────────────┐ │ POSTROUTING │ ← SNAT、路由后处理 └────────┬────────┘ ↓本地发包流程: ┌─────────────────┐ │ OUTPUT │ ← 本地生成包 └────────┬────────┘ ↓ ┌─────────────────┐ │ POSTROUTING │ └─────────────────┘本地收包流程: ┌─────────────────┐ │ PREROUTING │ └────────┬────────┘ ↓ ┌─────────────────┐ │ INPUT │ ← 本地接收包 └─────────────────┘
3.2 nftables 新一代防火墙
nftables 取代了 iptables,提供更统一的接口:
# 查看当前规则nft list ruleset# 创建表(inet 同时支持 IPv4 和 IPv6)nft add table inet filter# 创建链nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }# 添加规则# 允许 loopbacknft add rule inet filter input iif lo accept# 允许已建立连接nft add rule inet filter input ct state established,related accept# 允许 SSHnft add rule inet filter input tcp dport 22 ct state new accept# 允许 HTTP/HTTPSnft add rule inet filter input tcp dport { 80, 443 } ct state new accept# 允许 ICMPnft add rule inet filter input icmp type { echo-request, echo-reply } accept# 保存规则nft list ruleset > /etc/nftables.conf# 加载规则nft -f /etc/nftables.conf
nftables 配置示例:
#!/usr/sbin/nft -f# /etc/nftables.confflush rulesettable inet filter { chain input {type filter hook input priority 0; policy drop;# 允许 loopback iif lo accept# 允许已建立连接 ct state established,related accept# 丢弃无效包 ct state invalid drop# 允许 ICMP icmp type echo-request accept icmpv6 type echo-request accept# 允许 SSH(限制速率) tcp dport 22 ct state new limit rate 5/minute accept# 允许 HTTP/HTTPS tcp dport { 80, 443 } ct state new accept# 记录并丢弃其他包log prefix "nftables dropped: "limit rate 5/minute counter drop } chain forward {type filter hook forward priority 0; policy drop; ct state established,related accept } chain output {type filter hook output priority 0; policy accept; }}# NAT 表table ip nat { chain prerouting {type nat hook prerouting priority 0 } chain postrouting {type nat hook postrouting priority 100# MASQUERADE oif eth0 masquerade }}
3.3 iptables 迁移到 nftables
| | |
iptables -A INPUT -p tcp --dport 22 -j ACCEPT | nft add rule inet filter input tcp dport 22 accept | |
iptables -P INPUT DROP | nft add chain inet filter input { policy drop \; } | |
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE | nft add rule ip nat postrouting oif eth0 masquerade | |
iptables-save | nft list ruleset | |
iptables-restore | nft -f /etc/nftables.conf | |
3.4 流量控制(TC)
Traffic Control 用于带宽管理和 QoS:
# 查看当前 qdisc(队列规则)tc qdisc show# 添加 HTB(层次令牌桶)限速tc qdisc add dev eth0 root handle 1: htb default 12# 创建根类tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit burst 15k# 创建子类(HTTP 流量)tc class add dev eth0 parent 1:1 classid 1:10 htb rate 50mbit ceil 100mbit# 创建子类(其他流量)tc class add dev eth0 parent 1:1 classid 1:12 htb rate 30mbit ceil 50mbit# 使用过滤器分类流量tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \ match ip dport 80 0xffff flowid 1:10# 查看配置tc class show dev eth0tc filter show dev eth0# 删除配置tc qdisc del dev eth0 root
4. 网络性能调优
4.1 网卡优化
# 查看网卡信息ethtool eth0# 开启巨帧(Jumbo Frames)ethtool -G eth0 mtu 9000# 调整 Ring Bufferethtool -G eth0 rx 4096 tx 4096# 开启网卡多队列cat /sys/class/net/eth0/queues/rx-*/rps_cpusecho f > /sys/class/net/eth0/queues/rx-0/rps_cpus # 启用 RPS# 开启 GRO/TSO/LROcat /sys/class/net/eth0/gro_flush_timeoutecho 3 > /sys/class/net/eth0/gro_flush_timeout
中断亲和性:
# 查看网卡中断watch -n1 'cat /proc/interrupts | grep eth0'# 绑定中断到特定 CPU# 假设 eth0-rx-0 的中断号是 101echo"2" > /proc/irq/101/smp_affinity # 绑定到 CPU 1
4.2 内核网络参数调优
高并发服务器配置:
# /etc/sysctl.conf# ===== 连接处理 =====# SYN 队列长度net.ipv4.tcp_max_syn_backlog = 65535net.core.netdev_max_backlog = 65535net.core.somaxconn = 65535# 启用 SYN Cookiesnet.ipv4.tcp_syncookies = 1# 端口范围net.ipv4.ip_local_port_range = 1024 65535# ===== TCP 优化 =====# 拥塞控制算法net.ipv4.tcp_congestion_control = bbr# 缓冲区大小net.core.rmem_max = 134217728net.core.wmem_max = 134217728net.ipv4.tcp_rmem = 4096 87380 134217728net.ipv4.tcp_wmem = 4096 65536 134217728net.ipv4.tcp_mem = 134217728 134217728 134217728# TCP 优化选项net.ipv4.tcp_window_scaling = 1net.ipv4.tcp_sack = 1net.ipv4.tcp_fack = 1net.ipv4.tcp_timestamps = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_no_metrics_save = 1net.ipv4.tcp_moderate_rcvbuf = 1# ===== 连接复用 =====net.ipv4.tcp_keepalive_time = 600net.ipv4.tcp_keepalive_intvl = 30net.ipv4.tcp_keepalive_probes = 3# ===== 防火墙/Conntrack =====net.netfilter.nf_conntrack_max = 2000000net.netfilter.nf_conntrack_tcp_timeout_established = 600net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30# 应用配置sysctl -p
4.3 网络监控工具
# ss - Socket 统计(替代 netstat)ss -s # 概要统计ss -tlnp # TCP 监听端口(显示进程)ss -tan state established | wc -l # 统计 ESTABLISHED 连接数ss -tan state time-wait | wc -l # 统计 TIME_WAIT 连接数# 查看连接详细信息ss -ti# nstat - 内核网络统计nstat -az | grep -E "Tcp|Udp|Ip"# sar - 系统活动报告sar -n DEV 1 # 网卡流量sar -n TCP 1 # TCP 统计# bcc-tools - eBPF 网络工具tcptop-bpfcc # TCP 流量排名tcplife-bpfcc # TCP 连接生命周期tcpconnect-bpfcc # 连接追踪tcpaccept-bpfcc # 接受连接追踪
性能指标:
| | |
| 网络吞吐量 | | |
| PPS(包每秒) | | |
| 连接数 | | |
| TIME_WAIT | | |
| 重传率 | | |
5. 容器网络基础
5.1 容器网络模式
| | |
| Bridge | | |
| Host | | |
| None | | |
| Container | | |
| Overlay | | |
5.2 veth 与 Bridge
# 创建 bridgeip link add br0 type bridgeip addr add 172.18.0.1/24 dev br0ip linkset br0 up# 创建 veth 对ip link add veth-host type veth peer name veth-container# 一端接 bridgeip linkset veth-host master br0ip linkset veth-host up# 另一端给容器(在容器命名空间中)ip netns add container-nsip linkset veth-container netns container-nsip netns exec container-ns ip addr add 172.18.0.2/24 dev veth-containerip netns exec container-ns ip linkset veth-container upip netns exec container-ns ip route add default via 172.18.0.1# 启用 NATiptables -t nat -A POSTROUTING -s 172.18.0.0/24 ! -o br0 -j MASQUERADE
5.3 CNI 插件
CNI(Container Network Interface)是容器网络的标准接口:
# 常见 CNI 插件# - bridge:创建 veth pair 和 bridge# - host-local:分配 IP# - flannel:Overlay 网络# - calico:BGP 路由# - cilium:eBPF 网络# CNI 配置示例(/etc/cni/net.d/10-bridge.conf){"cniVersion": "0.4.0","name": "mynet","type": "bridge","bridge": "cni0","isGateway": true,"ipMasq": true,"ipam": {"type": "host-local","subnet": "10.244.0.0/24","routes": [{"dst": "0.0.0.0/0"}] }}
6. 网络故障排查
6.1 常用诊断工具
# ping - 测试连通性ping -c 4 8.8.8.8# traceroute - 路由追踪traceroute 8.8.8.8mtr 8.8.8.8 # 实时追踪# tcpdump - 抓包tcpdump -i eth0 port 80tcpdump -i eth0 host 192.168.1.1tcpdump -i eth0 -w capture.pcap # 保存到文件# Wireshark 分析# tshark - 命令行 Wiresharktshark -r capture.pcap# nmap - 端口扫描nmap -sT 192.168.1.1 # TCP 连接扫描nmap -sS 192.168.1.1 # SYN 扫描(需要 root)nmap -sU 192.168.1.1 # UDP 扫描# nc - 网络瑞士军刀nc -zv 192.168.1.1 80 # 测试端口连通性nc -l 8080 # 监听端口nc 192.168.1.1 80 # 连接端口# iperf3 - 带宽测试# 服务端iperf3 -s# 客户端iperf3 -c server_ip -t 30iperf3 -c server_ip -u -b 1G # UDP 测试
6.2 故障排查流程
场景 1:无法连接服务器
# 1. 检查本地网络配置ip addrip route# 2. 测试网关连通性ping <gateway_ip># 3. 测试目标连通性ping <target_ip>traceroute <target_ip># 4. 检查端口开放nc -zv <target_ip> <port>nmap <target_ip> -p <port># 5. 抓包分析tcpdump -i eth0 host <target_ip> and port <port>
场景 2:网络性能差
# 1. 检查带宽使用率iftop -i eth0nload eth0# 2. 检查丢包和错误ifconfig eth0 | grep -E "(RX|TX) (errors|dropped)"cat /proc/net/dev# 3. 检查 TCP 连接状态ss -tan | awk '{print $1}' | sort | uniq -c# 4. 检查重传率cat /proc/net/snmp | grep Tcpnstat -az | grep -i retrans# 5. 测试实际带宽iperf3 -c server_ip
场景 3:DNS 解析慢
# 1. 检查 DNS 配置cat /etc/resolv.conf# 2. 测试解析时间dig @8.8.8.8 google.comtime nslookup google.com# 3. 检查本地缓存systemd-resolve --statistics# 4. 检查 /etc/hostsgrep -v "^#" /etc/hosts | grep -v "^$"
6.3 自动化诊断脚本
#!/bin/bash# network-diag.shecho"=== 网络诊断报告 ==="echo"时间: $(date)"echo""echo"=== 1. 网络接口 ==="ip addrecho""echo"=== 2. 路由表 ==="ip routeecho""echo"=== 3. DNS 配置 ==="cat /etc/resolv.confecho""echo"=== 4. 连接统计 ==="ss -secho""echo"=== 5. TCP 状态统计 ==="ss -tan | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rnecho""echo"=== 6. 网卡统计 ==="cat /proc/net/dev | column -techo""echo"=== 7. 防火墙规则 ==="nft list ruleset 2>/dev/null || iptables -L -necho""echo"=== 8. 连通性测试 ==="ping -c 3 8.8.8.8echo""echo"=== 9. DNS 解析测试 ===dig +short google.comecho ""echo "=== 10. 路由追踪 ==="mtr --report --report-cycles 10 8.8.8.8echo ""echo "诊断完成"
参考资源
- • Linux Kernel Networking
- • Cilium - eBPF Networking