4. 网络栈优化(下):端口范围、积压队列、Keepalive 与多队列调优

Kubernetes 集群中,Pod 与 Service 的通信高度依赖宿主机的网络栈。本节深入剖析 ip_local_port_range、netdev_max_backlog、TCP Keepalive 系列参数以及 RPS/RFS/XPS 网卡多队列调优,确保节点在高并发场景下不丢包、不超时、不端口耗尽。

4.1 net.ipv4.ip_local_port_range:临时端口池

当节点作为客户端发起大量出站连接(如 NodePort 访问、HostNetwork Pod 调用外部服务)时,内核会从本地临时端口池中分配源端口。默认范围 32768 60999 仅提供约 28K 端口,极易耗尽。

参数默认值推荐值(K8s 节点)说明
net.ipv4.ip_local_port_range32768 6099910240 65535扩大临时端口池,避免端口耗尽
net.ipv4.ip_local_reserved_ports(空)30000-32767预留端口给系统服务或固定端口应用
调优要点:将起始端口降至 10240,上限扩展至 65535,可提供约 55K 可用端口。同时使用 ip_local_reserved_ports 预留 30000-32767 段,避免与 NodePort 范围(默认 30000-32767)冲突。
# 设置临时端口范围
cat >> /etc/sysctl.d/99-kubernetes.conf <<EOF
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.ip_local_reserved_ports = 30000-32767
EOF
sysctl -p /etc/sysctl.d/99-kubernetes.conf

4.2 net.core.netdev_max_backlog:网卡接收积压队列

当内核处理数据包的速度低于网卡接收速度时,数据包会在 netdev_max_backlog 队列中排队。默认值 1000 对于高吞吐 K8s 节点(特别是运行大量 Ingress Controller 或 LoadBalancer 的节点)明显不足。

参数默认值推荐值适用场景
net.core.netdev_max_backlog100010000 ~ 50000高并发入站流量节点
net.core.somaxconn1284096 ~ 65535Socket 监听队列,影响 Ingress/Service 接入
注意:增大 netdev_max_backlog 会占用更多内核内存。建议结合 netstat -s 或 dropwatch 观察实际丢包情况,逐步调高。
# 调整积压队列
cat >> /etc/sysctl.d/99-kubernetes.conf <<EOF
net.core.netdev_max_backlog = 20000
net.core.somaxconn = 65535
EOF
sysctl -p /etc/sysctl.d/99-kubernetes.conf

4.3 net.ipv4.tcp_keepalive_*:连接保活与资源回收

K8s 集群中大量闲置 TCP 连接(如 Service Mesh sidecar、监控采集、日志采集)会占用节点内存和文件描述符。合理配置 TCP Keepalive 参数可以及时回收死连接。

参数默认值推荐值作用
tcp_keepalive_time7200600连接空闲 600 秒后开始发送探测包
tcp_keepalive_intvl7530探测包间隔 30 秒
tcp_keepalive_probes93连续 3 次无响应即判定连接断开
效果:默认需要 7200 + 75×9 = 7875 秒(约 2.2 小时)才能回收死连接;调优后仅需 600 + 30×3 = 690 秒(约 11.5 分钟),大幅降低连接堆积风险。
# TCP Keepalive 调优
cat >> /etc/sysctl.d/99-kubernetes.conf <<EOF
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3
EOF
sysctl -p /etc/sysctl.d/99-kubernetes.conf

4.4 RPS / RFS / XPS:网卡多队列与 CPU 亲和性

现代网卡支持多队列(RSS),但软件层面仍需内核将中断和数据处理分散到多个 CPU。RPS(Receive Packet Steering)、RFS(Receive Flow Steering)和 XPS(Transmit Packet Steering)是内核提供的软中断分发机制。

适用条件:当网卡不支持硬件 RSS 或 RSS 队列数少于 CPU 核心数时,RPS/RFS 可以显著提升多核利用率。XPS 则优化发送路径的缓存局部性。
RPS / RFS / XPS 软件多队列分发架构 网卡硬件队列(NIC RX/TX Queues) RPS:将接收中断分发到多个 CPU(软中断负载均衡) RFS:根据流(Flow)将数据包定向到应用所在 CPU(缓存亲和性) XPS:发送队列绑定到特定 CPU(减少锁竞争与缓存失效) 数据流方向

4.4.1 RPS 配置示例

通过 /sys/class/net/<iface>/queues/rx-<n>/rps_cpus 设置 CPU 位图。以下脚本将 eth0 的所有接收队列分发到 CPU 0-3:

#!/bin/bash
IFACE=eth0
CPU_MASK=f  # 二进制 1111,表示 CPU 0-3
for f in /sys/class/net/$IFACE/queues/rx-*/rps_cpus; do
    echo $CPU_MASK > $f
done
# 同时增大 RPS 流表大小
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
for f in /sys/class/net/$IFACE/queues/rx-*/rps_flow_cnt; do
    echo 4096 > $f
done

4.4.2 XPS 配置示例

XPS 通过 tx-<n>/xps_cpus 设置发送队列的 CPU 亲和性:

# 将 eth0 的发送队列绑定到 CPU 0-3
for f in /sys/class/net/eth0/queues/tx-*/xps_cpus; do
    echo f > $f
done

4.4.3 验证多队列效果

工具命令观察指标
mpstatmpstat -P ALL 1各 CPU 软中断(%soft)是否均匀
ethtoolethtool -S eth0 | grep rx_packets各队列收包计数是否均衡
perfperf stat -e irq_vectors:local_timer_entry -a sleep 5中断分布是否分散
最佳实践:在 K8s 节点上,建议将 RPS/RFS 的 CPU 位图设置为除 CPU 0(通常用于管理中断)之外的所有业务 CPU。对于 NUMA 架构,优先将队列绑定到同一 NUMA 节点上的 CPU,避免跨 NUMA 访问。

4.5 综合调优清单

将本节所有参数汇总为一份可直接应用于 K8s 节点的 sysctl 配置:

# /etc/sysctl.d/99-kubernetes-network.conf
# 端口范围
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.ip_local_reserved_ports = 30000-32767

# 积压队列
net.core.netdev_max_backlog = 20000
net.core.somaxconn = 65535

# TCP Keepalive
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 3

# RPS 流表
net.core.rps_sock_flow_entries = 32768
验证与回滚:每次修改后使用 sysctl -p 加载,并通过 ss -s 观察连接状态、netstat -i 查看丢包统计。若出现异常(如连接超时增加),立即恢复默认值并逐步排查。