Quando você coloca uma aplicação em produção no Kubernetes, uma das decisões mais importantes é como especificar os recursos que seus pods precisam. Essa escolha determina qual classe de Quality of Service (QoS) seu pod recebe — e isso impacta diretamente na sua estabilidade e custo. Neste post, vou explicar em detalhe os três níveis de QoS: Guaranteed, Burstable e BestEffort.
O que é QoS no Kubernetes?
QoS (Quality of Service) é um mecanismo que o Kubernetes usa para classificar e priorizar seus pods em relação ao uso de recursos. Quando o nó está sem memória ou CPU disponível, o Kubernetes usa a classe QoS para decidir qual pod será removido (evicted) ou compactado.
O Kubernetes define três classes de QoS:
- BestEffort — mínima prioridade, primeira a ser removida
- Burstable — prioridade média, removida após Guaranteed
- Guaranteed — máxima prioridade, última a ser removida
Qual classe seu pod recebe depende de como você especifica os requests e limits de CPU e memória.
QoS BestEffort: Máxima Flexibilidade, Sem Garantias
Um pod é classificado como BestEffort quando:
- Você não define requests nem limits de CPU ou memória
- É a situação padrão quando você simplesmente não especifica nada
Essa é a classe mais precária do Kubernetes. Seus pods não têm nenhuma garantia de recursos e são os primeiros candidatos a eviction.
Como funciona BestEffort na prática
Imagine um pod criado sem especificar nenhum recurso:
apiVersion: v1
kind: Pod
metadata:
name: app-besteffort
spec:
containers:
- name: app
image: myapp:latest
Neste caso:
- Sem request — o Kubernetes não reserva nada. O scheduler coloca o pod em qualquer nó com espaço
- Sem limit — o pod pode usar quanto recurso quiser, até consumir toda a memória disponível do nó
- Prioridade mínima — quando o nó precisa liberar recursos, BestEffort é removido primeiro
O pod está completamente à mercê da contenção de recursos no nó.
O comportamento do BestEffort
Com BestEffort, seu pod:
- Usa qualquer recurso disponível — sem limite, pode usar até falhar
- Compete com todos — não há reserva, compartilha com qualquer outro workload
- É a primeira a ser evicted — em qualquer pressão de recurso, sai do nó
- Não tem previsibilidade — pode funcionar bem em um nó e morrer em outro
Se o nó está sob pressão de memória, todos os BestEffort são removidos imediatamente, sem piedade. A ordem de remoção entre BestEfforts é baseada em quanto cada um está usando além do seu ideal.
Quando (e por que) usar BestEffort
Pareça contraditório, mas há casos legítimos para BestEffort:
- Batch jobs não-críticos — processamento que pode ser retentado depois
- CI/CD agents — runners que podem ser recriados facilmente
- Dev/test environments — ambientes de desenvolvimento onde indisponibilidade é aceitável
- Workloads tolerantes a interrupção — qualquer coisa que possa ser reiniciada sem perda de estado
Nunca use BestEffort para:
- Aplicações críticas de produção
- Bancos de dados ou caches
- Serviços que precisam estar sempre disponíveis
- Qualquer coisa que você não quer que seja encerrada abruptamente
QoS Burstable: Flexibilidade com Limite
Um pod é classificado como Burstable quando:
- Você define requests e limits de forma inconsistente, OU
- Você define apenas requests
Nessa configuração, seu pod tem a flexibilidade de usar mais recursos do que solicitou inicialmente, mas está limitado por um valor máximo.
Como funciona Burstable na prática
Imagine uma aplicação que normalmente precisa de 100m de CPU, mas ocasionalmente pode pedir picos até 500m. Você especifica:
apiVersion: v1
kind: Pod
metadata:
name: app-burstable
spec:
containers:
- name: app
image: myapp:latest
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
Aqui acontece o seguinte:
- Request (100m CPU) — quantidade garantida que o Kubernetes reserva para seu pod. O scheduler só coloca esse pod em um nó se houver pelo menos 100m de CPU disponível.
- Limit (500m CPU) — limite máximo que o pod pode usar. Se tentar usar mais, será throttled (limitado).
O pod é Burstable porque os requests e limits são diferentes.
O comportamento do Burstable
Com Burstable, seu pod consegue:
- Usar mais recursos quando disponíveis — se o nó tem CPU livre além do request, seu pod pode usar
- Ser previsível no mínimo — garantidamente terá o que solicitou (100m)
- Estar vulnerável em contenção — quando o nó fica sem recursos, Burstable é removido antes de Guaranteed
Se o nó está sob pressão de memória e precisa liberar espaço, pods Burstable são candidatos a eviction. A ordem depende da urgência: quem está mais longe do seu limit é removido primeiro.
QoS Guaranteed: Máxima Segurança
Um pod é classificado como Guaranteed quando:
- Requests e limits são idênticos para CPU E memória
- OU quando você especifica apenas limits (tratado como request automaticamente)
Essa é a classe premium do Kubernetes. Seus pods têm garantia máxima de recursos.
Como funciona Guaranteed
apiVersion: v1
kind: Pod
metadata:
name: app-guaranteed
spec:
containers:
- name: app
image: myapp:latest
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "250m"
Neste exemplo:
- O pod recebe exatamente 250m de CPU e 512Mi de memória reservados
- Não pode usar mais do que isso (será throttled se tentar)
- O Kubernetes garante que esses recursos estarão sempre disponíveis
- Em caso de contenção, esse pod é a última a ser removida
O contrato do Guaranteed
Quando você marca um pod como Guaranteed, está fazendo um contrato com o Kubernetes:
“Eu prometo que minha aplicação nunca vai precisar de mais recursos do que especifiquei. Em troca, você garante que eu terei esses recursos sempre disponíveis.”
Violar esse contrato resulta em throttling de CPU ou OOMKill (morte por falta de memória).
Por que isso importa?
Entender QoS é fundamental para:
- Custo — Guaranteed custa mais (você paga por recursos que pode não usar)
- Estabilidade — Guaranteed garante que não será evicted
- Performance — Burstable oferece flexibilidade com risco de throttling
- Dimensionamento — saber quantos pods cabem em um nó depende de como você especifica recursos
O próximo passo
Agora que você entende os conceitos, no próximo post vou compartilhar um caso real que enfrentei em produção: como mudei a estratégia de QoS de uma aplicação crítica, os problemas que encontrei e como resolvemos.
Gostou do conteúdo?
- ✅ Inscreva-se na newsletter para receber mais dicas práticas sobre Kubernetes e Cloud diretamente no seu e-mail!
- 🚀 Conheça a Imersão Golang e leve seus conhecimentos em Go para o próximo nível!
Faça parte da comunidade!
Receba os melhores conteúdos sobre Go, Kubernetes, arquitetura de software, Cloud e esteja sempre atualizado com as tendências e práticas do mercado.