几周前,我正在努力优化 Vertical Pod Autoscaler 的性能。我通过演示发现它应该有 5 到 10 分钟的时间,所以默认的 VPA 行为对我们来说太慢了。最终,我不得不修改它的源代码以在几分钟内动态更改 pod 的资源请求。
在本文中,我描述了 VPA 的工作原理以及优化其性能的方法,包括代码修改。
什么是 Vertical Pod Autoscaler?
Vertical Pod Autoscaler,VPA,使我们能够动态定义资源请求 。它观察 Pod 的 cpu 和内存利用率,并在运行时更新这些资源请求。
Vertical Pod Autoscaler 如何工作?
VPA 由以下三个部分组成。
admission-controller
recommender
updater
admission -controller 注册一个 admission webhook 来修改 pod 创建请求。
recommender 检查目标 pod 的资源使用情况,并估计推荐的资源请求,然后更新与目标 pod 关联的 VPA 对象。这个过程是周期性执行。
updater 检查 VPA 对象中记录的推荐资源请求,如果 目标pod 的当前 资源请求与推荐不匹配,则删除该 pod。
当 deployment 或 replicaset 的一个 pod 被 updater 删除时 , replicaset controller 会检测到 pod 数量不够,会尝试创建一个新的 pod。Pod 创建请求发送到 api-server,api-server 调用admission-controller注册的 webhook 。admission-controller 根据推荐的资源请求值修改 pod 创建请求。最后,使用适当的资源请求创建新的 pod。
更改周期性任务频率
admission-controller 在创建 pod 请求时同步工作,因此我们可以忽略 本文中的admission-controller 。它永远不会影响 VPA 的响应能力。
由于 recommender 推荐器 和 updater 更新器 定期工作,因此它们的频率很重要。这些可以通过 --recommender-interval 和 --updater-interval 选项进行修改。
recommender-deployment.yaml 您可以通过修改来更改这些选项 updater-deployment.yaml,如下所示:
Patch license: Apache-2.0 (same as original autoscaler)
https://github.com/kubernetes/autoscaler
diff --git a/vertical-pod-autoscaler/deploy/recommender-deployment.yaml b/vertical-pod-autoscaler/deploy/recommender-deployment.yaml
index f45d87127..739c35da6 100644
--- a/vertical-pod-autoscaler/deploy/recommender-deployment.yaml
+++ b/vertical-pod-autoscaler/deploy/recommender-deployment.yaml
@@ -38,3 +38,9 @@ spec:
ports:
- name: prometheus
containerPort: 8942
+ command:
+ - /recommender
+ - --v=4
+ - --stderrthreshold=info
+ - --prometheus-address=http://prometheus.monitoring.svc
+ - --recommender-interval=10s
diff --git a/vertical-pod-autoscaler/deploy/updater-deployment.yaml b/vertical-pod-autoscaler/deploy/updater-deployment.yaml
index a97478a8e..b367f1a04 100644
--- a/vertical-pod-autoscaler/deploy/updater-deployment.yaml
+++ b/vertical-pod-autoscaler/deploy/updater-deployment.yaml
@@ -43,3 +43,7 @@ spec:
ports:
- name: prometheus
containerPort: 8943
+ args:
+ - --v=4
+ - --stderrthreshold=info
+ - --updater-interval=10s
其他选项 --v 是定义 --stderrthreshold 的 --recommender-interval 默认选项 。
警告:--recommender-interval=10s 并且 --updater-interval=10s 对于正常用例来说太频繁了。不要将其复制并粘贴到您的真实集群中!
推荐算法
尽管 更新器 响应只能由 控制 --updater-interval,但对于 推荐器 ,我们需要进行更多修改。要想提高推荐器的响应性,就必须了解推荐算法。
recommender 定义了 pod 的 资源请求的下限和上限,updater 检查 pod 当前的资源请求是否在推荐范围内。所以问题是,如果 pod 的资源利用率变化很快,推荐系统会扩大这些限制。这种设计对于真实世界的用例来说是合理的,但对于我们的演示,我希望它们能够更快地做出反应。
推荐器 记录目标 pod 的资源利用历史,如果其波动性过高,则推荐范围会更广。您可以通过期减少波动的影响 --cpu-histogram-decay-half-life 。
Patch license: Apache-2.0 (same as original autoscaler)
https://github.com/kubernetes/autoscaler
diff --git a/vertical-pod-autoscaler/deploy/recommender-deployment.yaml b/vertical-pod-autoscaler/deploy/recommender-deployment.yaml
index 739c35da6..09113a02e 100644
--- a/vertical-pod-autoscaler/deploy/recommender-deployment.yaml
+++ b/vertical-pod-autoscaler/deploy/recommender-deployment.yaml
@@ -44,3 +44,4 @@ spec:
- --stderrthreshold=info
- --prometheus-address=http://prometheus.monitoring.svc
- --recommender-interval=10s
+ - --cpu-histogram-decay-half-life=10s
警告:--cpu-histogram-decay-half-life=10s 对于正常用例来说太快了。不要将其复制并粘贴到您的真实集群中!
使推荐范围更宽的另一个因素是资源利用历史的长度。
根据 CreatePodResourceRecommender 实施,它结合了以下估算量。
percentileEstimator : 返回实际资源利用率
marginEstimator :建议 增加 安全阈值
confidenceMultiplier : 使关于资源利用历史长度的推荐范围更广
confidenceMultiplier 使用以下公式使推荐范围更宽。
如果我们只有 3 分钟长的历史记录,并且 MeasuredResourceUtilization = 0.6 cpu,则 confidenceMultiplier 计算如下:
在这种情况下,因为 pod resources.requests.cpu 在 [0.27 cpu, 289 cpu] 范围内,所以什么也没有发生。换句话说,updater 认为 pod 的请求资源在建议范围内,所以到目前为止我无事可做。
修改推荐算法
不幸的是,决定推荐范围范围的参数是硬编码的。所以我决定修改代码。
我们的要求是……
建议限制不应受历史长度的影响
建议应反映测量的资源利用率
能够在几分钟内将实际资源使用量控制在建议范围之外
我创建了反映这些要求的新设计如下。
这种新设计可以按如下方式实现。
Patch license: Apache-2.0 (same as original autoscaler)
https://github.com/kubernetes/autoscaler
diff --git a/vertical-pod-autoscaler/pkg/recommender/logic/recommender.go b/vertical-pod-autoscaler/pkg/recommender/logic/recommender.go
index bc2320cca..cdce617fd 100644
--- a/vertical-pod-autoscaler/pkg/recommender/logic/recommender.go
+++ b/vertical-pod-autoscaler/pkg/recommender/logic/recommender.go
@@ -111,9 +111,9 @@ func CreatePodResourceRecommender() PodResourceRecommender {
lowerBoundEstimator := NewPercentileEstimator(lowerBoundCPUPercentile, lowerBoundMemoryPeaksPercentile)
upperBoundEstimator := NewPercentileEstimator(upperBoundCPUPercentile, upperBoundMemoryPeaksPercentile)
- targetEstimator = WithMargin(*safetyMarginFraction, targetEstimator)
- lowerBoundEstimator = WithMargin(*safetyMarginFraction, lowerBoundEstimator)
- upperBoundEstimator = WithMargin(*safetyMarginFraction, upperBoundEstimator)
+ targetEstimator = WithMargin(0, targetEstimator)
+ lowerBoundEstimator = WithMargin(-0.3, lowerBoundEstimator)
+ upperBoundEstimator = WithMargin(0.3, upperBoundEstimator)
// Apply confidence multiplier to the upper bound estimator. This means
// that the updater will be less eager to evict pods with short history
@@ -126,7 +126,7 @@ func CreatePodResourceRecommender() PodResourceRecommender {
// 12h history : *3 (force pod eviction if the request is > 3 * upper bound)
// 24h history : *2
// 1 week history : *1.14
- upperBoundEstimator = WithConfidenceMultiplier(1.0, 1.0, upperBoundEstimator)
+ // upperBoundEstimator = WithConfidenceMultiplier(1.0, 1.0, upperBoundEstimator)
// Apply confidence multiplier to the lower bound estimator. This means
// that the updater will be less eager to evict pods with short history
@@ -140,7 +140,7 @@ func CreatePodResourceRecommender() PodResourceRecommender {
// 5m history : *0.6 (force pod eviction if the request is < 0.6 * lower bound)
// 30m history : *0.9
// 60m history : *0.95
- lowerBoundEstimator = WithConfidenceMultiplier(0.001, -2.0, lowerBoundEstimator)
+ // lowerBoundEstimator = WithConfidenceMultiplier(0.001, -2.0, lowerBoundEstimator)
return &podResourceRecommender{
targetEstimator,
结论
Vertical Pod Autoscaler 设计为不会满足过于频繁地修改资源请求;
修改频率的参数是硬编码的,为了在一分钟内对资源利用率的变化做出反应,您必须修改源代码。
参考
https://github.com/kubernetes/autoscaler/tree/vertical-pod-autoscaler-0.11.0/vertical-pod-autoscaler
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/
推荐
随手关注或者”在看“,诚挚感谢!