Blog Post

Desenvolvedores BR
19 MIN READ

Escalando Nodes e Pods no AKS

wdossantos's avatar
wdossantos
Icon for Microsoft rankMicrosoft
Nov 23, 2024

Escalar nodes e escalar pods são dois conceitos distintos no contexto do AKS (Azure Kubernetes Service).

Escalando Nodes e Pods no AKS

 Escalar nodes e escalar pods são dois conceitos distintos no contexto do AKS (Azure Kubernetes Service).

Escalar nodes refere-se ao aumento ou diminuição da quantidade de nós (VMs) em execução no cluster do AKS. Ao escalar os nodes, você adiciona mais capacidade de computação, memória e armazenamento ao seu cluster, o que ajuda a lidar com picos de tráfego ou carga de trabalho.

Por outro lado, escalar pods refere-se ao aumento ou diminuição da quantidade de instâncias de um pod específico em execução no cluster do AKS. Isso auxilia no gerenciamento de picos de tráfego ou demanda por recursos específicos, como CPU ou memória.

Para escalar manualmente os nodes no AKS, você pode utilizar o comando ‘az aks scale’. Por exemplo, para escalar o cluster para 3 nodes, execute o seguinte comando:

az aks scale --resource-group myResourceGroup --name myAKSCluster --node-count 3
 

Os dimensionadores automáticos de cluster e de pod horizontal podem operar em conjunto e geralmente são implantados em um cluster. Quando combinados, o dimensionador automático de pod horizontal foca na execução do número de pods necessário para atender à demanda do aplicativo. Já o dimensionador automático de cluster concentra-se na execução do número de nós necessários para dar suporte aos pods agendados.

 

O dimensionamento manual é desabilitado quando o dimensionador automático de cluster é usado. Deixe o dimensionador automático de cluster determinar o número de nós necessários. Caso deseje dimensionar o cluster manualmente, desabilite o dimensionador automático de cluster.

Habilitar o dimensionador automático em um cluster existente

az aks update \ --resource-group myResourceGroup \ --name myAKSCluster \ --enable-cluster-autoscaler \ --min-count 1 \ --max-count 3
 

Desabilitar o dimensionador automático de cluster em um cluster

 
az aks update \ --resource-group myResourceGroup \ --name myAKSCluster \ --disable-cluster-autoscaler

Mostrar configuração do profile padrão

az aks show --resource-group myResourceGroup --name myAKSCluster --query agentPoolProfiles
 

Você pode configurar detalhes mais granulares do autoscaler de cluster alterando os valores padrão no perfil.

 

Escalar pods (HPA)

 

Para escalar os pods no AKS, você pode usar a horizontal pod autoscaler (HPA) do Kubernetes. A HPA ajusta automaticamente o número de pods com base na utilização de recursos. Você pode configurar a HPA usando um arquivo YAML, que especifica a regra para aumentar ou diminuir o número de pods. Por exemplo, você pode definir uma regra para aumentar o número de pods em 1 sempre que a utilização de CPU de um pod ultrapassar 80%. Aqui está um exemplo de arquivo YAML para configurar a HPA:

 

apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler metadata: name: my-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: my-deployment minReplicas: 1 maxReplicas: 10 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 80

 

 

Esse arquivo YAML especifica que a HPA deve ajustar o número de pods para um deployment chamado my-deployment, aumentando ou diminuindo a quantidade de pods para manter a utilização média de CPU em 80%. Além disso, o número mínimo de pods é definido como 1 e o número máximo como 10.

Mas quando eu devo usar o KEDA no lugar do HPA ?

 

O KEDA (Kubernetes-based Event-Driven Autoscaling) é uma ferramenta de escala automática para cargas de trabalho de eventos baseada em Kubernetes. O KEDA estende o recurso de escala automática do Kubernetes e permite a escala com base em eventos, em vez de apenas na utilização de recursos.

Embora o HPA do Kubernetes seja capaz de escalar horizontalmente com base na utilização de recursos, ele não é projetado para escalar automaticamente as cargas de trabalho baseadas em eventos. O KEDA, por outro lado, é projetado especificamente para escalar cargas de trabalho baseadas em eventos, como filas de mensagens, stream de eventos e cronjobs.

Se sua carga de trabalho envolve eventos que acionam a criação de novas instâncias de pods ou ajustes no número de réplicas em tempo real, o KEDA pode ser uma opção melhor do que o HPA do Kubernetes quando o gatilho para a escala é uma fila por exemplo.

