文章

网络内核参数调优

网络内核参数调优

概述

Kubernetes 节点的网络不仅是 Pod 间通信的通道,更是 Service 转发、Ingress 流量、监控采集的基础设施。高并发场景下(大量 Service、密集 Pod 通信、东西向流量),网络内核参数的不当配置会直接导致连接丢失、延迟飙升和 CPU 软中断风暴。

一句话:K8s 每条 Service 规则 → iptables/nftables/eBPF 规则,每条连接 → nf_conntrack 条目。表满了,连接就丢了。

nf_conntrack —— 连接跟踪的生死线

原理

netfilter 的连接跟踪(connection tracking)是 Linux 防火墙的基石。它记录每条连接的状态(NEW / ESTABLISHED / RELATED / INVALID),Service 的 DNAT 转换依赖它来回映射。

Pod-A → Service ClusterIP:80
  → iptables DNAT → Pod-B:8080
  → nf_conntrack 记录: (Pod-A:随机端口 → ClusterIP:80) ↔ (Pod-A:随机端口 → Pod-B:8080)
  → 回包时根据 conntrack 做反向 DNAT

表的内部结构

# conntrack 表是一张哈希表
# 默认 hashsize = nf_conntrack_max / 8 (每 bucket 8 条)
# 链长超过 8 开始降级为链表遍历,性能急剧下降

# 查看当前设置
sysctl net.netfilter.nf_conntrack_max       # 总条目上限
sysctl net.netfilter.nf_conntrack_buckets   # 哈希桶数(只读)
cat /proc/sys/net/netfilter/nf_conntrack_count   # 当前使用量

调优参数

参数默认建议值原理
nf_conntrack_max2621441048576 ~ 2097152大型 K8s 集群(100+ 节点)需要百万级
nf_conntrack_tcp_timeout_established432000(5天)86400(1天)空闲 TCP 连接不及时回收,浪费条目
nf_conntrack_tcp_timeout_time_wait12030减少 TIME_WAIT 占用
nf_conntrack_tcp_be_liberal01容忍窗口外的包(避免 NAT 环境下的 RST)
nf_conntrack_generic_timeout600120UDP 等无连接协议的默认超时
nf_conntrack_udp_timeout3030DNS 查询常用 UDP
nf_conntrack_udp_timeout_stream12060UDP 流

爆表症状与处理

# 爆表确认
dmesg | grep "nf_conntrack: table full"
# nf_conntrack: table full, dropping packet

# 检查使用率
echo "scale=2; $(cat /proc/sys/net/netfilter/nf_conntrack_count) / $(cat /proc/sys/net/netfilter/nf_conntrack_max) * 100" | bc

# 紧急处理(不重启)
echo 2097152 > /proc/sys/net/netfilter/nf_conntrack_max

# 查看 Top 连接来源(谁在用最多 conntrack)
conntrack -S 2>/dev/null | sort -t'=' -k2 -nr | head -20
# 或
cat /proc/net/nf_conntrack | awk '{print $6}' | sort | uniq -c | sort -nr | head -20

什么时候可以禁用 conntrack

如果使用 Calico eBPF 模式Cilium KPR(kube-proxy replacement),Service 转发不走 iptables/nf_conntrack,可以显著降低 conntrack 压力。但这不意味着可以设为 0——kubelet 和 CNI 插件仍需 conntrack 处理基本网络。

TCP 调优

连接管理

参数默认建议原理
tcp_tw_reuse01(客户端)/ 0(NAT 网关)允许重用 TIME_WAIT 的 socket。NAT 网关慎用(可能连错 IP)
tcp_tw_recycle00(已废弃,内核 4.12 移除)曾导致 NAT 下连接异常
tcp_fin_timeout6030FIN_WAIT-2 状态超时
tcp_keepalive_time7200600空闲 10 分钟开始保活探测
tcp_keepalive_intvl7530保活探测间隔
tcp_keepalive_probes93保活探测失败次数
tcp_max_syn_backlog5128192SYN 队列大小(防 SYN flood)
tcp_max_tw_buckets180000360000TIME_WAIT socket 上限
tcp_retries2158丢包重试次数(减少僵尸连接)

