4. 网络容量基础:容量定义、连接数(Conntrack)、会话表大小、端口范围对网络性能的影响
在 Kubernetes 网络性能调优中,网络容量是决定 Pod 到 Pod、Pod 到 Service 通信质量的核心约束。容量不足时,即使链路带宽充裕,应用仍会遭遇丢包、延迟飙升或连接中断。本章从四个维度拆解网络容量的基础要素:容量定义、连接跟踪(Conntrack)、会话表大小与端口范围。
4.1 网络容量定义与度量模型
网络容量并非单一指标,而是由带宽、包率、并发连接数和会话建立速率共同构成的四维空间。在 CNI 插件场景下,容量瓶颈往往出现在主机侧(节点网络栈)而非物理链路。
| 容量维度 | 单位 | 典型瓶颈点 | K8s 场景影响 |
|---|---|---|---|
| 带宽(Bandwidth) | bps / Bps | 物理网卡、veth pair、隧道封装 | 大文件传输、日志采集、镜像拉取 |
| 包率(PPS) | packets/s | CPU 中断、网卡队列、iptables 规则 | 高频小包请求、DNS 查询、健康检查 |
| 并发连接数 | 条 | Conntrack 表、socket 内存 | 微服务网格、API 网关、长连接池 |
| 连接建立速率 | conns/s | TCP 半连接队列、CPU 调度 | 突发流量、滚动更新、HPA 弹性伸缩 |
容量调优黄金法则: 在 K8s 节点上,并发连接数和连接建立速率通常先于带宽达到上限。优先监控
conntrack 使用率与 listen-overflow 指标。
4.2 连接数(Conntrack)—— 网络容量第一道防线
Linux 内核的 Conntrack(连接跟踪)是 netfilter 框架的核心组件,负责记录所有经过主机的网络连接状态。K8s 中 kube-proxy 的 iptables/IPVS 模式、Calico 的网络策略、Cilium 的 eBPF 连接管理都依赖 Conntrack。
4.2.1 Conntrack 表结构与容量限制
- 哈希表:Conntrack 使用哈希表存储连接条目,默认大小由
nf_conntrack_buckets决定。 - 最大条目数:由
nf_conntrack_max控制,默认值通常为262144(约 26 万条)。 - 条目超时:TCP 建立状态默认 5 天,CLOSE_WAIT 默认 60 秒,UDP 默认 30 秒。
常见陷阱: 当 Conntrack 表满时,内核会丢弃新连接,表现为
dmesg 中出现 nf_conntrack: table full, dropping packet。此时 Pod 间通信间歇性失败,但带宽和 CPU 可能正常。
4.2.2 Conntrack 容量计算公式
# 查看当前 Conntrack 使用量
cat /proc/sys/net/netfilter/nf_conntrack_count
# 查看最大限制
cat /proc/sys/net/netfilter/nf_conntrack_max
# 查看哈希桶数
cat /proc/sys/net/netfilter/nf_conntrack_buckets
# 估算每个连接平均内存开销(约 352 字节)
# 总内存占用 ≈ nf_conntrack_max × 352 字节
# 例如 262144 × 352 ≈ 92 MB
4.2.3 Conntrack 容量与节点 Pod 密度关系
| 节点 Pod 数 | 平均每 Pod 连接数 | 总连接数估算 | Conntrack 使用率(max=262144) |
|---|---|---|---|
| 50 | 200 | 10,000 | 3.8% |
| 100 | 500 | 50,000 | 19.1% |
| 200 | 800 | 160,000 | 61.0% |
| 250 | 1000 | 250,000 | 95.4% → 溢出风险 |
调优建议: 对于高密度节点(>150 Pods/node),建议将
nf_conntrack_max 提升至 524288 或 1048576,同时按比例增加 nf_conntrack_buckets 以保持哈希效率。
4.3 会话表大小与协议栈容量
除 Conntrack 外,Linux 协议栈还维护多个会话相关队列,它们共同决定节点能承载的瞬时并发与突发建立速率。
4.3.1 关键会话表参数
| 参数 | 默认值 | 作用域 | 溢出后果 |
|---|---|---|---|
tcp_max_syn_backlog |
128 / 1024 | 半连接队列(SYN_RCVD) | SYN 丢包 → 连接超时 |
somaxconn |
128 | 全连接队列(ESTABLISHED 等待 accept) | 客户端连接被拒绝 |
tcp_max_tw_buckets |
262144 | TIME_WAIT 套接字数量 | 超过后丢弃 TIME_WAIT,可能影响旧连接 |
netdev_max_backlog |
1000 | 内核协议栈接收队列 | 网卡丢包,ifconfig 显示 dropped |
4.3.2 会话表容量与 Pod 通信质量
在 K8s 环境中,Service 的 ClusterIP 模式依赖 kube-proxy 将流量转发到后端 Pod。每个 Service 的 somaxconn 直接影响 Pod 的 accept() 能力。当 Pod 处理速度跟不上连接建立速率时,全连接队列溢出,客户端收到 connection refused。
排查命令:
ss -lnt | grep :80 | awk '{print $2}' 查看监听队列当前积压数。netstat -s | grep -i "overflow" 查看全连接队列溢出次数。cat /proc/net/stat/nf_conntrack 查看 Conntrack 统计。
4.4 端口范围 —— 容易被忽略的容量天花板
每个节点上的 Pod 发起对外连接时,需要分配一个临时端口(ephemeral port)。端口范围由 net.ipv4.ip_local_port_range 控制,默认值为 32768 60999,共 28232 个端口。
4.4.1 端口耗尽场景
- NAT 网关节点:所有 Pod 的出站流量经过节点 SNAT,共享同一 IP 的端口池。
- HostNetwork 模式:Pod 直接使用宿主机端口,与主机进程竞争。
- NodePort Service:每个 NodePort 占用一个宿主机端口,大量 Service 会快速消耗端口。
4.4.2 端口容量计算公式
# 查看当前端口范围
cat /proc/sys/net/ipv4/ip_local_port_range
# 输出示例: 32768 60999
# 可用端口数 = 上限 - 下限 + 1
# 默认: 60999 - 32768 + 1 = 28232
# 每个连接占用一个临时端口
# 节点最大并发出站连接数 ≤ 28232
# 调优示例:扩大端口范围
sysctl -w net.ipv4.ip_local_port_range="10240 65535"
# 可用端口数 = 65535 - 10240 + 1 = 55296
4.4.3 端口范围与连接数关系矩阵
| 节点 Pod 数 | 每 Pod 出站连接 | 总出站连接 | 默认端口池(28232) | 扩大端口池(55296) |
|---|---|---|---|---|
| 50 | 200 | 10,000 | 35.4% | 18.1% |
| 100 | 300 | 30,000 | 106.3% ❌ | 54.2% |
| 200 | 200 | 40,000 | 141.7% ❌ | 72.3% |
端口耗尽典型症状: 应用日志出现
Cannot assign requested address 或 errno 99;ss -s 显示大量 TIME_WAIT 连接;netstat -an | wc -l 接近端口上限。
4.5 容量四维联动效应
带宽、Conntrack、会话表、端口范围并非独立工作,它们之间存在木桶效应:
- 带宽充足但 Conntrack 满 → 新连接被丢弃,应用报错。
- Conntrack 正常但端口耗尽 → 出站连接失败,DNS 解析超时。
- 端口充足但
somaxconn太小 → 突发流量下连接被拒绝。 - 所有容量充足但 PPS 过高 → CPU 软中断 100%,吞吐骤降。
容量规划检查清单:
✅ 计算节点最大 Pod 数 × 每 Pod 平均连接数,确保 Conntrack max 有 20% 余量。
✅ 检查
✅ 调整
✅ 监控
✅ 计算节点最大 Pod 数 × 每 Pod 平均连接数,确保 Conntrack max 有 20% 余量。
✅ 检查
ip_local_port_range 是否满足出站并发需求,NAT 节点需重点调大。✅ 调整
tcp_max_syn_backlog 和 somaxconn 至 4096 以上,应对突发流量。✅ 监控
conntrack_count / conntrack_max 和 listen-overflow 指标,设置告警阈值 80%。