k8s优化之关闭swap

在 Kubernetes(k8s)集群中,默认要求关闭 Swap,主要原因涉及 调度准确性、性能稳定性容器隔离性。以下是具体影响和底层逻辑分析:


1. Kubernetes 官方明确要求禁用 Swap

  • 官方文档说明
    Kubernetes 从设计上假设节点资源(CPU、内存)是完全可分配的,而 Swap 的引入会打破这一假设,导致调度器(kube-scheduler)无法准确评估 Pod 的资源使用情况。

2. Swap 对 Kubernetes 性能的具体影响

(1) 调度器(kube-scheduler)失效

  • 问题
    Kubernetes 调度器依赖节点的 Allocatable Memory(可分配内存)决定 Pod 的放置。如果开启 Swap:
    • 节点可能过度承诺(Overcommit)内存资源,导致多个 Pod 被调度到同一节点。
    • 当物理内存不足时,Swap 的 I/O 延迟会拖慢所有 Pod,而调度器无法预判这种性能波动。
  • 表现
    Pod 看似调度成功,但实际运行时因 Swap 频繁读写导致性能骤降。

(2) 容器隔离性被破坏

  • 问题
    Linux Cgroups 的内存限制(memory.limit_in_bytes默认仅限制物理内存,不限制 Swap 使用。
    • 若开启 Swap,容器可能通过 Swap 绕过内存限制,导致:
      • 一个贪婪的 Pod 占用大量 Swap,挤占其他 Pod 的磁盘 I/O 带宽。
      • 节点整体性能下降(磁盘 I/O 成为瓶颈)。
  • 表现
    docker statskubectl top pod 显示内存未超限,但节点响应缓慢。

(3) 性能波动不可预测

  • 问题
    Swap 的触发依赖内核的内存回收机制(如 kswapd),而 Kubernetes 的 QoS(服务质量等级)无法与之协调。
    • Burstable Pod 可能因 Swap 频繁换入换出(si/so)导致延迟飙升。
    • Guaranteed Pod 的 SLA 无法保证(预期独占的资源被 Swap 间接共享)。
  • 表现
    应用延迟(P99)出现长尾现象,尤其影响数据库、实时计算等场景。

3. 为什么老师会说“Swap 影响性能”?

这里的“性能”是广义的,包括:

  • 调度性能:kube-scheduler 无法正确决策。
  • 运行时性能:Swap I/O 延迟导致应用响应变慢。
  • 集群稳定性:OOM Killer 可能误杀关键容器。

4. 如何正确关闭 Swap?

(1) 永久禁用 Swap

# 临时关闭
sudo swapoff -a

# 永久关闭(注释 /etc/fstab 中的 Swap 行)
sudo sed -i '/swap/s/^/#/' /etc/fstab

# 验证
free -h  # Swap 行应全为 0

(2) 修改 kubelet 参数(旧版本)

  • Kubernetes 1.22+ 已默认禁止 Swap,但旧版本需显式配置:
    # 在 /etc/default/kubelet 中添加
    KUBELET_EXTRA_ARGS="--fail-swap-on=false"
    

5. 特殊情况:如果必须使用 Swap?

极少场景下(如开发测试环境内存不足),可通过以下方式妥协:

(1) 调整内核参数

# 降低 Swappiness,减少 Swap 使用倾向
echo 1 | sudo tee /proc/sys/vm/swappiness

(2) 使用 Kubernetes Alpha 特性(不推荐生产)

  • Kubernetes 1.22+ 实验性支持 Swap,但需手动启用:
    # kubelet 配置
    featureGates:
      NodeSwap: true
    

总结:Swap 在 K8s 中的影响

维度 开启 Swap 的后果 关闭 Swap 的收益
调度准确性 资源过度承诺,Pod 调度失效 调度器精确判断节点可用资源
性能稳定性 磁盘 I/O 瓶颈,延迟波动大 避免不可预测的 Swap I/O 延迟
隔离性 容器可能通过 Swap 突破内存限制 Cgroups 限制严格生效
运维复杂度 需监控 Swap 使用,调试困难 问题排查更直接(OOM 即内存不足)

结论

  • 生产环境:严格禁用 Swap,确保 Kubernetes 的调度和资源隔离机制正常工作。
  • 开发环境:如果内存不足,建议扩容节点而非依赖 Swap。

对limits/request的影响

Pod 中的 limitsrequests 资源请求/限制会直接受到 Swap 的影响,因为 Kubernetes 的资源管理模型默认基于物理内存(RAM),而 Swap 的引入会打破这一假设。以下是具体影响和机制分析:


1. requestslimits 的本质

  • requests

    • 调度器(kube-scheduler)根据 requests 判断节点是否有足够的物理内存可供分配。
    • 例如:requests: memory: 1Gi 表示调度器会选择一个至少有 1Gi 物理内存可用的节点。
  • limits

    • 通过 Linux Cgroups 限制容器实际使用的物理内存(默认不限制 Swap)。
    • 例如:limits: memory: 2Gi 表示容器最多占用 2Gi 物理内存,超限时会被 OOM Killer 终止。

2. Swap 如何破坏 requestslimits 的语义?

(1) 对 requests 的影响

  • 问题
    调度器认为节点有 Allocatable Memory = 物理内存 - kube-reserved - system-reserved,但开启 Swap 后:

    • 节点可能过度承诺(Overcommit)资源(即调度器分配的总 requests 超过物理内存)。
    • 实际运行时,依赖 Swap 的 Pod 性能会因磁盘 I/O 严重下降,但调度器无法预判。
  • 示例

    • 节点物理内存:4Gi,Swap:2Gi。
    • 两个 Pod 的 requests.memory: 3Gi 可能被调度到该节点(因调度器只检查物理内存)。
    • 运行时,两个 Pod 争抢物理内存,触发 Swap,导致性能暴跌。

(2) 对 limits 的影响

  • 问题
    Cgroups 的 memory.limit_in_bytes 默认仅限制物理内存,不限制 Swap 使用。

    • 容器可能通过 Swap 绕过内存限制,导致:
      • 一个 Pod 占用大量 Swap,挤占其他 Pod 的磁盘 I/O 带宽。
      • 节点整体性能下降(尽管 kubectl top pod 显示内存未超限)。
  • 示例

    • 容器设置 limits.memory: 1Gi,但通过 Swap 实际占用 1.5Gi(物理内存 + Swap)。
    • 其他 Pod 因磁盘 I/O 被抢占而延迟飙升。

3. Kubernetes 的应对机制

(1) 默认行为(禁用 Swap)

  • 调度器:严格基于物理内存判断 requests
  • kubelet:强制 limits 限制物理内存,超限时触发 OOM Killer。

(2) 启用 Swap 的实验性支持(Kubernetes 1.22+)

  • 需显式配置 featureGates: NodeSwap: true,并设置 --fail-swap-on=false
  • 行为变化
    • limits 会包含 Swap 使用量(需配合 memory.swap.max Cgroups v2 参数)。
    • 仍不推荐生产环境使用,原因:
      • 调度器仍无法感知 Swap,requests 的语义被破坏。
      • 性能波动难以控制。

4. 用户需要做什么?

(1) 确保节点禁用 Swap

# 检查 Swap
free -h               # 确认 Swap 行全为 0
sudo swapoff -a       # 临时关闭
sudo sed -i '/swap/s/^/#/' /etc/fstab  # 永久关闭

(2) 合理设置 requestslimits

  • requests
    • 应接近容器的常态内存需求(调度依据)。
  • limits
    • 设置硬性上限(略高于 requests 以容忍峰值)。
    • 示例:
      resources:
        requests:
          memory: "1Gi"
        limits:
          memory: "1.5Gi"
      

(3) 监控与调优

  • 使用 kubectl top pod/node 监控实际内存使用。
  • 若需避免 OOM,可调整容器内存需求或扩容节点。

总结:Swap 对资源请求/限制的影响

场景 禁用 Swap(默认) 启用 Swap
requests 调度依据 严格依赖物理内存 物理内存 + Swap,调度器无法感知
limits 限制范围 仅限制物理内存 可能绕过限制(依赖 Cgroups 配置)
性能表现 稳定,OOM 可预测 不可控的 Swap I/O 延迟
推荐场景 生产环境(K8s 设计初衷) 仅开发测试(非关键负载)

结论

  • 务必禁用 Swap 以保障 requestslimits 的语义准确性。
  • 若节点内存不足,应通过垂直扩容(增大节点内存)水平扩容(增加节点数)解决,而非依赖 Swap。
posted on 2025-06-17 08:22  Leo-Yide  阅读(232)  评论(0)    收藏  举报