横向伸缩 Node

Node 的横向伸缩只在 云平台上部署 Kubernetes 集群时才会有效,并且需要云服务运营商提供相关的功能支持,具体可以参考各云服务运营商的使用文档。该特性由 Cluster Autoscaler 执行。

Cluster Autoscaler 会在 Node 资源不足,无法调度某 Pod 到已有 Node 时,自动部署新 Node;也会在 Node 长时间使用率低下的情况下,下线 Node。

请求 Node

当一个 Pod 创建后,Scheduler 组件无法调度到任何一个已有 Node 时,Cluster Autoscaler 会注意到这类 Pod,并请求云服务运营商启动新的 Node(在请求之前还会检查新申请的 Node 能否容纳 Pod)。

通常在云服务运营商中,它们会为 Node 分组,例如分为华东区、华南区等(可以通过 Node 的标签划分),因此 Cluster Autoscaler 在申请新 Node 时存在一个 Node 分组选择的问题(该调度算法是可配置的,最差的情况为随机选择):

  1. 无适合指定 Pod 的 Node 分组:不会请求 Node;

  2. 存在一个适合指定 Pod 的 Node 分组:在该 Node 分组中申请一个新的 Node;

  3. 存在多个适合指定 Pod 的 Node 分组:根据调度算法选择最适合的 Node 分组,并在其中申请一个新的 Node;

下线 Node

当 Node 中的资源利用率不足时,Cluster Autoscaler 也会下线这些节点。判断是否下线节点需要同时满足下面两种情况:

  1. Cluster Autoscaler 通过监控这些 Node 中的相关资源的 请求量 来实现这一特性,如果某个 Node 上的所有 Pod 请求的各类资源的 请求量 都不足 50%,则该 Node 被认为不再需要;

  2. Cluster Autoscaler 会检查是否有 系统 Pod(不包括 DaemonSet 管理的系统 Pod)、非托管 Pod(没有托管给任何控制器的 Pod)、有本地存储的 Pod,如果有的话,则不能下线;否则,可以下线;

🗣 手动标记 Node 为不可调度、排空 Node

  1. 标记节点为 不可调度,但对其上的 Pod 不做任何事:kubectl cordon <node>

  2. 标记节点为 不可调度,并且疏散其上所有 Pod:kubectl drain <node>

限制 Node 下线时对已有服务的干扰

在上面的介绍中,Cluster Autoscaler 在 Node 满足某些情况下,会疏散其上的 Pod 并下线 Node,但是假设存在这种情况:某个 Service 后端的所有 Pod 都存在该 Node 上,那么下线该 Node 会导致该 Service 的访问请求全部失败。

为了解决上面这种情况,我们可以通过 指定下线操作时需要保持的最少的 Pod 数量,该特性由 PodDisruptionBudget 资源实现。

下面创建一个案例,创建一个名为 kubia-pdb 的 PodDisruptionBudget 资源对象,该对象用于控制包含 app=kubia 标签的 Pod 需要维持的最少数量为 3

kubectl create pdb kubia-pdb --selector=app=kubia --min-available=3

--min-available 也可以用百分比而非绝对数来表示

从 1.7 版本开始,也支持了 --max-available 字段

在上面这个案例中,假设共有 4 个带有 app=kubia 标签的 Pod,并且被 ReplicaSet 接管,那么每次只会疏散一个 Pod,并等待 ReplicaSet 将其换到其他 Node 后才会继续疏散下一个。

Last updated

Was this helpful?