WordPress Multisite con Kubernetes y Orquestación de Contenedores
Introducción a WordPress Multisite en un Entorno Kubernetes
La gestión de múltiples sitios web con una sola instalación de WordPress es un desafío que tradicionalmente se abordaba con servidores dedicados o VPS de gran capacidad. WordPress Multisite permite administrar una red de sitios desde un único panel de administración, pero cuando el tráfico crece o se necesitan alta disponibilidad y escalabilidad, la arquitectura monolítica se queda corta.
Aquí es donde entra Kubernetes y la orquestación de contenedores. Kubernetes no solo automatiza el despliegue, el escalado y la operación de contenedores, sino que permite gestionar cada componente de WordPress Multisite como un servicio independiente. El resultado es una plataforma robusta, tolerante a fallos y con capacidad de escalado automático bajo demanda.
[INFO] Este artículo está dirigido a administradores de sistemas y desarrolladores con experiencia media en Docker y conceptos básicos de Kubernetes. No cubre la instalación inicial de un clúster, sino la configuración específica para WordPress Multisite.
¿Por qué Kubernetes para WordPress Multisite?
La orquestación de contenedores resuelve problemas clave en entornos Multisite:
- Aislamiento de recursos: Cada sitio puede tener sus propios límites de CPU/memoria sin interferir con otros.
- Balanceo de carga: Distribuye el tráfico entre múltiples réplicas de WordPress, evitando cuellos de botella.
- Actualizaciones sin caídas: Los despliegues rolling update permiten actualizar PHP o plugins sin tiempo de inactividad.
- Gestión de configuraciones: Los ConfigMaps y Secrets de Kubernetes separan la configuración del código.
Arquitectura de Referencia
Un despliegue típico incluye:
- Pods de WordPress con PHP-FPM y el código de Multisite.
- Servicio de base de datos (MariaDB o MySQL) en un StatefulSet.
- Volumen compartido para
wp-content/uploadsusando NFS o un sistema de archivos distribuido. - Ingress Controller (Nginx o Traefik) con reglas de enrutamiento por dominio.
- Servicio de caché (Redis o Memcached) para objetos y sesiones.
Configuración del Clúster para WordPress Multisite
Requisitos Previos
- Un clúster Kubernetes funcional (puede ser minikube para pruebas o un clúster en la nube como EKS, AKS o GKE).
kubectlconfigurado.- Helm chart personalizado o manifiestos YAML.
- Un registro de contenedores con la imagen de WordPress Multisite.
Imagen Docker Personalizada
La imagen base de WordPress no soporta Multisite de forma predeterminada. Necesitas crear un Dockerfile que active el modo Multisite en wp-config.php:
FROM wordpress:6.4-php8.2-fpm
# Activar Multisite
RUN echo "define('WP_ALLOW_MULTISITE', true);" >> /usr/src/wordpress/wp-config-docker.php
# Configurar subdominios o subdirectorios
RUN echo "define('SUBDOMAIN_INSTALL', true);" >> /usr/src/wordpress/wp-config-docker.php
# Añadir constantes de red
RUN echo "define('DOMAIN_CURRENT_SITE', 'example.com');" >> /usr/src/wordpress/wp-config-docker.php
RUN echo "define('PATH_CURRENT_SITE', '/');" >> /usr/src/wordpress/wp-config-docker.php
RUN echo "define('SITE_ID_CURRENT_SITE', 1);" >> /usr/src/wordpress/wp-config-docker.php
RUN echo "define('BLOG_ID_CURRENT_SITE', 1);" >> /usr/src/wordpress/wp-config-docker.php
# Opcional: configurar Redis para caché
RUN pecl install redis && docker-php-ext-enable redis
Construye y sube la imagen a tu registro:
docker build -t myregistry/wordpress-multisite:latest .
docker push myregistry/wordpress-multisite:latest
Manifiesto de Despliegue (Deployment)
Crea un archivo wordpress-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-multisite
spec:
replicas: 3
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: myregistry/wordpress-multisite:latest
ports:
- containerPort: 9000
env:
- name: WORDPRESS_DB_HOST
value: mysql-service
- name: WORDPRESS_DB_USER
valueFrom:
secretKeyRef:
name: wp-secrets
key: db-user
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: wp-secrets
key: db-password
- name: WORDPRESS_DB_NAME
value: wordpress
volumeMounts:
- name: wp-content
mountPath: /var/www/html/wp-content
volumes:
- name: wp-content
persistentVolumeClaim:
claimName: wp-content-pvc
[TIP] Usa
envFromcon un ConfigMap para variables no sensibles comoWP_HOMEoWP_SITEURL.
Base de Datos con StatefulSet
WordPress Multisite requiere una base de datos centralizada. Un StatefulSet garantiza identidad de red estable:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql-service
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: wp-secrets
key: root-password
- name: MYSQL_DATABASE
value: wordpress
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 20Gi
Balanceo de Carga y Escalado Automático
Ingress Controller para Multisite
El balanceo de carga a nivel de aplicación se logra con un Ingress que enruta por nombre de host. Para Multisite con subdominios (ej: site1.example.com, site2.example.com), necesitas un controlador que soporte wildcards:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wordpress-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-buffer-size: "8k"
spec:
tls:
- hosts:
- "*.example.com"
secretName: wildcard-tls
rules:
- host: "*.example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: wordpress-service
port:
number: 80
El servicio interno expone el puerto 80 y apunta a los pods de WordPress:
apiVersion: v1
kind: Service
metadata:
name: wordpress-service
spec:
selector:
app: wordpress
ports:
- port: 80
targetPort: 9000
Escalado Automático con HPA
El escalado automático basado en métricas de CPU y memoria es crucial para picos de tráfico. Configura un HorizontalPodAutoscaler:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: wordpress-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: wordpress-multisite
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
[WARNING] El escalado automático solo funciona si los pods no tienen estado persistente. Para archivos subidos, usa un volumen compartido como NFS o un objeto storage como S3 con el plugin
WP Offload Media.
Gestión de Archivos y Medios en Multisite
Uno de los mayores desafíos en Kubernetes es la persistencia de archivos subidos. En Multisite, cada sitio tiene su propia carpeta wp-content/uploads/sites/{ID}. Soluciones:
- Volumen compartido: Usa un PV con modo
ReadWriteMany(NFS, GlusterFS, EFS). - Object Storage: Con el plugin
WP Offload Media, los archivos se almacenan en S3, GCS o Azure Blob. - Sidecar de sincronización: Un contenedor adicional que sincroniza archivos entre pods usando rsync.
Ejemplo de PVC para wp-content
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-content-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 100Gi
storageClassName: nfs-client
Caché Distribuida con Redis
WordPress Multisite se beneficia enormemente de la caché de objetos. Redis en Kubernetes puede desplegarse como un StatefulSet con replicación:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
spec:
serviceName: redis-service
replicas: 3
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
command: ["redis-server", "--appendonly", "yes"]
ports:
- containerPort: 6379
Luego, en el wp-config.php de la imagen Docker, configura Redis:
define('WP_REDIS_HOST', 'redis-service');
define('WP_REDIS_PORT', 6379);
define('WP_REDIS_DATABASE', 0);
define('WP_CACHE', true);
Monitoreo y Logging
Para mantener la salud del clúster, implementa:
- Prometheus + Grafana: Métricas de pods, HPA, y latencia de peticiones.
- Fluentd o Loki: Recopilación centralizada de logs de todos los sitios Multisite.
- Kubernetes Dashboard: Para visualizar el estado de los recursos.
Alertas Críticas
# Ejemplo de regla de alerta (PrometheusRule)
groups:
- name: wordpress-alerts
rules:
- alert: WordPressHighMemoryUsage
expr: sum(container_memory_usage_bytes{container="wordpress"}) / sum(kube_pod_container_resource_limits{resource="memory"}) > 0.85
for: 5m
labels:
severity: warning
annotations:
summary: "Alto uso de memoria en WordPress Multisite"
Mejores Prácticas y Consideraciones Finales
Seguridad
- Usa Secrets de Kubernetes para credenciales de base de datos y claves de API.
- Implementa NetworkPolicies para restringir tráfico entre pods.
- Mantén actualizadas las imágenes base (WordPress, PHP, Redis).
- Configura WAF (Web Application Firewall) a nivel de Ingress.
Copias de Seguridad
La base de datos y los archivos wp-content deben respaldarse periódicamente. Herramientas como Velero permiten hacer snapshots de volúmenes y bases de datos en Kubernetes.
Migración desde un Entorno Tradicional
- Exporta la base de datos Multisite con
mysqldump. - Copia
wp-content/uploadsa un volumen persistente. - Ajusta
wp-config.phppara usar las nuevas variables de entorno. - Configura el Ingress con los mismos dominios.
- Realiza pruebas de humo con un subconjunto de sitios.
[TIP] Si usas subdominios, asegúrate de que tu DNS tenga un registro wildcard
*.example.comapuntando a la IP del Ingress Controller.
Conclusión
Combinar WordPress Multisite con Kubernetes y orquestación de contenedores no solo es posible, sino que ofrece ventajas significativas en términos de escalabilidad, mantenibilidad y resiliencia. La clave está en diseñar correctamente la arquitectura: separar el estado efímero (pods) del estado persistente (base de datos y archivos), implementar balanceo de carga inteligente y configurar el escalado automático para absorber picos de tráfico.
Con las herramientas adecuadas (Helm, Prometheus, Redis, Nginx Ingress) y una imagen Docker optimizada, puedes gestionar cientos de sitios desde un único clúster Kubernetes, reduciendo costos operativos y mejorando la experiencia del usuario final.
La inversión inicial en configuración se amortiza rápidamente cuando necesitas añadir un nuevo sitio o escalar ante una campaña de marketing. Kubernetes no es una bala de plata, pero para WordPress Multisite es, sin duda, el mejor estándar de la industria.
