K8S弹性伸缩之Nodes 资源扩容(CA,Ansible)

弹性伸缩

1 传统弹性伸缩的困境

从传统意义上,弹性伸缩主要解决的问题是容量规划与实际负载的矛盾。

蓝色水位线表示集群资源容量随着负载的增加不断扩容,红色曲线表示集群资源实际负载变化。

弹性伸缩就是要解决当实际负载增大,而集群资源容量没来得及反应的问题。

1、Kubernetes中弹性伸缩存在的问题

常规的做法是给集群资源预留保障集群可用,通常20%左右。这种方式看似没什么问题,但放到Kubernetes中,就会发现如下2个问题。

  1. 机器规格不统一造成机器利用率百分比碎片化

    在一个Kubernetes集群中,通常不只包含一种规格的机器,假设集群中存在4C8G与16C32G两种规格的机器,对于10%的资源预留,这两种规格代表的意义是完全不同的。

特别是在缩容的场景下,为了保证缩容后集群稳定性,我们一般会一个节点一个节点从集群中摘除,那么如何判断节点是否可以摘除其利用率百分比就是重要的指标。此时如果大规格机器有较低的利用率被判断缩容,那么很有可能会造成节点缩容后,容器重新调度后的争抢。如果优先缩容小规格机器,则可能造成缩容后资源的大量冗余。

  1. 机器利用率不单纯依靠宿主机计算

    在大部分生产环境中,资源利用率都不会保持一个高的水位,但从调度来讲,调度应该保持一个比较高的水位,这样才能保障集群稳定性,又不过多浪费资源。

2、弹性伸缩概念的延伸

不是所有的业务都存在峰值流量,越来越细分的业务形态带来更多成本节省和可用性之间的跳转。

  1. 在线负载型:微服务、网站、API
  2. 离线任务型:离线计算、机器学习
  3. 定时任务型:定时批量计算

不同类型的负载对于弹性伸缩的要求有所不同,在线负载对弹出时间敏感,离线任务对价格敏感,定时任务对调度敏感。

2.2 kubernetes 弹性伸缩布局

在 Kubernetes 的生态中,在多个维度、多个层次提供了不同的组件来满足不同的伸缩场景。

有三种弹性伸缩:

  • CA(Cluster Autoscaler):Node级别自动扩/缩容

    cluster-autoscaler组件

  • HPA(Horizontal Pod Autoscaler):Pod个数自动扩/缩容

  • VPA(Vertical Pod Autoscaler):Pod配置自动扩/缩容,主要是CPU、内存

    addon-resizer组件

如果在云上建议 HPA 结合 cluster-autoscaler 的方式进行集群的弹性伸缩管理。

2.3 Node 自动扩容/缩容

1、Cluster AutoScaler

扩容:Cluster AutoScaler 定期检测是否有充足的资源来调度新创建的 Pod,当资源不足时会调用 Cloud Provider 创建新的 Node。

缩容:Cluster AutoScaler 也会定期监测 Node 的资源使用情况,当一个 Node 长时间资源利用率都很低时(低于 50%)自动将其所在虚拟机从云服务商中删除。此时,原来的 Pod 会自动调度到其他 Node 上面。

支持的云提供商:

2、Ansible扩容Node

自动化流程:

  1. 触发新增Node
  2. 调用Ansible脚本部署组件
  3. 检查服务是否可用
  4. 调用API将新Node加入集群或者启用Node自动加入
  5. 观察新Node状态
  6. 完成Node扩容,接收新Pod

扩容

# cat hosts 
...
[newnode]
192.168.31.71 node_name=k8s-node3
# ansible-playbook -i hosts add-node.yml -k

缩容

如果你想从Kubernetes集群中删除节点,正确流程如下:

1、获取节点列表

kubectl get node

2、设置不可调度

kubectl cordon $node_name

3、驱逐节点上的Pod

kubectl drain $node_name --ignore-daemonsets

4、移除节点

该节点上已经没有任何资源了,可以直接移除节点:

kubectl delete node $node_name

这样,我们平滑移除了一个 k8s 节点。