排查正常节点的“未就绪”状态问题

本文讨论在节点处于一段时间正常状态后,Azure Kubernetes 服务 (AKS) 群集节点的状态更改为“未就绪” 的方案。 本文概述了特定原因,并提供可能的解决方案。

先决条件

症状

运行) 的所有服务的群集节点的状态 (意外更改为 “未就绪”。 若要查看节点的状态,请运行以下 kubectl describe 命令:

kubectl describe nodes

原因

kubelet 已停止发布其“就绪”状态。

检查命令的 kubectl describe nodes 输出以查找 “条件” 字段以及 “容量”和“可分配” 块。 这些字段的内容是否按预期显示? (例如,在“条件”字段中,属性是否message包含“kubelet 正在发布就绪状态”字符串?) 在这种情况下,如果具有直接安全外壳 (SSH) 访问节点,检查最近的事件以了解错误。 在 /var/log/messages 文件中查找。 或者,通过运行以下 shell 命令生成 kubelet 和容器守护程序日志文件:

journalctl --directory=. --unit=kubelet > kubelet.log
journalctl --directory=. --unit=docker > docker.log

运行这些命令后,请检查守护程序日志文件,了解有关错误的详细信息。

步骤 1:检查是否有任何网络级更改

如果所有群集节点都回归到“未就绪”状态,检查网络级别是否发生了任何更改。 网络级更改的示例包括以下项:

  • 域名系统 (DNS) 更改
  • 防火墙端口更改
  • (NSG) 添加了网络安全组

如果网络级别发生更改,请进行必要的更正。 修复问题后,停止并重启正在运行的节点。 如果节点在这些修复后保持正常状态,则可以安全地跳过剩余的步骤。

步骤 2:停止并重启节点

如果只有少数节点回归到 “未就绪” 状态,只需停止并重启节点。 单独此操作可能会使节点返回到正常状态。 然后,检查Azure Kubernetes 服务 诊断概述以确定是否存在任何问题,例如以下问题:

  • 节点故障
  • 源网络地址转换 (SNAT) 失败
  • 每秒节点输入/输出操作数 (IOPS) 性能问题
  • Other issues

如果诊断未发现任何根本问题,可以放心地跳过其余步骤。

步骤 3:修复公共 AKS API 群集的 SNAT 问题

AKS 是否诊断发现任何 SNAT 问题? 如果是这样,请根据需要执行以下操作中的一些操作:

  • 检查连接是否长时间保持空闲状态,并依赖默认空闲超时来释放其端口。 如果连接表现出此行为,则可能需要减少默认超时 30 分钟。

  • 确定应用程序如何创建出站连接。 例如,它是否使用代码评审或数据包捕获?

  • 确定此活动是表示预期行为,还是显示应用程序行为不正常。 使用 Azure Monitor 中的指标和日志来证实你的发现结果。 例如,可以使用“失败”类别作为 SNAT Connections指标。

  • 评估是否遵循适当的模式。

  • 评估是否应通过使用额外的出站 IP 地址和更多分配的出站端口来缓解 SNAT 端口耗尽。 有关详细信息,请参阅 缩放托管出站公共 IP 的数量配置分配的出站端口

步骤 4:修复 IOPS 性能问题

如果 AKS 诊断发现降低 IOPS 性能的问题,请根据需要执行以下操作:

  • 若要增加虚拟机 (VM) 规模集的 IOPS,请通过部署新的节点池来更改磁盘大小。

  • 增加节点 SKU 大小以获取更多内存和 CPU 处理功能。

  • 请考虑使用 临时 OS

  • 限制 Pod 的 CPU 和内存使用量。 这些限制有助于防止节点 CPU 消耗和内存不足的情况。

  • 使用计划拓扑方法添加更多节点并在节点之间分配负载。 有关详细信息,请参阅 Pod 拓扑分布约束

步骤 5:修复线程问题

Kubernetes 组件(如 kubelets 和 容器化运行时 )严重依赖于线程,它们会定期生成新线程。 如果新线程的分配不成功,此失败可能会影响服务就绪情况,如下所示:

  • 节点状态更改为 “未就绪”,但它已由修正程序重新启动,并且能够恢复。

  • /var/log/messages/var/log/syslog 日志文件中,以下错误条目反复出现:

    pthread_create失败:资源因各种进程暂时不可用

    引用的进程包括容器化和可能为 kubelet。

  • 将失败项写入日志文件后,pthread_create节点状态会很快更改为“未就绪”。

进程 ID (PID) 表示线程。 Pod 可以使用的默认 PID 数可能取决于操作系统。 但是,默认数字至少为 32,768。 在大多数情况下,此数量足以满足 PID 要求。 对于更高的 PID 资源,是否有任何已知的应用程序要求? 如果没有,则即使将 8 倍增加到 262,144 个 PID 也不足以容纳高资源应用程序。

相反,请确定有问题的应用程序,然后采取适当的操作。 请考虑其他选项,例如增加 VM 大小或升级 AKS。 这些操作可以暂时缓解问题,但不能保证问题不会再次出现。

若要监视每个控制组的线程计数 (cgroup) 并打印前八个 cgroup,请运行以下 shell 命令:

watch 'ps -e -w -o "thcount,cgname" --no-headers | awk "{a[\$2] += \$1} END{for (i in a) print a[i], i}" | sort --numeric-sort --reverse | head --lines=8'

有关详细信息,请参阅 进程 ID 限制和预留

Kubernetes 提供了两种在节点级别管理 PID 耗尽的方法:

  1. 使用 --pod-max-pids 参数配置 kubelet 中的 Pod 上允许的最大 PID 数。 此配置在每个 pids.max Pod 的 cgroup 中设置设置。 还可以使用 --system-reserved--kube-reserved 参数分别配置系统和 kubelet 限制。

  2. 配置基于 PID 的逐出。

注意

默认情况下,不会设置这两种方法。 此外,目前不能使用 AKS 节点池的节点配置来配置任一方法。

步骤 6:使用更高的服务层级

可以通过使用更高的服务层来确保 AKS API 服务器具有高可用性。 有关详细信息,请参阅 Azure Kubernetes 服务 (AKS) 运行时间 SLA

更多信息