Para configurar o HPA (Horizontal Pod Autoscaler) no AKS

 

Para configurar o HPA (Horizontal Pod Autoscaler) no AKS (Azure Kubernetes Service) do zero, você pode seguir os seguintes passos:

  1. Certifique-se de ter uma conta do Azure e um cluster do AKS criados.
  2. Instale o kubectl em sua máquina local e configure-o para acessar seu cluster do AKS.
  3. Crie um deployment no cluster do AKS:
  4. kubectl create deployment <deployment-name> --image=<container-image>
  5. Verifique se o deployment foi criado corretamente:
  6. kubectl get deployments
  7. Crie um serviço para expor o deployment:
  8. kubectl expose deployment <deployment-name> --port=<port-number> --type=LoadBalancer
  9. Verifique se o serviço foi criado corretamente:
  10. kubectl get services
  11. Crie um HPA para o deployment:
  12. kubectl autoscale deployment <deployment-name> --cpu-percent=<cpu-percent> --min=<min-replicas> --max=<max-replicas>
  13. Substitua <cpu-percent><min-replicas> e <max-replicas> pelos valores desejados.
  14. Verifique se o HPA foi criado corretamente:
  15. kubectl get hpa

Demo aplicação aspnet

 

Vamos utilizar a imagem de uma aplicação dotnet simples. O objetivo é testar diferentes configurações de HPA para os cenários de aumento de escala (Scale Up) e redução de escala (Scale Down).

 

Primeiro passo vamos connecter nos cluster

az aks get-credentials --resource-group AKS_BLOG --name ask_poc_hpa
 

Vamos criar uma Namespace

kubectl create namespace aspnet

 

 

Criando um manifesto de deploy

kubectl create deploy aspnetapp --image=mcr.microsoft.com/dotnet/samples:aspnetapp --dry-run=client -o yaml > samples-aspnetapp-deploy.yaml
 

o seguinte arquivo será gerado

 
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: aspnetapp name: aspnetapp spec: replicas: 1 selector: matchLabels: app: aspnetapp strategy: {} template: metadata: creationTimestamp: null labels: app: aspnetapp spec: containers: - image: mcr.microsoft.com/dotnet/samples:aspnetapp name: aspnetapp resources: {} status: {}

Rodar o deploy

kubectl apply -f samples-aspnetapp-deploy.yaml -n aspnet
 

Criando um manifesto de serviço

kubectl expose -f samples-aspnetapp-deploy.yaml --name=sampleapisvc --type=LoadBalancer --port=80 --target-port=8080 --dry-run=client -o yaml > samples-aspnetapp-svc.yaml

 

o seguinte arquivo será gerado

apiVersion: v1 kind: Service metadata: creationTimestamp: null labels: app: aspnetapp name: sampleapisvc spec: ports: - port: 80 protocol: TCP targetPort: 8080 selector: app: aspnetapp type: LoadBalancer status: loadBalancer: {}

 

 

Rodar Servico

kubectl apply -f samples-aspnetapp-svc.yaml -n aspnet
 

Criando um manifesto de hpa

kubectl autoscale deployment aspnetapp --cpu-percent=60 --min=1 --max=5 --dry-run=client -o yaml > samples-aspnetapp-hpa-01.yaml

 

o seguinte arquivo será gerado

apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: creationTimestamp: null name: aspnetapp spec: maxReplicas: 5 minReplicas: 1 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: aspnetapp targetCPUUtilizationPercentage: 60 status: currentReplicas: 0 desiredReplicas: 0
 

rodar o hpa

kubectl apply -f samples-aspnetapp-hpa-01.yaml -n aspnet
 

Usando os comandos abaixo pode verificar o estado dos objetos

 

kubectl top pods # Visualiza o consumo de CPU e memória dos pods kubectl get hpa # Mostra a configuração corrente do HPA com os valores das métricas kubectl describe hpa <name> # Visualiza as configurações do HPA, assim como eventos de aumento e diminuição de pods

 

 
Detalhes da configuração HPA

Um dos erros mais comuns ao configurar HPA

 

Tudo ocorreu conforme esperado. No entanto, ao executar o comando kubectl get hpa, recebi a informação <unknown>/60% no campo TARGETS. Comecei verificando se o metrics-server está em execução no seu cluster do AKS utilizando o comando kubectl.

 

kubectl get pods -n kube-system
 

Verificando os detalhes do HPA

kubectl describe hpa <nome>

 

 

The HPA was unable to compute the replica count: failed to get cpu utilization: missing request for cpu