缓冲区

参数默认建议
core.rmem_max21299216777216(16MB)
core.wmem_max21299216777216(16MB)
tcp_rmem4096 131072 62914564096 87380 16777216
tcp_wmem4096 16384 41943044096 65536 16777216
core.netdev_max_backlog10005000

tcp_rmem/wmem 的格式:min default max。大缓冲区对跨可用区(高延迟)的 K8s Pod 通信和 GPU 集群的 RDMA 流量有显著帮助。

注意:缓冲区不是越大越好。16MB max 意味着每连接最多预留 16MB 内核内存,10000 连接就是 160GB。按需设。

拥塞控制

# 查看可用算法
sysctl net.ipv4.tcp_available_congestion_control
# 查看当前算法
sysctl net.ipv4.tcp_congestion_control

# 推荐
# - 通用 → cubic(默认,稳定)
# - 长肥网络(跨地域 K8s)→ BBR(高吞吐、低延迟)
echo bbr > /proc/sys/net/ipv4/tcp_congestion_control

# BBR 还需加载模块
modprobe tcp_bbr

Socket 与 backlog

监听队列

Client → SYN → [SYN Queue (tcp_max_syn_backlog)]
           ← SYN-ACK ←
Client → ACK → [Accept Queue (somaxconn)]

                    accept()
参数作用建议
net.core.somaxconnAccept 队列最大长度32768
net.ipv4.tcp_max_syn_backlogSYN 队列最大长度8192
net.core.netdev_max_backlog网卡驱动 ring buffer 溢出后软件接收队列5000

应用层(如 Nginx、Envoy)的 backlog 参数不能超过 somaxconn,否则被截断。

防 SYN flood 攻击,但不影响正常连接:

sysctl net.ipv4.tcp_syncookies=1   # 始终启用

ARP / 邻居表

K8s 节点有大量 Pod IP,ARP 表(邻居表)容易溢出。

参数默认建议
gc_thresh11282048
gc_thresh25124096
gc_thresh310248192
  • thresh1:低于此值不触发 GC
  • thresh2:超过此值开始温和 GC
  • thresh3:超过此值强制 GC
# 检查 ARP 表大小
arp -an | wc -l
# 或
ip neigh show | wc -l

生产 K8s 节点网络调优脚本

#!/bin/bash
# k8s-network-tuning.sh

cat << 'EOF' > /etc/sysctl.d/99-k8s-net.conf
# === conntrack ===
net.netfilter.nf_conntrack_max = 2097152
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
net.netfilter.nf_conntrack_tcp_be_liberal = 1
net.netfilter.nf_conntrack_generic_timeout = 120

# === TCP ===
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 360000
net.ipv4.tcp_retries2 = 8

# === 缓冲区 ===
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.core.netdev_max_backlog = 5000

# === Socket ===
net.core.somaxconn = 32768

# === IP 转发 ===
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1

# === ARP ===
net.ipv4.neigh.default.gc_thresh1 = 2048
net.ipv4.neigh.default.gc_thresh2 = 4096
net.ipv4.neigh.default.gc_thresh3 = 8192
EOF

sysctl --system
echo "Network tuning applied."

排障工具速查

# 查看当前 conntrack 条目(top talkers)
conntrack -L -o extended 2>/dev/null | awk '{print $5, $6, $7, $8}' | sort | uniq -c | sort -nr | head

# 查看 socket 统计
ss -s     # 汇总:TCP/UDP/RAW 各状态数量
ss -tan state time-wait | wc -l   # TIME_WAIT 数量
ss -tan state established '( sport = :6443 )' | wc -l  # to API Server

# 查看网络软中断分布(检查是否集中在单个 CPU)
cat /proc/net/softnet_stat
# 每列:processed, dropped, time_squeeze, ...
# 如果 dropped 持续增长 → CPU 不够

# 查看网卡中断分布
cat /proc/interrupts | grep eth0

关联知识

参考资源

学习时间

阶段时间备注
梳理完成2026-06-30nf_conntrack 原理、TCP 连接管理、缓冲区、ARP 表、生产脚本

状态: 🌱 学习中 下次复习日期: 2026-07-07