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:
107
aula-06/README.md
Normal file
107
aula-06/README.md
Normal 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
51
aula-06/cleanup.sh
Executable 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 ""
|
||||
@@ -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:
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user