E por fim precisei editar com os limites do manifesto de deploy segue referência https://stacksimplify.com/azure-aks/azure-kubernetes-service-requests-and-limits/

 

resources: limits: cpu: "500m" memory: "512Mi" requests: cpu: "100m" memory: "256Mi"
 

Onde:

  1. é o valor da CPU solicitado pelo deployment. Por exemplo, “100m” representa 100 milicores (ou 0,1 CPU).
  2. é o valor máximo da CPU que o deployment pode usar. Por exemplo, “500m” representa 500 milicores (ou 0,5 CPU).

final

apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: aspnetapp name: aspnetapp spec: replicas: 1 selector: matchLabels: app: aspnetapp strategy: {} template: metadata: creationTimestamp: null labels: app: aspnetapp spec: containers: - image: mcr.microsoft.com/dotnet/samples:aspnetapp name: samples resources: limits: cpu: "500m" memory: "512Mi" requests: cpu: "100m" memory: "256Mi" status: {}

 

 

após atualizar o deploy rodei

kubectl get hpa -n aspnet
 
kubectl get hpa -n aspnet

 

Vemos os percentuais de CPU, o atual e o gatilho do algoritmo HPA, acima de 60 % aumenta e abaixo disso diminui respeitando o parâmetro stabilizationWindowSeconds para evitar as flutuações

Considerações sobre recursos disponíveis para pods

 

Em uma máquina virtual de 8 GB e 2 vCPU, você pode esperar:

  • 100 MB de memória e 0,1 vCPU a serem reservados para o sistema operacional.
  • 1,8 GB de memória e 0,07 vCPU a serem reservados para o Kubelet.
  • 100 MB de memória para o limite de despejo.

Os ~6 GB restantes de memória e 1,83 vCPU podem ser usados ​​pelos pods.

O Kubelet é um agente que executa em cada nó de um cluster do Kubernetes. Ele é responsável por garantir que os containers estejam em execução no nó e em conformidade com o estado desejado declarado no manifesto do Kubernetes.

 

Adicionando o fortio para teste de carga

 

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/httpbin/sample-client/fortio-deploy.yaml
 

Fortio é uma ferramenta de teste de carga inicialmente parte do Istio e depois se tornou independente. Executa consultas por segundo, registra tempo de execução.É uma biblioteca Go rápida e pequena, com uma imagem Docker de 4 MB.

executando uma chamada de teste usando curl

 

kubectl exec fortio-deploy-5669d4866b-bqp8n -c fortio -n httpbin -- /usr/bin/fortio curl -quiet http://localhost:8080

 

Usando o Fortio, este comando, por exemplo, executa 20 threads, totalizando 20 mil requisições.

kubectl exec fortio-deploy-5669d4866b-bqp8n -c fortio -- /usr/bin/fortio load -c 20 -qps 0 -n 20000 -loglevel Warning http://52.226.198.73/
 

Quais as opções de configuração do HPA

 

Exemplo samples-aspnetapp-hpa-01.yaml 

 

Utilizando targetCPUUtilizationPercentage

 

kubectl autoscale deployment aspnetapp --cpu-percent=60 --min=1 --max=5 --dry-run=client -o yaml > samples-aspnetapp-hpa-01.yaml

 

manifesto gerado pelo kubctl

 

apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: creationTimestamp: null name: aspnetapp spec: maxReplicas: 5 minReplicas: 1 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: aspnetapp targetCPUUtilizationPercentage: 60 status: currentReplicas: 0 desiredReplicas: 0

 

 
kubectl get hpa -n aspnet

 

Exemplo samples-aspnetapp-hpa-02.yaml 

 

Utilizando um comportamento que permite um controle mais preciso dos detalhes do movimento para cima ou para baixo, e adotando a métrica de CPU baseada na porcentagem de utilização média como gatilho para iniciar os movimentos.

 

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: creationTimestamp: null name: aspnetapp spec: maxReplicas: 5 minReplicas: 1 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: aspnetapp metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 10 behavior: scaleDown: stabilizationWindowSeconds: 30 policies: - type: Percent value: 50 periodSeconds: 30

 

 
  1. stabilizationWindowSeconds A janela de estabilização é usada para restringir a oscilação da contagem de réplicas quando as métricas usadas para dimensionamento continuam flutuand
  2. periodSecondsindica o período de tempo no passado durante o qual a política deve ser válida
  3. A política (Porcentagem) permite que no máximo 50% das réplicas atuais sejam reduzidas em 30 segundos. saiba mais
  4. A seleção da política pode ser alterada especificando o selectPolicy
