主题
Kubernetes 节点内核参数调优清单
在规模化生产环境中,Kubernetes 节点的默认内核参数往往无法支撑高并发、高密度的容器负载,常见症状包括:conntrack 表满导致丢包、文件句柄耗尽导致容器启动失败、TIME_WAIT 堆积导致端口耗尽等。本文面向需要在生产集群中批量规范节点内核参数的运维工程师,按网络、连接跟踪、文件句柄、内存、容器运行时五个维度整理了一份经过验证的参数清单,并给出持久化配置与验证方法。
适用对象:运行 Kubernetes(含 RKE、RKE2、K3s 等发行版)的 Linux 物理机或虚拟机节点,内核版本建议 4.x 及以上。
一、完整参数清单
以下配置可直接写入 /etc/sysctl.d/99-kubernetes.conf:
yaml
# ===== 网络性能调优 =====
net.ipv4.tcp_max_orphans = 131072 # 最大孤儿套接字数量
net.ipv4.tcp_retries2 = 7 # TCP 重传次数上限
net.ipv4.ip_forward = 1 # 启用 IP 转发(K8s 必需)
net.core.somaxconn = 32768 # 监听队列最大长度(高并发必需)
net.core.rmem_max = 16777216 # socket 最大接收缓冲区(16MB)
net.core.wmem_max = 16777216 # socket 最大发送缓冲区(16MB)
net.core.netdev_max_backlog = 262144 # 网卡收包队列长度
net.ipv4.tcp_max_syn_backlog = 262144 # SYN 半连接队列长度
net.ipv4.tcp_wmem = 8192 12582912 16777216 # TCP 写缓冲区(最小/默认/最大)
net.ipv4.tcp_rmem = 8192 12582912 16777216 # TCP 读缓冲区(最小/默认/最大)
net.ipv4.tcp_max_tw_buckets = 2000000 # TIME_WAIT 套接字最大数量
# ===== 连接跟踪(conntrack)与桥接 =====
net.netfilter.nf_conntrack_max = 1000000 # 连接跟踪表大小
net.bridge.bridge-nf-call-iptables = 1 # 桥接 IPv4 流量经过 iptables
net.bridge.bridge-nf-call-ip6tables = 1 # 桥接 IPv6 流量经过 ip6tables
# ===== 文件句柄与 inotify =====
fs.file-max = 75756220 # 系统级最大文件句柄数
fs.inotify.max_user_watches = 1048576 # 单用户 inotify 可监控文件数
fs.inotify.max_user_instances = 1280 # 单用户 inotify 实例数
fs.may_detach_mounts = 1 # 允许卸载仍有引用的挂载点
# ===== 内存管理 =====
vm.dirty_background_ratio = 5 # 脏页后台回写触发阈值(%)
vm.dirty_ratio = 10 # 脏页强制同步回写阈值(%)
vm.swappiness = 0 # 尽量避免使用 swap
vm.max_map_count = 262144 # 单进程最大内存映射区域数
# ===== 系统信号量 =====
kernel.sem = 250 32000 32 1024 # 信号量:SEMMSL SEMMNS SEMOPM SEMMNI二、参数逐项说明
2.1 网络性能调优
| 参数 | 含义 | 推荐值 | 适用场景 |
|---|---|---|---|
| net.ipv4.ip_forward | 启用内核 IP 转发 | 1 | 所有 K8s 节点必需,否则 Pod 跨节点通信失败 |
| net.core.somaxconn | TCP listen 全连接队列上限 | 32768 | 承载大量并发连接的节点(Ingress、API 网关类 Pod) |
| net.ipv4.tcp_max_syn_backlog | 半连接队列长度 | 262144 | 突发新建连接高的场景,防止 SYN 洪峰时丢连接 |
| net.core.netdev_max_backlog | 网卡驱动层收包排队长度 | 262144 | 万兆及以上网卡、网络密集节点 |
| net.core.rmem_max / wmem_max | socket 收发缓冲区上限 | 16777216 | 大流量传输(镜像拉取、数据同步) |
| net.ipv4.tcp_rmem / tcp_wmem | TCP 缓冲区自动调优区间 | 8192 12582912 16777216 | 与上面两个 max 值配套生效 |
| net.ipv4.tcp_max_tw_buckets | TIME_WAIT 套接字上限 | 2000000 | 短连接高频场景,防止端口耗尽报错 |
| net.ipv4.tcp_max_orphans | 不属于任何进程的孤儿套接字上限 | 131072 | 应用异常退出较多时避免内存被孤儿连接占满 |
| net.ipv4.tcp_retries2 | TCP 重传次数(决定超时断开时间) | 7 | 默认值 15 会使故障连接挂起约 15-30 分钟,调低可快速失败 |
2.2 连接跟踪与桥接
| 参数 | 含义 | 推荐值 | 适用场景 |
|---|---|---|---|
| net.netfilter.nf_conntrack_max | conntrack 表容量 | 1000000 | iptables 模式 kube-proxy 必需;表满会报 nf_conntrack: table full, dropping packet |
| net.bridge.bridge-nf-call-iptables | 桥接二层流量送 iptables 处理 | 1 | 所有 K8s 节点必需,否则 Service/NetworkPolicy 规则不生效 |
| net.bridge.bridge-nf-call-ip6tables | 桥接 IPv6 流量送 ip6tables | 1 | 启用 IPv6 或双栈时必需 |
注意:nf_conntrack_max 调大后,建议同步调整哈希桶大小:
bash
echo "options nf_conntrack hashsize=262144" > /etc/modprobe.d/nf_conntrack.conf一般经验:hashsize = nf_conntrack_max / 4。
2.3 文件句柄与 inotify
| 参数 | 含义 | 推荐值 | 适用场景 |
|---|---|---|---|
| fs.file-max | 系统全局文件句柄上限 | 75756220 | 大节点、高密度 Pod;句柄耗尽报 too many open files |
| fs.inotify.max_user_watches | 单用户 inotify 监控条目数 | 1048576 | 容器运行时和日志采集 agent(Fluent Bit 等)需要监控大量文件 |
| fs.inotify.max_user_instances | 单用户 inotify 实例数 | 1280 | 多 Pod 同时使用 inotify 的场景 |
| fs.may_detach_mounts | 允许卸载仍有进程引用的挂载点 | 1 | K8s 官方推荐,避免 Pod 删除后挂载点残留 |
除了内核级 fs.file-max,还需确认进程级限制(容器运行时继承 systemd 配置):
bash
# /etc/systemd/system/containerd.service.d/limits.conf
[Service]
LimitNOFILE=10485762.4 内存管理
| 参数 | 含义 | 推荐值 | 适用场景 |
|---|---|---|---|
| vm.swappiness | 使用 swap 的倾向程度 | 0 | kubelet 官方要求关闭 swap;此参数兜底防误开启 |
| vm.dirty_background_ratio | 脏页占比达此值时后台异步回写 | 5 | 写密集型负载(日志、数据库类 Pod),避免 IO 尖峰 |
| vm.dirty_ratio | 脏页占比达此值时强制同步回写 | 10 | 配合上一参数,降低突发写时进程阻塞时间 |
| vm.max_map_count | 单进程 mmap 区域上限 | 262144 | Elasticsearch、OpenSearch 等强制要求 |
2.5 系统信号量
kernel.sem = 250 32000 32 1024 四个值依次为:
| 字段 | 含义 | 值 |
|---|---|---|
| SEMMSL | 每个信号量集合的最大信号量数 | 250 |
| SEMMNS | 系统级信号量总数 | 32000 |
| SEMOPM | 单次 semop 调用最大操作数 | 32 |
| SEMMNI | 信号量集合最大数量 | 1024 |
部分中间件(如 PostgreSQL、Oracle 类容器)对信号量有最低要求,默认值过低会导致启动失败。
三、持久化与生效
3.1 写入配置并加载
bash
# 写入独立配置文件,避免覆盖系统默认文件
cat > /etc/sysctl.d/99-kubernetes.conf <<'EOF'
# 此处粘贴第一节的完整参数清单
EOF
# 加载 br_netfilter 模块(bridge-nf-call-iptables 的前置条件)
modprobe br_netfilter
echo "br_netfilter" > /etc/modules-load.d/k8s.conf
# 使配置立即生效
sysctl --system3.2 验证
bash
# 单项检查
sysctl net.ipv4.ip_forward
sysctl net.netfilter.nf_conntrack_max
sysctl fs.file-max
# 批量核对所有已生效项
sysctl -a | grep -E "ip_forward|conntrack_max|somaxconn|file-max|swappiness|max_map_count"
# 检查 br_netfilter 模块
lsmod | grep br_netfilter3.3 内核参数调整时的节点维护流程
调整内核参数本身不需要重启即可生效(sysctl --system),但如需重启节点(如内核升级),务必先驱逐业务:
bash
# 驱逐节点上的 Pod 并封锁调度
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
# 维护完成后恢复
kubectl uncordon node-1注意事项
| 事项 | 说明 |
|---|---|
| conntrack 表满 | dmesg 出现 nf_conntrack: table full 即为表满,需调大 nf_conntrack_max 并同步调整 hashsize |
| swap | kubelet 要求关闭 swap(swapoff -a 并注释 /etc/fstab 中 swap 条目),vm.swappiness=0 只是兜底 |
| 参数冲突 | 多份 sysctl 配置文件按文件名排序加载,后加载覆盖先加载,建议统一放在 99-kubernetes.conf |
| 重启验证 | 首次配置后建议找一台节点重启验证,确认参数开机后仍生效 |
| 不要盲目调大 | tcp_max_tw_buckets、conntrack_max 等值会占用内核内存,按节点规格与业务规模评估 |