Ubuntu 交换分区与 Kubernetes 的配合
推荐做法与原因
- 在主流的 Kubernetes 部署中,节点应禁用 Swap,这是官方与社区的通行做法。原因在于:启用 Swap 会掩盖 OOM 压力、导致节点响应变慢甚至“卡死”,并且会干扰 kubelet 对内存压力的准确判断与驱逐策略,影响调度与稳定性。因此,Ubuntu 作为节点系统时,通常先关闭 Swap 再部署集群。
标准操作步骤
- 临时关闭并永久禁用 Swap
- 执行:
sudo swapoff -a
- 注释 fstab 中的 swap 行:
sudo sed -i '/ swap / s/^/#/' /etc/fstab
- 验证:
free -h 应显示 Swap 为 0B
- 完成其他节点前置(与 kubelet 启动相关)
- 加载内核模块:
sudo modprobe overlay && sudo modprobe br_netfilter
- 配置 sysctl:
net.bridge.bridge-nf-call-iptables=1、net.bridge.bridge-nf-call-ip6tables=1、net.ipv4.ip_forward=1,并 sudo sysctl --system
- 配置容器运行时与 kubelet 的 cgroup driver 为 systemd(保持一致),然后重启容器运行时与 kubelet
- 初始化或加入集群
- 使用
kubeadm init 或 kubeadm join 完成集群搭建;若未禁用 Swap,kubeadm 预检会报错并提示生产环境应关闭 Swap。
必须使用 Swap 时的受限方案
- 背景与限制
- 自 v1.22 起,Kubernetes 提供 NodeSwap 特性门控用于“有限地启用 Swap”,但默认仍为关闭;即便启用,也仅对 memory 生效,且要求节点启用 cgroup v2 的 memory 子系统。多数发行版默认仍是 cgroup v1,需要先迁移到 cgroup v2 后再评估该功能。
- 启用步骤概览
- 升级系统并启用 cgroup v2(GRUB 启动参数添加
systemd.unified_cgroup_hierarchy=1,重启后 mount | grep cgroup 应看到 unified 层级)
- 打开 kubelet 的 NodeSwap(示例):
--feature-gates=NodeSwap=true,并根据需要设置 --fail-swap-on=false(旧版本行为,新版本以特性门控为准)
- 按需配置驱逐阈值(如
--eviction-hard=memory.available<500Mi),避免系统失稳
- 注意:开启 Swap 后,kubelet 的 OOM 行为与调度信号会发生变化,节点可能出现较长 GC/换页停顿,生产环境需谨慎评估与压测。
不启用 Swap 时的稳定性替代方案
- 使用 Node Allocatable 为系统组件与内核预留资源,避免与业务 Pod 争抢内存
- 关键参数:
--kube-reserved、--system-reserved、--eviction-hard
- 可分配量计算:allocatable = NodeCapacity − kube-reserved − system-reserved − eviction-threshold
- 建议为关键系统切片设置 cgroup 并开启 QoS 级别限制,提升节点抗压与可观测性
- 配置合理的驱逐策略与阈值,结合 Metrics Server 做内存压力观测与 HPA 扩缩容
- 通过
kubectl top nodes/pods 与指标告警,提前扩容或降载,减少节点级 OOM 触发概率。