WordPress Multisitio Escalable con Kubernetes y Docker
Imagina un WordPress Multisitio que no se cae cuando un sitio se vuelve viral, que escala horizontalmente sin sudar y que despliega actualizaciones en segundos. Eso no es un sueño, es una realidad cuando combinas la potencia de WordPress Kubernetes con la flexibilidad de Docker WordPress. Este artículo es una guía técnica, paso a paso, para construir una arquitectura de multisitio escalable que soporte miles de sitios sin despeinarse.
Vamos a enterrar los viejos servidores LAMP y a dar la bienvenida a la orquestación contenedores. Prepárate para una inmersión profunda en alta disponibilidad, almacenamiento persistente y redes definidas por software.
¿Por qué Kubernetes y Docker para WordPress Multisitio?
Un WordPress Multisitio tradicional (subdominios o subdirectorios) tiene un talón de Aquiles: el cuello de botella en la base de datos y el servidor web. Cuando un sitio recibe picos de tráfico, todo el ecosistema sufre. Con Docker WordPress empaquetamos la aplicación en contenedores ligeros y con WordPress Kubernetes orquestamos esos contenedores para que se auto-gestionen.
Beneficios clave de esta arquitectura
- Escalado horizontal automático: Kubernetes añade o quita réplicas de WordPress según la carga de CPU o memoria.
- Alta disponibilidad: Si un contenedor muere, Kubernetes lo reinicia en segundos. Si un nodo falla, los pods se redistribuyen.
- Despliegues sin downtime: Actualizas plugins, temas o el core de WordPress con actualizaciones progresivas (rolling updates).
- Aislamiento por sitio: Cada sitio del multisitio puede tener sus propios recursos, límites y configuraciones.
- Portabilidad: Tu stack funciona igual en AWS, GCP, Azure o tu propio datacenter.
[INFO] Kubernetes no es una varita mágica. Requiere curva de aprendizaje y un equipo con conocimientos de contenedores. Pero para proyectos que necesitan escalar de verdad, es la mejor inversión.
Arquitectura de Referencia: Componentes Esenciales
Antes de escribir código, entendamos los bloques de construcción. Nuestra arquitectura se compone de:
1. Cluster Kubernetes (el cerebro)
- Nodos: Al menos 2 nodos worker (para alta disponibilidad) y un plano de control gestionado (EKS, AKS, GKE) o auto-gestionado (kubeadm).
- Namespaces: Un namespace dedicado (ej:
wordpress-multisite) para aislar recursos.
2. WordPress como contenedor (Docker WordPress)
- Imagen base:
wordpress:latestcon PHP-FPM y Nginx (o Apache) en el mismo pod. - Configuración dinámica: Variables de entorno para
WP_HOME,WP_SITEURL,DOMAIN_CURRENT_SITE. - Persistencia: Los uploads y los archivos de temas/plugins se guardan en un volumen persistente (NFS, EBS, o Longhorn).
3. Base de datos escalable (el talón de Aquiles)
- Opción A: Base de datos externa gestionada (RDS, Cloud SQL) con réplicas de lectura.
- Opción B: MariaDB o MySQL en Kubernetes con StatefulSet y almacenamiento persistente. Ideal para entornos on-premise.
4. Almacenamiento compartido (el pegamento)
- NFS o S3: Los archivos subidos por los usuarios deben ser accesibles desde todos los pods. Un volumen NFS o un bucket S3 con plugin como
WP Offload Mediaes obligatorio.
5. Ingress Controller (la puerta de entrada)
- Ingress Nginx o Traefik: Enruta el tráfico a los pods de WordPress según el dominio. Para multisitio, necesitas un Ingress que soporte
server-snippetpara mapear subdominios.
Setup Paso a Paso: Despliegue de WordPress Multisitio
Vamos a la práctica. Asumimos que tienes un cluster Kubernetes funcionando y kubectl configurado.
1. Crear el Namespace y los Secrets
kubectl create namespace wordpress-multisite
kubectl create secret generic wordpress-secrets \
--from-literal=WORDPRESS_DB_HOST=tu-db-host \
--from-literal=WORDPRESS_DB_USER=admin \
--from-literal=WORDPRESS_DB_PASSWORD=supersecreto \
--from-literal=AUTH_KEY=$(openssl rand -base64 32) \
--from-literal=SECURE_AUTH_KEY=$(openssl rand -base64 32) \
-n wordpress-multisite
2. Configurar el Storage Class y Persistent Volume
Para los uploads, necesitamos un volumen compartido. Usaremos NFS como ejemplo.
# nfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: wordpress-uploads-pv
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany
nfs:
server: 192.168.1.100
path: "/exports/wordpress-uploads"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress-uploads-pvc
namespace: wordpress-multisite
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Gi
3. Desplegar WordPress con ConfigMap para Multisitio
Aquí está el corazón del asunto. Necesitamos activar el modo multisitio en wp-config.php mediante un ConfigMap.
# wordpress-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: wordpress-config
namespace: wordpress-multisite
data:
wp-config.php: |
<?php
define('WP_DEBUG', false);
define('WP_ALLOW_MULTISITE', true);
define('MULTISITE', true);
define('SUBDOMAIN_INSTALL', true); // o false para subdirectorios
define('DOMAIN_CURRENT_SITE', $_SERVER['HTTP_HOST']);
define('PATH_CURRENT_SITE', '/');
define('SITE_ID_CURRENT_SITE', 1);
define('BLOG_ID_CURRENT_SITE', 1);
define('WP_HOME', 'https://' . $_SERVER['HTTP_HOST']);
define('WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST']);
// ... resto de configuraciones de seguridad
Ahora, el Deployment con la imagen Docker WordPress y el ConfigMap montado.
# wordpress-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
namespace: wordpress-multisite
spec:
replicas: 3
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress:6.4-php8.2-fpm-alpine
envFrom:
- secretRef:
name: wordpress-secrets
env:
- name: WORDPRESS_CONFIG_EXTRA
valueFrom:
configMapKeyRef:
name: wordpress-config
key: wp-config.php
volumeMounts:
- name: uploads
mountPath: /var/www/html/wp-content/uploads
- name: wordpress-config
mountPath: /var/www/html/wp-config.php
subPath: wp-config.php
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
volumes:
- name: uploads
persistentVolumeClaim:
claimName: wordpress-uploads-pvc
- name: wordpress-config
configMap:
name: wordpress-config
4. El Ingress que maneja subdominios
Para un multisitio con subdominios (ej: site1.tudominio.com, site2.tudominio.com), el Ingress debe capturar todos los subdominios y pasarlos a WordPress.
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wordpress-ingress
namespace: wordpress-multisite
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/server-snippet: |
if ($host ~* ^(.+)\.tudominio\.com$) {
set $subdomain $1;
}
spec:
rules:
- host: "*.tudominio.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: wordpress-service
port:
number: 80
[WARNING] No olvides configurar un certificado SSL wildcard (
*.tudominio.com) con Cert-Manager para que todos los subdominios tengan HTTPS. Sin SSL, WordPress Multisitio se volverá loco con redirecciones.
Escalado Automático y Alta Disponibilidad
La belleza de WordPress Kubernetes es el escalado automático. Configuramos un Horizontal Pod Autoscaler (HPA) para que el número de pods suba o baje según la carga.
kubectl autoscale deployment wordpress \
--cpu-percent=70 \
--min=3 \
--max=20 \
-n wordpress-multisite
Estrategias para alta disponibilidad real
- Anti-afinidad de pods: Evita que dos pods de WordPress estén en el mismo nodo físico.
- Distribución de nodos: Usa nodos en diferentes zonas de disponibilidad.
- Base de datos con réplicas: Configura un proxy de base de datos (ProxySQL o MaxScale) para balancear lecturas entre réplicas.
# Ejemplo de anti-afinidad en el Deployment
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- wordpress
topologyKey: "kubernetes.io/hostname"
Gestión de Archivos y Plugins en un Entorno Multisitio
Aquí viene el punto más crítico: los archivos subidos por los usuarios. En un multisitio, cada sitio tiene su propia carpeta de uploads (wp-content/uploads/sites/ID). Si no compartes el almacenamiento, cada pod tendrá sus propios archivos y los usuarios verán errores 404 aleatorios.
Soluciones probadas
- NFS o GlusterFS: Volumen compartido entre todos los pods. Simple pero con latencia.
- S3 Object Storage: Usa el plugin
WP Offload Mediapara subir todos los archivos a S3. Es la solución más escalable. - Longhorn (Rancher): Almacenamiento block distribuido con replicación. Ideal para Kubernetes on-premise.
# Ejemplo de montaje de bucket S3 con s3fs (no recomendado para producción)
# Mejor usar el plugin de WordPress directamente
[TIP] Si usas S3, no olvides configurar la variable
AS3CF_SETTINGSen elwp-config.phppara que todos los pods usen las mismas credenciales. Además, activa la entrega vía CDN (CloudFront) para reducir latencia.
Monitoreo y Logging: No Vueles a Ciegas
Un cluster sin monitoreo es como un avión sin instrumentos. Para mantener la alta disponibilidad, necesitas visibilidad total.
Stack recomendado
- Prometheus + Grafana: Métricas de CPU, memoria, red y número de requests por pod.
- Loki: Logs centralizados de todos los contenedores. Filtra por
site_idpara depurar errores de un sitio específico. - Kubernetes Events: Usa
kubectl get events -n wordpress-multisite --watchpara ver fallos de pods.
Alertas críticas
- Pod en CrashLoopBackOff: Algo mal en la configuración de PHP o la conexión a BD.
- Alto uso de memoria en MySQL: Escalar las réplicas de lectura.
- Errores 5xx en el Ingress: Problemas con el plugin o el tema.
Consideraciones Finales y Buenas Prácticas
Construir un WordPress Multisitio Escalable con Kubernetes y Docker no es un proyecto de fin de semana. Requiere planificación, pero los beneficios son enormes:
- Cero downtime en despliegues.
- Escalado elástico para picos de tráfico.
- Aislamiento entre sitios (un sitio con malware no afecta a los demás).
- Facilidad de backup: Respaldas todo el cluster con Velero o Stash.
Checklist de producción
- ¿Los secrets están en un gestor externo (Vault, AWS Secrets Manager)?
- ¿Los volúmenes persistentes tienen backup automático?
- ¿El Ingress tiene límites de tasa (rate limiting) para evitar abusos?
- ¿Las imágenes de Docker están escaneadas por vulnerabilidades?
- ¿Tienes un plan de disaster recovery (DR) con réplicas en otra región?
[WARNING] No olvides que WordPress Multisitio tiene sus propias complejidades: la red de plugins puede ser conflictiva, y las actualizaciones de red requieren cuidado. Kubernetes no resuelve los bugs de WordPress, solo los escala.
Conclusión: El Futuro es Contenerizado
La combinación de WordPress Kubernetes y Docker WordPress no es una moda, es la respuesta a los problemas de escalabilidad que han atormentado a los administradores de multisitios durante años. Con la orquestación contenedores, dejas de apagar incendios y empiezas a construir un ecosistema que crece contigo.
Ahora tienes el mapa. El siguiente paso es levantar tu propio cluster y poner a prueba esta arquitectura. Empieza con un multisitio pequeño, mide el rendimiento, y escala. Tu WordPress te lo agradecerá.
