Descargo de responsabilidad : este proyecto está en versión beta. La API puede cambiar.
El controlador Watermark Pod Autoscaler (WPA) es un controlador personalizado que amplía el Horizontal Pod Autoscaler (HPA).
El controlador Watermark Pod Autoscaler es un controlador alternativo al controlador Horizontal Pod Autoscaler ascendente.
Si desea escalar automáticamente algunas de sus aplicaciones, pero:
p.ej
apiVersion : datadoghq.com/v1alpha1
kind : WatermarkPodAutoscaler
[...]
spec :
algorithm : absolute
[...]
Hay dos opciones para calcular la cantidad deseada de réplicas:
average
El controlador utilizará el value from the external metrics provider
/ current number of replicas
y lo comparará con las marcas de agua. El número recomendado de réplicas es value from the external metrics provider
/ watermark
(bajo o alto según el valor actual).
El algoritmo average
es una buena opción si utiliza una métrica que no dependa del número de réplicas. Normalmente, la cantidad de solicitudes recibidas por un ELB puede indicar cuántos servidores web queremos tener, dado que sabemos que un solo servidor web debe manejar n
rq/s. Agregar una réplica no aumentará ni disminuirá la cantidad de solicitudes recibidas por el balanceador de carga.
absolute
El valor predeterminado es absolute
. Se debe utilizar una métrica promedio . El número recomendado de réplicas se calcula como current number of replicas
* value from the external metrics provider
/ watermark
.
El algoritmo absolute
es el predeterminado, ya que representa el caso de uso más común. Por ejemplo, si desea que su aplicación se ejecute entre el 60 % y el 80 % de la CPU, y avg:cpu.usage
está al 85 %, debe ampliarla. La métrica debe estar correlacionada con el número de réplicas.
Nota : En el controlador ascendente, solo se utiliza la función math.Ceil
para redondear el número recomendado de réplicas.
Esto significa que si tiene un umbral de 10, deberá alcanzar una utilización de 8,999... del proveedor de métricas externo para reducir la escala en una réplica. Sin embargo, una utilización de 10.001 le permitirá ampliar la escala en una réplica.
El controlador WPA utilizará math.Floor
si el valor está por debajo de la marca de agua inferior. Esto garantiza un comportamiento simétrico. Combinado con otras opciones de escala, esto permite un control más preciso sobre cuándo reducir la escala.
Para utilizar Watermark Pod Autoscaler, impleméntelo en su clúster de Kubernetes:
Descargue el archivo zip del proyecto Watermark Pod Autoscaler. El código fuente se puede encontrar en DataDog/watermarkpodautoscaler
.
Descomprima el proyecto y vaya a la carpeta ./watermarkpodautoscaler
.
Defina su espacio de nombres y su controlador Watermark Pod Autoscaler:
DD_NAMESPACE= " datadog "
DD_NAMEWPA= " wpacontroller "
Crea el espacio de nombres:
kubectl create ns $DD_NAMESPACE
Instale el controlador Watermark Pod Autoscaler con Helm:
helm install $DD_NAMEWPA -n $DD_NAMESPACE ./chart/watermarkpodautoscaler
El controlador WatermarkPodAutoscaler viene con un complemento kubectl que proporciona un conjunto de utilidades auxiliares. más información en la página de documentación dedicada: docs/kubectl-plugin.md
Cree su WPA en el mismo espacio de nombres que su implementación de destino.
El agente de clúster Datadog recogerá el evento de creación/actualización/eliminación. Analiza la especificación WPA para extraer la métrica y el alcance que se obtendrán de Datadog.
En este ejemplo, utilizamos la siguiente configuración de especificaciones:
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 "
Se admiten los tipos de métricas External
y Resource
. El controlador WPA utiliza el mismo formato que el HPA. Más información aquí.
Comenzando con las marcas de agua, el valor de la métrica recopilada ( watermarkpodautoscaler.wpa_controller_value
) de Datadog en violeta cuando está entre los límites ( watermarkpodautoscaler.wpa_controller_low_watermark
y watermarkpodautoscaler.wpa_controller_high_watermark
) indicará al controlador que no active un evento de escalado. Se especifican como Quantities
, por lo que puedes usar m | "" | k | M | G | T | P | E
para representar fácilmente el valor que desea utilizar.
Podemos usar la métrica watermarkpodautoscaler.wpa_controller_restricted_scaling{reason:within_bounds}
para verificar que efectivamente esté restringida. Nota : la métrica se multiplicó por 1000 para hacer más explícito que durante este tiempo, el controlador no pudo haber activado ningún evento de escala.
El segundo conjunto de opciones de configuración pertenece a la velocidad de escalamiento de su implementación, controlada por scaleDownLimitFactor
y scaleUpLimitFactor
. Estos son números enteros entre 0 y 100. Representan la proporción máxima de reducción y ampliación respectivamente, dado el número actual de réplicas.
En este caso, si tuviéramos 10 réplicas y un número recomendado de réplicas de 14 (consulte la sección Algoritmo para obtener más detalles sobre la recomendación) con un scaleUpFactor
del 30 (%), tendríamos un límite de 13 réplicas.
En el siguiente gráfico, podemos ver que el número sugerido de réplicas (en violeta), representado por la métrica watermarkpodautoscaler.wpa_controller_replicas_scaling_proposal
es demasiado alto en comparación con el número actual de réplicas. Esto activará la lógica de limitación de nivel superior, que se puede monitorear usando la métrica watermarkpodautoscaler.wpa_controller_restricted_scaling{reason:upscale_capping}
( Nota : igual que arriba, la métrica se multiplicó para hacerla más explícita). Por lo tanto, el número efectivo de réplicas watermarkpodautoscaler.wpa_controller_replicas_scaling_effective
Effective aumentará, pero de acuerdo con scaleUpLimitFactor
.
En este ejemplo similar, evitamos reducir demasiado la escala y podemos usar el mismo conjunto de métricas para garantizar que solo reducimos una cantidad razonable de réplicas.
Es importante tener en cuenta que siempre tomamos decisiones de escala conservadoras.
scaleUpLimitFactor
del 29%: si tenemos 10 réplicas y nos recomiendan 13, escalaremos a 12.scaleDownLimitFactor
del 29%: si tenemos 10 réplicas y nos recomiendan 7, bajaremos a 8.minReplicas
y maxReplicas
tienen prioridad. Consulte la sección Prioridad. Finalmente, las últimas opciones disponibles son downscaleForbiddenWindowSeconds
y upscaleForbiddenWindowSeconds
. Estos representan cuánto tiempo (en segundos) después de un evento de escalamiento se debe esperar antes de reducir y aumentar, respectivamente. Solo mantenemos el último evento de escala y no comparamos upscaleForbiddenWindowSeconds
con la última vez que solo ampliamos.
En el siguiente ejemplo podemos ver que el número recomendado de réplicas se ignora si estamos en un periodo de recuperación. El período de recuperación de la reducción de escala se puede visualizar con watermarkpodautoscaler.wpa_controller_transition_countdown{transition:downscale}
y se representa en amarillo en el siguiente gráfico. Podemos ver que es significativamente mayor que el período de recuperación de escala superior ( transition:upscale
) en naranja en nuestro gráfico. Una vez que se nos recomienda escalar, solo lo haremos si finaliza la ventana de recuperación adecuada. Esto restablecerá ambas cuentas regresivas.
Para evitar el escalado por ráfagas, puede utilizar las siguientes funciones: downscaleDelayBelowWatermarkSeconds
y/o upscaleDelayAboveWatermarkSeconds
. Estas opciones se especifican como números enteros. Las métricas deben permanecer por encima o por debajo de su respectiva marca de agua durante el tiempo configurado. Puedes realizar un seguimiento de cuánto tiempo queda en el estado del 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
O en los registros del controlador:
{"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}
Nota: Si utiliza varias métricas con esta función, la condición anterior/inferior se considera utilizando el OR
de las métricas.
Por ejemplo, supongamos que tiene un upscaleDelay
de 60 segundos con dos métricas, M1 y M2. Si M1 se mantiene por encima de su marca de agua máxima durante 40 segundos [t0; t40]
, y el M2 supera su marca de agua máxima durante 30 segundos, superponiéndose con M1 durante sus últimos 10 segundos, [t30; t60]
, esto valida la condición upscaleDelay
y permite un evento de ampliación.
A medida que recuperamos el valor de la métrica externa, primero lo compararemos con la suma highWatermark
+ tolerance
y con la diferencia lowWatermark
- tolerance
. Si estamos fuera de los límites, calculamos el número recomendado de réplicas. Luego comparamos este valor con la cantidad actual de réplicas para limitar potencialmente la cantidad recomendada de réplicas también de acuerdo con minReplicas
y maxReplicas
. Finalmente, analizamos si se nos permite escalar, dados downscaleForbiddenWindowSeconds
y upscaleForbiddenWindowSeconds
.
Para tener un control más granular sobre las condiciones bajo las cuales se puede escalar un objetivo, puede utilizar las siguientes funciones:
minAvailableReplicaPercentage
: indica el porcentaje mínimo de réplicas que deben estar disponibles para que el controlador escale automáticamente el destino. Por ejemplo, si se establece en 50 y menos de la mitad de los pods detrás del objetivo están en estado Disponible, el controlador no escalará el objetivo.
readinessDelaySeconds
: especifica cuánto tiempo deben ejecutarse las réplicas antes de que se tengan en cuenta en las decisiones de escalado.
Si se cumplen todas las condiciones, el controlador escalará el objeto de destino en scaleTargetRef
al número recomendado de réplicas solo si el indicador dryRun
no está establecido en true
. Lo indicará iniciando sesión:
{ "level" : " info " , "ts" : 1566327479.866722 , "logger" : " wpa_controller " , "msg" : " DryRun mode: scaling change was inhibited currentReplicas:8 desiredReplicas:12 " }
El Agente de clúster ejecuta un informador contra los recursos WPA y, de manera similar al HPA, tras la creación/actualización/eliminación analizará la especificación para consultar la métrica de Datadog.
El Agente de clúster no ejecuta el detector WPA de forma predeterminada. Para habilitar WPA en el Agente de clúster, configure la variable de entorno DD_EXTERNAL_METRICS_PROVIDER_WPA_CONTROLLER=true
y actualice el ClusterRole asignado a la cuenta de servicio del Agente de clúster para tener acceso a los objetos WatermarkPodAutoscaler:
[...]
- apiGroups : ["datadoghq.com"]
resources :
- watermarkpodautoscalers
verbs :
- get
- list
- watch
[...]
Nota: Para habilitar WPA en el Agente de clúster mediante el gráfico de timón de datadog, establezca clusterAgent.metricsProvider.wpaController
en true
. El ClusterRole se actualizará automáticamente.
Una vez que haya aplicado esos cambios y haya creado un objeto WPA, si ejecuta el pod del Agente de clúster de Datadog y ejecuta agent status
podrá ver detalles más específicos sobre las especificaciones de los escaladores automáticos que se analizaron (ya sea horizontal o vertical). escalador automático de pods de marcas de agua).
* 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
Además de las métricas mencionadas anteriormente, estos son registros que te ayudarán a comprender mejor el correcto funcionamiento de WPA.
Cada 15 segundos, recuperamos la métrica enumerada en la sección de metrics
de la especificación de Datadog.
{ "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 }
Aquí, la cantidad actual de réplicas vistas en la implementación de destino es seis. Luego vemos el valor bruto recuperado del proveedor de métricas externas y lo comparamos con las marcas de agua máxima y mínima. Dado el resultado de esta comparación, imprimimos el número de réplicas recomendado. En este caso son cinco.
Si desea consultar directamente al proveedor de métricas externas, puede utilizar el siguiente comando:
kubectl get --raw " /apis/external.metrics.k8s.io/v1beta1/namespaces// | jq ."
Opcionalmente, también puede agregar selectores de etiquetas agregando ?labelSelector=key%3Dvalue
. Si quisiéramos recuperar nuestra métrica en este caso, podríamos usar:
kubectl get --raw " /apis/external.metrics.k8s.io/v1beta1/namespaces// | jq .?labelSelector=key%3Dvalue%2Cotherkey%3Dothervalue%2Cshort_image%3Dimage "
Si ve registros como:
{ "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 " }
Luego podrá verificar que esta métrica no esté disponible en el proveedor de métricas externas. Esto podría deberse a un error tipográfico en las etiquetas o a que la métrica no se puede recuperar de Datadog (lo que podría deberse a varios factores: demasiado escasa, API inactiva, límite de velocidad alcanzado, etc.). Puede consultar los registros del proveedor de métricas externas para realizar más investigaciones.
Luego verificamos el límite de velocidad de escala y las ventanas de enfriamiento. En el caso de una limitación de escala, verá algo como:
{ "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 " }
Luego consideramos los períodos de recuperación. Tendrá registros indicativos de cuándo fue el último evento de escala, así como también cuándo están prohibidos los próximos eventos de subida y bajada hasta:
{ "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 " }
Finalmente, tenemos la verificación de que la implementación se escaló automáticamente correctamente:
{ "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
para agregar valores clave adicionales en los registros asociados con el objeto WPA subyacente. Ejemplo: apiVersion: datadoghq.com/v1alpha1
kind: WatermarkPodAutoscaler
metadata:
annotations:
wpa.datadoghq.com/logs-attributes: '{"mywpa": "isgreat"}'
name: watermarkpodautoscaler-sinus
namespace: default
[...]
Producirá:
{"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}
¿Qué sucede si escale manualmente mi implementación?
En el siguiente ciclo de conciliación, se considerará la nueva cantidad de réplicas para calcular la cantidad deseada de réplicas. Es posible que vea un registro que indique que otra persona modificó el recurso. Sin embargo, si el número de réplicas configuradas está fuera de los límites, el controlador lo reducirá a un número de réplicas dentro del rango aceptable.
¿Cómo deshabilitar temporalmente WPA para aumentar o reducir manualmente mi implementación?
La forma recomendada es configurar el WPA en modo de ejecución en seco y luego escalarlo al número deseado de réplicas. Puede configurar el WPA en ejecución en seco usando este comando de parche:
kubectl patch wpa --type='json' -p='[{"op": "replace", "path": "/spec/dryRun", "value":true}]'
No olvide volver a configurar el modo de ejecución en seco a false
una vez que finalice la anulación temporal para que WPA vuelva a estar activo.
¿Cuál es la huella del controlador?
Según nuestras pruebas, es un factor de la cantidad de implementaciones en el clúster.
¿El controlador es apátrida?
Sí.
¿WPA admite múltiples métricas?
Sí, WPA puede escalar en múltiples métricas y funciona de manera similar a HPA. WPA evalúa cada métrica por separado y propone la cantidad de réplicas asociadas a la métrica que requiere la mayor cantidad. Por ejemplo, si WPA evalúa métrica1, métrica2, métrica3 y para cada una calcula 10, 20, 30 propuestas de réplica respectivamente, la propuesta final es 30.
Dado que observamos todas las definiciones de WPA en todo el clúster, utilizamos un rol de clúster.
Una opción útil es hacerse pasar por el usuario para verificar los derechos. Por ejemplo, para verificar que tiene derecho a obtener una implementación como cuenta de servicio del controlador WPA:
kubectl get deploy < your_deploy > --as system:serviceaccount:datadog:watermarkpodautoscaler -n < your_ns >
O consulte al proveedor de métricas externo:
kubectl get --raw " /apis/external.metrics.k8s.io/v1beta1/namespaces//metric --as system:serviceaccount::watermarkpodautoscaler
Requisitos:
Después de clonar el repositorio https://github.com/DataDog/watermarkpodautoscaler
, configure algunas variables de entorno:
export GO111MODULE=on
unset GOPATH
export PATH= $PATH : $( pwd ) /bin
Luego, para instalar algunas dependencias de herramientas, ejecute make install-tools
.
make install-tools
: instale las herramientas para utilizar el SDK del operador.make build
: construye el controlador localmente.make generate
: ejecuta el generador de SDK de varios operadores, que genera código para el controlador y el registro del informador.make test
: Ejecute pruebas unitarias.make validate
: ejecuta linters Golang comunes ( golangci-lint
).make e2e
: ejecute pruebas de un extremo a otro en el clúster de Kubernetes configurado actualmente.make container
: crea la imagen de Docker del controlador utilizando el SDK del operador.make container-ci
: crea la imagen Docker del controlador con el Dockerfile de varias etapas.La documentación del proceso de lanzamiento está disponible aquí.
Algunas de las características se inspiraron en el HPA o CHPA configurable. La mayor parte de la estructura del código también se utilizó para Watermark Pod Autoscaler, aunque el empaquetado general del CRD se realizó con el SDK del operador.