Um cluster Kubernetes é um ambiente compartilhado para o processamento de aplicações de diversas equipes. Para que os picos de consumo de CPU e memória de uma aplicação não degrade a performance de outra aplicação rodando em um mesmo node, é necessário que seja aplicado limites.
Além disto, para que seja possível garantir que os recursos mínimos estejam disponíveis em um node para rodar uma determinada aplicação, é necessário o uso de requests.
Por isso, é muito comum vermos nos Charts Helm e no YAML dos deployments configurações como estas:
resources:
limits:
cpu: 200m
memory: 512Mi
requests:
cpu: 100m
memory: 256Mi
O problema é que o mal dimensionamento destas configurações podem gerar dois cenários:
-
requisições de CPU e memória altos podem aumentar o custo da fatura da AWS, pois mais nodes EKS irão ser provisionados desnecessariamente para evitar que os pods fiquem em estado de Pending.
-
limites de CPU e memória inferior ao consumo médio esperado pela aplicação podem causar degradação da performance (gerando problemas como CPU Throttling e Out of Memory).
Exemplo de requests potencialmente mal dimensionado:
resources:
limits:
cpu: 3000m
memory: 4Gi
requests:
cpu: 3000m
memory: 4Gi
Isto exigirá um node com 4GiB de memória livre e 3 cores ociosas só para sua aplicação. Certamente seu microsserviço precisará de muito menos que isto, certo?
Exemplo de request melhor dimensionado:
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 192Mi
Agora o cenário está mais otimizado: a aplicação exigirá no mínimo 192MiB de memória livre e 10% de 1 core ocioso.
Mas como saber quais requests de CPU e memória devemos ajustar nas nossas aplicações?
Recomendações do Kubecost
O Kubecost é uma ferramenta com interface Web que consome a API do Kubernetes e a API Pública de Pricing da AWS para mensurar os custos de um cluster EKS e disponibilizar recomendações de ajustes de limits e requests.
Na página principal do Kubecost ele te apresenta uma série de valores que ele mensurou. Um valor interessante a se destacar é a eficiência:
Quando a eficiência de um cluster EKS está próximo de 100%, isto indica um bom uso dos nodes provisionados. Devemos nos esforçar para subir cada vez mais esta eficiência.
Vejamos um exemplo de melhoria da eficiência de apps do namespace “monitoring”:
Na tela acima temos recomendações de ajustes de três componentes. Vamos acessar o YAML destes DaemonSets e Deployments e aplicar os ajustes recomendados. Por exemplo:
monitoring\daemonset\newrelic-infra antes:
resources:
limits:
memory: 300M
requests:
cpu: 100m
memory: 150M
monitoring\daemonset\newrelic-infra depois:
resources:
limits:
memory: 300M
requests:
cpu: 85m
memory: 95M
Após os ajustes, demorará cerca de 3 horas para o Kubecost reavaliar as alterações. Depois de reavaliado, verifique novamente a eficiência dos objetos k8s.