我在 k8s 集群上创建了 HPA,它应该在内存利用率达到 90% 时自动扩展。然而,它在没有达到目标百分比的情况下扩大了规模。我使用以下配置:
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
namespace: {{ .Values.namespace }}
name: {{ include "helm-generic.fullname" . }}
labels:
{{- include "helm-generic.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "helm-generic.fullname" . }}
minReplicas: 1
maxReplicas: 2
metrics:
- type: Resource
resource:
name: memory
targetAverageUtilization: 90
因此,对于此配置,它创建了 2 个 pod,即 maxReplicas 数量。如果我为 maxReplicas 添加 4 个,它将创建 3 个。
这是我从 kubectl 描述 hpa 得到的内容
$ kubectl describe hpa -n trunkline
Name: test-v1
Namespace: trunkline
Labels: app.kubernetes.io/instance=test-v1
app.kubernetes.io/managed-by=Helm
app.kubernetes.io/name=helm-generic
app.kubernetes.io/version=0.0.0
helm.sh/chart=helm-generic-0.1.3
Annotations: meta.helm.sh/release-name: test-v1
meta.helm.sh/release-namespace: trunkline
CreationTimestamp: Wed, 12 Oct 2022 17:36:54 +0300
Reference: Deployment/test-v1
Metrics: ( current / target )
**resource memory on pods (as a percentage of request): 59% (402806784) / 90%**
resource cpu on pods (as a percentage of request): 11% (60m) / 80%
Min replicas: 1
Max replicas: 2
Deployment pods: **2 current / 2** desired
Conditions:
Type Status Reason Message
---- ------ ------ -------
AbleToScale True ReadyForNewScale recommended size matches current size
ScalingActive True ValidMetricFound the HPA was able to successfully calculate a replica count from memory resource utilization (percentage of request)
ScalingLimited False DesiredWithinRange the desired count is within the acceptable range
Events: <none>
如您所见,pod 内存 % 为 59 ,目标为 90,我预计仅生成 1 个 pod。
最佳答案
水平 Pod 自动缩放器有 very specific formula用于计算目标副本数量:
desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
根据您显示的输出,currentMetricValue
为 59%,desiredMetricValue
为 90%。将其乘以 2 的 currentReplicas
,您将得到大约 1.3 个副本,四舍五入为 2。
此公式,尤其是 ceil()
向上取整行为,可能会使 HPA 缩小规模非常缓慢,尤其是在副本数量较少的情况下。
更广泛地说,Kubernetes 可观察内存的自动缩放可能不会按您预期的方式工作。大多数编程语言都是垃圾收集的(C、C++ 和 Rust 是最明显的异常(exception)),并且垃圾收集器通常倾向于分配一大块操作系统内存并重用它,而不是在以下情况下将其返回给操作系统:负载减少。如果你的 pod 从 Kubernetes 的角度来看达到了 90% 的内存,那么内存使用量可能永远不会减少。您可能需要根据不同的指标自动缩放,或者附加 Prometheus 等外部指标系统,以获取可以采取行动的更详细的内存管理器统计信息。
关于kubernetes - HPA 创建的 Pod 数量超出预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74057433/