即使使用量低于阈值,Kubernetes 部署也不会缩减

Posted

技术标签:

【中文标题】即使使用量低于阈值,Kubernetes 部署也不会缩减【英文标题】:Kubernetes deployment not scaling down even though usage is below threshold 【发布时间】:2020-07-12 12:25:56 【问题描述】:

我很难理解我的水平 pod 自动缩放器发生了什么。

如果内存或 CPU 使用率超过 80%,我会尝试扩大我的部署。

这是我的 HPA 模板:

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: my-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-deployment
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 80
    - type: Resource
      resource:
        name: memory
        target:
          type: Utilization
          averageUtilization: 80

问题是,尽管使用率低于 80%,但它已经坐在 3 个副本上好几天了,我不明白为什么。

$ kubectl get hpa --all-namespaces

NAMESPACE        NAME             REFERENCE                  TARGETS            MINPODS   MAXPODS   REPLICAS   AGE
my-ns            my-hpa           Deployment/my-deployment   61%/80%, 14%/80%   2         10        3          2d15h

这是 top 命令的输出:

$ kubectl top pods

NAME                             CPU(cores)   MEMORY(bytes)   
my-deployment-86874588cc-chvxq   3m           146Mi           
my-deployment-86874588cc-gkbg9   5m           149Mi           
my-deployment-86874588cc-nwpll   7m           149Mi   

每个 pod 消耗大约 60% 的请求内存(因此它们低于 80% 的目标):

resources:
  requests:
    memory: "256Mi"
    cpu: "100m"
  limits:
    memory: "512Mi"
    cpu: "200m"

这是我的部署:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: my-deployment
  labels:
    app: my-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: ...
          imagePullPolicy: Always
          resources:
            requests:
              memory: "256Mi"
              cpu: "100m"
            limits:
              memory: "512Mi"
              cpu: "200m"
          livenessProbe:
            httpGet:
              path: /liveness
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 3
            timeoutSeconds: 3
          readinessProbe:
            httpGet:
              path: /readiness
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 3
            timeoutSeconds: 3
          ports:
            - containerPort: 3000
              protocol: TCP

我手动缩减到 2 个副本,它会立即无缘无故地恢复到 3 个:

Normal   SuccessfulRescale             28s (x4 over 66m)    horizontal-pod-autoscaler  New size: 3; reason:

有人知道发生了什么吗?

【问题讨论】:

您能描述一下您的部署吗?有没有可能手动设置 3 个副本? 可能是因为ceil(3 * (60/80))3,见kubernetes.io/docs/tasks/run-application/…。 @TonyStark 我手动缩小到 2 个副本,然后又恢复到 3 个。这很奇怪,因为 ceil(2 * (60/80))2 您能否提供更多信息(例如,将“部署”RD 导出为 yaml),例如 @UroshT。说? @TonyStark 我更新了我的问题 【参考方案1】:

https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#algorithm-details

根据您当前的数字,除非您的内存使用量下降到所需百分比的一半,否则它永远不会缩小。

即当前 cpu 和内存的利用率应达到 40%(在您的情况下)或以下

根据以下公式

desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
                = ceil[3 * (61/80)]
                = ceil[3 * (0.7625)]
                = ceil[2.2875]
desiredReplicas = 3

你可能会怀疑你的 cpu 低于 40% 为什么它没有降级。但 hpa 不会以这种方式工作。它总是会寻找更大的数字。

【讨论】:

花了我大约 3 分钟的时间来弄清楚 ceil 的事情,但在我弄清楚它的 ceiling 之后,我立刻明白了你的意思。谢谢。【参考方案2】:

我遇到了同样的问题,因为我和你一样使用 2 个指标 CPU 和内存。应用程序永远不会像 CPU 那样快速释放内存资源。 一旦我删除了内存资源,当利用率较低时,pod 就会缩小。

【讨论】:

以上是关于即使使用量低于阈值,Kubernetes 部署也不会缩减的主要内容,如果未能解决你的问题,请参考以下文章

PySpark 将低于计数阈值的值替换为值

计算超过和低于阈值的项目数

使用nagios监控交换机端口流量,对低于阈值的流量进行报警

使用 boto3 在 aws 中其 CPU 扩展策略低于特定阈值的所有自动扩展组的列表

seals部署kubernetes1.14.1

检测值已返回到低于阈值,然后允许更改值