O que voce vai aprender neste tutorial
- Construir um cluster Kubernetes local com minikube
- Conceitos basicos de Pod, Deployment e Service
- Como escrever manifestos YAML
- Deploy e exposicao de aplicacoes
- Escalonamento e rolling updates
- Uso de ConfigMap, Secret e Namespace
- Melhores praticas para ambiente de producao
Pre-requisitos: Docker Desktop instalado. Instalacao de kubectl e minikube necessarios.
Historia e Contexto do Kubernetes
Por que o Kubernetes foi criado
Kubernetes (tambem conhecido como K8s) e uma plataforma de orquestracao de containers lancada como open source pelo Google em 2014. Sua origem remonta aos sistemas de gerenciamento de containers em larga escala “Borg” e “Omega” que o Google operou internamente por mais de 10 anos.
“Kubernetes is based on a decade and a half of experience at Google running production workloads at scale, combined with best-of-breed ideas and practices from the community.”
Diz-se que o Google inicia bilhoes de containers toda semana, e o conhecimento obtido dessa experiencia operacional foi consolidado no Kubernetes.
Origem do nome Kubernetes
“Kubernetes” vem do grego e significa “timoneiro” ou “piloto”. O significado e pilotar o “navio” de containers, e o logo e baseado no timao de um navio. A abreviacao “K8s” vem do fato de haver 8 letras (ubernete) entre K e s.
Necessidade de Orquestracao de Containers
A tecnologia de containers (Docker) simplificou dramaticamente o empacotamento e distribuicao de aplicacoes. No entanto, novos desafios surgiram em ambientes de producao:
| Desafio | Descricao |
|---|---|
| Escalonamento | Ajustar dinamicamente o numero de containers conforme o trafego |
| Recuperacao de falhas | Reinicio automatico quando containers falham |
| Balanceamento de carga | Distribuicao de trafego entre multiplos containers |
| Service Discovery | Gerenciamento de enderecos IP de containers que mudam dinamicamente |
| Rolling Updates | Atualizacao de aplicacoes sem downtime |
| Gerenciamento de secrets | Distribuicao segura de senhas e chaves de API |
O Kubernetes resolve esses desafios com configuracao declarativa (definindo o estado desejado).
CNCF e Ecossistema Cloud Native
Em 2015, o Google doou o Kubernetes para a CNCF (Cloud Native Computing Foundation). A CNCF e uma organizacao sob a Linux Foundation que promove a adocao e padronizacao de tecnologias cloud native.
Atualmente, a CNCF inclui projetos importantes como:
- Kubernetes - Orquestracao de containers
- Prometheus - Monitoramento e alertas
- Envoy - Proxy de servicos
- Helm - Gerenciador de pacotes
- Argo - Workflow GitOps
Referencia: CNCF Cloud Native Interactive Landscape
Visao Geral da Arquitetura Kubernetes
O cluster Kubernetes e composto por Control Plane (master) e Worker Nodes.
Componentes do Control Plane
flowchart TB
subgraph ControlPlane["Control Plane"]
API["API Server"]
Sched["Scheduler"]
CM["Controller Manager"]
etcd["etcd<br/>(Armazenamento KV Distribuido)"]
end
| Componente | Funcao |
|---|---|
| kube-apiserver | Ponto de entrada para todas as operacoes de API no cluster |
| etcd | Banco de dados distribuido que armazena o estado do cluster |
| kube-scheduler | Decide em qual no colocar os Pods |
| kube-controller-manager | Executa varios controladores (ReplicaSet, Node, etc.) |
Componentes dos Worker Nodes
flowchart TB
subgraph WorkerNode["Worker Node"]
kubelet["kubelet"]
kproxy["kube-proxy"]
runtime["Container Runtime"]
subgraph Pods["Pods"]
P1["Pod"]
P2["Pod"]
P3["Pod"]
P4["Pod"]
end
end
| Componente | Funcao |
|---|---|
| kubelet | Agente que gerencia Pods no no |
| kube-proxy | Gerencia regras de rede e implementa funcionalidade de Service |
| Container Runtime | Executa containers (containerd, CRI-O, etc.) |
Step 1: Iniciando o minikube
minikube e uma ferramenta que permite construir facilmente um cluster Kubernetes em ambiente local. Ideal para aprendizado e desenvolvimento.
# Iniciar cluster minikube
# Opcao --driver especifica o driver (docker, virtualbox, hyperkit, etc.)
minikube start
# Iniciar com memoria e CPU especificados (para reproduzir ambiente proximo a producao)
minikube start --memory=4096 --cpus=2
# Verificar estado do cluster
minikube status
# Verificar conexao do kubectl
kubectl cluster-info
# Verificar informacoes dos nos
kubectl get nodes -o wide
Outras ferramentas locais: kind (Kubernetes in Docker), k3s (Kubernetes leve) tambem sao populares. Escolha conforme o uso.
Step 2: Conceitos Basicos do Kubernetes
Vamos entender os principais recursos do Kubernetes. Explicacoes detalhadas estao disponiveis na documentacao oficial de conceitos.
Relacionamento entre Recursos Principais
flowchart BT
External["Trafego Externo"]
Service["Service
(LB)"]
External --> Service
subgraph Deployment["Deployment
(Gerencia replicas, estrategia de atualizacao, rollback)"]
subgraph ReplicaSet["ReplicaSet
(Mantem numero especificado de replicas de Pod)"]
Pod1["Pod
(Container)"]
Pod2["Pod
(Container)"]
Pod3["Pod
(Container)"]
Pod4["Pod
(Container)"]
end
end
Service --> Pod1
Service --> Pod2
Service --> Pod3
Service --> Pod4
Detalhes de Cada Recurso
| Recurso | Descricao | Caso de Uso |
|---|---|---|
| Pod | Unidade minima de deploy. Contem um ou mais containers | Instancia unica de aplicacao |
| ReplicaSet | Mantem numero especificado de replicas de Pod | Geralmente gerenciado automaticamente pelo Deployment |
| Deployment | Gerenciamento de replicas e rolling updates de Pods | Aplicacoes stateless |
| StatefulSet | Gerenciamento ordenado de Pods e armazenamento persistente | Bancos de dados, sistemas distribuidos |
| DaemonSet | Coloca um Pod em cada no | Coleta de logs, agentes de monitoramento |
| Service | Abstrai acesso de rede aos Pods | Balanceamento de carga, service discovery |
| Ingress | Roteamento HTTP/HTTPS e terminacao TLS | Exposicao externa, roteamento por caminho |
| ConfigMap | Armazena dados de configuracao | Variaveis de ambiente, arquivos de configuracao |
| Secret | Armazena dados confidenciais | Senhas, chaves de API, certificados |
| Namespace | Isolamento logico de recursos | Separacao de ambientes (dev/staging/prod) |
Step 3: Fazendo Deploy do Primeiro Pod
Criacao Direta via Linha de Comando (para desenvolvimento/depuracao)
# Criar Pod nginx
kubectl run my-nginx --image=nginx:latest
# Verificar estado do Pod
# Aguardar STATUS ficar Running
kubectl get pods
# Monitorar estado em tempo real
kubectl get pods -w
# Verificar detalhes do Pod (eventos, uso de recursos, etc.)
kubectl describe pod my-nginx
# Verificar logs do Pod
kubectl logs my-nginx
# Deletar Pod
kubectl delete pod my-nginx
Dica: Pods criados com
kubectl runnao sao recriados automaticamente quando deletados. Em producao, sempre use Deployment.
Depuracao dentro do Pod
# Iniciar shell dentro do Pod
kubectl exec -it my-nginx -- /bin/bash
# Executar comando especifico
kubectl exec my-nginx -- cat /etc/nginx/nginx.conf
# Verificar rede de dentro do Pod
kubectl exec my-nginx -- curl -s localhost
Step 4: Deploy com Manifesto YAML
Em producao, seguindo o principio de Infrastructure as Code, definimos recursos em arquivos YAML. Isso garante controle de versao, revisao e reprodutibilidade.
“Store the declarative configuration in source control. This allows you to roll back and roll forward configurations.”
Manifesto de Deployment
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
# Use labels para organizar recursos
environment: development
version: v1.0.0
spec:
replicas: 3 # Manter 3 replicas de Pod
selector:
matchLabels:
app: my-app
# Configuracao de estrategia de atualizacao
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # Numero de Pods extras que podem ser criados durante atualizacao
maxUnavailable: 0 # Numero de Pods que podem ficar indisponiveis durante atualizacao
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: nginx:1.24
ports:
- containerPort: 80
# Limites de recursos (melhor pratica obrigatoria)
resources:
requests: # Recursos reservados durante agendamento
memory: "64Mi"
cpu: "250m" # 250 milicores = 0.25 CPU
limits: # Limites (OOMKilled ou throttling se exceder)
memory: "128Mi"
cpu: "500m"
# Liveness Probe: Verifica se o Pod esta vivo
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 5
# Readiness Probe: Verifica se pode aceitar trafego
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 3
Aplicando o Deploy
# Aplicar manifesto
kubectl apply -f deployment.yaml
# Verificar estado do Deployment
kubectl get deployments
# Verificar ReplicaSet (criado automaticamente pelo Deployment)
kubectl get replicasets
# Verificar estado dos Pods (filtrar por label selector)
kubectl get pods -l app=my-app
# Exportar informacoes detalhadas em formato YAML
kubectl get deployment my-app -o yaml
Importancia dos Health Checks (Probes)
Os Probes do Kubernetes sao mecanismos para verificar a saude da aplicacao.
| Probe | Proposito | Acao em caso de falha |
|---|---|---|
| livenessProbe | Verifica se o Pod esta vivo | Reinicia o container |
| readinessProbe | Verifica se pode aceitar requisicoes | Remove dos endpoints do Service |
| startupProbe | Verifica se a inicializacao foi concluida | Desabilita liveness/readiness ate conclusao |
Atencao: Se usar verificacao de conexao com DB no livenessProbe, pode causar falha em cascata com reinicio infinito dos Pods quando o DB falhar.
Step 5: Expondo a Aplicacao com Service
Service fornece acesso de rede estavel aos Pods. Pods sao criados e deletados dinamicamente e seus IPs mudam, mas o Service fornece DNS e IP fixos.
Tipos de Service
| Tipo | Uso | Escopo de Acesso |
|---|---|---|
| ClusterIP | Padrao. Apenas interno ao cluster | Comunicacao entre microservicos internos |
| NodePort | Expoe externamente via porta do no | Ambientes de desenvolvimento/teste |
| LoadBalancer | Provisiona LB na nuvem automaticamente | Exposicao externa em producao |
| ExternalName | Alias para servico externo | Conexao com DB externo |
Manifesto de Service
service.yaml
apiVersion: v1
kind: Service
metadata:
name: my-app-service
labels:
app: my-app
spec:
type: NodePort # Para desenvolvimento. Use LoadBalancer em producao
selector:
app: my-app # Encaminha trafego para Pods com este label
ports:
- name: http
protocol: TCP
port: 80 # Porta do Service
targetPort: 80 # Porta do Pod
nodePort: 30080 # Porta do no (30000-32767)
Aplicando e Verificando o Service
# Criar Service
kubectl apply -f service.yaml
# Verificar Service
kubectl get services
# Detalhes do Service (verificar IPs dos Pods nos Endpoints)
kubectl describe service my-app-service
# Verificar Endpoints diretamente
kubectl get endpoints my-app-service
# Obter URL de acesso no minikube
minikube service my-app-service --url
# Abrir no navegador
minikube service my-app-service
Exemplo de Service ClusterIP (para comunicacao interna)
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
type: ClusterIP # Padrao
selector:
app: backend
ports:
- port: 8080
targetPort: 8080
Acessivel de dentro do cluster via backend-service.default.svc.cluster.local ou simplesmente backend-service.
Step 6: Escalonamento
Uma das funcionalidades poderosas do Kubernetes e o escalonamento flexivel.
Escalonamento Manual
# Alterar numero de replicas
kubectl scale deployment my-app --replicas=5
# Verificar aumento de Pods
kubectl get pods -l app=my-app
# Verificar estado do Deployment
kubectl get deployment my-app
Horizontal Pod Autoscaler (HPA)
HPA ajusta automaticamente o numero de Pods com base na utilizacao de CPU ou metricas customizadas.
# Configurar autoscaling baseado em CPU
# Scale out quando CPU exceder 50%
kubectl autoscale deployment my-app --min=2 --max=10 --cpu-percent=50
# Verificar estado do HPA
kubectl get hpa
# Verificar detalhes
kubectl describe hpa my-app
Manifesto YAML do HPA
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
# Controle fino do comportamento de escalonamento
behavior:
scaleDown:
stabilizationWindowSeconds: 300 # Aguardar 5 minutos de estabilidade antes de scale down
Nota: Para usar HPA, o Metrics Server deve estar instalado no cluster. No minikube, habilite com
minikube addons enable metrics-server.
Step 7: Rolling Updates
Os Rolling Updates do Kubernetes permitem atualizar aplicacoes sem downtime.
Executando Atualizacoes
# Atualizar imagem
kubectl set image deployment/my-app my-app=nginx:1.25
# Ou editar manifesto e aplicar
kubectl apply -f deployment.yaml
# Verificar estado do rollout em tempo real
kubectl rollout status deployment/my-app
# Verificar historico de rollout
kubectl rollout history deployment/my-app
# Verificar detalhes de revisao especifica
kubectl rollout history deployment/my-app --revision=2
Rollback
# Rollback para versao anterior
kubectl rollout undo deployment/my-app
# Rollback para revisao especifica
kubectl rollout undo deployment/my-app --to-revision=1
# Pausar rollout (para canary release, etc.)
kubectl rollout pause deployment/my-app
# Retomar rollout
kubectl rollout resume deployment/my-app
Estrategias de Atualizacao
O campo strategy do Deployment especifica a estrategia de atualizacao:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 25% # Porcentagem de Pods extras permitidos durante atualizacao
maxUnavailable: 25% # Porcentagem de Pods que podem parar durante atualizacao
| Configuracao | Efeito |
|---|---|
| maxSurge: 1, maxUnavailable: 0 | Prioridade seguranca (novo Pod inicia antes de parar o antigo) |
| maxSurge: 0, maxUnavailable: 1 | Economia de recursos (para Pod antigo primeiro) |
Step 8: ConfigMap e Secret
Externalizando configuracao e informacoes confidenciais da aplicacao, voce pode alterar configuracoes sem reconstruir a imagem. Isso segue o principio The Twelve-Factor App de “armazenar configuracao em variaveis de ambiente”.
ConfigMap
Armazena dados de configuracao em formato chave-valor.
configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
# Formato chave-valor
APP_ENV: "production"
LOG_LEVEL: "info"
MAX_CONNECTIONS: "100"
# Incorporar como arquivo
nginx.conf: |
server {
listen 80;
location / {
root /usr/share/nginx/html;
}
}
Secret
Armazena dados confidenciais. Valores sao codificados em base64.
secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
data:
# Valores codificados em base64
# echo -n "password123" | base64 → cGFzc3dvcmQxMjM=
DB_PASSWORD: cGFzc3dvcmQxMjM=
API_KEY: c2VjcmV0LWFwaS1rZXk=
Aviso de Seguranca: Por padrao, Secrets do Kubernetes sao apenas codificados em base64, nao criptografados. Para producao, considere:
Usando ConfigMap/Secret em Pods
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: my-app
image: nginx:1.24
# Injetar como variaveis de ambiente
env:
- name: APP_ENVIRONMENT
valueFrom:
configMapKeyRef:
name: app-config
key: APP_ENV
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: app-secret
key: DB_PASSWORD
# Injetar todas as chaves como variaveis de ambiente
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secret
# Montar como arquivo
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
readOnly: true
volumes:
- name: config-volume
configMap:
name: app-config
items:
- key: nginx.conf
path: default.conf
Step 9: Isolamento de Recursos com Namespace
Use Namespace para isolar recursos logicamente.
Criando e Usando Namespaces
# Criar Namespace
kubectl create namespace development
kubectl create namespace staging
kubectl create namespace production
# Verificar Namespaces existentes
kubectl get namespaces
# Criar recurso em Namespace especifico
kubectl apply -f deployment.yaml -n development
# Verificar recursos especificando Namespace
kubectl get pods -n development
# Verificar recursos de todos os Namespaces
kubectl get pods --all-namespaces
kubectl get pods -A # Forma abreviada
Alterando Namespace Padrao
# Verificar contexto atual
kubectl config current-context
# Alterar Namespace padrao
kubectl config set-context --current --namespace=development
# Verificar alteracao
kubectl config view --minify | grep namespace
ResourceQuota por Namespace
Voce pode limitar o uso de recursos por equipe ou ambiente.
apiVersion: v1
kind: ResourceQuota
metadata:
name: development-quota
namespace: development
spec:
hard:
requests.cpu: "4"
requests.memory: "8Gi"
limits.cpu: "8"
limits.memory: "16Gi"
pods: "20"
services: "10"
Comandos kubectl Uteis
Verificando Recursos
# Mostrar todos os recursos
kubectl get all
# Formato de saida amplo
kubectl get pods -o wide
# Saida em formato YAML/JSON
kubectl get deployment my-app -o yaml
kubectl get deployment my-app -o json
# Saida com colunas customizadas
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase
# Watch de recursos (atualizacao em tempo real)
kubectl get pods -w
Depuracao e Troubleshooting
# Executar comando dentro do Pod
kubectl exec -it pod-name -- /bin/sh
# Com multiplos containers, especificar container
kubectl exec -it pod-name -c container-name -- /bin/sh
# Port forward (acesso direto do local para o Pod)
kubectl port-forward pod/my-app-xxx 8080:80
# Port forward para Service
kubectl port-forward service/my-app-service 8080:80
# Verificar eventos do recurso
kubectl get events --sort-by='.lastTimestamp'
# Eventos de Pod especifico
kubectl describe pod my-app-xxx | grep -A 10 Events
Deletando Recursos
# Deletar via manifesto
kubectl delete -f deployment.yaml
# Deletar em lote por label
kubectl delete pods -l app=my-app
# Deletar Namespace (atencao: deleta todos os recursos dentro)
kubectl delete namespace development
# Deletar forcadamente (Pods travados, etc.)
kubectl delete pod my-app-xxx --force --grace-period=0
Melhores Praticas para Ambiente de Producao
1. Configurar Limites de Recursos
Defina requests e limits em todos os containers.
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
Por que e importante: Sem limites de recursos, um Pod pode consumir todos os recursos do no, afetando outros Pods.
2. Implementar Health Checks (Probes)
Sempre configure livenessProbe e readinessProbe.
3. Pod Disruption Budget (PDB)
Manter numero minimo de Pods mesmo durante manutencao.
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: my-app-pdb
spec:
minAvailable: 2 # Ou maxUnavailable: 1
selector:
matchLabels:
app: my-app
4. Configuracao de Anti-Affinity
Distribua Pods em diferentes nos para melhorar disponibilidade.
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: my-app
topologyKey: kubernetes.io/hostname
5. NetworkPolicy
Restrinja trafego de rede dos Pods.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
6. Security Context
Configure privilegios minimos para containers.
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: my-app
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
Erros Comuns e Antipatterns
O que Evitar
| Antipattern | Problema | Solucao |
|---|---|---|
Usar tag latest | Sem reprodutibilidade, atualizacoes inesperadas | Use tags de versao explicitas |
| Sem limites de recursos | Esgotamento de recursos, no down | Sempre configure requests/limits |
| Sem Probes | Deteccao tardia de falhas | Configure liveness/readinessProbe |
| Secrets hardcoded | Risco de seguranca | Use ConfigMap/Secret |
| Executar como root | Risco de seguranca | Configure runAsNonRoot: true |
| Replica unica | Ponto unico de falha | Manter minimo 2 replicas |
Praticas Recomendadas
# Bom exemplo
spec:
replicas: 3
template:
spec:
containers:
- name: my-app
image: my-app:1.2.3 # Versao explicita
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 8080
readinessProbe:
httpGet:
path: /ready
port: 8080
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true
Cleanup
# Deletar recursos
kubectl delete -f service.yaml
kubectl delete -f deployment.yaml
kubectl delete -f configmap.yaml
kubectl delete -f secret.yaml
# Ou deletar tudo de uma vez
kubectl delete -f .
# Deletar Namespace (deleta recursos internos tambem)
kubectl delete namespace development
# Parar minikube
minikube stop
# Deletar minikube completamente
minikube delete
# Deletar todos os profiles
minikube delete --all
Proximos Passos
Com base nos fundamentos aprendidos neste tutorial, recomendamos prosseguir para os seguintes topicos:
Topicos Avancados
- Ingress Controller: Roteamento HTTP/HTTPS e terminacao TLS
- Persistent Volume: Persistencia de dados
- Helm: Gerenciador de pacotes Kubernetes
- Kustomize: Customizacao de manifestos
- Prometheus/Grafana: Monitoramento e dashboards
- Argo CD: Automacao de deploy com GitOps
Links de Referencia
Documentacao Oficial
- Documentacao Oficial do Kubernetes
- Cheat Sheet do kubectl
- Referencia da API Kubernetes
- Documentacao do minikube
Recursos de Aprendizado
- Kubernetes The Hard Way - Por Kelsey Hightower, construa cluster manualmente para entender o funcionamento
- CNCF Cloud Native Trail Map - Roteiro de aprendizado de tecnologias cloud native
- Kubernetes Patterns - Padroes de design do Kubernetes
Melhores Praticas
- Kubernetes Best Practices
- Google Cloud: Kubernetes Best Practices
- Production Best Practices Checklist
Ferramentas
- Lens - IDE para Kubernetes
- k9s - UI baseada em terminal para Kubernetes
- kubectx/kubens - Ferramenta para troca de contexto/Namespace
- stern - Visualizacao de logs multi-Pod
Certificacoes
- CKA (Certified Kubernetes Administrator)
- CKAD (Certified Kubernetes Application Developer)
- CKS (Certified Kubernetes Security Specialist)