Configuração e Escalabilidade¶
Nos capítulos anteriores, criamos Deployments e Services com as configurações escritas diretamente nos manifests YAML — incluindo, no caso do PostgreSQL, credenciais em texto dentro do arquivo. Em aplicações reais, isso é um problema: o mesmo container pode precisar rodar com configurações diferentes em cada ambiente (desenvolvimento, homologação, produção), e senhas não devem estar versionadas no repositório.
O Kubernetes oferece dois recursos para separar a configuração do código: ConfigMaps e Secrets. Além disso, veremos o conceito de escalonamento automático com o Horizontal Pod Autoscaler.
ConfigMap¶
O ConfigMap armazena dados de configuração não sensíveis na forma de pares chave-valor. Esses dados podem ser injetados nos pods como variáveis de ambiente ou como arquivos montados em um volume.
Criando um ConfigMap¶
Vamos criar um ConfigMap para a nossa API, armazenando o nome da aplicação e a versão — valores que a aplicação poderia consumir como variáveis de ambiente.
| k8s/configmap.yaml | |
|---|---|
Aplique:
Verifique o conteúdo:
Usando o ConfigMap no Deployment¶
Para que os pods da API tenham acesso a essas variáveis, precisamos atualizar o Deployment. Edite o arquivo k8s/deployment.yaml e adicione a referência ao ConfigMap:
| k8s/deployment.yaml | |
|---|---|
O campo envFrom com configMapRef injeta todas as chaves do ConfigMap como variáveis de ambiente no contêiner. Após aplicar, você pode verificar que as variáveis existem dentro do pod:
kubectl apply -f k8s/deployment.yaml
kubectl exec -it $(kubectl get pods -l app=soma-api -o jsonpath='{.items[0].metadata.name}') -- env | grep APP
A saída deve mostrar APP_NAME=API de Soma e APP_VERSION=1.0.0.
Variáveis individuais¶
Se quiser injetar apenas algumas chaves (e não todas), use env com valueFrom:
Essa abordagem dá mais controle sobre quais variáveis ficam visíveis no pod.
Secret¶
O Secret funciona de forma semelhante ao ConfigMap, mas é projetado para dados sensíveis: senhas, tokens, chaves de API. Os valores são armazenados codificados em base64 dentro do cluster.
Sobre a segurança dos Secrets
Codificação base64 não é criptografia. Qualquer pessoa com acesso ao cluster pode decodificar os valores. Para ambientes de produção, é recomendável habilitar a encriptação em repouso (encryption at rest) no etcd, ou usar soluções externas como HashiCorp Vault ou Sealed Secrets. Para fins de estudo, o Secret padrão do Kubernetes é suficiente.
Criando um Secret¶
Vamos migrar as credenciais do PostgreSQL (que deixamos em texto no capítulo anterior) para um Secret:
| k8s/postgres-secret.yaml | |
|---|---|
O campo stringData aceita valores em texto puro (o Kubernetes converte automaticamente para base64 ao armazenar). Aplique:
Verifique (os valores aparecerão em base64):
Usando o Secret no Deployment do PostgreSQL¶
Atualize o Deployment do PostgreSQL para usar o Secret em vez de valores em texto:
| k8s/postgres-deployment.yaml | |
|---|---|
Aplique:
O comportamento é idêntico ao que tínhamos antes — mas agora as credenciais não estão no manifest do Deployment. Elas ficam no Secret, que pode ser gerenciado separadamente e não precisa ser versionado junto com o código da aplicação.
Escalabilidade¶
Escalonamento manual¶
Já vimos no capítulo de Deployments que podemos alterar o número de réplicas com kubectl scale:
Isso é útil quando sabemos antecipadamente qual carga o sistema receberá. Mas em muitos cenários, a carga varia ao longo do dia — e não queremos manter recursos ociosos nem ficar sem capacidade nos horários de pico.
Horizontal Pod Autoscaler (HPA)¶
O Horizontal Pod Autoscaler ajusta automaticamente o número de réplicas de um Deployment com base em métricas observadas — tipicamente uso de CPU ou memória.
Para que o HPA funcione, precisamos de duas coisas:
- Definir limites de recursos nos pods (para que o Kubernetes saiba quanto cada pod pode usar).
- Ter um servidor de métricas instalado no cluster (o Metrics Server).
Instalando o Metrics Server no Kind¶
No Kind, o Metrics Server não vem instalado por padrão. Para instalá-lo:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
O Metrics Server no Kind pode precisar de uma configuração adicional para funcionar sem TLS. Edite o deployment do metrics-server:
kubectl -n kube-system patch deployment metrics-server --type='json' \
-p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]'
Aguarde o pod do Metrics Server ficar pronto:
Definindo limites de recursos¶
Atualize o Deployment da API para incluir os limites de CPU e memória:
| k8s/deployment.yaml (trecho) | |
|---|---|
requests: o mínimo garantido. O escalonador usa esse valor para decidir em qual nó alocar o pod.limits: o máximo permitido. Se o pod exceder o limite de memória, ele é encerrado (OOMKilled). Se exceder o de CPU, é limitado (throttled).
A unidade 100m significa 100 milicores de CPU (0.1 CPU). 128Mi significa 128 mebibytes de memória.
Aplique:
Criando o HPA¶
| k8s/hpa.yaml | |
|---|---|
Esse HPA mantém entre 2 e 8 réplicas do Deployment soma-api. Se o uso médio de CPU ultrapassar 50% do requests, o HPA adiciona réplicas. Se cair, remove.
Acompanhe o estado do HPA:
A coluna TARGETS mostra o uso atual de CPU vs. o alvo (50%). Se mostrar <unknown>/50%, aguarde alguns minutos para o Metrics Server coletar dados.
Gerando carga para testar¶
Para observar o HPA em ação, podemos gerar carga na API. Em um terminal, mantenha o port-forward ativo:
Em outro terminal, execute repetidamente requisições:
Acompanhe o escalonamento com:
Você verá o número de réplicas aumentar à medida que a CPU se aproxima ou ultrapassa 50%. Ao parar as requisições (Ctrl+C no loop), o HPA reduz gradualmente o número de réplicas após alguns minutos de estabilidade.
Organização dos arquivos¶
Após este capítulo, o diretório k8s/ contém:
k8s/
├── pod.yaml
├── deployment.yaml
├── service.yaml
├── service-nodeport.yaml
├── postgres-deployment.yaml
├── postgres-service.yaml
├── postgres-secret.yaml
├── configmap.yaml
└── hpa.yaml
Exercícios¶
-
Crie um ConfigMap com ao menos 3 variáveis de configuração. Injete todas no Deployment da API usando
envFrom. Acesse um pod e confirme comenvque as variáveis estão presentes. -
Crie um Secret com as credenciais do PostgreSQL. Atualize o Deployment do banco para usar
secretRefem vez de variáveis em texto. Verifique que o banco continua funcionando normalmente. -
Defina limites de recursos (
requestselimits) no Deployment da API. Observe o que acontece se você definir umrequestsde memória muito alto (por exemplo,2Giem um cluster Kind com pouca RAM) — o pod é alocado? -
(Proposta aberta) Instale o Metrics Server no cluster Kind, crie o HPA e gere carga na API. Observe o escalonamento automático e documente o comportamento: quantas réplicas foram criadas, quanto tempo levou para escalar, e quanto tempo para reduzir após parar a carga.