Kubernetes - 如何调试失败的调度“0 个节点可用”

asp*_*yct 5 kubernetes

我经常发现自己尝试启动一个新的 Pod,却收到一条错误消息,指出没有可用的节点。就像是:

0/9 nodes are available: 1 node(s) had no available volume zone, 8 node(s) didn't match node selector.

当我收到这些消息时,我总是不知所措。我应该如何调试它?

小智 4

首先我的建议是看一下Kubernetes Scheduler Component

\n\n
\n

主控上的组件,用于监视未分配节点的新创建的 Pod,并选择一个节点供它们运行。[-]\n 调度决策时考虑的因素包括个人和集体资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据局部性、工作负载间干扰和截止日期。

\n\n

调度程序会监视新创建的未分配节点的 Pod。对于调度程序发现的每个 Pod,调度程序负责找到该 Pod 运行的最佳节点\n 对于每个新创建的 pod 或其他未调度的 pod,kube-scheduler 会选择一个最佳节点供它们运行。然而,Pod 中的每个容器对资源都有不同的要求,每个 Pod 也有不同的要求。因此,需要根据具体的调度需求对现有节点进行过滤。

\n
\n\n

根据文档:

\n\n
\n

在集群中,满足Pod调度要求的节点称为可行节点。如果没有合适的节点,则 Pod 将保持未调度状态,直到调度程序能够放置它。

\n
\n\n

kube-scheduler 通过两步操作为 pod 选择节点。基于默认策略的标准 kube-scheduler标准 kube-scheduler :

\n\n
    \n
  • 过滤
  • \n
  • 评分
  • \n
\n\n

查看这两项政策,您可以找到更多决策制定的信息。例如:

\n\n
for scoring at the stage CalculateAntiAffinityPriorityMap This policy helps implement pod anti-affinity.\n
Run Code Online (Sandbox Code Playgroud)\n\n

您可以在下面找到基于影响Kubernetes 调度程序决策的快速回顾

\n\n
    \n
  • 节点名称:通过将 node\xe2\x80\x99s 主机名添加到 Pod 定义的 .spec.nodeName 参数,可以强制此 Pod 在该特定节点上运行。调度程序使用的任何选择算法都将被忽略。这种方法是最不推荐的。
  • \n
  • 节点选择器:通过在节点上放置有意义的标签,Pod 可以使用 nodeSelector 参数来指定一个或多个键值标签映射,这些标签映射必须存在于目标节点上才能被选择运行该 Pod。更推荐这种方法,因为它增加了很多灵活性并建立了松散耦合的节点-pod 关系。
  • \n
  • 节点亲和力:在选择应考虑哪个节点来调度特定 Pod 时,此方法增加了更大的灵活性。使用节点亲和性,Pod 可能严格要求调度到具有特定标签的节点上。它还可以通过影响调度程序给予特定节点更多的权重来表达对特定节点的某种程度的偏好。
  • \n
  • Pod 亲和力和反亲和性:当 Pod 必须与同一节点上的其他 Pod 共存(或不共存)时,可以使用此方法。Pod 关联性允许 Pod 要求将其部署在运行具有特定标签的 Pod 的节点上。类似地,Pod 可能会强制调度程序不将其放置在具有特定标签的 Pod 的节点上。
  • \n
  • 污染和容忍:在此方法中,您无需决定 Pod 被调度到哪些节点,而是决定哪些节点根本不应接受任何 Pod 或仅接受选定的 Pod。通过污染节点,您\xe2\x80\x99指示调度程序不要考虑将此节点用于任何 Pod 放置,除非 Pod 容忍污染。容忍度由键、值和污点的影响组成。使用运算符,您可以决定整个污点是否必须与成功 Pod 放置的容忍度相匹配,或者仅数据的子集必须匹配。
  • \n
\n\n

根据k8s 文档

\n\n

1 . NodeName是节点选择约束的最简单形式,但由于其局限性,通常不使用它。\n使用 nodeName 选择节点的一些限制是:

\n\n
    \n
  • 如果指定的节点不存在,pod将不会运行,并且在某些情况下可能会被自动删除。
  • \n
  • 如果指定节点没有资源来容纳 Pod,则 Pod 将失败,其原因将指示原因,例如 OutOfmemory 或 OutOfcpu。\n云环境中的节点名称并不总是可预测或稳定的。
  • \n
\n\n

2 . 亲和力/反亲和力功能极大地扩展了您可以表达的约束类型。主要增强功能是:\n- 语言更具表现力(不仅仅是 \xe2\x80\x9cAND 精确匹配 \xe2\x80\x9d)\n- 您可以指示规则为 \xe2\x80\x9csoft\xe2 \x80\x9d/\xe2\x80\x9cpreference\xe2\x80\x9d 而不是硬性要求,因此如果调度程序可以 \xe2\x80\x99t 满足它,则 pod 仍会被调度\n-你可以约束节点(或其他拓扑域)上运行的其他 pod 上的标签,而不是节点本身的标签,这允许关于哪些 pod 可以和不能共置的规则

\n\n

亲和性特征包括两种类型的亲和性,节点亲和性pod间亲和性/反亲和性。节点亲和力类似于现有的nodeSelector(但具有上面列出的前两个优点),

\n\n
\n

目前有两种类型的 Pod 亲和性和反亲和性,称为requiredDuringSchedulingIgnoredDuringExecutionPreferredDuringSchedulingIgnoredDuringExecution,分别表示 \xe2\x80\x9chard\xe2\x80\x9d 与 \xe2\x80\x9csoft\xe2\x80\x9d 要求。

\n
\n\n

希望这有帮助。

\n\n

其他资源:

\n\n\n