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:
233
aula-09/README.md
Normal file
233
aula-09/README.md
Normal file
@@ -0,0 +1,233 @@
|
||||
# Aula 09 - n8n via Helm (Cluster Hetzner Cloud)
|
||||
|
||||
Deploy do n8n workflow automation em cluster Kubernetes na Hetzner Cloud com volumes persistentes, LoadBalancer e TLS configurável.
|
||||
|
||||
## Arquitetura
|
||||
|
||||
```
|
||||
Internet
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ LoadBalancer │
|
||||
│ (Hetzner LB) │
|
||||
└────────┬────────┘
|
||||
│
|
||||
▼
|
||||
┌────────────────────────┐
|
||||
│ NGINX Ingress │
|
||||
│ n8n.{domain}:443 │
|
||||
└───────────┬────────────┘
|
||||
│
|
||||
┌─────────────────────────┼─────────────────────────┐
|
||||
│ Namespace: n8n │
|
||||
│ │ │
|
||||
│ ┌────────────────────┼────────────────────┐ │
|
||||
│ │ ▼ │ │
|
||||
│ │ ┌──────────┐ │ │
|
||||
│ │ │ Main │ │ │
|
||||
│ │ │ (n8n) │ │ │
|
||||
│ │ └────┬─────┘ │ │
|
||||
│ │ │ │ │
|
||||
│ │ ┌─────────────┼─────────────┐ │ │
|
||||
│ │ ▼ ▼ ▼ │ │
|
||||
│ │ ┌───────┐ ┌──────────┐ ┌────────┐ │ │
|
||||
│ │ │Workers│ │ Webhooks │ │ MCP │ │ │
|
||||
│ │ │ (2-5) │ │ (1-3) │ │Webhook │ │ │
|
||||
│ │ └───────┘ └──────────┘ └────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ Queue Mode │ │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────────────┼───────────────┐ │
|
||||
│ ▼ ▼ │
|
||||
│ ┌──────────┐ ┌──────────┐ │
|
||||
│ │PostgreSQL│ │ Redis │ │
|
||||
│ │ (10Gi) │ │ (10Gi) │ │
|
||||
│ │ hcloud │ │ hcloud │ │
|
||||
│ └──────────┘ └──────────┘ │
|
||||
└───────────────────────────────────────────────────┘
|
||||
Hetzner Cloud
|
||||
```
|
||||
|
||||
## Pré-requisitos
|
||||
|
||||
1. **Cluster Talos na Hetzner** (aula-08) com:
|
||||
- Hetzner CSI Driver (StorageClass: hcloud-volumes)
|
||||
- NGINX Ingress Controller com LoadBalancer
|
||||
2. **kubectl** instalado
|
||||
3. **Helm** 3.x instalado
|
||||
|
||||
## Contexto do Cluster
|
||||
|
||||
Esta aula usa o cluster Kubernetes provisionado na **aula-08**. O `kubeconfig` foi gerado automaticamente pelo OpenTofu e está em `aula-08/kubeconfig`.
|
||||
|
||||
```bash
|
||||
# Verificar se o cluster está acessível
|
||||
export KUBECONFIG=$(pwd)/../aula-08/kubeconfig
|
||||
kubectl cluster-info
|
||||
|
||||
# Esperado:
|
||||
# Kubernetes control plane is running at https://<floating-ip>:6443
|
||||
```
|
||||
|
||||
## Instalação
|
||||
|
||||
```bash
|
||||
cd aula-09
|
||||
|
||||
# Configurar acesso ao cluster (kubeconfig da aula-08)
|
||||
export KUBECONFIG=$(pwd)/../aula-08/kubeconfig
|
||||
|
||||
# Executar setup interativo
|
||||
chmod +x setup.sh
|
||||
./setup.sh
|
||||
```
|
||||
|
||||
O script é interativo e pergunta:
|
||||
1. **Hostname do n8n** (ex: `n8n.kube.quest`) - FQDN completo
|
||||
2. **Usa CloudFlare?** (com proxy/CDN)
|
||||
3. **Ativar Let's Encrypt?** (se não usar CloudFlare)
|
||||
|
||||
### Opções de TLS
|
||||
|
||||
| Cenário | TLS Provider | Configuração |
|
||||
|---------|--------------|--------------|
|
||||
| **CloudFlare (proxy)** | CloudFlare Edge | Sem cert-manager, TLS na borda |
|
||||
| **Outro DNS + Let's Encrypt** | cert-manager | HTTP-01 challenge automático |
|
||||
| **Outro DNS + HTTP** | Nenhum | Apenas HTTP (dev/workshop) |
|
||||
|
||||
### Exemplo de Instalação
|
||||
|
||||
```
|
||||
═══════════════════════════════════════════════════
|
||||
n8n no Kubernetes (Hetzner Cloud)
|
||||
═══════════════════════════════════════════════════
|
||||
|
||||
Digite o hostname do n8n (ex: n8n.kube.quest): n8n.kube.quest
|
||||
|
||||
Você usa CloudFlare para DNS?
|
||||
1) Sim (com proxy/CDN ativado - ícone laranja)
|
||||
2) Não
|
||||
Escolha [1/2]: 1
|
||||
|
||||
[INFO] CloudFlare irá gerenciar TLS automaticamente na edge
|
||||
[OK] Configuração salva em .env
|
||||
|
||||
...instalação...
|
||||
|
||||
═══════════════════════════════════════════════════
|
||||
Configure o DNS
|
||||
═══════════════════════════════════════════════════
|
||||
|
||||
No painel do CloudFlare (https://dash.cloudflare.com):
|
||||
|
||||
Tipo: A
|
||||
Nome: n8n
|
||||
Conteúdo: 123.45.67.89
|
||||
Proxy: ✓ (ícone laranja)
|
||||
|
||||
O CloudFlare cuida do TLS automaticamente!
|
||||
|
||||
Acesse: https://n8n.kube.quest
|
||||
```
|
||||
|
||||
## Componentes Instalados
|
||||
|
||||
**Da aula-08 (infraestrutura):**
|
||||
- Hetzner CSI Driver (StorageClass: hcloud-volumes)
|
||||
- NGINX Ingress Controller com LoadBalancer
|
||||
|
||||
**Instalados por este script:**
|
||||
- **cert-manager** (se Let's Encrypt ativado)
|
||||
- **n8n** com todos os componentes
|
||||
|
||||
| Componente | Réplicas | Recursos | Volume |
|
||||
|------------|----------|----------|--------|
|
||||
| Main (n8n) | 1 | 256Mi-1Gi RAM | 10Gi |
|
||||
| Workers | 2-5 (HPA) | 256Mi-512Mi RAM | - |
|
||||
| Webhooks | 1-3 (HPA) | 128Mi-256Mi RAM | - |
|
||||
| PostgreSQL | 1 | - | 10Gi |
|
||||
| Redis | 1 | - | 10Gi |
|
||||
|
||||
**Total volumes:** 30Gi (~$1.45/mês)
|
||||
|
||||
## Multi-Tenant: Adicionar Clientes
|
||||
|
||||
Para provisionar n8n para múltiplos clientes em namespaces separados:
|
||||
|
||||
```bash
|
||||
# Adicionar novo cliente
|
||||
./add-client.sh acme
|
||||
|
||||
# Isso cria:
|
||||
# - Namespace: acme-n8n
|
||||
# - n8n em: https://acme-n8n.{domain}
|
||||
# - Grupo GitLab: /acme/ (se GitLab instalado - aula-10)
|
||||
```
|
||||
|
||||
O script `add-client.sh` herda a configuração do `.env` gerado pelo `setup.sh`.
|
||||
|
||||
### Padrão de Domínio
|
||||
|
||||
Os clientes usam o padrão `{cliente}-n8n.{domain}`:
|
||||
- `acme-n8n.kube.quest`
|
||||
- `empresa-n8n.kube.quest`
|
||||
|
||||
Se você configurou um wildcard DNS (`*.kube.quest`), os novos clientes funcionam automaticamente.
|
||||
|
||||
## Arquivo de Configuração
|
||||
|
||||
O `setup.sh` gera um arquivo `.env` com as configurações:
|
||||
|
||||
```bash
|
||||
# aula-09/.env (gerado automaticamente)
|
||||
N8N_HOST=n8n.kube.quest
|
||||
DOMAIN=kube.quest
|
||||
USE_CLOUDFLARE=true
|
||||
USE_LETSENCRYPT=false
|
||||
LETSENCRYPT_EMAIL=
|
||||
```
|
||||
|
||||
Este arquivo é usado pelo `add-client.sh` e em re-execuções do `setup.sh`.
|
||||
|
||||
## 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
|
||||
|
||||
# Ver volumes
|
||||
kubectl get pvc -n n8n
|
||||
|
||||
# Ver certificado (se Let's Encrypt)
|
||||
kubectl get certificate -n n8n
|
||||
|
||||
# Desinstalar (apenas n8n)
|
||||
./cleanup.sh
|
||||
|
||||
# Ou manualmente:
|
||||
helm uninstall n8n -n n8n
|
||||
kubectl delete pvc --all -n n8n
|
||||
kubectl delete ns n8n
|
||||
```
|
||||
|
||||
**Nota:** O `cleanup.sh` remove apenas n8n, clientes e cert-manager. A infraestrutura (CSI Driver, NGINX Ingress, LoadBalancer) é mantida pois pertence à aula-08.
|
||||
|
||||
## Custos Estimados
|
||||
|
||||
| Recurso | Custo/mês |
|
||||
|---------|-----------|
|
||||
| Volumes (3x 10Gi) | ~$1.45 |
|
||||
| Worker (compartilhado) | ~$0.80 |
|
||||
| **Total por cliente** | ~$2.25 |
|
||||
|
||||
## Para Ambiente Local
|
||||
|
||||
Se você quer testar em um cluster local (Docker Desktop, minikube), veja a **aula-06**.
|
||||
Reference in New Issue
Block a user