Agora você tem uma imagem definida, é hora de ajudar o Kubernetes a agendar essa imagem com eficiência para os nodes apropriados e uma das melhores dicas de otimização é que você precisa ser mais específico com as restrições de recursos.
O que isso significa é que você pode definir as solicitações e colocar limites na CPU, memória e outros recursos, pois caso você decida usar um microsserviço baseado em Go como servidor de e-mail, portanto, pode designar o perfil de recurso abaixo:
resources:
requests:
memory: 1Gi
cpu: 250m
limits:
memory: 2.5Gi
cpu: 750m
Alguns pontos merecem atenção para essa definição:
- As solicitações da CPU geralmente não são definidas ou são muito baixas;
- Em alta demanda, os CPUs do nodes são totalmente utilizadas e o workload está recebendo apenas o que foi solicitado e fica com a CPU com consumo alto, causando aumento de latência, timeout e etc.
Por favor não faço isso:
resources: {}
E nem isso com CPU muito baixo:
resources:
requests:
cpu: "1m"
- Por outro lado, ter limite de CPU pode aumentar o consumo dos pods, mesmo que a CPU do node não seja totalmente utilizado no que novamente pode causar aumento da latência.
- A super alocação de memória pode causar mais problemas. Atingir um limite de CPU resulta em estrangulamento, atingir o limite de memória fará com que seu pod seja encerrado.
Já viu OOMKilled?
Seria dele que estamos falando. Quer minimizar a frequência com que isso pode acontecer?
Não comprometa demais sua memória e use a solicitação de memória de configuração de QoS (Quality of Service) garantida igual ao limite.
Estável | "Burstable"
Provável obter OOMkilled com mais frequência:
resources:
requests:
memory: "128Mi"
cpu: "500m"
limits:
memory: "256Mi"
cpu: 2
Garantido | "Guaranteed"
Indicado e Garantido para aplicações que usam desses valores de recursos, onde a boa prática é configurar valores iguais, tanto em requests e limits:
resources:
requests:
memory: "128Mi"
cpu: 2
limits:
memory: "128Mi"
cpu: 2
O que pode ajudá-lo ao definir recursos?
Você pode ver o uso atual de CPU e memória de pods usando o servidor de métricas. As chances são de que você já o esteja executando. Basta executar:
kubectl top pods
kubectl top pods --containers
kubectl top nodes
No entanto, mostram apenas o uso atual. Isso é ótimo para ter uma idéia aproximada do uso atual, mas você acaba querendo ver métricas mais acuradas para responder a pergunta como:
Qual foi o uso da CPU no pico de ontem de manhã ?
Para isso, você pode usar Prometheus, New Relic, DataDog e muitos outros.
Usando VPA para auxiliar na descoberta de quanto sua aplicação usa de CPU e Memória:
Você pode usar o Kubernetes Vertical Pod Autoscaler para ajustar automaticamente as solicitações e os limites de recursos dos containers executados nos pods de uma implantação.
O Vertical Pod Autoscaler, conhecido como VPA pode melhorar a utilização de recursos do cluster:
- Definindo solicitações automaticamente com base no uso para garantir que o valor de recurso apropriado esteja disponível para cada pod;
- Mantendo proporções entre limites e solicitações que foram especificadas nas configurações iniciais dos containers;
- Reduzindo pods que estão solicitando recursos em excesso, com base no uso ao longo do tempo;
- Ampliando pods que estão solicitando recursos insuficientes, com base no uso ao longo do tempo;
VerticalPodAutoscaler pode ajudá-lo, observando o uso de CPU e memória e te auxiliando a definir esses valores em seu deployment.
A FairWinds fez um bom trabalho com o Goldilock onde te ajuda com essa tarefa de descoberta de quanto seu aplicativo vai consumir de recursos:
1 - Com o VPA configurado, Instale o client do Goldilock:
curl -L "https://github.com/FairwindsOps/goldilocks/releases/download/v4.0.0/goldilocks_4.0.0_linux_amd64.tar.gz" > goldilocks.tar.gz
tar -xvf goldilocks.tar.gz
sudo mv goldilocks /usr/local/bin/
2 - Agora instale o controller e o dashboard com helm:
helm install goldilocks --namespace goldilocks fairwinds-stable/goldilocks
3 - Próximo passo seria criar a label na namespace onde estáo aplicativo que deseja fazer a descoberta:
kubectl label ns <NAMESPACE> goldilocks.fairwinds.com/enabled=true
4 - Criamos outro label para o VPA sempre operar em modo Off, assim nada será alterado de modo automático em seu Deployment
kubectl label ns <NAMESPACE> goldilocks.fairwinds.com/vpa-update-mode="off"
5 - Rodamos o comando abaixo para automaticamente ser criado um VPA por deployment para seu devido monitoramento
goldilocks controller
6 - E por fim executamos o comando a seguir para fazer o port-forward para o serviço e abrir um front que auxiliará nas visualizações das recomendações de CPU e memória de cada deployment
goldilocks dashboard
`
Para maiores detalhes, o github do Goldilock: https://github.com/FairwindsOps/goldilocks