优化 Kubernetes Vertical Pod Autoscaler 响应能力

几周前,我正在努力优化 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 对象。这个过程是周期性执行。

784a4c081cbdaf97d270b6afee05b23b.png

updater 检查 VPA 对象中记录的推荐资源请求,如果 目标pod 的当前 资源请求与推荐不匹配,则删除该 pod。

510011b46c9ea8cc895a5e31f4ef377f.png

当 deployment 或 replicaset 的一个 pod 被 updater 删除时 , replicaset controller 会检测到 pod 数量不够,会尝试创建一个新的 pod。Pod 创建请求发送到 api-server,api-server 调用admission-controller注册的 webhook  。admission-controller 根据推荐的资源请求值修改 pod 创建请求。最后,使用适当的资源请求创建新的 pod。

e3ae39afe8f6f0eca8d85faae8b6f78d.png

更改周期性任务频率

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 使用以下公式使推荐范围更宽。

95f434bc72072a9682f4ea85cf04962f.png

如果我们只有 3 分钟长的历史记录,并且 MeasuredResourceUtilization = 0.6 cpu,则 confidenceMultiplier 计算如下:

a32f1555aa9b36c36ca997f0c48c10d7.png

在这种情况下,因为 pod resources.requests.cpu 在 [0.27 cpu, 289 cpu] 范围内,所以什么也没有发生。换句话说,updater 认为 pod 的请求资源在建议范围内,所以到目前为止我无事可做。

修改推荐算法

不幸的是,决定推荐范围范围的参数是硬编码的。所以我决定修改代码。

我们的要求是……

  • 建议限制不应受历史长度的影响

  • 建议应反映测量的资源利用率

  • 能够在几分钟内将实际资源使用量控制在建议范围之外

我创建了反映这些要求的新设计如下。

6079341d27052b8bfa257d56504d2181.png

这种新设计可以按如下方式实现。

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 设计为不会满足过于频繁地修改资源请求;

  • 修改频率的参数是硬编码的,为了在一分钟内对资源利用率的变化做出反应,您必须修改源代码。

参考

  1. https://github.com/kubernetes/autoscaler/tree/vertical-pod-autoscaler-0.11.0/vertical-pod-autoscaler

  2. https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/

  3. https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/

5a1e0ce09fadb92dc5bfdd07ae48f64e.png

推荐

A Big Picture of Kubernetes

Kubernetes入门培训(内含PPT)


随手关注或者”在看“,诚挚感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值