群集升级到 Kubernetes 1.25 后,Pod 中出现内存饱和

本文介绍如何修复由于内存饱和或内存不足(OOM)错误而停止工作的 Pod,这些错误会在将 Microsoft Azure Kubernetes 服务 (AKS) 群集升级到 Kubernetes 1.25 后发生。x.

现象

发生以下一个或多个问题:

  • 节点上的内存压力

  • 与升级前应用的内存使用量相比,应用的内存使用量增加了

  • 节点上的 CPU 限制

  • Pod 失败,因为 OOM 错误

在以下环境中运行的应用中可能会出现性能下降:

注意

出现性能下降的环境列表不是一个全面的列表。 可能有其他环境遇到内存饱和或 OOM 问题。

解决方案

注意

如果您只遇到内存使用量增加的现象,且没有症状部分中提到的其他症状,则无需执行任何操作。

从 Kubernetes 1.25 版本开始, cgroup 版本 2 API 已正式发布(正式发布)。 AKS 现在使用 Ubuntu Linux 版本 22.04。 默认情况下,版本 22.04 使用 cgroup 版本 2 API。 若要确保 cgroup 版本 2 API 可用于其他环境以防止内存饱和问题,请遵循以下指南:

  • 如果运行 Java 应用程序,请升级到支持 cgroup 版本 2 的 Java 版本,并按照容器化 Java 应用程序中的指南进行操作。 你可能能够在修复已向后移植的某些版本中更新基本映像。 使用本机支持 cgroup 版本 2 的版本或框架。 对于 Azure 客户,Microsoft正式支持 Eclipse Temurin 二进制文件(Java 8)和 Microsoft OpenJDK 二进制文件(Java 11+)的生成。

  • 同样,如果使用 .NET,请升级到 .NET 版本 5.0 或更高版本。

  • 如果您在 Pod 上看到更高的驱逐率,请 对 Pod 使用更高的限制和请求

  • cgroup v2 使用与 v1 不同的 API cgroup 。 如果有任何应用程序直接访问 cgroup 文件系统,请将其更新为支持 cgroup v2 的更高版本。 例如:

    • 第三方监视和安全代理

      某些监视和安全代理依赖于 cgroup 文件系统。 将这些代理更新为支持 cgroup v2 的版本。

    • Java 应用程序

      使用完全支持 cgroup v2 的版本:

      • OpenJDK/HotSpot: jdk8u37211.0.1615和更高版本。
      • IBM Semeru Runtimes: 8.0.382.011.0.20.017.0.8.0和更高版本。
      • IBM Java: 8.0.8.6 和更高版本。
    • uber-go/automaxprocs
      如果使用包 uber-go/automaxprocs ,请确保版本为 v1.5.1 或更高版本。

  • 另一种临时解决方案是使用 DaemonSet 还原 cgroup 节点上的版本。 有关详细信息,请参阅 “还原为 cgroup v1 DaemonSet”。

    重要

    • 谨慎使用 DaemonSet。 在应用于生产环境之前,请在较低的环境中对其进行测试,以确保兼容性并避免中断。
    • 默认情况下,DaemonSet 适用于群集中的所有节点,并重新启动它们以实现 cgroup 更改。
    • 若要控制 DaemonSet 的应用方式,请将 a nodeSelector 配置为面向特定节点。

状态

Microsoft 正在与 Kubernetes 社区合作解决此问题。 在 Azure/AKS 问题 #3443 中跟踪进度。

作为解决方案的一部分,计划是根据修复的结果调整驱逐阈值或更新 资源预留

参考文献

第三方信息免责声明

本文中提到的第三方产品由 Microsoft 以外的其他公司提供。 Microsoft 对这些产品的性能和可靠性不作任何明示或默示担保。

第三方联系人免责声明

Microsoft 会提供第三方联系信息来帮助你查找有关本主题的其他信息。 此联系信息可能会更改,恕不另行通知。 Microsoft 不保证第三方联系信息的准确性。

联系我们寻求帮助

如果你有任何疑问或需要帮助,请创建支持请求联系 Azure 社区支持。 你还可以将产品反馈提交到 Azure 反馈社区