Workshop completo: aulas 08-10 com Talos, n8n e GitLab na Hetzner

Aula 08 - Cluster Kubernetes HA:
- Setup interativo com OpenTofu para Talos na Hetzner
- CCM, CSI Driver, Cluster Autoscaler, Metrics Server
- NGINX Ingress com LoadBalancer (HTTP/HTTPS/SSH)

Aula 09 - n8n na Hetzner:
- Deploy via Helm com PostgreSQL e Redis
- Suporte multi-tenant com add-client.sh
- Integração com Hetzner CSI para volumes persistentes

Aula 10 - GitLab na Hetzner:
- Setup agnóstico: CloudFlare (trusted proxies) ou Let's Encrypt
- Anti-affinity para distribuir webservice/sidekiq em nós diferentes
- Container Registry e SSH via TCP passthrough
- Documentação do erro 422 e solução com trustedCIDRsForXForwardedFor

Melhorias gerais:
- READMEs atualizados com arquitetura e troubleshooting
- Scripts cleanup.sh para todas as aulas
- CLAUDE.md atualizado com contexto do projeto
This commit is contained in:
Allyson de Paula
2025-12-31 17:57:02 -03:00
parent 50dc74c1d8
commit 07b7ee62d3
35 changed files with 4665 additions and 311 deletions

107
aula-06/README.md Normal file
View File

