Kubernetes Horizo​​ntal Pod Autoscaler 如何计算 CPU Multi Container Pods 的利用率?

How does Kubernetes Horizontal Pod Autoscaler calculate CPU Utilization for Multi Container Pods?


问题1.)
给定一个多容器 pod 的场景,其中所有容器都有一个已定义的 CPU 请求:
Kubernetes Horizo​​ntal Pod Autoscaler 如何计算 CPU 多容器 pods 的利用率?
它平均它们吗? (((500m cpu req + 50m cpu req) /2) * X% HPA 目标 cpu 利用率
它会添加它们吗? ((500m cpu req + 50m cpu req) * X% HPA 目标 cpu 利用率
它会单独跟踪它们吗? (500m cpu req * X% HPA 目标 cpu utilization = target #1, 50m cpu req * X% HPA target cpu utilization = target #2.)

问题2.)
给定多容器 pod 的场景,其中 1 个容器有一个已定义的 CPU 请求和一个针对其他容器的空白 CPU 请求:
Kubernetes Horizo​​ntal Pod Autoscaler 如何计算 CPU Multi Container pods 的利用率?

它是否像只有 1 个容器 pod 一样工作?

问题3.)
问题 1 和 2 的答案会根据 HPA API 版本而改变吗?
我注意到 stable/nginx-ingress helm 图表,图表版本 1.10.2 , 为我部署一个具有这些规格的 HPA:

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler

(我注意到 apiVersion:autoscaling/v2beta2 现在存在)

背景信息:
我最近遇到了一个问题,即在将 sidecar(第二个容器)添加到 nginx 入口控制器部署(通常是一个带有一个容器)。在我的例子中,它是一个 oauth2 代理,尽管我认为 istio sidecar 容器的人可能 运行 也一直遇到这类问题。

apiVersion: apps/v1
kind: Deployment
spec:
  replicas: 3
  template:
    spec:
      containers:
        - name: nginx-ingress-controller #(primary-container)
          resources:
            requests:
              cpu: 500m    #baseline light load usage in my env 
              memory: 2Gi  #according to kubectl top pods
            limits:
              memory: 8Gi  #(oom kill pod if this high, because somethings wrong)
        - name: oauth2-proxy #(newly-added-2nd-sidecar-container)
          resources: 
            requests:
              cpu: 50m
              memory: 50Mi
            limits:
              memory: 4Gi

我有一个 HPA(apiVersion:autoscaling/v1):

我突然想到我的错误配置导致意外的疯狂扩展是由 2 个问题引起的:

  1. 我实际上不明白当 pod 有多个容器时 HPA 是如何工作的
  2. 我不知道如何深入挖掘以获取正在发生的事情的指标。

解决第一个问题:我头脑风暴了我对它在单容器场景下如何工作的理解(然后意识到我不知道多容器场景所以我决定问这个问题)

这是我对 HPA (autoscaling/v1) 在有 1 个容器时如何工作的理解(暂时忽略上述部署规范中的第二个容器):
当所有 pods 的 CPU 平均利用率从我正常预期的 500m 或更少负载转移到 750m(150% x 500m 请求)时,HPA 会生成更多副本


为了解决第二个问题:我发现了如何深入了解基于具体数值的指标与基于相对百分比的指标,以帮助弄清楚幕后发生的事情:

bash# kubectl describe horizontalpodautoscaler nginx-ingress-controller -n=ingress | grep Metrics: -A 1
Metrics:                                               ( current / target )
  resource cpu on pods  (as a percentage of request):  5% (56m) / 100%

(注意:kubectl top pods -n=ingress,显示 cpu 5 个副本的使用情况为 36m、34m、88m、36m、91m,因此 57m 当前与 56m 匹配当前)

此外,现在它是一个基本比例数学问题,可以求解目标静态值:
(5% / 56m) = (100% / x m) --> x = 56 * 100 / 5 = 1120m 目标 cpu
(注意:此 HPA 与上述部署无关,这就是数字关闭的原因。)

基于 Whosebug 社区成员在其他

中的回答

"HPA calculates pod cpu utilization as total cpu usage of all containers in pod divided by total request. I don't think that's specified in docs anywhere, but the relevant code is here"

以上link中的示例,您获得了更多信息。


基于文档

Horizontal Pod Autoscaler 根据观察到的 CPU 利用率(或者, 支持 beta,自动扩展复制控制器、部署或副本集中 pods 的数量在其他一些应用程序提供的指标上)。

所以基本上:

apiVersion autoscaling/v1 HPA 基于 cpu.

apiVersion autoscaling/v2beta2 基于 cpu、内存、自定义指标.

更多信息here

对于问题 2,如果我们查看 source code,我们可以看到它单独查看所有容器,returns 如果容器没有请求。

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
}