https://github.com/migbertweb/mi-cluster-k3s-hetzner
MI CLUSTER K3S CON TERRAFORM
https://github.com/migbertweb/mi-cluster-k3s-hetzner
Last synced: 4 months ago
JSON representation
MI CLUSTER K3S CON TERRAFORM
- Host: GitHub
- URL: https://github.com/migbertweb/mi-cluster-k3s-hetzner
- Owner: migbertweb
- Created: 2025-05-25T00:59:36.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2025-06-09T21:05:08.000Z (12 months ago)
- Last Synced: 2025-06-09T22:20:11.918Z (12 months ago)
- Language: HCL
- Size: 71.3 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# 🚀 Mi Cluster K3s en Hetzner Cloud
> Infraestructura como Código (IaC) completa para desplegar un cluster Kubernetes (K3s) en Hetzner Cloud usando Terraform, con un stack moderno de herramientas y aplicaciones.
[](https://opensource.org/licenses/MIT)
[](https://www.terraform.io/)
[](https://k3s.io/)
## 📋 Tabla de Contenidos
- [Descripción](#-descripción)
- [Características](#-características)
- [Arquitectura](#-arquitectura)
- [Requisitos Previos](#-requisitos-previos)
- [Instalación](#-instalación)
- [Estructura del Proyecto](#-estructura-del-proyecto)
- [Uso](#-uso)
- [Aplicaciones Incluidas](#-aplicaciones-incluidas)
- [Monitoreo y Observabilidad](#-monitoreo-y-observabilidad)
- [CI/CD](#cicd)
- [Seguridad](#-seguridad)
- [Troubleshooting](#-troubleshooting)
- [Contribuir](#-contribuir)
- [Licencia](#-licencia)
- [Autor](#-autor)
## 🎯 Descripción
Este proyecto proporciona una solución completa para desplegar un cluster Kubernetes ligero (K3s) en Hetzner Cloud utilizando Terraform. Incluye toda la infraestructura necesaria, desde la creación de servidores hasta el despliegue de aplicaciones, pasando por la configuración de controladores de ingreso, gestión de certificados SSL/TLS, monitoreo y almacenamiento persistente.
### ¿Por qué K3s?
- **Ligero**: Diseñado para entornos con recursos limitados
- **Rápido**: Inicio en segundos
- **Compatible**: 100% compatible con Kubernetes
- **Simple**: Instalación y mantenimiento sencillos
## ✨ Características
### Infraestructura
- ✅ **Terraform** para IaC (Infrastructure as Code)
- ✅ **Hetzner Cloud** como proveedor de infraestructura
- ✅ **Red privada** para comunicación entre nodos
- ✅ **Firewall** configurado con reglas de seguridad
- ✅ **Volúmenes persistentes** para almacenamiento NFS
### Kubernetes
- ✅ **K3s** como distribución de Kubernetes
- ✅ **Hetzner Cloud Controller Manager** para integración nativa
- ✅ **Múltiples nodos** (1 master + workers configurables)
- ✅ **Almacenamiento dinámico** con NFS-subdir-external-provisioner
### Networking
- ✅ **Traefik Ingress Controller** (configurado por defecto)
- ✅ **Nginx Ingress Controller** (opcional)
- ✅ **Let's Encrypt** con DNS-01 challenge (Cloudflare)
- ✅ **Cert-Manager** para gestión automática de certificados
### Aplicaciones
- ✅ **MariaDB** con phpMyAdmin
- ✅ **Redis** para caché y sesiones
- ✅ **Aplicación PHP** de ejemplo con CI/CD
- ✅ **ArgoCD** para GitOps (opcional)
### Monitoreo
- ✅ **Prometheus** para métricas
- ✅ **Grafana** para visualización
- ✅ **Metrics Server** para métricas del cluster
- ✅ **AlertManager** (incluido en kube-prometheus-stack)
### Seguridad
- ✅ **SOPS** para encriptación de secretos
- ✅ **KSOPS** para integración con Kubernetes
- ✅ **RBAC** configurado
- ✅ **Security contexts** en pods
## 🏗️ Arquitectura
```
┌─────────────────────────────────────────────────────────────┐
│ Hetzner Cloud │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Master Node │ │ Worker Nodes │ │
│ │ (K3s) │◄────►│ (K3s) │ │
│ │ │ │ │ │
│ │ - NFS Vol │ │ │ │
│ └──────┬───────┘ └──────┬───────┘ │
│ │ │ │
│ └─────────┬───────────┘ │
│ │ │
│ ┌─────────▼──────────┐ │
│ │ Private Network │ │
│ │ (10.0.0.0/16) │ │
│ └────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Load Balancer (Traefik/Nginx) │ │
│ └──────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
## 📦 Requisitos Previos
Antes de comenzar, asegúrate de tener instalado:
- **Terraform** >= 1.11.1
- **kubectl** (última versión estable)
- **Helm** >= 3.0
- **SOPS** (Mozilla SOPS para encriptación)
- **Kustomize** (incluido en kubectl >= 1.14)
- **Git**
- **SSH** configurado con clave privada
- **Cuenta de Hetzner Cloud** con API token
- **Cuenta de Cloudflare** (para DNS-01 challenge, opcional)
### Instalación de herramientas
```bash
# Terraform
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=$(dpkg --print-architecture)] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt update && sudo apt install terraform
# kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# SOPS
wget https://github.com/mozilla/sops/releases/download/v3.8.1/sops-v3.8.1.linux
chmod +x sops-v3.8.1.linux
sudo mv sops-v3.8.1.linux /usr/local/bin/sops
```
## 🚀 Instalación
### 1. Clonar el Repositorio
```bash
git clone https://github.com/migbertweb/mi-cluster-k3s-hetzner.git
cd mi-cluster-k3s-hetzner
```
### 2. Configurar Terraform
Navega al directorio de Terraform:
```bash
cd infrastructure/terraform-install/
```
#### 2.1. Verificar versión del provider
Edita `main.tf` y verifica/actualiza la versión del provider de Hetzner Cloud:
```hcl
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
version = "1.50.0" # Verifica la última versión en Terraform Registry
}
}
```
#### 2.2. Crear archivo de variables
Crea un archivo `.tfvars` con tu token de API de Hetzner:
```bash
cat > .tfvars < cloud-init.yaml
sops --decrypt cloud-init-worker.enc.yaml > cloud-init-worker.yaml
```
Revisa los archivos generados y luego elimínalos (no los commitees):
```bash
rm cloud-init.yaml cloud-init-worker.yaml
```
### 4. Desplegar Infraestructura
```bash
# Inicializar Terraform
terraform init
# Verificar plan (sin aplicar cambios)
terraform plan -var-file .tfvars
# Aplicar cambios (creará servidores en Hetzner Cloud)
terraform apply -var-file .tfvars
```
⚠️ **NOTA CRÍTICA**: Guarda todos los IDs de la salida (outputs), especialmente:
- `network_id`: ID de la red privada
- `volume_id`: ID del volumen NFS
- `master_private_ip`: IP privada del nodo master
- `worker_ips`: IPs privadas de los nodos worker
### 5. Configurar kubectl
```bash
# Crear directorio de configuración
mkdir -p ~/.kube
# Copiar configuración de K3s desde el master
scp -i ~/.ssh/tu_clave_privada root@:/etc/rancher/k3s/k3s.yaml ~/.kube/config
# Editar configuración para usar IP pública
sed -i "s/127.0.0.1//g" ~/.kube/config
# Verificar conexión
kubectl get nodes
kubectl get pods -A
```
### 6. Instalar Hetzner Cloud Controller Manager
```bash
cd ../../infrastructure/hcloud-secret/
# Editar el secret encriptado con el network_id obtenido
sops hcloud-secret.enc.yaml
# Actualiza el network-id en el archivo
# Aplicar el secret
kustomize build --enable-alpha-plugins --enable-exec . | kubectl apply -f -
# Instalar Cloud Controller Manager (verifica la versión más reciente)
kubectl -n kube-system apply -f https://github.com/hetznercloud/hcloud-cloud-controller-manager/releases/download/v1.23.0/ccm-networks.yaml
```
### 7. Instalar Traefik Ingress Controller
```bash
cd ../traefik-ingress-controller/
# Aplicar secret de Cloudflare (si usas DNS-01)
kubectl apply -f traefik-secret.yaml
# Editar values.yaml con tu dominio
nano values.yaml
# Actualiza el dominio en las anotaciones del LoadBalancer
# Añadir repositorio de Helm
helm repo add traefik https://traefik.github.io/charts
helm repo update
# Instalar Traefik
helm upgrade --install traefik traefik/traefik \
--namespace traefik \
--create-namespace \
-f values.yaml
```
Verifica que el LoadBalancer se haya creado correctamente:
```bash
kubectl get svc -n traefik
kubectl describe node master-node | grep "ProviderID"
```
### 8. Instalar StorageClass NFS
```bash
cd ../storage-nfs-provisoring/
# Añadir repositorio de Helm
helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
helm repo update
# Instalar NFS Provisioner
helm install nfs-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \
--namespace nfs-provisioner \
--create-namespace \
--values nfs-provisioner-values.yaml
```
### 9. Instalar Metrics Server
```bash
cd ../metric-server/
# Añadir repositorio
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm repo update
# Instalar
helm upgrade --install metrics-server metrics-server/metrics-server \
--namespace kube-system \
-f values.yaml
```
### 10. Instalar Cert-Manager (Opcional)
```bash
cd ../otros/cert-manager/
# Añadir repositorio
helm repo add jetstack https://charts.jetstack.io
helm repo update
# Instalar cert-manager
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--values=values.yaml \
--version v1.17.1
# Aplicar ClusterIssuers
cd kustomize/
kustomize build --enable-alpha-plugins --enable-exec overlays/prod | kubectl apply -f -
# Verificar
kubectl get ClusterIssuer -A
```
### 11. Instalar Stack de Monitoreo (Opcional)
```bash
cd ../monitoring/
# Aplicar secret de Grafana
kustomize build --enable-alpha-plugins --enable-exec . | kubectl apply -f -
# Añadir repositorio
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
# Instalar Prometheus y Grafana
helm install monitoring prometheus-community/kube-prometheus-stack \
-f values.yaml \
-n monitoring \
--create-namespace
# Verificar
kubectl get pods -n monitoring
```
## 📁 Estructura del Proyecto
```
mi-cluster-k3s-hetzner/
├── apps/ # Aplicaciones desplegadas en el cluster
│ ├── deployCICD/ # Aplicación PHP con CI/CD
│ │ ├── app/ # Código fuente de la aplicación
│ │ ├── Dockerfile # Imagen Docker
│ │ └── k8s/ # Manifiestos Kubernetes
│ ├── mariadb/ # MariaDB + phpMyAdmin
│ │ ├── base/ # Configuración base
│ │ └── overlays/ # Overlays para dev/prod
│ └── redis/ # Redis
│ ├── base/
│ └── overlays/
├── infrastructure/ # Infraestructura y componentes del cluster
│ ├── terraform-install/ # Terraform para crear infraestructura
│ │ ├── main.tf # Configuración principal
│ │ ├── cloud-init.enc.yaml # Configuración master (encriptado)
│ │ └── cloud-init-worker.enc.yaml
│ ├── hcloud-secret/ # Secret para Hetzner Cloud Controller
│ ├── traefik-ingress-controller/ # Traefik
│ ├── storage-nfs-provisoring/ # NFS StorageClass
│ ├── metric-server/ # Metrics Server
│ └── otros/ # Componentes adicionales
│ ├── cert-manager/ # Cert-Manager
│ ├── monitoring/ # Prometheus + Grafana
│ ├── nginx-ingress-controller/ # Nginx Ingress (alternativa)
│ └── argocd/ # ArgoCD (GitOps)
├── .github/
│ └── workflows/ # GitHub Actions para CI/CD
├── LICENSE # Licencia MIT
└── README.md # Este archivo
```
## 💻 Uso
### Desplegar una Aplicación
#### MariaDB
```bash
cd apps/mariadb/
kustomize build overlays/prod | kubectl apply -f -
```
**Importante**: Después de desplegar, agrega el puerto 3306 al Load Balancer en Hetzner Cloud:
- Protocol: TCP
- Public Port: 3306
- Target Port: 32306
#### Redis
```bash
cd apps/redis/
kustomize build overlays/prod | kubectl apply -f -
```
#### Aplicación PHP (CI/CD)
La aplicación se despliega automáticamente mediante GitHub Actions al hacer push al repositorio.
### Acceder a Aplicaciones
- **Traefik Dashboard**: `https://traefik.tu-dominio.com`
- **Grafana**: `https://grafana.tu-dominio.com` (si está instalado)
- **phpMyAdmin**: `https://phpmyadmin.tu-dominio.com` (si está instalado)
### Gestión de Secretos
Los secretos están encriptados con SOPS. Para editarlos:
```bash
sops archivo-secreto.enc.yaml
```
Para aplicar secretos con KSOPS:
```bash
kustomize build --enable-alpha-plugins --enable-exec . | kubectl apply -f -
```
## 🔧 Aplicaciones Incluidas
### 1. Aplicación PHP con Redis
- Aplicación PHP simple que usa Redis para contador de visitas
- Incluye Dockerfile y CI/CD con GitHub Actions
- Despliegue automático al hacer push
### 2. MariaDB
- Base de datos MariaDB con StatefulSet
- phpMyAdmin para gestión web
- Configuración con Kustomize para dev/prod
- Persistencia con PVC
### 3. Redis
- Redis para caché y sesiones
- Configuración con secretos encriptados
- Persistencia opcional
## 📊 Monitoreo y Observabilidad
### Prometheus
- Recolecta métricas del cluster y aplicaciones
- Configurado con ServiceMonitors
- Retención configurable
### Grafana
- Dashboards preconfigurados
- Visualización de métricas
- Alertas configurables
### Metrics Server
- Métricas de recursos (CPU, memoria)
- Requerido para HPA y VPA
## 🔄 CI/CD
El proyecto incluye GitHub Actions para CI/CD:
- **Build**: Construye imagen Docker
- **Test**: Ejecuta pruebas (si están configuradas)
- **Deploy**: Despliega automáticamente al cluster
- **Notifications**: Envía notificaciones a Telegram
Ver `.github/workflows/deploycicd.yml` para más detalles.
## 🔒 Seguridad
### Buenas Prácticas Implementadas
- ✅ Secretos encriptados con SOPS
- ✅ RBAC configurado
- ✅ Security contexts en pods
- ✅ Network policies (configurables)
- ✅ Firewall de Hetzner configurado
- ✅ Certificados SSL/TLS automáticos
- ✅ Read-only root filesystem donde es posible
### Recomendaciones Adicionales
- Rotar tokens y secretos regularmente
- Usar namespaces para aislar aplicaciones
- Implementar Network Policies
- Habilitar audit logging
- Revisar logs regularmente
## 🐛 Troubleshooting
### Problemas Comunes
#### Los pods no se crean
```bash
kubectl describe pod -n
kubectl logs -n
```
#### Problemas con el Load Balancer
```bash
kubectl get svc -A
kubectl describe svc -n
```
Verifica en Hetzner Cloud que el Load Balancer esté configurado correctamente.
#### Problemas con certificados
```bash
kubectl get cert -A
kubectl describe cert -n
kubectl get challenges
kubectl describe challenge
```
#### Problemas con almacenamiento
```bash
kubectl get pvc -A
kubectl describe pvc -n
kubectl get pv
```
### Comandos Útiles
```bash
# Ver estado del cluster
kubectl get nodes
kubectl get pods -A
kubectl get svc -A
# Ver logs
kubectl logs -f -n
# Ejecutar shell en pod
kubectl exec -it -n -- /bin/sh
# Describir recursos
kubectl describe -n
# Ver eventos
kubectl get events -A --sort-by='.lastTimestamp'
```
## 🤝 Contribuir
Las contribuciones son bienvenidas. Por favor:
1. Fork el proyecto
2. Crea una rama para tu feature (`git checkout -b feature/AmazingFeature`)
3. Commit tus cambios (`git commit -m 'Add some AmazingFeature'`)
4. Push a la rama (`git push origin feature/AmazingFeature`)
5. Abre un Pull Request
## 📝 Licencia
Este proyecto está bajo la Licencia MIT. Ver el archivo [LICENSE](LICENSE) para más detalles.
**Nota especial**: Se recomienda encarecidamente (aunque no es obligatorio) que las obras derivadas mantengan este mismo espíritu de código libre y abierto, especialmente cuando se utilicen con fines educativos o de investigación.
## 👤 Autor
**Migbertweb**
- GitHub: [@migbertweb](https://github.com/migbertweb)
- Repositorio: [https://github.com/migbertweb/mi-cluster-k3s-hetzner](https://github.com/migbertweb/mi-cluster-k3s-hetzner)
## 🙏 Agradecimientos
- [K3s](https://k3s.io/) - Kubernetes ligero
- [Hetzner Cloud](https://www.hetzner.com/cloud) - Proveedor de infraestructura
- [Terraform](https://www.terraform.io/) - Infrastructure as Code
- [Traefik](https://traefik.io/) - Ingress Controller
- [Prometheus](https://prometheus.io/) - Monitoreo
- [Grafana](https://grafana.com/) - Visualización
---
⭐ Si este proyecto te ha sido útil, considera darle una estrella en GitHub.