@@ -0,0 +1,107 @@
# Aula 06 - n8n via Helm (Ambiente LOCAL)
Deploy do n8n workflow automation em cluster Kubernetes local usando Helm.
## Arquitetura
```
┌─────────────────────────────────────────────────────────────┐
│ Cluster Local │
│ (Docker Desktop / minikube / kind / k3d) │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ NGINX Ingress │ │
│ │ http://n8n.localhost │ │
│ └────────────────────────┬────────────────────────────┘ │
│ │ │
│ ┌────────────────────────┼────────────────────────────┐ │
│ │ Namespace: n8n │ │
│ │ │ │ │
│ │ ┌────────────────────┼────────────────────┐ │ │
│ │ │ ▼ │ │ │
│ │ │ ┌──────────┐ │ │ │
│ │ │ │ Main │ │ │ │
│ │ │ │ (n8n) │ │ │ │
│ │ │ └────┬─────┘ │ │ │
│ │ │ │ │ │ │
│ │ │ ┌─────────────┼─────────────┐ │ │ │
│ │ │ ▼ ▼ ▼ │ │ │
│ │ │ ┌───────┐ ┌──────────┐ ┌────────┐ │ │ │
│ │ │ │Workers│ │ Webhooks │ │ MCP │ │ │ │
│ │ │ │ (2-5) │ │ (1-3) │ │Webhook │ │ │ │
│ │ │ └───────┘ └──────────┘ └────────┘ │ │ │
│ │ │ │ │ │
│ │ │ Queue Mode │ │ │
│ │ └────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌───────────────┼───────────────┐ │ │
│ │ ▼ ▼ │ │
│ │ ┌──────────┐ ┌──────────┐ │ │
│ │ │PostgreSQL│ │ Redis │ │ │
│ │ │ (1Gi) │ │ (1Gi) │ │ │
│ │ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
## Pré-requisitos
- Cluster Kubernetes local:
- Docker Desktop com Kubernetes habilitado
- minikube (`minikube start`)
- kind (`kind create cluster`)
- k3d (`k3d cluster create`)
- kubectl configurado
- Helm 3.x instalado
## Instalação
```bash
cd aula-06
chmod +x setup.sh
./setup.sh
```
O script instala automaticamente:
1. NGINX Ingress Controller
2. n8n com todos os componentes
## Acesso
**URL:** http://n8n.localhost
Se `n8n.localhost` não resolver, adicione ao `/etc/hosts`:
```
127.0.0.1 n8n.localhost
```
## Componentes
| Componente | Réplicas | Recursos |
|------------|----------|----------|
| Main (n8n) | 1 | 256Mi-1Gi RAM |
| Workers | 2-5 (HPA) | 256Mi-512Mi RAM |
| Webhooks | 1-3 (HPA) | 128Mi-256Mi RAM |
| PostgreSQL | 1 | 1Gi volume |
| Redis | 1 | 1Gi volume |
## Comandos Úteis
```bash
# Ver pods
kubectl get pods -n n8n
# Ver logs do n8n
kubectl logs -f -n n8n deployment/n8n
# Ver autoscaling
kubectl get hpa -n n8n
# Desinstalar
helm uninstall n8n -n n8n
kubectl delete ns n8n
```
## Para Cluster Hetzner Cloud
Se você quer fazer deploy em um cluster Hetzner Cloud com volumes persistentes e LoadBalancer, veja a **aula-09**.

51
aula-06/cleanup.sh Executable file
View File

@@ -0,0 +1,51 @@
#!/bin/bash
# =============================================================================
# Cleanup da Aula 06 - Remove n8n (ambiente LOCAL)
# =============================================================================
set -e
# Cores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
echo ""
echo "============================================"
echo " Cleanup - Aula 06 (n8n LOCAL)"
echo "============================================"
echo ""
# Remover n8n
log_info "Removendo n8n..."
helm uninstall n8n -n n8n 2>/dev/null || true
log_success "Helm release removida"
# Remover PVCs
log_info "Removendo PVCs..."
kubectl delete pvc --all -n n8n 2>/dev/null || true
log_success "PVCs removidos"
# Remover namespace
log_info "Removendo namespace n8n..."
kubectl delete namespace n8n 2>/dev/null || true
log_success "Namespace removido"
# Opcional: remover NGINX Ingress
read -p "Remover NGINX Ingress também? (s/N): " remove_ingress
if [[ "$remove_ingress" =~ ^[Ss]$ ]]; then
log_info "Removendo NGINX Ingress..."
helm uninstall nginx-ingress -n ingress-nginx 2>/dev/null || true
kubectl delete namespace ingress-nginx 2>/dev/null || true
log_success "NGINX Ingress removido"
fi
echo ""
log_success "Cleanup concluído!"
echo ""

View File

@@ -1,10 +1,12 @@
# =============================================================================
# n8n Helm Chart - Custom Values
# n8n Helm Chart - Custom Values (Ambiente LOCAL)
# =============================================================================
# Aula 06 - Deploy n8n via Helm
# Aula 06 - Deploy n8n via Helm em cluster local
#
# Chart: community-charts/n8n
# Docs: https://community-charts.github.io/docs/charts/n8n/configuration
#
# Para cluster Hetzner Cloud, veja aula-09/
# =============================================================================
# -----------------------------------------------------------------------------
@@ -35,7 +37,7 @@ postgresql:
primary:
persistence:
enabled: true
size: 5Gi
size: 1Gi # Ambiente local - sem mínimo
# -----------------------------------------------------------------------------
# Redis (necessário para Queue Mode)
@@ -46,6 +48,10 @@ redis:
auth:
enabled: true
password: "n8n-redis-workshop-2025"
master:
persistence:
enabled: true
size: 1Gi # Ambiente local - sem mínimo
# -----------------------------------------------------------------------------
# Ingress NGINX
@@ -58,7 +64,7 @@ ingress:
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
hosts:
- host: n8n.kube.quest
- host: n8n.localhost
paths:
- path: /
pathType: Prefix
@@ -71,7 +77,7 @@ main:
N8N_SECURE_COOKIE: "false" # Permite HTTP sem HTTPS (apenas para dev/workshop)
persistence:
enabled: true
size: 2Gi
size: 1Gi # Ambiente local - sem mínimo
mountPath: "/home/node/.n8n"
resources:
requests:
@@ -121,7 +127,7 @@ worker:
webhook:
mode: queue
count: 1
url: "https://n8n.kube.quest"
url: "http://n8n.localhost"
extraEnvVars:
N8N_SECURE_COOKIE: "false"
resources:

View File

@@ -1,6 +1,6 @@
#!/bin/bash
# =============================================================================
# Setup da Aula 06 - n8n via Helm
# Setup da Aula 06 - n8n via Helm (Ambiente LOCAL)
# =============================================================================
#
# Este script instala e configura:
@@ -8,7 +8,7 @@
# 2. n8n com PostgreSQL, Redis, Workers e Webhooks
#
# Pré-requisitos:
# - Kubernetes cluster rodando (k3s, minikube, kind, etc)
# - Kubernetes cluster LOCAL rodando (Docker Desktop, minikube, kind, k3d)
# - kubectl configurado
# - Helm 3.x instalado
#
@@ -52,6 +52,10 @@ log_success "kubectl encontrado"
# Verificar conexão com cluster
if ! kubectl cluster-info &> /dev/null; then
log_error "Não foi possível conectar ao cluster Kubernetes."
log_info "Verifique se seu cluster local está rodando:"
log_info " - Docker Desktop: Habilite Kubernetes nas configurações"
log_info " - minikube: minikube start"
log_info " - kind: kind create cluster"
exit 1
fi
log_success "Conectado ao cluster Kubernetes"
@@ -67,68 +71,7 @@ log_success "Helm $(helm version --short) encontrado"
echo ""
# =============================================================================
# 1. INSTALAR HETZNER CSI DRIVER (para provisionar volumes)
# =============================================================================
log_info "=== Configurando Hetzner CSI Driver ==="
# Verificar se secret já existe (evita pedir token novamente)
if kubectl get secret hcloud -n kube-system &> /dev/null; then
log_success "Secret hcloud já existe em kube-system"
else
# Pedir token via input interativo
echo ""
log_info "Token da Hetzner Cloud necessário para provisionar volumes."
log_info "Crie um token em: https://console.hetzner.cloud/projects/*/security/tokens"
echo ""
log_info "Cole o token e pressione ENTER:"
# Desabilita echo, lê linha completa, reabilita echo
stty -echo
IFS= read -r HCLOUD_TOKEN
stty echo
echo ""
if [ -z "$HCLOUD_TOKEN" ]; then
log_error "Token não pode ser vazio."
exit 1
fi
log_info "Criando secret hcloud em kube-system..."
kubectl create secret generic hcloud \
--namespace=kube-system \
--from-literal=token="$HCLOUD_TOKEN"
log_success "Secret hcloud criado"
fi
# Instalar Hetzner CSI Driver via Helm (se não instalado)
if helm status hcloud-csi -n kube-system &> /dev/null; then
log_success "Hetzner CSI Driver já está instalado"
else
log_info "Instalando Hetzner CSI Driver..."
helm repo add hcloud https://charts.hetzner.cloud 2>/dev/null || true
helm repo update hcloud
helm install hcloud-csi hcloud/hcloud-csi \
--namespace kube-system \
--wait \
--timeout 5m
log_success "Hetzner CSI Driver instalado"
fi
# Verificar StorageClass
log_info "Verificando StorageClass..."
if kubectl get storageclass hcloud-volumes &> /dev/null; then
log_success "StorageClass hcloud-volumes disponível"
else
log_error "StorageClass hcloud-volumes não encontrado"
exit 1
fi
echo ""
# =============================================================================
# 2. INSTALAR NGINX INGRESS (se não existir)
# 1. INSTALAR NGINX INGRESS (se não existir)
# =============================================================================
log_info "=== Verificando NGINX Ingress ==="
@@ -152,7 +95,7 @@ fi
echo ""
# =============================================================================
# 3. CRIAR NAMESPACE E APLICAR SECRETS
# 2. CRIAR NAMESPACE E APLICAR SECRETS
# =============================================================================
log_info "=== Configurando namespace n8n ==="
@@ -169,7 +112,7 @@ fi
echo ""
# =============================================================================
# 4. INSTALAR n8n VIA HELM
# 3. INSTALAR n8n VIA HELM
# =============================================================================
log_info "=== Instalando n8n ==="
@@ -201,7 +144,7 @@ fi
echo ""
# =============================================================================
# 5. AGUARDAR PODS FICAREM PRONTOS
# 4. AGUARDAR PODS FICAREM PRONTOS
# =============================================================================
log_info "=== Aguardando pods ficarem prontos ==="
@@ -248,7 +191,6 @@ echo -e "${GREEN} Setup Completo!${NC}"
echo "=============================================="
echo ""
echo "Componentes instalados:"
echo " - Hetzner CSI Driver (StorageClass: hcloud-volumes)"
echo " - NGINX Ingress Controller"
echo " - n8n (namespace: n8n)"
echo " - Main node"
@@ -279,15 +221,6 @@ echo ""
echo " # Desinstalar"
echo " helm uninstall n8n -n n8n"
echo ""
echo " # Fazer upgrade do helm chart"
echo " helm upgrade --reuse-values --values custom-values.yaml n8n community-charts/n8n --namespace n8n"
echo ""
echo " # Verificar historico de releases"
echo " helm history n8n -n n8n"
echo ""
echo " # Fazer rollback do historico de releases"
echo " helm rollback n8n <nº da release>"
echo ""
echo "=============================================="
echo ""