kubernetes hpa问题

https://qingwave.github.io/k8s-hpa-enchance/#hpa-resource%E7%B1%BB%E5%9E%8B%E4%B8%8D%E8%B6%B3

1.默认HPA提供了Resource类型,通过CPU/MEM使用率指标(由metrics-server提供原始指标)来扩缩应用。在Resource类型中,使用率计算是通过request而不是limit。

通常在Paas平台中会对资源进行超配,limit即用户请求资源,request即实际分配资源,如果按照request来计算使用率(会超过100%)是不符合预期的。相关issue见72811,目前还存在争论。可以修改源码,或者使用自定义指标来代替。源码如下

 

复制代码
// 获取Pod resource request
func calculatePodRequests(pods []*v1.Pod, resource v1.ResourceName) (map[string]int64, error) {
    requests := make(map[string]int64, len(pods))
    for _, pod := range pods {
        podSum := int64(0)
        for _, container := range pod.Spec.Containers {
            if containerRequest, ok := container.Resources.Requests[resource]; ok {
                podSum += containerRequest.MilliValue()
            } else {
                return nil, fmt.Errorf("missing request for %s", resource)
            }
        }
        requests[pod.Name] = podSum
    }
    return requests, nil
}
// 计算使用率
func GetResourceUtilizationRatio(metrics PodMetricsInfo, requests map[string]int64, targetUtilization int32) (utilizationRatio float64, currentUtilization int32, rawAverageValue int64, err error) {
    metricsTotal := int64(0)
    requestsTotal := int64(0)
    numEntries := 0

    for podName, metric := range metrics {
        request, hasRequest := requests[podName]
        if !hasRequest {
            // we check for missing requests elsewhere, so assuming missing requests == extraneous metrics
            continue
        }

        metricsTotal += metric.Value
        requestsTotal += request
        numEntries++
    }


    currentUtilization = int32((metricsTotal * 100) / requestsTotal)

    return float64(currentUtilization) / float64(targetUtilization), currentUtilization, metricsTotal / int64(numEntries), nil
}
复制代码

 2.多容器多pod使用问题

计算出所有container的资源使用量再比总的申请量,对于单容器Pod这没影响。但对于多容器Pod,比如Pod包含多个容器con1、con2(request都为1cpu),con1使用率10%,con2使用率100%,HPA目标使用率60%,按照目前方式得到使用率为55%不会进行扩容,但实际con2已经达到资源瓶颈,势必会影响服务质量。当前系统中,多容器Pod通常都是1个主容器与多个sidecar,依赖主容器的指标更合适点。

好在1.20版本中已经支持了ContainerResource可以配置基于某个容器的资源使用率来进行扩缩,如果是之前的版本建议使用自定义指标替换。

对于自定义指标用户需要实现custom.metrics.k8s.ioexternal.metrics.k8s.io,目前已经有部分开源实现见custom-metrics-api。另外,hpa核心的扩缩算法根据当前指标和期望指标来计算扩缩比例,并不适合所有场景,只适用于线性增长的指标。watermarkpodautoscaler提供了更灵活的扩缩算法,比如平均值、水位线等,可以作为参考。

posted @   潇潇暮鱼鱼  阅读(185)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示