Isenção de responsabilidade : este projeto está em beta - a API pode mudar.
O controlador Watermark Pod Autoscaler (WPA) é um controlador personalizado que estende o Horizontal Pod Autoscaler (HPA).
O controlador Watermark Pod Autoscaler é um controlador alternativo ao controlador horizontal Pod Autoscaler upstream.
Se você deseja dimensionar automaticamente alguns de seus aplicativos, mas:
por exemplo
apiVersion : datadoghq.com/v1alpha1
kind : WatermarkPodAutoscaler
[...]
spec :
algorithm : absolute
[...]
Existem duas opções para calcular o número desejado de réplicas:
average
O controlador usará o value from the external metrics provider
/ current number of replicas
e o comparará com as marcas d'água. O número recomendado de réplicas é value from the external metrics provider
/ watermark
(baixo ou alto dependendo do valor atual).
O algoritmo average
é uma boa opção se você usar uma métrica que não dependa do número de réplicas. Normalmente, o número de solicitações recebidas por um ELB pode indicar quantos servidores web queremos ter, visto que sabemos que um único servidor web deve lidar com n
rq/s. Adicionar uma réplica não aumentará nem diminuirá o número de solicitações recebidas pelo balanceador de carga.
absolute
O valor padrão é absolute
. Uma métrica média deve ser usada. O número recomendado de réplicas é calculado como o valor current number of replicas
* value from the external metrics provider
/ watermark
.
O algoritmo absolute
é o padrão, pois representa o caso de uso mais comum. Por exemplo, se você deseja que seu aplicativo seja executado entre 60% e 80% da CPU e avg:cpu.usage
estiver em 85%, você precisará aumentar a escala. A métrica deve ser correlacionada ao número de réplicas.
Nota : No controlador upstream, apenas a função math.Ceil
é usada para arredondar o número recomendado de réplicas.
Isso significa que se você tiver um limite de 10, precisará atingir uma utilização de 8.999... do provedor de métricas externo para reduzir a escala em uma réplica. No entanto, uma utilização de 10.001 fará com que você aumente em uma réplica.
O controlador WPA usará math.Floor
se o valor estiver abaixo da marca d'água inferior. Isso garante um comportamento simétrico. Combinado com outras opções de escala, isso permite um controle mais preciso sobre quando reduzir a escala.
Para usar o Watermark Pod Autoscaler, implante-o em seu cluster Kubernetes:
Baixe o arquivo zip do projeto Watermark Pod Autoscaler. O código-fonte pode ser encontrado em DataDog/watermarkpodautoscaler
.
Descompacte o projeto e vá para a pasta ./watermarkpodautoscaler
.
Defina seu namespace e controlador Watermark Pod Autoscaler:
DD_NAMESPACE= " datadog "
DD_NAMEWPA= " wpacontroller "
Crie o espaço para nome:
kubectl create ns $DD_NAMESPACE
Instale o controlador Watermark Pod Autoscaler com Helm:
helm install $DD_NAMEWPA -n $DD_NAMESPACE ./chart/watermarkpodautoscaler
O WatermarkPodAutoscaler Controler vem com um plugin kubectl que fornece um conjunto de utilitários auxiliares. mais informações na página de documentação dedicada: docs/kubectl-plugin.md
Crie seu WPA no mesmo namespace da implantação de destino.
O Datadog Cluster Agent selecionará o evento de criação/atualização/exclusão. Ele analisa a especificação WPA para extrair a métrica e o escopo obtidos do Datadog.
Neste exemplo, estamos usando a seguinte configuração de especificações:
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 "
Os tipos de métrica External
e Resource
são suportados. O controlador WPA usa o mesmo formato que o HPA. Mais informações aqui.
Começando com as marcas d'água, o valor da métrica coletada ( watermarkpodautoscaler.wpa_controller_value
) do Datadog em roxo quando entre os limites ( watermarkpodautoscaler.wpa_controller_low_watermark
e watermarkpodautoscaler.wpa_controller_high_watermark
) instruirá o controlador a não acionar um evento de escala. Eles são especificados como Quantities
, então você pode usar m | "" | k | M | G | T | P | E
para representar facilmente o valor que você deseja usar.
Podemos usar a métrica watermarkpodautoscaler.wpa_controller_restricted_scaling{reason:within_bounds}
para verificar se ela é realmente restrita. Nota : a métrica foi multiplicada por 1000 para deixar mais explícito que durante esse tempo nenhum evento de escalonamento poderia ter sido acionado pelo controlador.
O segundo conjunto de opções de configuração refere-se à velocidade de escalabilidade da sua implantação, controlada por scaleDownLimitFactor
e scaleUpLimitFactor
. São números inteiros entre 0 e 100. Eles representam a proporção máxima de redução e aumento de escala, respectivamente, dado o número atual de réplicas.
Neste caso, se tivéssemos 10 réplicas e um número recomendado de réplicas de 14 (veja a seção Algoritmo para mais detalhes sobre a recomendação) com um scaleUpFactor
de 30 (%), teríamos um limite de 13 réplicas.
No gráfico a seguir, podemos ver que o número sugerido de réplicas (em roxo), representado pela métrica watermarkpodautoscaler.wpa_controller_replicas_scaling_proposal
é muito alto comparado ao número atual de réplicas. Isso acionará a lógica de limite de upscale, que pode ser monitorada usando a métrica watermarkpodautoscaler.wpa_controller_restricted_scaling{reason:upscale_capping}
( Observação : igual ao acima, a métrica foi multiplicada para torná-la mais explícita). Assim, o número efetivo de réplicas watermarkpodautoscaler.wpa_controller_replicas_scaling_effective
aumentará, mas de acordo com o scaleUpLimitFactor
.
Neste exemplo semelhante, evitamos reduzir muito a escala e podemos usar o mesmo conjunto de métricas para garantir que reduziremos apenas um número razoável de réplicas.
É importante observar que sempre tomamos decisões conservadoras de escala.
scaleUpLimitFactor
de 29%: se tivermos 10 réplicas e forem recomendadas 13, faremos o upscale para 12.scaleDownLimitFactor
de 29%: se tivermos 10 réplicas e forem recomendadas 7, faremos o downscale para 8.minReplicas
e maxReplicas
têm precedência. Consulte a seção Precedência. Por fim, as últimas opções disponíveis são downscaleForbiddenWindowSeconds
e upscaleForbiddenWindowSeconds
. Eles representam quanto tempo (em segundos) após um evento de escalabilidade deve ser esperado antes de reduzir e aumentar, respectivamente. Mantemos apenas o último evento de escalonamento e não comparamos o upscaleForbiddenWindowSeconds
com a última vez que apenas aumentamos o escalonamento.
No exemplo a seguir, podemos ver que o número recomendado de réplicas é ignorado se estivermos em um período de espera. O período de resfriamento do downscale pode ser visualizado com watermarkpodautoscaler.wpa_controller_transition_countdown{transition:downscale}
e é representado em amarelo no gráfico abaixo. Podemos ver que é significativamente maior do que o período de espera do upscale ( transition:upscale
) em laranja em nosso gráfico. Uma vez recomendado o dimensionamento, só o escalaremos se a janela de resfriamento apropriada terminar. Isso redefinirá ambas as contagens regressivas.
Para evitar o escalonamento de rajadas, você pode usar os seguintes recursos: downscaleDelayBelowWatermarkSeconds
e/ou upscaleDelayAboveWatermarkSeconds
. Essas opções são especificadas como números inteiros. A(s) métrica(s) deve(m) permanecer acima ou abaixo da respectiva marca d'água durante o período configurado. Você pode acompanhar quanto tempo resta no status do 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
Ou nos logs do 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}
Observação: se você estiver usando diversas métricas com esse recurso, a condição acima/abaixo será considerada usando o OR
das métricas.
Por exemplo, suponha que você tenha um upscaleDelay
de 60 segundos com duas métricas, M1 e M2. Se M1 permanecer acima de seu limite máximo por 40 segundos [t0; t40]
, e o M2 ultrapassa sua marca d'água máxima por 30 segundos, sobrepondo-se ao M1 durante os últimos 10 segundos, [t30; t60]
, isso valida a condição upscaleDelay
e permite um evento de aumento de escala.
À medida que recuperamos o valor da métrica externa, iremos primeiro compará-lo com a soma highWatermark
+ tolerance
e com a diferença lowWatermark
tolerance
. Se estivermos fora dos limites, calculamos o número recomendado de réplicas. Em seguida, comparamos esse valor com o número atual de réplicas para limitar potencialmente o número recomendado de réplicas também de acordo com minReplicas
e maxReplicas
. Por fim, veremos se temos permissão para escalar, dados downscaleForbiddenWindowSeconds
e upscaleForbiddenWindowSeconds
.
Para ter um controle mais granular sobre as condições sob as quais um destino pode ser dimensionado, você pode usar os seguintes recursos:
minAvailableReplicaPercentage
: indica a porcentagem mínima de réplicas que precisam estar disponíveis para que o controlador escale automaticamente o destino. Por exemplo, se definido como 50 e menos da metade dos pods atrás do destino estiverem no estado Disponível, o destino não será dimensionado pelo controlador.
readinessDelaySeconds
: especifica por quanto tempo as réplicas precisam estar em execução, antes de serem levadas em consideração nas decisões de escalonamento.
Se todas as condições forem atendidas, o controlador dimensionará o objeto de destino em scaleTargetRef
para o número recomendado de réplicas somente se o sinalizador dryRun
não estiver definido como true
. Isso indicará isso registrando:
{ "level" : " info " , "ts" : 1566327479.866722 , "logger" : " wpa_controller " , "msg" : " DryRun mode: scaling change was inhibited currentReplicas:8 desiredReplicas:12 " }
O Cluster Agent está executando um informante nos recursos WPA e, semelhante ao HPA, após a criação/atualização/exclusão, analisará a especificação para consultar a métrica do Datadog.
O Cluster Agent não executa o ouvinte WPA por padrão. Para ativar o WPA no Cluster Agent, defina a variável de ambiente DD_EXTERNAL_METRICS_PROVIDER_WPA_CONTROLLER=true
e atualize o ClusterRole atribuído à conta de serviço do Cluster Agent para ter acesso aos objetos WatermarkPodAutoscaler:
[...]
- apiGroups : ["datadoghq.com"]
resources :
- watermarkpodautoscalers
verbs :
- get
- list
- watch
[...]
Nota: Para ativar o WPA no Cluster Agent usando o gráfico do helm datadog, configure clusterAgent.metricsProvider.wpaController
como true
. O ClusterRole será atualizado automaticamente.
Depois de aplicar essas alterações e criar um objeto WPA, se você executar no pod Datadog Cluster Agent e executar agent status
poderá ver detalhes mais específicos sobre as especificações dos escalonadores automáticos que foram analisados (seja horizontal ou horizontal). escalonador automático de pod de marca d'água).
* 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
Além das métricas mencionadas acima, são logs que o ajudarão a entender melhor o bom funcionamento do WPA.
A cada 15 segundos, recuperamos a métrica listada na seção de metrics
da especificação do 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 }
Aqui, o número atual de réplicas vistas na implantação de destino é seis. Em seguida, vemos o valor bruto recuperado do provedor de métricas externas e o comparamos com as marcas d’água máxima e mínima. Dado o resultado desta comparação, imprimimos o número recomendado de réplicas. Neste caso, são cinco.
Se quiser consultar diretamente o Provedor de Métricas Externas, você pode usar o seguinte comando:
kubectl get --raw " /apis/external.metrics.k8s.io/v1beta1/namespaces// | jq ."
Opcionalmente, você também pode adicionar seletores de rótulo adicionando ?labelSelector=key%3Dvalue
. Se quiséssemos recuperar nossa métrica neste caso, poderíamos usar:
kubectl get --raw " /apis/external.metrics.k8s.io/v1beta1/namespaces// | jq .?labelSelector=key%3Dvalue%2Cotherkey%3Dothervalue%2Cshort_image%3Dimage "
Se você vir 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 " }
Em seguida, você pode verificar se essa métrica realmente não está disponível no provedor de métricas externas. Isso pode ser devido a um erro de digitação nos rótulos ou a métrica não pode ser obtida no Datadog (o que pode ser devido a vários fatores: muito escasso, API inativa, limite de taxa atingido, etc.). Você pode consultar os logs do Provedor de Métricas Externas para uma investigação mais aprofundada.
Em seguida, verificamos o limite de velocidade de escala e as janelas de resfriamento. No caso de um limite de escala, você veria 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 " }
Em seguida, consideramos os períodos de espera. Você terá registros indicativos de quando foi o último evento de escalabilidade, bem como quando os próximos eventos de aumento e redução serão proibidos até:
{ "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 " }
Por fim, temos a verificação de que a implantação foi escalonada automaticamente corretamente:
{ "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 adicionar valores de chave extras nos logs associados ao objeto WPA subjacente. Exemplo: apiVersion: datadoghq.com/v1alpha1
kind: WatermarkPodAutoscaler
metadata:
annotations:
wpa.datadoghq.com/logs-attributes: '{"mywpa": "isgreat"}'
name: watermarkpodautoscaler-sinus
namespace: default
[...]
Irá render:
{"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}
O que acontece se eu dimensionar manualmente minha implantação?
No próximo loop de reconciliação, o novo número de réplicas será considerado para calcular o número desejado de réplicas. Você poderá ver um log informando que o recurso foi modificado por outra pessoa. Entretanto, se o número de réplicas configuradas estiver fora dos limites, o controlador reduzirá esse número para um número de réplicas dentro do intervalo aceitável.
Como desabilitar temporariamente o WPA para aumentar/diminuir manualmente minha implantação?
A maneira recomendada é definir o WPA no modo de simulação e depois dimensionar para o número desejado de réplicas. Você pode definir o WPA em simulação usando este comando de patch:
kubectl patch wpa --type='json' -p='[{"op": "replace", "path": "/spec/dryRun", "value":true}]'
Não se esqueça de redefinir o modo de simulação para false
assim que a substituição temporária terminar, para que o WPA esteja ativo novamente.
Qual é a pegada do controlador?
Em nossos testes, é um fator do número de implantações no cluster.
O controlador é sem estado?
Sim.
O WPA oferece suporte a múltiplas métricas?
Sim, o WPA pode ser dimensionado em diversas métricas e funciona de maneira semelhante ao HPA. O WPA avalia cada métrica separadamente e propõe o número de réplicas associadas à métrica que requer o maior número. Por exemplo, se o WPA avaliar metric1, metric2, metric3, e para cada um calcular 10, 20, 30 réplicas de propostas respectivamente, a proposta final será 30.
Como observamos todas as definições WPA em todo o cluster, usamos um clusterrole.
Uma opção útil é personificar o usuário para verificar os direitos. Por exemplo, para verificar se você tem o direito de obter uma implantação como conta de serviço do controlador WPA:
kubectl get deploy < your_deploy > --as system:serviceaccount:datadog:watermarkpodautoscaler -n < your_ns >
Ou consulte o provedor de métricas externas:
kubectl get --raw " /apis/external.metrics.k8s.io/v1beta1/namespaces//metric --as system:serviceaccount::watermarkpodautoscaler
Requisitos:
Após clonar o repositório https://github.com/DataDog/watermarkpodautoscaler
, defina algumas variáveis de ambiente:
export GO111MODULE=on
unset GOPATH
export PATH= $PATH : $( pwd ) /bin
Então, para instalar algumas dependências de ferramentas, execute make install-tools
.
make install-tools
: instale as ferramentas para usar o SDK do operador.make build
: Construa o controlador localmente.make generate
: Executa o gerador SDK de diversos operadores, que gera código para o controlador e cadastro do informante.make test
: executa testes unitários.make validate
: execute linters Golang comuns ( golangci-lint
).make e2e
: execute testes ponta a ponta no cluster Kubernetes atualmente configurado.make container
: construa a imagem Docker do controlador usando o operador SDK.make container-ci
: Construa a imagem Docker do controlador com o Dockerfile de vários estágios.A documentação do processo de lançamento está disponível aqui.
Alguns dos recursos foram inspirados no HPA ou CHPA configurável. A maior parte da estrutura do código também foi usada para o Watermark Pod Autoscaler, embora o empacotamento geral do CRD tenha sido feito com o SDK do operador.