kubectl get hpa -n aspnet

 

Exemplo samples-aspnetapp-hpa-03.yaml 

 

Utilizando um comportamento que permite um controle mais refinado dos detalhes do movimento para cima ou para baixo, e adotando a métrica de CPU baseada no consumo médio em milissegundos como gatilho para iniciar os movimentos.

 

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: creationTimestamp: null name: aspnetapp spec: maxReplicas: 5 minReplicas: 1 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: aspnetapp metrics: - type: Resource resource: name: cpu target: type: AverageValue averageValue: 10m behavior: scaleDown: stabilizationWindowSeconds: 30 policies: - type: Percent value: 50 periodSeconds: 30

 

 
 
kubectl get hpa -n aspnet

 

Exemplo samples-aspnetapp-hpa-04.yml 

 

Utilizando o comportamento que permite um controle mais preciso dos detalhes do movimento para cima ou para baixo, e adotando a métrica de CPU e memória baseada na porcentagem de utilização média como gatilho para iniciar os movimentos.

 

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: creationTimestamp: null name: aspnetapp spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: aspnetapp minReplicas: 1 maxReplicas: 6 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 80 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 100 behavior: scaleDown: stabilizationWindowSeconds: 300 policies: - type: Percent value: 100 periodSeconds: 20 scaleUp: stabilizationWindowSeconds: 0 policies: - type: Pods value: 1 periodSeconds: 30

 

 
kubectl get hpa -n aspnet

 

Vou fazer um teste com a configuração 4, para simular a carga vou usar o fortio e analisar o comportamento de up e down.

 

O teste começou as 14:22

 

kubectl get hpa -n aspnet

 

então usei o parâmetro -w para observar as mudanças de replicas

kubectl get hpa -n aspnet -w

 

As 14:25 cheguei em 6 réplicas, podemos observar que os pods são acionados um por um conforme o comportamento definido.

kubectl get hpa -n aspnet -w

 

As 14:35 baixou para 2 pods

kubectl get hpa -n aspnet -w

 

e as 14:38 chegamos em 1

kubectl get hpa -n aspnet -w

 

O Comportamento de Scale Down não aconteceu exatamente como eu pensei, ele não baixou 100% no primeiro ciclo de verificação.

Testes com 30 pods

Para finalizar fiz um teste com mais pods e coloquei os dados aqui para análise, mudei o deploy para o seguinte:

apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: aspnetapp name: aspnetapp spec: replicas: 1 selector: matchLabels: app: aspnetapp strategy: {} template: metadata: creationTimestamp: null labels: app: aspnetapp spec: containers: - image: mcr.microsoft.com/dotnet/samples:aspnetapp name: samples resources: limits: cpu: "100m" memory: "256Mi" requests: cpu: "30m" memory: "128Mi" status: {}

 

 

Alterei o HPA para

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: creationTimestamp: null name: aspnetapp spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: aspnetapp minReplicas: 1 maxReplicas: 30 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 80 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 100 behavior: scaleDown: stabilizationWindowSeconds: 300 policies: - type: Percent value: 100 periodSeconds: 20 scaleUp: stabilizationWindowSeconds: 0 policies: - type: Pods value: 1 periodSeconds: 30

 

 

e comecei a monitorar

