如何利用kubernetes实现应用的水平扩展(HPA)

本文详细介绍了Kubernetes中的Horizontal Pod Autoscaling(HPA)功能,用于实现Pod的水平自动伸缩。HPA通过监控CPU使用率来决定Pod的数量,保证系统稳定运行并提高资源利用率。文章涵盖了HPA的工作流程、自动伸缩算法、依赖部署、服务测试、增压和减压测试等关键步骤,并讨论了其局限性和未来展望。
摘要由CSDN通过智能技术生成

云计算具有水平弹性的特性,这个是云计算区别于传统IT技术架构的主要特性。对于Kubernetes中的POD集群来说,HPA就是实现这种水平伸缩的控制器, 它能在当POD中业务负载上升的时候,创建新的POD来保证业务系统稳定运行,当POD中业务负载下降的时候,可以销毁POD来提高资源利用率。

HPA介绍

Horizontal Pod Autoscaling,简称HPA,是Kubernetes中实现POD水平自动伸缩的功能。为什么要水平而不叫垂直, 那是因为自动扩展主要分为两种:

  • 水平扩展(scale out),针对于实例数目的增减
  • 垂直扩展(scal up),即单个实例可以使用的资源的增减, 比如增加cpu和增大内存
    而HPA属于前者。它可以根据CPU使用率或应用自定义metrics自动扩展Pod数量(支持 replication controller、deployment 和 replica set)

架构介绍


获取metrics的两种方式:

  • Heapster: heapster提供metrics服务, 但是在v1(autoscaling/v1)版本中仅支持以CPU作为扩展度量指标, 而其他比如:内存, 网络流量, qps等目前处于beta阶段(autoscaling/v2beta1)
  • Cousom: 同样处于beta阶段(autoscaling/v2beta1), 但是涉及到自定义的REST API的开发, 复杂度会大一些, 并且当需要从自定义的监控中获取数据时,只能设置绝对值,无法设置使用率

工作流程:

  • 1.创建HPA资源,设定目标CPU使用率限额,以及最大、最小实例数, 一定要设置Pod的资源限制参数: request, 负责HPA不会工作。
  • 2.控制管理器每隔30s(可以通过–horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用情况
  • 3.然后与创建时设定的值和指标做对比(平均值之和/限额),求出目标调整的实例个数
  • 4.目标调整的实例数不能超过1中设定的最大、最小实例数,如果没有超过,则扩容;超过,则扩容至最大的实例个数
  • 重复2-4步

自动伸缩算法:
HPA Controller会通过调整副本数量使得CPU使用率尽量向期望值靠近,而且不是完全相等.另外,官方考虑到自动扩展的决策可能需要一段时间才会生效:例如当pod所需要的CPU负荷过大,从而在创建一个新pod的过程中,系统的CPU使用量可能会同样在有一个攀升的过程。所以,在每一次作出决策后的一段时间内,将不再进行扩展决策。对于扩容而言,这个时间段为3分钟,缩容为5分钟(可以通过--horizontal-pod-autoscaler-downscale-delay, --horizontal-pod-autoscaler-upscale-delay进行调整)。

  • HPA Controller中有一个tolerance(容忍力)的概念,它允许一定范围内的使用量的不稳定,现在默认为0.1,这也是出于维护系统稳定性的考虑。例如,设定HPA调度策略为cpu使用率高于50%触发扩容,那么只有当使用率大于55%或者小于45%才会触发伸缩活动,HPA会尽力把Pod的使用率控制在这个范围之间。
  • 具体的每次扩容或者缩容的多少Pod的算法为: Ceil(前采集到的使用率 / 用户自定义的使用率) * Pod数量)
  • 每次最大扩容pod数量不会超过当前副本数量的2倍

依赖部署

这是kuberntes整个系列的第四篇, 该篇依赖Heapster服务成功安装, 如果未安装请参考:

因为基于HeapsterHPA仅支持CPU为维度的自动伸缩, 因此写了个计算100位π的HTTP服务, 该程序已打包放于百度网盘下, 下载hpa-test-app.tar 导入然后推到自己私有仓库, 等待后续测试(放心该镜像仅有5M多点)
源代码如下:

package main

import (
    "fmt"
    "log"
    "net/http"
    "strconv"
    "strings"
)

func main() {
    http.HandleFunc("/", compPiHandler)
    log.Println("Server work at :8080 ...")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

func compPiHandler(w http.ResponseWriter, r *http.Request) {
    var (
        lenI int
        err  error
    )

    lenS := r.URL.Query().Get("length")
    if lenS != 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值