应用容器化改造后,不可避免地会面临这样一个问题:Kubernetes 集群的 Node 资源配置不足会导致 Pod 无法及时运行,购买过多的 Node 又会导致资源的闲置浪费。
那么如何利用 Kubernetes 的容器编排能力和云上资源的灵活性及规模化优势,来保证业务的高弹性、低成本?
本文主要探讨比心云平台如何利用阿里云容器服务 ACK,来构建应用弹性架构,进一步优化计算成本。
注意:文中的「Node」等同于节点。集群中的Node和集群中的节点,是一个意思。
弹性伸缩是根据业务需求和策略,经济地自动调整弹性计算资源的管理服务。
弹性伸缩可以分为两个维度:
两层的弹性组件与能力可以分开使用,也可以结合在一起使用,并且两者之间是通过调度层面的容量状态进行解耦。
Kubernetes 中共有三种不同的弹性伸缩策略:HPA(HorizontalPodAutoscaling)、 VPA(VerticalPodAutoscaling)与 CA(ClusterAutoscaler)。其中,HPA 和 VPA 的扩缩容对象是 Pod ,而 CA 的扩缩容对象是 Node 。
另外各大云厂商(例如阿里云等)还提供了 Virtual Node 组件,提供无服务器运行时环境。用户无需关心 Node 资源,只需针对 Pod 按量付费即可。适用于在线流量突增、CI/CD、大数据作业等场景。本文在介绍 Virtual Node 时会以阿里云为例。
HPA(Horizontal Pod Autoscaler)是 Kubernetes 的内置组件,也是最常用的 Pod 弹性方案。通过 HPA 可以自动调整 Workload 的副本数。HPA 自动伸缩特性使 Kubernetes 具有非常灵活的自适应能力,能够在用户设定内快速扩容多个 Pod 副本来应对业务负载的急剧飙升,也可以在业务负载变小的情况下根据实际情况适当缩容来节省计算资源给其他的服务,整个过程自动化无需人为干预,适合服务波动较大、服务数量多且需要频繁扩缩容的业务场景。
HPA 适用于 Deployment、StatefulSet 等实现 scale 接口的对象,不适用于无法扩缩的对象,例如 DaemonSet 资源。Kubernetes 内置有 HorizontalPodAutoscaler 资源,通常是对需要配置水平自动伸缩的 Workload 创建一个 HorizontalPodAutoscaler 资源,Workload 与 HorizontalPodAutoscaler 相对应 。
Pod 水平自动扩缩特性由 Kubernetes API 资源和控制器实现。资源利用指标决定控制器的行为,控制器会周期性的根据 Pod 资源利用情况调整服务 Pod 的副本数量,以使得工作负载的度量水平与用户所设定的目标值匹配。以 Deployment 和 CPU 使用率为例,其扩缩容流程如下图所示:
默认 HPA 只支持基于 CPU 和内存的自动伸缩,例如当 CPU 使用率超过阈值时就自动增加应用实例数,当 CPU 使用率又低于阈值时就自动减少实例数。
但是默认 HPA 驱动弹性的维度比较单一,并不能满足日常的运维需求。可以将 HPA 和开源的 Keda 结合使用,Keda 可以从事件、定时、自定义指标等维度来驱动弹性。
VPA(VerticalPodAutoscaling) 是社区开源组件,需要在 Kubernetes 集群上手动部署安装,VPA 提供垂直的 Pod 伸缩的功能。
VPA 会基于 Pod 的资源使用情况自动为 Pod 设置资源占用的限制,从而让集群将 Pod 调度到有足够资源的最佳节点上。VPA 也会保持最初容器定义中资源 request 和 limit 的占比。此外,VPA 可用于向用户推荐更合理的 Request,在保证容器有足够使用的资源的情况下,提升容器的资源利用率。
相较于 HPA,VPA 具有以下优势:
使用 VPA 有以下限制和注意事项:
HPA 和 VPA 都是调度层的弹性,解决了 Pod 的弹性伸缩。如果集群整体的资源容量不能满足集群调度容量时,HPA 和 VPA 弹出的 Pod 还是会处于 Pending 状态。这时就需要资源层的弹性伸缩。
在 Kubernetes 中,Node 自动水平伸缩是通过社区开源的 CA(ClusterAutoscaler) 组件实现的。社区 CA 支持设置多个伸缩组,支持设置扩容和缩容策略。各大云厂商在社区 CA 的基础上会加入一些特有的功能,例如支持