NAME        REFERENCE              TARGETS                   MINPODS   MAXPODS   REPLICAS   AGE  
aspnetapp   Deployment/aspnetapp   <unknown>/80%, 21%/100%   1         30        1          45m  
aspnetapp   Deployment/aspnetapp   13%/80%, 21%/100%         1         30        1          45m  
aspnetapp   Deployment/aspnetapp   3%/80%, 21%/100%          1         30        1          46m  
aspnetapp   Deployment/aspnetapp   223%/80%, 54%/100%        1         30        1          47m  
aspnetapp   Deployment/aspnetapp   256%/80%, 51%/100%        1         30        2          48m  
aspnetapp   Deployment/aspnetapp   223%/80%, 54%/100%        1         30        2          48m  
aspnetapp   Deployment/aspnetapp   256%/80%, 54%/100%        1         30        3          48m  
aspnetapp   Deployment/aspnetapp   333%/80%, 31%/100%        1         30        3          48m  
aspnetapp   Deployment/aspnetapp   330%/80%, 31%/100%        1         30        4          49m  
aspnetapp   Deployment/aspnetapp   333%/80%, 31%/100%        1         30        4          49m  
aspnetapp   Deployment/aspnetapp   114%/80%, 28%/100%        1         30        4          49m  
aspnetapp   Deployment/aspnetapp   114%/80%, 28%/100%        1         30        4          50m  
aspnetapp   Deployment/aspnetapp   109%/80%, 43%/100%        1         30        4          50m  
aspnetapp   Deployment/aspnetapp   82%/80%, 45%/100%         1         30        5          51m  
aspnetapp   Deployment/aspnetapp   265%/80%, 42%/100%        1         30        5          51m  
aspnetapp   Deployment/aspnetapp   266%/80%, 42%/100%        1         30        6          52m  
aspnetapp   Deployment/aspnetapp   266%/80%, 42%/100%        1         30        6          52m  
aspnetapp   Deployment/aspnetapp   265%/80%, 42%/100%        1         30        7          52m  
aspnetapp   Deployment/aspnetapp   108%/80%, 36%/100%        1         30        7          52m  
aspnetapp   Deployment/aspnetapp   101%/80%, 36%/100%        1         30        8          53m  
aspnetapp   Deployment/aspnetapp   108%/80%, 36%/100%        1         30        8          53m  
aspnetapp   Deployment/aspnetapp   200%/80%, 42%/100%        1         30        8          53m  
aspnetapp   Deployment/aspnetapp   200%/80%, 42%/100%        1         30        9          54m  
aspnetapp   Deployment/aspnetapp   200%/80%, 42%/100%        1         30        9          54m  
aspnetapp   Deployment/aspnetapp   200%/80%, 42%/100%        1         30        10         54m  
aspnetapp   Deployment/aspnetapp   158%/80%, 42%/100%        1         30        10         54m  
aspnetapp   Deployment/aspnetapp   158%/80%, 42%/100%        1         30        11         55m  
aspnetapp   Deployment/aspnetapp   158%/80%, 42%/100%        1         30        11         55m  
aspnetapp   Deployment/aspnetapp   158%/80%, 42%/100%        1         30        12         55m  
aspnetapp   Deployment/aspnetapp   146%/80%, 43%/100%        1         30        12         55m  
aspnetapp   Deployment/aspnetapp   158%/80%, 43%/100%        1         30        13         56m  
aspnetapp   Deployment/aspnetapp   158%/80%, 43%/100%        1         30        13         56m  
aspnetapp   Deployment/aspnetapp   109%/80%, 42%/100%        1         30        14         56m  
aspnetapp   Deployment/aspnetapp   113%/80%, 43%/100%        1         30        14         56m  
aspnetapp   Deployment/aspnetapp   109%/80%, 43%/100%        1         30        15         57m  
aspnetapp   Deployment/aspnetapp   39%/80%, 42%/100%         1         30        15         57m  
aspnetapp   Deployment/aspnetapp   39%/80%, 42%/100%         1         30        15         57m  
aspnetapp   Deployment/aspnetapp   39%/80%, 42%/100%         1         30        15         58m  
aspnetapp   Deployment/aspnetapp   32%/80%, 42%/100%         1         30        15         58m  
aspnetapp   Deployment/aspnetapp   94%/80%, 45%/100%         1         30        15         58m  
aspnetapp   Deployment/aspnetapp   91%/80%, 45%/100%         1         30        16         59m  
aspnetapp   Deployment/aspnetapp   91%/80%, 45%/100%         1         30        16         59m  
aspnetapp   Deployment/aspnetapp   130%/80%, 44%/100%        1         30        16         59m  
aspnetapp   Deployment/aspnetapp   138%/80%, 44%/100%        1         30        17         59m  
aspnetapp   Deployment/aspnetapp   130%/80%, 44%/100%        1         30        17         60m  
aspnetapp   Deployment/aspnetapp   138%/80%, 44%/100%        1         30        18         60m  
aspnetapp   Deployment/aspnetapp   138%/80%, 43%/100%        1         30        18         60m  
aspnetapp   Deployment/aspnetapp   52%/80%, 43%/100%         1         30        19         60m  
aspnetapp   Deployment/aspnetapp   66%/80%, 44%/100%         1         30        19         61m  
aspnetapp   Deployment/aspnetapp   52%/80%, 44%/100%         1         30        19         61m  
aspnetapp   Deployment/aspnetapp   122%/80%, 44%/100%        1         30        19         61m  
aspnetapp   Deployment/aspnetapp   122%/80%, 43%/100%        1         30        20         61m  
aspnetapp   Deployment/aspnetapp   122%/80%, 43%/100%        1         30        20         62m  
aspnetapp   Deployment/aspnetapp   122%/80%, 43%/100%        1         30        21         62m **  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         62m  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         62m  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         63m  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         63m  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         63m  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         64m  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         64m  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         65m  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         66m  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         66m  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         67m  
aspnetapp   Deployment/aspnetapp   3%/80%, 41%/100%          1         30        21         67m  
aspnetapp   Deployment/aspnetapp   54%/80%, 42%/100%         1         30        9          67m **  
aspnetapp   Deployment/aspnetapp   81%/80%, 44%/100%         1         30        9          67m  
aspnetapp   Deployment/aspnetapp   54%/80%, 44%/100%         1         30        9          68m  
aspnetapp   Deployment/aspnetapp   81%/80%, 44%/100%         1         30        9          68m  
aspnetapp   Deployment/aspnetapp   81%/80%, 45%/100%         1         30        9          68m  
aspnetapp   Deployment/aspnetapp   216%/80%, 45%/100%        1         30        9          68m  
aspnetapp   Deployment/aspnetapp   217%/80%, 45%/100%        1         30        10         69m  
aspnetapp   Deployment/aspnetapp   216%/80%, 45%/100%        1         30        10         69m  
aspnetapp   Deployment/aspnetapp   217%/80%, 40%/100%        1         30        11         69m  
aspnetapp   Deployment/aspnetapp   174%/80%, 40%/100%        1         30        11         69m  
aspnetapp   Deployment/aspnetapp   150%/80%, 40%/100%        1         30        12         70m  
aspnetapp   Deployment/aspnetapp   150%/80%, 40%/100%        1         30        12         70m  
aspnetapp   Deployment/aspnetapp   150%/80%, 40%/100%        1         30        13         70m  
aspnetapp   Deployment/aspnetapp   143%/80%, 42%/100%        1         30        13         70m  
aspnetapp   Deployment/aspnetapp   125%/80%, 42%/100%        1         30        14         71m  
aspnetapp   Deployment/aspnetapp   125%/80%, 42%/100%        1         30        14         71m  
aspnetapp   Deployment/aspnetapp   108%/80%, 40%/100%        1         30        15         71m  
aspnetapp   Deployment/aspnetapp   96%/80%, 40%/100%         1         30        15         71m  
aspnetapp   Deployment/aspnetapp   108%/80%, 40%/100%        1         30        15         72m  
aspnetapp   Deployment/aspnetapp   96%/80%, 39%/100%         1         30        16         72m **  
aspnetapp   Deployment/aspnetapp   13%/80%, 39%/100%         1         30        16         72m  
aspnetapp   Deployment/aspnetapp   13%/80%, 39%/100%         1         30        16         73m  
aspnetapp   Deployment/aspnetapp   3%/80%, 39%/100%          1         30        16         73m  
aspnetapp   Deployment/aspnetapp   3%/80%, 39%/100%          1         30        16         74m  
aspnetapp   Deployment/aspnetapp   3%/80%, 39%/100%          1         30        16         74m  
aspnetapp   Deployment/aspnetapp   3%/80%, 39%/100%          1         30        16         74m  
aspnetapp   Deployment/aspnetapp   3%/80%, 39%/100%          1         30        16         74m  
aspnetapp   Deployment/aspnetapp   3%/80%, 39%/100%          1         30        16         75m  
aspnetapp   Deployment/aspnetapp   3%/80%, 39%/100%          1         30        16         75m  
aspnetapp   Deployment/aspnetapp   3%/80%, 39%/100%          1         30        16         76m  
aspnetapp   Deployment/aspnetapp   3%/80%, 38%/100%          1         30        16         77m  
aspnetapp   Deployment/aspnetapp   3%/80%, 39%/100%          1         30        16         77m  
aspnetapp   Deployment/aspnetapp   3%/80%, 31%/100%          1         30        7          77m **  
aspnetapp   Deployment/aspnetapp   3%/80%, 31%/100%          1         30        7          78m  
aspnetapp   Deployment/aspnetapp   3%/80%, 31%/100%          1         30        7          78m  
aspnetapp   Deployment/aspnetapp   3%/80%, 31%/100%          1         30        7          78m  
aspnetapp   Deployment/aspnetapp   3%/80%, 31%/100%          1         30        7          79m  
aspnetapp   Deployment/aspnetapp   3%/80%, 31%/100%          1         30        7          80m  
aspnetapp   Deployment/aspnetapp   3%/80%, 31%/100%          1         30        7          81m  
aspnetapp   Deployment/aspnetapp   4%/80%, 31%/100%          1         30        7          81m  
aspnetapp   Deployment/aspnetapp   4%/80%, 31%/100%          1         30        7          81m  
aspnetapp   Deployment/aspnetapp   4%/80%, 31%/100%          1         30        7          82m  
aspnetapp   Deployment/aspnetapp   4%/80%, 31%/100%          1         30        7          82m  
aspnetapp   Deployment/aspnetapp   4%/80%, 31%/100%          1         30        7          82m  
aspnetapp   Deployment/aspnetapp   3%/80%, 36%/100%          1         30        3          82m  
aspnetapp   Deployment/aspnetapp   3%/80%, 36%/100%          1         30        3          83m  
aspnetapp   Deployment/aspnetapp   4%/80%, 36%/100%          1         30        3          83m  
aspnetapp   Deployment/aspnetapp   4%/80%, 36%/100%          1         30        3          83m  
aspnetapp   Deployment/aspnetapp   4%/80%, 36%/100%          1         30        3          84m  
aspnetapp   Deployment/aspnetapp   3%/80%, 36%/100%          1         30        3          84m  
aspnetapp   Deployment/aspnetapp   4%/80%, 36%/100%          1         30        3          85m  
aspnetapp   Deployment/aspnetapp   4%/80%, 36%/100%          1         30        3          85m  
aspnetapp   Deployment/aspnetapp   4%/80%, 36%/100%          1         30        3          86m  
aspnetapp   Deployment/aspnetapp   5%/80%, 36%/100%          1         30        3          86m  
aspnetapp   Deployment/aspnetapp   3%/80%, 36%/100%          1         30        3          86m  
aspnetapp   Deployment/aspnetapp   3%/80%, 36%/100%          1         30        3          86m  
aspnetapp   Deployment/aspnetapp   3%/80%, 36%/100%          1         30        3          87m  
aspnetapp   Deployment/aspnetapp   3%/80%, 36%/100%          1         30        3          87m  
aspnetapp   Deployment/aspnetapp   3%/80%, 32%/100%          1         30        2          87m  
aspnetapp   Deployment/aspnetapp   3%/80%, 32%/100%          1         30        2          88m  
aspnetapp   Deployment/aspnetapp   3%/80%, 32%/100%          1         30        2          88m  
aspnetapp   Deployment/aspnetapp   5%/80%, 33%/100%          1         30        2          88m  
aspnetapp   Deployment/aspnetapp   3%/80%, 32%/100%          1         30        2          89m  
aspnetapp   Deployment/aspnetapp   3%/80%, 32%/100%          1         30        2          90m  
aspnetapp   Deployment/aspnetapp   3%/80%, 32%/100%          1         30        2          90m  
aspnetapp   Deployment/aspnetapp   3%/80%, 32%/100%          1         30        2          91m  
aspnetapp   Deployment/aspnetapp   3%/80%, 32%/100%          1         30        2          91m  
aspnetapp   Deployment/aspnetapp   3%/80%, 32%/100%          1         30        2          92m  
aspnetapp   Deployment/aspnetapp   3%/80%, 44%/100%          1         30        1          92m  
aspnetapp   Deployment/aspnetapp   3%/80%, 43%/100%          1         30        1          93m  
aspnetapp   Deployment/aspnetapp   3%/80%, 44%/100%          1         30        1          94m  
aspnetapp   Deployment/aspnetapp   3%/80%, 44%/100%          1         30        1          95m  
aspnetapp   Deployment/aspnetapp   3%/80%, 44%/100%          1         30        1          95m
 

