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
az aks update \ --resource-group myResourceGroup \ --name myAKSCluster \ --disable-cluster-autoscalerMostrar 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.
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.
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 (Azure Kubernetes Service) do zero, você pode seguir os seguintes passos:
- Certifique-se de ter uma conta do Azure e um cluster do AKS criados.
- Instale o kubectl em sua máquina local e configure-o para acessar seu cluster do AKS.
- Crie um deployment no cluster do AKS:
kubectl create deployment <deployment-name> --image=<container-image>- Verifique se o deployment foi criado corretamente:
kubectl get deployments- Crie um serviço para expor o deployment:
kubectl expose deployment <deployment-name> --port=<port-number> --type=LoadBalancer- Verifique se o serviço foi criado corretamente:
kubectl get services- Crie um HPA para o deployment:
kubectl autoscale deployment <deployment-name> --cpu-percent=<cpu-percent> --min=<min-replicas> --max=<max-replicas>- Substitua
<cpu-percent>,<min-replicas>e<max-replicas>pelos valores desejados. - Verifique se o HPA foi criado corretamente:
kubectl get hpa
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
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
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:
- é o valor da CPU solicitado pelo deployment. Por exemplo, “100m” representa 100 milicores (ou 0,1 CPU).
- é 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
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
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.
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/
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
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
- 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
periodSecondsindica o período de tempo no passado durante o qual a política deve ser válida- A política (Porcentagem) permite que no máximo 50% das réplicas atuais sejam reduzidas em 30 segundos. saiba mais
- A seleção da política pode ser alterada especificando o
selectPolicy
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
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
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.
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.
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.
- Dimensionar automaticamente um cluster para atender às demandas de aplicativo no AKS (Serviço de Kubernetes do Azure)
- Dimensionar a contagem de nós em um cluster do AKS (Serviço de Kubernetes do Azure)
- A contagem de nós atual não está no intervalo mínimo e mínimo do dimensionador automático — Azure | Microsoft Learn
- Horizontal Pod Autoscaling | Kubernetes
- Tutorial do Kubernetes no Azure — Dimensionar Aplicativo — Azure Kubernetes Service | Microsoft Learn
- Architecting Kubernetes clusters — choosing the best autoscaling strategy (learnk8s.io)
- Kubernetes instance calculator (learnk8s.io)
- Conceitos — dimensionar aplicativos no AKS (Serviço de Kubernetes do Azure) — Azure Kubernetes Service | Microsoft Learn
- Tutorial do Kubernetes no Azure — Dimensionar aplicativos no AKS (Serviço de Kubernetes do Azure) — Azure Kubernetes Service | Microsoft Learn
- Horizontal Pod Autoscaling | Kubernetes