En este post quiero compartir la arquitectura y el proceso que seguí para desplegar mi blog y portfolio personal en un cluster de Kubernetes completamente auto-hospedado. Lo que comenzó como un proyecto de aprendizaje se convirtió en una infraestructura robusta que combina virtualización, networking avanzado y GitOps.
La Aplicación: Blog Penny
El portfolio está construido con Django 5.2.7 y Python 3.13, con soporte completo para Markdown, resaltado de sintaxis para código, y un panel de administración personalizado. La aplicación incluye un blog técnico y un portfolio para mostrar proyectos y habilidades.
El stack tecnológico incluye:
- Backend: Django + Gunicorn + PostgreSQL 15
- Frontend: HTML5, CSS3, JavaScript vanilla
- Containerización: Docker multi-stage
- Orquestación: Kubernetes + Helm Charts
El código fuente está disponible en github.com/luisito666/portfolio-blog.
Arquitectura de la Infraestructura

Capa de Virtualización: Proxmox
Todo corre sobre un servidor físico en OVH que ejecuta Proxmox VE como hipervisor. Proxmox me permite gestionar máquinas virtuales y aprovechar al máximo los recursos del servidor dedicado.
La configuración de red del host es fundamental para exponer los servicios:
auto vmbr0
iface vmbr0 inet static
address 158.69.253.159/24
gateway 158.69.253.254
bridge-ports eno1
post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up echo 1 > /proc/sys/net/ipv4/conf/vmbr0/proxy_arp
auto vmbr1
iface vmbr1 inet static
address 10.10.0.1/30
bridge-ports eno2
post-up iptables -t nat -A POSTROUTING -s '10.10.0.0/30' -o vmbr0 -j MASQUERADE
post-up iptables -t nat -A PREROUTING -p tcp -d 158.69.253.159 --dport 80 -j DNAT --to-destination 10.10.0.2
post-up iptables -t nat -A PREROUTING -p tcp -d 158.69.253.159 --dport 443 -j DNAT --to-destination 10.10.0.2
La configuración crea dos bridges: vmbr0 conectado a internet con la IP pública, y vmbr1 como red interna que conecta con pfSense. Las reglas de iptables hacen NAT y port-forwarding de los puertos 80, 443 y 1194 (OpenVPN) hacia pfSense.
Capa de Seguridad: pfSense
pfSense actúa como firewall y gateway entre internet y la red interna del laboratorio. Tiene dos interfaces:
- WAN: 10.10.0.2/30 (conectada a vmbr1 del Proxmox)
- LAN: 192.168.17.1/24 (red interna donde viven las VMs)
pfSense recibe todo el tráfico HTTP/HTTPS desde el Proxmox y lo reenvía hacia el LoadBalancer de MetalLB (192.168.17.230). Esta capa adicional me permite tener control granular sobre qué servicios expongo y añade protección contra ataques.
También tengo configurado OpenVPN para acceder de forma segura a la red 192.168.17.0/24 desde cualquier lugar, lo que me permite administrar el cluster sin exponerlo directamente a internet.
El Cluster de Kubernetes
El cluster fue aprovisionado con kubeadm sobre 4 máquinas virtuales Ubuntu:
| Rol | IP | Notas |
|---|---|---|
| Master | 192.168.17.52 | API Server (no expuesto a internet) |
| Node 1 | 192.168.17.53 | Worker |
| Node 2 | 192.168.17.54 | Worker |
| Node 3 | 192.168.17.55 | Worker |
Una decisión importante de seguridad fue no exponer el API Server de Kubernetes a internet. Solo es accesible desde la red LAN o a través de la VPN, añadiendo una capa extra de protección.
Servicios del Cluster: El Ecosistema Cloud-Native
ArgoCD: GitOps y App of Apps Pattern
ArgoCD es el corazón del despliegue continuo. Implementé el patrón App of Apps, donde una aplicación raíz de ArgoCD gestiona todas las demás aplicaciones del cluster.
La infraestructura como código está en github.com/Mt2-SAAS/bootstrap, que contiene:
- Definiciones de aplicaciones ArgoCD
- Helm charts para cada servicio
- Configuración centralizada
Cuando hago un push a cualquier repositorio, ArgoCD detecta los cambios y sincroniza automáticamente el estado del cluster.
Sealed Secrets: Secretos Seguros en Git
Un problema clásico de GitOps es cómo manejar secretos sin commitearlos en texto plano. Sealed Secrets resuelve esto mediante encriptación asimétrica: los secretos se encriptan con la clave pública del cluster y solo pueden desencriptarse dentro del mismo.
Esto me permite versionar los secretos junto con el resto de la infraestructura sin comprometer la seguridad.
Longhorn: Almacenamiento Distribuido
Longhorn proporciona almacenamiento persistente distribuido para el cluster. Cada volumen se replica automáticamente entre los nodos, garantizando alta disponibilidad para:
- La base de datos PostgreSQL del portfolio
- Archivos media subidos por usuarios
- Datos de otras aplicaciones
CloudNativePG: PostgreSQL Cloud-Native
En lugar de gestionar PostgreSQL manualmente, uso CloudNativePG como operador. Esto me da:
- Despliegue declarativo de clusters PostgreSQL
- Backups automatizados
- Failover automático
- Integración nativa con los volúmenes de Longhorn
Cert-Manager: Certificados SSL Automáticos
Cert-Manager gestiona automáticamente los certificados SSL con Let's Encrypt. Cada Ingress que creo obtiene su certificado válido sin intervención manual, renovándose automáticamente antes de expirar.
NGINX Gateway Fabric + MetalLB: Exposición de Servicios
NGINX Gateway Fabric actúa como ingress controller, manejando todo el tráfico HTTP/HTTPS entrante y enrutándolo a los servicios correctos.
Para que funcione en un cluster bare-metal, uso MetalLB como LoadBalancer. MetalLB asigna IPs del pool 192.168.17.230-235 a los servicios de tipo LoadBalancer.
El flujo del tráfico es:
Internet → IP Pública (OVH) → Proxmox (iptables) → pfSense (WAN)
→ pfSense (LAN) → MetalLB (192.168.17.230) → NGINX Gateway Fabric
→ Pod del Portfolio
El Helm Chart del Portfolio
El portfolio se despliega usando un Helm chart personalizado ubicado en charts/portfolio/. El chart incluye:
- Deployment: Pod con Django + Nginx sidecar
- Service: ClusterIP para acceso interno
- Ingress: Configuración con anotaciones para cert-manager
- ConfigMap: Variables de entorno no sensibles
- Secrets: Credenciales de base de datos (gestionados con Sealed Secrets)
- PVC: Volúmenes para media files
- HPA: Auto-scaling horizontal basado en CPU
La configuración permite ajustar réplicas, recursos, dominio y TLS simplemente modificando el values.yaml.
Flujo de Despliegue Completo
- Desarrollo local: Desarrollo y pruebo con Docker Compose
- Push a GitHub: Subo los cambios al repositorio
- Build automático: GitHub Actions construye la imagen Docker
- Push a registry: La imagen se publica en Docker Hub
- Detección de ArgoCD: ArgoCD detecta el nuevo tag de imagen
- Sincronización: ArgoCD aplica los cambios al cluster
- Rollout: Kubernetes hace rolling update de los pods
- Verificación: Los health checks confirman que todo está funcionando
Todo el proceso es automático después del push inicial. Si algo falla, ArgoCD puede hacer rollback al estado anterior.
Lecciones Aprendidas
La seguridad en capas es fundamental. Tener pfSense como gateway, no exponer el API de Kubernetes, y usar Sealed Secrets crea múltiples barreras que un atacante tendría que superar.
GitOps simplifica todo. Una vez configurado, ArgoCD hace que los despliegues sean predecibles y auditables. Puedo ver exactamente qué está desplegado y revertir cambios fácilmente.
Los operadores de Kubernetes valen la pena. CloudNativePG y Longhorn abstraen complejidad que sería difícil de manejar manualmente, especialmente para alta disponibilidad.
Documentar la infraestructura es crítico. Sin la documentación de las reglas de iptables y la topología de red, sería muy difícil troubleshootear problemas.
Conclusión
Este proyecto demuestra que es posible tener una infraestructura de nivel producción en un homelab o servidor dedicado. La combinación de Proxmox, pfSense, Kubernetes y herramientas cloud-native proporciona una plataforma robusta, segura y automatizada.
El portfolio está corriendo en luisito.dev, desplegado automáticamente cada vez que hago cambios al código. La infraestructura como código está versionada, los secretos están seguros, y puedo dormir tranquilo sabiendo que cert-manager renovará mis certificados.
Si estás considerando montar algo similar, mi consejo es empezar simple e ir añadiendo componentes gradualmente. Cada pieza añade complejidad, pero también capacidades que hacen que valga la pena.
Repositorios: - Portfolio: github.com/luisito666/portfolio-blog - Bootstrap (IaC): github.com/Mt2-SAAS/bootstrap
Stack completo: Django • PostgreSQL • Docker • Kubernetes • Helm • ArgoCD • Sealed Secrets • Longhorn • CloudNativePG • Cert-Manager • NGINX Gateway Fabric • MetalLB • pfSense • Proxmox • OpenVPN