Podemos observar que, ao atingir 21 réplicas por volta dos 62 minutos, houve uma diminuição nas cargas. Logo após a janela de estabilização, que durou cerca de 5 minutos, o número de réplicas diminui para 9 por volta dos 67 minutos. Fiz uma segunda simulação de carga e as réplicas aumentam para 16 por volta dos 72 minutos e, aproximadamente 5 minutos depois, ou seja, aos 77 minutos, elas diminuem para 7.

samples-aspnetapp-hpa-05.yaml

Mudei a politicas de Scale Down e Scale up para pods, baixando um pod de cada vez

apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: creationTimestamp: null name: aspnetapp spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: aspnetapp minReplicas: 1 maxReplicas: 30 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 80 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 100 behavior: scaleDown: stabilizationWindowSeconds: 300 policies: - type: Pods value: 1 periodSeconds: 20 scaleUp: stabilizationWindowSeconds: 0 policies: - type: Pods value: 1 periodSeconds: 30
 

e dessa forma foi deterministico um por um

NAME        REFERENCE              TARGETS             MINPODS   MAXPODS   REPLICAS   AGE  
aspnetapp   Deployment/aspnetapp   30%/80%, 61%/100%   1         30        1          20h  
aspnetapp   Deployment/aspnetapp   330%/80%, 58%/100%   1         30        1          20h  
aspnetapp   Deployment/aspnetapp   330%/80%, 58%/100%   1         30        2          20h  
aspnetapp   Deployment/aspnetapp   330%/80%, 58%/100%   1         30        2          20h  
aspnetapp   Deployment/aspnetapp   330%/80%, 58%/100%   1         30        3          20h  
aspnetapp   Deployment/aspnetapp   330%/80%, 33%/100%   1         30        3          20h  
aspnetapp   Deployment/aspnetapp   330%/80%, 32%/100%   1         30        4          20h  
aspnetapp   Deployment/aspnetapp   330%/80%, 33%/100%   1         30        4          20h  
aspnetapp   Deployment/aspnetapp   114%/80%, 30%/100%   1         30        4          20h  
aspnetapp   Deployment/aspnetapp   77%/80%, 31%/100%    1         30        4          20h  
aspnetapp   Deployment/aspnetapp   77%/80%, 31%/100%    1         30        4          20h  
aspnetapp   Deployment/aspnetapp   4%/80%, 31%/100%     1         30        4          20h  
aspnetapp   Deployment/aspnetapp   4%/80%, 31%/100%     1         30        4          20h  
aspnetapp   Deployment/aspnetapp   4%/80%, 31%/100%     1         30        4          20h  
aspnetapp   Deployment/aspnetapp   4%/80%, 31%/100%     1         30        4          20h  
aspnetapp   Deployment/aspnetapp   4%/80%, 32%/100%     1         30        4          20h  
aspnetapp   Deployment/aspnetapp   6%/80%, 32%/100%     1         30        4          20h  
aspnetapp   Deployment/aspnetapp   8%/80%, 32%/100%     1         30        4          20h  
aspnetapp   Deployment/aspnetapp   8%/80%, 32%/100%     1         30        4          20h  
aspnetapp   Deployment/aspnetapp   5%/80%, 32%/100%     1         30        4          20h  
aspnetapp   Deployment/aspnetapp   5%/80%, 32%/100%     1         30        4          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 35%/100%     1         30        3          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 35%/100%     1         30        3          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 43%/100%     1         30        2          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 43%/100%     1         30        2          20h  
aspnetapp   Deployment/aspnetapp   5%/80%, 43%/100%     1         30        2          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 43%/100%     1         30        2          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 43%/100%     1         30        2          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 43%/100%     1         30        2          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 43%/100%     1         30        2          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 43%/100%     1         30        2          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 43%/100%     1         30        2          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 43%/100%     1         30        2          20h  
aspnetapp   Deployment/aspnetapp   3%/80%, 63%/100%     1         30        1          20h
 

