From e75b245c3bdc96bdc87c8baa7f0cca6e00b9fd96 Mon Sep 17 00:00:00 2001 From: Allyson de Paula Date: Wed, 31 Dec 2025 21:58:43 -0300 Subject: [PATCH] docs: Adicionar README.md e simplificar CLAUDE.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - README.md com visão completa do workshop (jornada, arquitetura, custos) - CLAUDE.md simplificado para instruções concisas ao Claude Code --- CLAUDE.md | 211 ++++++++++++++---------------------------------------- README.md | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 254 insertions(+), 159 deletions(-) create mode 100644 README.md diff --git a/CLAUDE.md b/CLAUDE.md index 554d5a6..155078e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,177 +1,70 @@ # CLAUDE.md -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. +Instruções para Claude Code neste repositório. -## Project Overview +## Visão Geral -This is a workshop repository for teaching Docker and Kubernetes concepts, specifically focusing on container health checks and liveness probes. It contains a deliberately "buggy" Node.js app that hangs after a configurable number of requests to demonstrate how container orchestration handles unhealthy containers. +Workshop progressivo: Docker → Kubernetes → GitOps na Hetzner Cloud. +App de demonstração: `node-bugado` - trava após N requests para demonstrar health checks. -## Repository Structure +## Estrutura -- **aula-01/**: Docker Compose lesson - basic container deployment with restart policies -- **aula-02/**: Kubernetes lesson - deployment with liveness probes and ConfigMaps -- **aula-03/**: Kubernetes lesson - high availability with replicas and readiness probes -- **aula-04/**: Kubernetes lesson - NGINX Ingress with Keep Request (Lua) for zero-downtime -- **aula-05/**: Kubernetes lesson - KEDA + Victoria Metrics for metrics-based auto-scaling -- **aula-06/**: Kubernetes lesson - n8n deployment via Helm (LOCAL environment - Docker Desktop, minikube, kind) -- **aula-07/**: Talos Linux - creating custom Talos image for Hetzner Cloud -- **aula-08/**: OpenTofu - provisioning HA Talos Kubernetes cluster on Hetzner Cloud with CCM and LoadBalancer -- **aula-09/**: Kubernetes lesson - n8n deployment via Helm (Hetzner Cloud with CSI Driver and multi-tenant support) -- **aula-10/**: Kubernetes lesson - GitLab deployment via Helm with Container Registry and SSH -- **aula-11/**: Kubernetes lesson - ArgoCD + GitLab Runner for GitOps CI/CD pipelines +| Aula | Tema | Ambiente | +|------|------|----------| +| 01 | Docker Compose, restart policies | Local | +| 02 | Liveness Probe | Local | +| 03 | Replicas + Readiness Probe | Local | +| 04 | NGINX Keep Request (Lua) | Local | +| 05 | KEDA + Victoria Metrics | Local | +| 06 | n8n via Helm | Local | +| 07 | Talos Linux (snapshot Hetzner) | Hetzner | +| 08 | Cluster HA (OpenTofu + CCM + CSI) | Hetzner | +| 09 | n8n multi-tenant | Hetzner | +| 10 | GitLab + Registry + SSH | Hetzner | +| 11 | ArgoCD + GitLab Runner | Hetzner | -## Running the Examples - -### Aula 01 (Docker Compose) -```bash -cd aula-01 -docker-compose up -``` -The app runs on port 3000. After MAX_REQUESTS (default 3), the app stops responding. - -### Aula 02 (Kubernetes) -```bash -cd aula-02 -kubectl apply -f configmap.yaml -kubectl apply -f deployment.yaml -kubectl apply -f service.yaml -``` -Access via NodePort 30080. The liveness probe at `/health` will detect when the app hangs and restart the container. - -### Aula 03 (Kubernetes - High Availability) -```bash -cd aula-03 -kubectl apply -f configmap.yaml -kubectl apply -f deployment.yaml -kubectl apply -f service.yaml -``` -Builds on Aula 02 with multiple replicas and a readiness probe. When one pod hangs, the others continue serving requests. The readiness probe removes unhealthy pods from the Service immediately, while the liveness probe restarts them. - -### Aula 04 (Kubernetes - NGINX Ingress with Keep Request) -Requires NGINX Ingress Controller with Lua support. +## Comandos Rápidos ```bash -cd aula-04 -kubectl apply -f configmap.yaml -kubectl apply -f deployment.yaml -kubectl apply -f service.yaml -kubectl apply -f ingress-nginx.yaml +# Aulas 01-06 (Local) +cd aula-XX && ./setup.sh # ou kubectl apply -f . + +# Aulas 07-11 (Hetzner) +cd aula-08 && ./setup.sh # Cluster base +cd aula-09 && ./setup.sh # n8n +cd aula-10 && ./setup.sh # GitLab +cd aula-11 && ./setup.sh # ArgoCD ``` -Access via NGINX Ingress. The Keep Request pattern uses Lua to hold requests when backends are unavailable, waiting up to 99s for a pod to become ready instead of returning 503 immediately. This eliminates user-visible failures during pod restarts. -### Aula 05 (Kubernetes - KEDA Auto-scaling) -```bash -cd aula-05 -./setup.sh +## App node-bugado + +```javascript +// Aceita requests até MAX_REQUESTS (default: 3) +// Depois para de responder (simula crash) +// /health também para de responder ``` -Installs Victoria Metrics (metrics collection), KEDA (event-driven autoscaling), and NGINX Ingress. The ScaledObject monitors metrics like unavailable pods and restart counts, automatically scaling the deployment from 5 to 30 replicas based on demand. -### Aula 06 (Kubernetes - n8n via Helm - LOCAL) -```bash -cd aula-06 -./setup.sh -``` -Deploys n8n workflow automation platform via Helm chart in a LOCAL Kubernetes cluster (Docker Desktop, minikube, kind). Queue Mode architecture with main node, workers (2-5 replicas with HPA), webhooks (1-3 replicas with HPA), PostgreSQL, and Redis. Access via http://n8n.localhost (requires NGINX Ingress). +Demonstra: +- `restart: always` não é suficiente +- Liveness probes detectam apps travadas +- Readiness probes evitam tráfego para pods não-prontos -### Aula 07 (Talos Linux - Custom Image) -Follow the instructions in `aula-07/README.md` to create a custom Talos Linux image on Hetzner Cloud using Talos Factory. This is a prerequisite for Aula 08. +## Variáveis de Ambiente -### Aula 08 (OpenTofu - Talos Cluster on Hetzner Cloud) -```bash -cd aula-08 -./setup.sh -``` -Provisions a full HA Kubernetes cluster on Hetzner Cloud using OpenTofu: -- 3x Control Plane nodes (CAX11 ARM64) -- 1x Worker node (CAX11 ARM64) -- Private network, Floating IP, Firewall -- Cluster Autoscaler support (1-5 workers) -- Estimated cost: ~€18/month (base), up to ~€33/month with max autoscaling +- `MAX_REQUESTS`: Requests antes de travar (default: 3) +- `HCLOUD_TOKEN`: Token da Hetzner Cloud (aulas 08-11) -Prerequisites: -- OpenTofu (`brew install opentofu`) -- talosctl (`brew install siderolabs/tap/talosctl`) -- kubectl -- Hetzner Cloud API token -- Talos image ID from Aula 07 +## Padrões do Projeto -Optional - Enable cluster autoscaling: -```bash -./install-autoscaler.sh -``` -This installs the Kubernetes Cluster Autoscaler configured for Hetzner Cloud, automatically scaling workers from 1 to 5 based on pending pods. +Cada aula contém: +- `README.md` - Documentação completa +- `setup.sh` - Instalação automatizada +- `cleanup.sh` - Remoção limpa +- Manifests YAML ou Helm values -Optional - Install Hetzner Cloud Controller Manager and NGINX Ingress with LoadBalancer: -```bash -./install-ccm.sh -./install-nginx-ingress.sh -``` -This enables automatic LoadBalancer provisioning and exposes HTTP/HTTPS/SSH via a single Hetzner LoadBalancer (~$5/month). - -To destroy the infrastructure: `./cleanup.sh` - -### Aula 09 (Kubernetes - n8n via Helm - Hetzner Cloud) -```bash -cd aula-09 -export KUBECONFIG=/path/to/aula-08/kubeconfig -./setup.sh -``` -Deploys n8n workflow automation platform via Helm chart on Hetzner Cloud. Installs Hetzner CSI Driver for persistent volumes (10Gi minimum). Includes multi-tenant support with `add-client.sh` script for provisioning clients in separate namespaces. - -Prerequisites: -- Completed Aula 08 (Talos cluster on Hetzner) -- Hetzner Cloud API token - -### Aula 10 (Kubernetes - GitLab via Helm) -```bash -cd aula-10 -./setup.sh -``` -Deploys GitLab via official Helm chart with: -- Web UI at git.kube.quest -- Container Registry at registry.git.kube.quest -- SSH access via port 22 (TCP passthrough through NGINX) -- PostgreSQL, Redis, and MinIO for storage -- Resource requests of ~4GB to occupy one dedicated CAX11 worker - -Prerequisites: -- Completed Aula 08 (Talos cluster) -- Hetzner CSI Driver (Aula 09) -- Hetzner CCM and NGINX Ingress with LoadBalancer (Aula 08) -- DNS configured pointing to LoadBalancer IP - -To remove: `./cleanup.sh` - -### Aula 11 (Kubernetes - ArgoCD + GitLab Runner) -```bash -cd aula-11 -export KUBECONFIG=/path/to/aula-08/kubeconfig -./setup.sh -``` -Implements GitOps CI/CD pipeline with: -- GitLab Runner (Kubernetes executor) for CI pipelines -- ArgoCD for declarative GitOps continuous deployment -- Integration with GitLab self-hosted (aula-10) -- Example application with Dockerfile and GitLab CI pipeline - -Pipeline flow: git push → GitLab CI (build) → Registry (push) → GitOps repo (update) → ArgoCD (sync) → Kubernetes (deploy) - -Prerequisites: -- Completed Aula 10 (GitLab) -- NGINX Ingress with LoadBalancer -- DNS configured for ArgoCD hostname - -To remove: `./cleanup.sh` - -## App Behavior - -The Node.js app (`app.js`) is intentionally designed to: -1. Accept requests normally until `MAX_REQUESTS` is reached -2. Stop responding (hang) after the limit, simulating a crashed but running process -3. The `/health` endpoint also stops responding when the app is "stuck" - -This behavior demonstrates why process-level monitoring (restart: always) is insufficient and why application-level health checks (liveness probes) are necessary. - -## Environment Variables - -- `MAX_REQUESTS`: Number of requests before the app hangs (default: 3) +Scripts seguem o padrão: +1. Verificar pré-requisitos +2. Coletar configuração interativamente +3. Salvar em `.env` para reutilização +4. Instalar via kubectl/helm +5. Exibir URLs e credenciais diff --git a/README.md b/README.md new file mode 100644 index 0000000..e5794fc --- /dev/null +++ b/README.md @@ -0,0 +1,202 @@ +# Workshop: Docker, Kubernetes e GitOps na Prática + +Workshop progressivo que evolui de containers básicos até um cluster Kubernetes de produção com GitOps na Hetzner Cloud. + +## Jornada de Aprendizado + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ FUNDAMENTOS (Local) │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ Aula 01 Aula 02 Aula 03 Aula 04 Aula 05 │ +│ Docker Liveness Replicas Keep Request KEDA │ +│ Compose Probe Readiness (Lua) Auto-scaling │ +│ │ │ │ │ │ │ +│ └──────────────┴──────────────┴──────────────┴──────────────┘ │ +│ │ │ +│ App "node-bugado" │ +│ (trava após N requests) │ +└─────────────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────────────┐ +│ APLICAÇÕES (Local) │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ Aula 06 │ +│ n8n via Helm (Queue Mode + HPA) │ +│ PostgreSQL + Redis │ +└─────────────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────────────┐ +│ INFRAESTRUTURA (Hetzner Cloud) │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ Aula 07 Aula 08 │ +│ Talos Linux ──────────────► Cluster K8s HA │ +│ (imagem custom) OpenTofu + CCM + CSI │ +│ Autoscaler (1-5 workers) │ +└─────────────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────────────┐ +│ PLATAFORMA (Hetzner Cloud) │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ Aula 09 Aula 10 Aula 11 │ +│ n8n (Hetzner) GitLab ArgoCD + Runner │ +│ Multi-tenant Registry + SSH GitOps CI/CD │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +## Aulas + +| Aula | Tema | Ambiente | Conceitos | +|------|------|----------|-----------| +| 01 | Docker Compose | Local | Containers, restart policies | +| 02 | Liveness Probe | Local | Health checks, auto-restart | +| 03 | High Availability | Local | Replicas, readiness probe | +| 04 | Keep Request | Local | NGINX Lua, zero-downtime | +| 05 | KEDA | Local | Auto-scaling por métricas | +| 06 | n8n (Local) | Local | Helm, Queue Mode, HPA | +| 07 | Talos Linux | Hetzner | Imagem customizada, Factory | +| 08 | Cluster HA | Hetzner | OpenTofu, CCM, CSI, Autoscaler | +| 09 | n8n (Cloud) | Hetzner | Multi-tenant, CSI Driver | +| 10 | GitLab | Hetzner | Registry, SSH, Helm | +| 11 | ArgoCD | Hetzner | GitOps, Runner, CI/CD | + +## Pré-requisitos + +### Aulas 01-06 (Local) +- Docker Desktop, OrbStack, ou similar +- kubectl +- Helm 3.x + +### Aulas 07-11 (Hetzner Cloud) +- Conta na Hetzner Cloud +- hcloud CLI +- OpenTofu +- talosctl +- Domínio configurado (ex: kube.quest) + +## Quick Start + +### Local (Docker Desktop) +```bash +# Aula 01 - Docker básico +cd aula-01 && docker-compose up + +# Aula 02-05 - Kubernetes local +cd aula-02 && kubectl apply -f . +``` + +### Hetzner Cloud +```bash +# 1. Criar imagem Talos (aula-07) +# Siga o README.md da aula-07 + +# 2. Provisionar cluster (aula-08) +cd aula-08 && ./setup.sh + +# 3. Instalar aplicações +cd aula-09 && ./setup.sh # n8n +cd aula-10 && ./setup.sh # GitLab +cd aula-11 && ./setup.sh # ArgoCD +``` + +## Custos Estimados (Hetzner Cloud) + +| Componente | Recurso | Custo/mês | +|------------|---------|-----------| +| Control Plane | 3x CAX11 | ~€13.77 | +| Workers | 1-5x CAX11 | €4.59-€22.95 | +| LoadBalancer | LB11 | ~€5.99 | +| Volumes | 40-80Gi | €1.94-€3.88 | +| **Total** | | **~€26-€47** | + +## Arquitetura Final + +``` + CloudFlare (DNS + CDN) + │ + ┌─────────────┼─────────────┐ + │ │ │ + ▼ ▼ ▼ + git.kube.quest n8n.kube.quest argocd.kube.quest + │ │ │ + └─────────────┼─────────────┘ + │ + ▼ + ┌─────────────────────────┐ + │ Hetzner LoadBalancer │ + │ :80 :443 :22 │ + └───────────┬─────────────┘ + │ + ▼ + ┌─────────────────────────┐ + │ NGINX Ingress │ + │ (TCP passthrough) │ + └───────────┬─────────────┘ + │ + ┌───────────────────────┼───────────────────────┐ + │ │ │ + ▼ ▼ ▼ +┌───────────────┐ ┌───────────────┐ ┌───────────────┐ +│ GitLab │ │ n8n │ │ ArgoCD │ +│ (namespace) │ │ (namespace) │ │ (namespace) │ +│ │ │ │ │ │ +│ - Webservice │ │ - Main │ │ - Server │ +│ - Sidekiq │ │ - Workers │ │ - Repo Server │ +│ - Registry │ │ - Webhooks │ │ - Controller │ +│ - PostgreSQL │ │ - PostgreSQL │ │ - Redis │ +│ - Redis │ │ - Redis │ │ │ +│ - MinIO │ │ │ │ GitLab Runner │ +└───────────────┘ └───────────────┘ └───────────────┘ + │ │ + └───────────────────────────────────────────┘ + GitOps Pipeline + git push → build → registry → sync → deploy +``` + +## App de Demonstração: node-bugado + +Aplicação Node.js que **trava intencionalmente** após N requisições: + +```javascript +// Aceita requests até MAX_REQUESTS +// Depois para de responder (simula crash) +// /health também para de responder +``` + +Usada para demonstrar: +- Por que `restart: always` não é suficiente +- Como liveness probes detectam apps travadas +- Como readiness probes evitam tráfego para pods não-prontos +- Como KEDA escala baseado em métricas de saúde + +## Estrutura do Repositório + +``` +workshop/ +├── README.md # Este arquivo +├── CLAUDE.md # Instruções para Claude Code +├── aula-01/ # Docker Compose +├── aula-02/ # Liveness Probe +├── aula-03/ # Replicas + Readiness +├── aula-04/ # NGINX Keep Request +├── aula-05/ # KEDA + Victoria Metrics +├── aula-06/ # n8n Local +├── aula-07/ # Talos Linux Image +├── aula-08/ # Cluster Hetzner (OpenTofu) +├── aula-09/ # n8n Hetzner +├── aula-10/ # GitLab +└── aula-11/ # ArgoCD + GitLab Runner +``` + +Cada aula contém: +- `README.md` - Documentação completa +- `setup.sh` - Script de instalação (quando aplicável) +- `cleanup.sh` - Script de remoção +- Manifests YAML ou Helm values + +## Licença + +MIT