免责声明:该项目处于测试阶段 - API 可能会发生变化。
Watermark Pod Autoscaler (WPA) 控制器是扩展 Horizontal Pod Autoscaler (HPA) 的自定义控制器。
Watermark Pod Autoscaler 控制器是上游 Horizontal Pod Autoscaler 控制器的替代控制器。
如果您想自动缩放某些应用程序,但是:
例如
apiVersion : datadoghq.com/v1alpha1
kind : WatermarkPodAutoscaler
[...]
spec :
algorithm : absolute
[...]
有两个选项可以计算所需的副本数量:
控制器将使用来自外部average
value from the external metrics provider
/ current number of replicas
,并将其与水印进行比较。建议的副本数量是value from the external metrics provider
/ watermark
值(低或高取决于当前值)。
如果您使用不依赖于副本数量的指标,则average
算法非常适合。通常,ELB 收到的请求数量可以表明我们想要有多少个 Web 服务器,因为我们知道单个 Web 服务器应该处理n
rq/s。添加副本不会增加或减少负载均衡器收到的请求数。
absolute
默认值是absolute
。应使用平均指标。建议的副本数计算为current number of replicas
* value from the external metrics provider
/ watermark
的值。
absolute
算法是默认算法,因为它代表最常见的用例。例如,如果您希望应用程序运行在 CPU 的 60% 到 80% 之间,而avg:cpu.usage
为 85%,则需要进行扩展。该指标必须与副本数量相关。
注意:在上游控制器中,仅使用math.Ceil
函数对建议的副本数进行舍入。
这意味着,如果阈值为 10,则外部指标提供程序的利用率需要达到 8.999,才能缩减一个副本。但是,利用率为 10.001 将使您扩展一个副本。
如果该值低于下水位线,WPA 控制器将使用math.Floor
。这确保了对称行为。与其他缩放选项相结合,可以更好地控制何时缩小规模。
要使用 Watermark Pod Autoscaler,请将其部署在 Kubernetes 集群中:
下载 Watermark Pod Autoscaler 项目 zip 文件。源代码可以在DataDog/watermarkpodautoscaler
中找到。
解压缩项目,然后进入./watermarkpodautoscaler
文件夹。
定义您的命名空间和 Watermark Pod Autoscaler 控制器:
DD_NAMESPACE= " datadog "
DD_NAMEWPA= " wpacontroller "
创建命名空间:
kubectl create ns $DD_NAMESPACE
使用 Helm 安装 Watermark Pod Autoscaler 控制器:
helm install $DD_NAMEWPA -n $DD_NAMESPACE ./chart/watermarkpodautoscaler
WatermarkPodAutoscaler 控制器附带一个 kubectl 插件,提供一组帮助实用程序。有关专用文档页面的更多信息:docs/kubectl-plugin.md
在与目标部署相同的命名空间中创建 WPA。
Datadog Cluster Agent 将拾取创建/更新/删除事件。它解析 WPA 规范以提取从 Datadog 获取的指标和范围。
在此示例中,我们使用以下规格配置:
apiVersion : datadoghq.com/v1alpha1
kind : WatermarkPodAutoscaler
metadata :
name : example-watermarkpodautoscaler
spec :
downscaleForbiddenWindowSeconds : 60
downscaleDelayBelowWatermarkSeconds : 300
upscaleForbiddenWindowSeconds : 30
upscaleDelayAboveWatermarkSeconds : 30
scaleDownLimitFactor : 30
scaleUpLimitFactor : 50
minReplicas : 4
maxReplicas : 9
scaleTargetRef :
kind : " Deployment "
name : " some_app "
apiVersion : " apps/v1 "
metrics :
- external :
highWatermark : 400m
lowWatermark : 150m
metricName : custom.request_duration.max
metricSelector :
matchLabels :
kubernetes_cluster : mycluster
service : billing
short_image : billing-app
type : External
tolerance : " 0.01 "
支持External
和Resource
度量类型。 WPA 控制器使用与 HPA 相同的格式。更多信息请点击这里。
从水印开始,在边界( watermarkpodautoscaler.wpa_controller_value
和watermarkpodautoscaler.wpa_controller_high_watermark
watermarkpodautoscaler.wpa_controller_low_watermark
之间从紫色 Datadog 收集的指标值( watermarkpodautoscaler.wpa_controller_value )将指示控制器不要触发缩放事件。它们被指定为Quantities
,因此您可以使用m | "" | k | M | G | T | P | E
轻松表示您要使用的值。
我们可以使用指标watermarkpodautoscaler.wpa_controller_restricted_scaling{reason:within_bounds}
来验证它确实受到限制。注意:该指标被乘以 1000,以便更明确地表明在此期间控制器不会触发任何缩放事件。
第二组配置选项与部署的扩展速度有关,由scaleDownLimitFactor
和scaleUpLimitFactor
控制。这些是 0 到 100 之间的整数。它们分别表示在给定当前副本数量的情况下缩小和放大的最大比率。
在这种情况下,如果我们有 10 个副本,建议副本数为 14(有关建议的更多详细信息,请参阅算法部分), scaleUpFactor
为 30 (%),则副本数上限为 13 个。
在下图中,我们可以看到由指标watermarkpodautoscaler.wpa_controller_replicas_scaling_proposal
表示的建议副本数(紫色)与当前副本数相比过高。这将触发升级上限逻辑,可以使用指标watermarkpodautoscaler.wpa_controller_restricted_scaling{reason:upscale_capping}
进行监控(注意:与上面相同,指标被相乘以使其更明确)。因此,副本的有效数量watermarkpodautoscaler.wpa_controller_replicas_scaling_effective
effective 将根据scaleUpLimitFactor
进行扩展。
在这个类似的示例中,我们避免过度缩减规模,并且可以使用同一组指标来保证仅缩减合理数量的副本。
值得注意的是,我们总是做出保守的扩展决策。
scaleUpLimitFactor
为 29%:如果我们有 10 个副本,建议为 13 个,我们将升级到 12 个。scaleDownLimitFactor
为29%时:如果我们有10个副本并且建议为7,我们将缩小到8。minReplicas
和maxReplicas
优先。请参阅优先级部分。最后,最后一个可用选项是downscaleForbiddenWindowSeconds
和upscaleForbiddenWindowSeconds
。这些分别表示缩放事件之后在缩小和放大之前等待的时间(以秒为单位)。我们只保留最后一次缩放事件,并且不会将upscaleForbiddenWindowSeconds
与上次仅放大的时间进行比较。
在下面的示例中,我们可以看到,如果我们处于冷却期,则建议的副本数将被忽略。缩减冷却时间可以使用watermarkpodautoscaler.wpa_controller_transition_countdown{transition:downscale}
进行可视化,并在下图中以黄色表示。我们可以看到它明显高于图表中橙色的高档冷却时间( transition:upscale
)。一旦我们被建议扩展,我们只会在适当的冷却窗口结束时进行扩展。这将重置两个倒计时。
为了避免突发缩放,您可以使用以下功能: downscaleDelayBelowWatermarkSeconds
和/或upscaleDelayAboveWatermarkSeconds
。这些选项指定为整数。在配置的持续时间内,指标必须保持在其各自的水位之上或之下。您可以跟踪 WPA 状态还剩多少时间:
- lastTransitionTime: "2022-11-15T02:02:09Z"
message: Allow downscaling if the value stays under the Watermark
reason: Value below Low Watermark
status: "False"
type: BelowLowWatermark
或者在控制器的日志中:
{"level":"info","ts":1668481092517.446,"logger":"controllers.WatermarkPodAutoscaler","msg":"Will not scale: value has not been out of bounds for long enough","watermarkpodautoscaler":"datadog/example-watermarkpodautoscaler","wpa_name":"example-watermarkpodautoscaler","wpa_namespace":"datadog","time_left":3209}
注意:如果您使用具有此功能的多个指标,则使用指标的OR
来考虑以上/以下条件。
例如,假设您有一个 60 秒的upscaleDelay
,其中包含两个指标:M1 和 M2。如果 M1 保持在高水位线以上 40 秒[t0; t40]
,并且 M2 高于其高水位线 30 秒,在最后 10 秒内与 M1 重叠, [t30; t60]
,这验证了upscaleDelay
条件并允许放大事件。
当我们检索外部指标的值时,我们首先将其与highWatermark
+ tolerance
之和以及lowWatermark
- tolerance
差进行比较。如果超出范围,我们会计算建议的副本数量。然后,我们将此值与当前副本数进行比较,以根据minReplicas
和maxReplicas
潜在限制建议的副本数。最后,我们看看是否允许在给定downscaleForbiddenWindowSeconds
和upscaleForbiddenWindowSeconds
的情况下进行缩放。
为了更精细地控制可缩放目标的条件,您可以使用以下功能:
minAvailableReplicaPercentage
:指示控制器自动缩放目标所需可用副本的最小百分比。例如,如果设置为 50 并且目标后面的 pod 少于一半处于可用状态,则控制器将不会缩放目标。
readinessDelaySeconds
:指定在扩展决策中考虑之前副本需要运行的时间。
如果满足所有条件,则仅当dryRun
标志未设置为true
时,控制器才会将scaleTargetRef
中的目标对象缩放到建议的副本数。它将通过记录来表明这一点:
{ "level" : " info " , "ts" : 1566327479.866722 , "logger" : " wpa_controller " , "msg" : " DryRun mode: scaling change was inhibited currentReplicas:8 desiredReplicas:12 " }
集群代理针对 WPA 资源运行通知程序,与 HPA 类似,在创建/更新/删除时将解析规范以从 Datadog 查询指标。
默认情况下,群集代理不运行 WPA 侦听器。要在集群代理中启用 WPA,请设置环境变量DD_EXTERNAL_METRICS_PROVIDER_WPA_CONTROLLER=true
并更新分配给集群代理服务帐户的 ClusterRole 以有权访问 WatermarkPodAutoscaler 对象:
[...]
- apiGroups : ["datadoghq.com"]
resources :
- watermarkpodautoscalers
verbs :
- get
- list
- watch
[...]
注意:要使用 datadog helm 图表在集群代理中启用 WPA,请将clusterAgent.metricsProvider.wpaController
设置为true
。 ClusterRole 将自动更新。
应用这些更改并创建 WPA 对象后,如果您在 Datadog Cluster Agent pod 中执行并运行agent status
您将能够看到有关已解析的自动缩放器规范的更多具体详细信息(无论是水平还是水平)水印 Pod 自动缩放器)。
* watermark pod autoscaler: default/example2-watermarkpodautoscaler
- name : example2-watermarkpodautoscaler
- namespace : default
- type : watermark
- uid : ff09b7d8-d99b-11e9-a8c1-42010a8001c4
Metric name : sinus
Labels :
- foo : bar
Value : 75.1297378540039
Timestamp : 15688259400
Valid : true
* horizontal pod autoscaler: default/nginxext
- name : nginxext
- namespace : default
- type : horizontal
- uid : 61ef3f6e-af32-11e9-a8c1-42010a8001c4
Metric name : docker.mem.rss
Labels :
- cluster-location : us-central1-a
- cluster-name : charly
Value : 263888700952
Timestamp : 15688259400
Valid : true
除了上面提到的指标之外,这些日志还可以帮助您更好地了解 WPA 的正常运行。
每 15 秒,我们从 Datadog 检索规范的metrics
部分中列出的指标。
{ "level" : " info " , "ts" : 1668484420515.7678 , "logger" : " controllers.WatermarkPodAutoscaler " , "msg" : " Metrics from the External Metrics Provider " , "watermarkpodautoscaler" : " datadog/example-watermarkpodautoscaler " , "wpa_name" : " example-watermarkpodautoscaler " , "wpa_namespace" : " datadog " , "metrics" :[ 33959 ]}
{ "level" : " info " , "ts" : 1668484420515.8203 , "logger" : " controllers.WatermarkPodAutoscaler " , "msg" : " Value is below lowMark " , "watermarkpodautoscaler" : " datadog/example-watermarkpodautoscaler " , "wpa_name" : " example-watermarkpodautoscaler " , "wpa_namespace" : " datadog " , "usage" : " 33959m " , "replicaCount" : 7 , "currentReadyReplicas" : 8 , "tolerance (%)" : 1 , "adjustedLM" : 34650 , "adjustedUsage" : 33959 }
{ "level" : " info " , "ts" : 1668484420515.8906 , "logger" : " controllers.WatermarkPodAutoscaler " , "msg" : " Proposing replicas " , "watermarkpodautoscaler" : " datadog/example-watermarkpodautoscaler " , "wpa_name" : " example-watermarkpodautoscaler " , "wpa_namespace" : " datadog " , "proposedReplicas" : 7 , "metricName" : " datadogmetric@datadog:example-watermarkpodautoscaler-utilization-metric{map[kube_container_name:my-container service:my-target]} " , "reference" : " Deployment/datadog/example-watermarkpodautoscaler " , "metric timestamp" : " Tue, 15 Nov 2022 03:53:20 UTC " }
{ "level" : " info " , "ts" : 1668484420515.9324 , "logger" : " controllers.WatermarkPodAutoscaler " , "msg" : " Normalized Desired replicas " , "watermarkpodautoscaler" : " datadog/example-watermarkpodautoscaler " , "wpa_name" : " example-watermarkpodautoscaler " , "wpa_namespace" : " datadog " , "desiredReplicas" : 7 }
{ "level" : " info " , "ts" : 1668484420515.946 , "logger" : " controllers.WatermarkPodAutoscaler " , "msg" : " Cooldown status " , "watermarkpodautoscaler" : " datadog/example-watermarkpodautoscaler " , "wpa_name" : " example-watermarkpodautoscaler " , "wpa_namespace" : " datadog " , "backoffUp" : false , "backoffDown" : false , "desiredReplicas" : 7 , "currentReplicas" : 8 }
{ "level" : " info " , "ts" : 1668484420515.9563 , "logger" : " controllers.WatermarkPodAutoscaler " , "msg" : " Will not scale: value has not been out of bounds for long enough " , "watermarkpodautoscaler" : " datadog/example-watermarkpodautoscaler " , "wpa_name" : " example-watermarkpodautoscaler " , "wpa_namespace" : " datadog " , "time_left" : 2335 }
此处,目标部署中当前看到的副本数量为 6。然后,我们看到从外部指标提供程序检索到的原始值,并将其与高水位线和低水位线进行比较。根据比较结果,我们打印建议的副本数量。在本例中,它是五个。
如果想直接查询External Metrics Provider,可以使用以下命令:
kubectl get --raw " /apis/external.metrics.k8s.io/v1beta1/namespaces// | jq ."
您也可以通过添加?labelSelector=key%3Dvalue
来选择添加标签选择器。如果我们想在这种情况下检索我们的指标,我们可以使用:
kubectl get --raw " /apis/external.metrics.k8s.io/v1beta1/namespaces// | jq .?labelSelector=key%3Dvalue%2Cotherkey%3Dothervalue%2Cshort_image%3Dimage "
如果您看到如下日志:
{ "level" : " info " , "ts" : 1566397216.8918724 , "logger" : " wpa_controller " , "msg" : " failed to compute desired number of replicas based on listed metrics for Deployment/datadog/propjoe-green: failed to get external metric dd.propjoe.request_duration.max: unable to get external metric datadog/propjoe-green/&LabelSelector{MatchLabels:map[string]string{fooa: bar,},MatchExpressions:[],}: no metrics returned from external metrics API " }
然后您可以验证外部指标提供商确实无法提供该指标。这可能是由于标签中的拼写错误,或者无法从 Datadog 获取指标(这可能是由于各种因素造成的:太稀疏、API 关闭、达到速率限制等)。您可以查看外部指标提供程序日志以进行进一步调查。
然后我们验证缩放速度上限和冷却时间窗口。在缩放上限的情况下,您会看到类似以下内容:
{ "level" : " info " , "ts" : 1566327268.8839815 , "logger" : " wpa_controller " , "msg" : " Upscaling rate higher than limit of 50.0% up to 9 replicas. Capping the maximum upscale to 9 replicas " }
{ "level" : " info " , "ts" : 1566327268.884001 , "logger" : " wpa_controller " , "msg" : " Returning 9 replicas, condition: ScaleUpLimit reason the desired replica count is increasing faster than the maximum scale rate " }
{ "level" : " info " , "ts" : 1566327479.8845513 , "logger" : " wpa_controller " , "msg" : " -> after normalization: 9 " }
然后我们考虑冷却时间。您将拥有指示上次缩放事件发生时间以及禁止下一次缩放事件的时间的日志,直到:
{ "level" : " info " , "ts" : 1566327479.8845847 , "logger" : " wpa_controller " , "msg" : " Too early to downscale. Last scale was at 2019-08-20 18:57:44 +0000 UTC, next downscale will be at 2019-08-20 18:58:44 +0000 UTC, last metrics timestamp: 2019-08-20 18:57:59 +0000 UTC " }
{ "level" : " info " , "ts" : 1566327479.8846018 , "logger" : " wpa_controller " , "msg" : " Too early to upscale. Last scale was at 2019-08-20 18:57:44 +0000 UTC, next upscale will be at 2019-08-20 18:58:14 +0000 UTC, last metrics timestamp: 2019-08-20 18:57:59 +0000 UTC " }
{ "level" : " info " , "ts" : 1566327479.884608 , "logger" : " wpa_controller " , "msg" : " backoffUp: true, backoffDown: true, desiredReplicas 5, currentReplicas: 6 " }
最后,我们验证部署是否已正确自动缩放:
{ "level" : " info " , "ts" : 1566327253.7887673 , "logger" : " wpa_controller " , "msg" : " Successful rescale of watermarkpodautoscaler, old size: 8, new size: 9, reason: cutom_metric.max{map[kubernetes_cluster:my-cluster service:my-service short_image:my-image]} above target " }
wpa.datadoghq.com/logs-attributes
在与基础 WPA 对象关联的日志中添加额外的键值。例子: apiVersion: datadoghq.com/v1alpha1
kind: WatermarkPodAutoscaler
metadata:
annotations:
wpa.datadoghq.com/logs-attributes: '{"mywpa": "isgreat"}'
name: watermarkpodautoscaler-sinus
namespace: default
[...]
将产生:
{"level":"info","ts":1643642642091.062,"logger":"controllers.WatermarkPodAutoscaler","msg":"getReadyPodsCount","watermarkpodautoscaler":"default/watermarkpodautoscaler-sinus","mywpa":"isgreat","full podList length":2,"toleratedAsReadyPodCount":2,"incorrectly targeted pods":0}
如果我手动扩展部署会发生什么?
在下一个协调循环中,将考虑新的副本数量来计算所需的副本数量。您可能会看到一条日志,指出该资源已被其他人修改。但是,如果配置的副本数量超出范围,控制器会将其缩小到可接受范围内的副本数量。
如何暂时禁用 WPA 以手动扩大/缩小我的部署?
推荐的方法是将 WPA 设置为试运行模式,然后扩展到所需的副本数量。您可以使用以下补丁命令在试运行中设置 WPA:
kubectl patch wpa --type='json' -p='[{"op": "replace", "path": "/spec/dryRun", "value":true}]'
临时覆盖结束后,不要忘记将试运行模式设置为false
以便 WPA 再次处于活动状态。
控制器的占地面积是多少?
根据我们的测试,它是集群中部署数量的一个因素。
控制器是无状态的吗?
是的。
WPA 是否支持多个指标?
是的,WPA 可以根据多个指标进行扩展,并且工作原理与 HPA 类似。 WPA 单独评估每个指标,并建议与需要最大数量的指标相关联的副本数量。例如,如果 WPA 评估 metric1、metric2、metric3,并分别计算 10、20、30 个副本提案,则最终提案为 30。
由于我们观察集群范围内的所有 WPA 定义,因此我们使用集群角色。
一个有用的选项是模拟用户来验证权限。例如,要验证您是否有权作为 WPA 控制器的服务帐户进行部署:
kubectl get deploy < your_deploy > --as system:serviceaccount:datadog:watermarkpodautoscaler -n < your_ns >
或者,查询外部指标提供程序:
kubectl get --raw " /apis/external.metrics.k8s.io/v1beta1/namespaces//metric --as system:serviceaccount::watermarkpodautoscaler
要求:
克隆存储库https://github.com/DataDog/watermarkpodautoscaler
后,设置一些环境变量:
export GO111MODULE=on
unset GOPATH
export PATH= $PATH : $( pwd ) /bin
然后,要安装一些工具依赖项,请运行make install-tools
。
make install-tools
:安装工具以使用操作员 SDK。make build
:在本地构建控制器。make generate
:运行多个操作员SDK生成器,生成控制器和通知者注册的代码。make test
:运行单元测试。make validate
:运行常见的 Golang linter ( golangci-lint
)。make e2e
:在当前配置的 Kubernetes 集群上运行端到端测试。make container
:使用operator SDK构建控制器Docker镜像。make container-ci
:使用多阶段 Dockerfile 构建控制器 Docker 映像。发布流程文档可在此处获取。
其中一些功能的灵感来自可配置 HPA 或 CHPA。尽管 CRD 的整体打包是通过运营商 SDK 完成的,但大部分代码结构也用于 Watermark Pod Autoscaler。