Parece que o problema está associado à tentativa de encerrar pods que ainda estão em uso, resultando na baixa de apenas uma fração da quantidade especificada na política. O único cenário em que pude observar um determinismo em relação à quantidade de pods baixados foi no exemplo em que defini o comportamento de redução para apenas um pod por vez.

Referências

  1. Dimensionar automaticamente um cluster para atender às demandas de aplicativo no AKS (Serviço de Kubernetes do Azure)
  2. Dimensionar a contagem de nós em um cluster do AKS (Serviço de Kubernetes do Azure)
  3. A contagem de nós atual não está no intervalo mínimo e mínimo do dimensionador automático — Azure | Microsoft Learn
  4. Horizontal Pod Autoscaling | Kubernetes
  5. Tutorial do Kubernetes no Azure — Dimensionar Aplicativo — Azure Kubernetes Service | Microsoft Learn
  6. Architecting Kubernetes clusters — choosing the best autoscaling strategy (learnk8s.io)
  7. Kubernetes instance calculator (learnk8s.io)
  8. Conceitos — dimensionar aplicativos no AKS (Serviço de Kubernetes do Azure) — Azure Kubernetes Service | Microsoft Learn
  9. Tutorial do Kubernetes no Azure — Dimensionar aplicativos no AKS (Serviço de Kubernetes do Azure) — Azure Kubernetes Service | Microsoft Learn
  10. Horizontal Pod Autoscaling | Kubernetes
Updated Nov 23, 2024
Version 1.0
No CommentsBe the first to comment