Este projeto demonstra como usar Tilt.dev para desenvolvimento local com Kubernetes usando Go. A aplicação consiste em dois componentes:
- API Server: Servidor HTTP com logs estruturados usando Zap e endpoints de saúde.
- Worker: Processo em background que executa uma tarefa agendada com logs estruturados e endpoint de saúde.
.
├── api/ # Código do servidor API
│ ├── main.go # Implementação do servidor API
│ └── Dockerfile # Definição do container da API
├── worker/ # Código do worker
│ ├── main.go # Implementação do worker
│ └── Dockerfile # Definição do container do worker
├── k8s/ # Manifests Kubernetes
│ ├── api.yaml # Deployment da API
│ └── worker.yaml # Deployment do worker
├── Makefile # Comandos de build e desenvolvimento
├── Tiltfile # Configuração do Tilt.dev
└── README.md # Documentação do projeto
- Go 1.23.0 ou superior (toolchain 1.23.1)
- Docker
- Kubernetes (local ou remoto)
- Tilt.dev CLI
Você tem várias opções para rodar Kubernetes localmente:
- Instale o Docker Desktop para Windows
- Ative o WSL2 e instale o Ubuntu
- No Docker Desktop:
- Vá em Settings > Kubernetes
- Ative o Kubernetes
- Clique em "Apply & Restart"
- Aguarde o cluster iniciar
-
Instale o MicroK8s:
# Instalação sudo snap install microk8s --classic # Adicione seu usuário ao grupo microk8s sudo usermod -a -G microk8s $USER sudo chown -f -R $USER ~/.kube # Reinicie sua sessão ou execute: newgrp microk8s
-
Inicie o MicroK8s:
# Iniciar microk8s start # Habilitar addons necessários microk8s enable dns storage # Verificar status microk8s status
-
Configure o kubectl:
# Criar alias para kubectl echo "alias kubectl='microk8s kubectl'" >> ~/.bashrc source ~/.bashrc
# Instalar Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# Iniciar Minikube
minikube start
# Verificar status
minikube status
# Instalar Minikube via Homebrew
brew install minikube
# Iniciar Minikube
minikube start
# Verificar status
minikube status
O Tilt.dev é uma ferramenta que simplifica o desenvolvimento de aplicações em Kubernetes. Com Golang, ele oferece:
- Live Reload: Atualiza automaticamente os containers quando há mudanças no código
- Build Otimizado: Utiliza cache de camadas do Docker para builds mais rápidos
- Logs em Tempo Real: Mostra logs dos containers em tempo real
- Deploy Automático: Faz deploy das alterações no Kubernetes automaticamente
-
O Tiltfile configura:
- Quais arquivos monitorar para mudanças
- Como construir as imagens Docker
- Como fazer deploy no Kubernetes
- Como expor os serviços
-
Quando você faz uma alteração:
- Tilt detecta a mudança
- Reconstrói apenas o container afetado
- Faz deploy da nova versão
- Atualiza os logs em tempo real
-
Instale o Tilt:
curl -fsSL https://raw.githubusercontent.com/tilt-dev/tilt/master/scripts/install.sh | bash
-
Inicie o ambiente:
make tilt-up
- API Server: http://localhost:8080
- Health Check API: http://localhost:8080/health
- Health Check Worker: http://localhost:8081/health
- Healthz Endpoints (usados pelos probes):
- Logs: Disponíveis no terminal do Tilt
- Servidor HTTP com logs estruturados usando Zap
- Endpoint de health check (
/health
) e probe (/healthz
) - Logs em formato JSON com timestamp em UTC-3
- Processo em background com agendamento
- Executa tarefa a cada minuto (configurável)
- Logs estruturados com Zap
- Timestamp em UTC-3 (horário de Brasília)
- Endpoint de health check (
/health
) e probe (/healthz
) em um pequeno servidor HTTP dedicado
Os probes são verificações de saúde que o Kubernetes usa para monitorar a aplicação. Existem três tipos:
- Liveness Probe: Verifica se a aplicação está viva. Se falhar, o Kubernetes reinicia o pod.
- Readiness Probe: Verifica se a aplicação está pronta para receber tráfego. Se falhar, o pod é removido do balanceamento de carga.
- Startup Probe: Verifica se a aplicação iniciou corretamente. Se falhar, o pod é reiniciado.
# Exemplo para a API (k8s/api.yaml)
livenessProbe:
httpGet:
path: /livez # Endpoint específico para liveness
port: 8080
initialDelaySeconds: 5 # Tempo de espera antes da primeira verificação
periodSeconds: 10 # Intervalo entre verificações
timeoutSeconds: 2 # Tempo máximo para a resposta
failureThreshold: 3 # Número de falhas antes de reiniciar
successThreshold: 1 # Número de sucessos para considerar saudável
readinessProbe:
httpGet:
path: /readyz # Endpoint específico para readiness
port: 8080
initialDelaySeconds: 3 # Menor que liveness para começar a receber tráfego mais rápido
periodSeconds: 5 # Verificações mais frequentes que liveness
timeoutSeconds: 1 # Timeout menor que liveness
failureThreshold: 2 # Menos tentativas que liveness
successThreshold: 1 # Um sucesso é suficiente
startupProbe:
httpGet:
path: /healthz # Endpoint específico para startup
port: 8080
initialDelaySeconds: 0 # Começa imediatamente
periodSeconds: 5 # Verifica a cada 5 segundos
timeoutSeconds: 1 # Timeout de 1 segundo
failureThreshold: 30 # Permite até 30 falhas (2.5 minutos) para iniciar
successThreshold: 1 # Um sucesso é suficiente
-
initialDelaySeconds: Tempo de espera antes da primeira verificação
- Liveness: 5s - Dá tempo para a aplicação inicializar
- Readiness: 3s - Começa a verificar mais cedo
- Startup: 0s - Começa imediatamente
-
periodSeconds: Intervalo entre verificações
- Liveness: 10s - Verificações menos frequentes
- Readiness: 5s - Verificações mais frequentes
- Startup: 5s - Verificações moderadas
-
timeoutSeconds: Tempo máximo para a resposta
- Liveness: 2s - Mais tolerante
- Readiness: 1s - Mais rigoroso
- Startup: 1s - Mais rigoroso
-
failureThreshold: Número de falhas antes de tomar ação
- Liveness: 3 - Mais tolerante a falhas
- Readiness: 2 - Menos tolerante
- Startup: 30 - Muito tolerante para dar tempo de iniciar
-
successThreshold: Número de sucessos para considerar saudável
- Todos: 1 - Um sucesso é suficiente
A aplicação expõe endpoints de saúde seguindo as melhores práticas do Kubernetes:
-
/livez
: Endpoint para Liveness Probe- Verifica se o processo está vivo
- Deve ser rápido e leve
- Não verifica dependências externas
- Usado pelo Kubernetes para decidir se deve reiniciar o pod
-
/readyz
: Endpoint para Readiness Probe- Verifica se a aplicação está pronta para receber tráfego
- Pode verificar dependências (banco de dados, cache, etc.)
- Usado pelo Kubernetes para balanceamento de carga
-
/healthz
: Endpoint para Startup Probe- Verifica se a aplicação iniciou corretamente
- Similar ao liveness, mas com threshold mais alto
- Usado pelo Kubernetes durante a inicialização do pod
-
/health
: Endpoint legado para monitoramento- Retorna informações detalhadas sobre a saúde da aplicação
- Pode ser usado para monitoramento externo
- Não é usado pelos probes do Kubernetes
O graceful shutdown é uma prática importante que permite que a aplicação encerre suas operações de forma ordenada quando recebe um sinal de término (SIGTERM ou SIGINT). Isso é crucial para:
- Integridade dos Dados: Garantir que operações em andamento sejam concluídas
- Conexões: Fechar conexões com banco de dados e outros serviços adequadamente
- Logs: Registrar informações importantes antes do encerramento
- Kubernetes: Permitir que o Kubernetes gerencie o ciclo de vida dos pods corretamente
Tanto a API quanto o Worker implementam graceful shutdown usando:
// Criação do canal para sinais
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
// Aguarda o sinal
<-quit
// Executa o shutdown
logger.Info("service_shutting_down")
Você pode testar o graceful shutdown de várias formas:
-
Usando o Makefile:
# Testa o graceful shutdown da API make test-shutdown-api # Testa o graceful shutdown do Worker make test-shutdown-worker
-
Manual:
# Encontra o PID do processo ps aux | grep api-server # ou ps aux | grep worker-server # Envia o sinal SIGTERM kill -TERM <PID>
-
Via Kubernetes:
# Escala o deployment para 0 kubectl scale deployment api-server --replicas=0 # ou kubectl scale deployment worker-server --replicas=0
Ao testar o graceful shutdown, observe:
- Logs: Deve aparecer a mensagem "service_shutting_down"
- Tempo: O processo deve encerrar em até 30 segundos (default do Kubernetes)
- Conexões: Conexões ativas devem ser fechadas adequadamente
- Estado: O estado da aplicação deve estar consistente
# 1. Inicie a aplicação
make tilt-up
# 2. Em outro terminal, teste o graceful shutdown
make test-shutdown-api
# 3. Observe os logs no terminal do Tilt
# Você deve ver:
# - "service_shutting_down"
# - "service_stopped"
# - Conexões sendo fechadas adequadamente
Renato Magalhães
Este projeto está hospedado em: https://github.com/renatomagalhaes/tilt-go
Este projeto está licenciado sob a MIT License - veja o arquivo LICENSE para detalhes.