Kubernetes Horizontal Pod Autoscaler 如何计算多容器 Pod 的 CPU 利用率?
Posted
技术标签:
【中文标题】Kubernetes Horizontal Pod Autoscaler 如何计算多容器 Pod 的 CPU 利用率?【英文标题】:How does Kubernetes Horizontal Pod Autoscaler calculate CPU Utilization for Multi Container Pods? 【发布时间】:2020-01-16 16:53:18 【问题描述】:问题 1.) 给定一个多容器 pod 的场景,其中所有容器都有一个定义的 CPU 请求: Kubernetes Horizontal Pod Autoscaler 如何计算多容器 pod 的 CPU 利用率? 它是平均它们吗? ((((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 利用率 = 目标 #1,50m cpu req * X% HPA 目标 cpu 利用率 = 目标 #2。)问题 2。) 鉴于多容器 pod 的场景,其中 1 个容器具有已定义的 CPU 请求,而其他容器的 CPU 请求为空白: Kubernetes Horizontal Pod Autoscaler 如何计算多容器 pod 的 CPU 利用率? 它是否像您只有 1 个容器 pod 一样工作?
问题 3.) 问题 1 和 2 的答案是否会根据 HPA API 版本而变化? 我注意到 stable/nginx-ingress helm chart,chart 版本 1.10.2,为我部署了具有以下规范的 HPA:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
(我注意到 apiVersion: autoscaling/v2beta2 现在存在)
背景信息: 我最近遇到了一个问题,即在将 sidecar(第二个容器)添加到 nginx 入口控制器部署(通常是带有单个容器的 pod)之后,意外的疯狂扩展/在最小和最大 pod 之间不断来回切换。在我的例子中,它是一个 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):
最少 3 个副本(在滚动更新期间保留 HA) targetCPUUtilizationPercentage = 150%我突然想到,我的错误配置导致意外的疯狂扩展是由 2 个问题引起的:
-
我真的不明白当 pod 有多个容器时 HPA 是如何工作的
我不知道如何深入了解正在发生的事情的指标。
解决第一个问题:我集思广益,了解它在单容器场景中的工作原理(然后意识到我不知道多容器场景,所以我决定问这个问题)
这是我对当我有 1 个容器时 HPA(自动缩放/v1)如何工作的理解(暂时忽略上述部署规范中的第二个容器): 当所有 pod 的 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,显示 5 个副本的 cpu 使用率分别为 36m、34m、88m、36m、91m,因此 57m 电流 ~ 与 56m 电流相匹配)
现在它是一个基本的比例数学问题,允许求解目标静态值: (5% / 56m) = (100% / x m) --> x = 56 * 100 / 5 = 1120m 目标cpu (注意:此 HPA 与上述部署无关,这就是数字被关闭的原因。)
【问题讨论】:
实现细节可以看kubernetes.io/docs/tasks/run-application/…。 记录在案的实现细节仅描述了在 pod 级别发生的情况。我的问题是专门提出的,因为在容器级别(多容器 pod)发生的事情似乎没有记录。 【参考方案1】:基于***社区成员在其他case的回答
“HPA 将 pod cpu 利用率计算为 pod 中所有容器的总 cpu 使用率除以总请求。我认为在任何地方的文档中都没有指定,但相关代码是 here”
您已经获得了更多信息,上面的链接中有示例。
根据文档
Horizontal Pod Autoscaler 根据观察到的 CPU 利用率(或者,在 beta 支持下,在其他一些应用程序提供的指标上)自动扩展复制控制器、部署或副本集中的 pod 数量。
所以基本上:
apiVersion autoscaling/v1 HPA 基于 cpu。
apiVersion 自动缩放/v2beta2 基于cpu、内存、自定义指标。
更多信息here
【讨论】:
源代码链接是黄金链接。这有点愚蠢,你可以有 1GB req + 10mb req,但是当它平均使用 505mb 作为目标时......这正是我意外地疯狂缩放到最大值的原因。似乎如果第二个容器没有请求,它将被忽略/HPA 会将容器视为只有 1 个请求【参考方案2】:对于问题 2,如果我们查看 source code,我们可以看到它单独查看所有容器,如果容器没有请求则返回。
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
【讨论】:
以上是关于Kubernetes Horizontal Pod Autoscaler 如何计算多容器 Pod 的 CPU 利用率?的主要内容,如果未能解决你的问题,请参考以下文章
Kubernetes Pod Horizontal Autoscaler pod 和对象选择器字段是字符串吗?
Kubernetes Horizontal Pod Autoscaler 如何计算多容器 Pod 的 CPU 利用率?
难以使用外部指标配置 Horizontal Pod Autoscaler
HTML jQuery Horizontal Accordion