Arquitecturas de Resiliencia

El arte de optimizar WordPress en Kubernetes

Desarrollo Web 14 min. de lectura

WordPress no nació para la nube, pero puede domarse. A través de una auditoría forense de recursos y el despliegue de un esquema en cascada con Varnish y Sharp, exploramos el camino para optimizar el CMS más popular del mundo en entornos críticos, logrando escalabilidad real sin el lastre de los plugins pesados.

Llevar WordPress a un entorno de Kubernetes es un camino lleno de claroscuros. Por una parte, la promesa de escalar y controlar los recursos de forma granular es fantástica; por otra, ejecutar esta transición con propiedad es una tarea compleja. No hablo simplemente de gestionar un blog, sino de sostener sitios con requerimientos particulares, galerías de imágenes, secciones, calendarios de actividades o incluso sistemas críticos como una ticketera. Aunque me formé profesionalmente al amparo de WordPress y su eslogan de Code is Poetry, hay que reconocer que el CMS es una bestia hambrienta de recursos, que a ratos se siente de otra era y que no se adapta completamente bien a la lógica de servicios de hoy, donde el enfoque es puramente pragmático. Y por eso, más allá de cualquier afinidad, mi objetivo hoy es extraer el máximo rendimiento de una arquitectura que no siempre se lo pone fácil al desarrollador.

En mis primeros acercamientos a Google Kubernetes Engine (GKE) y WordPress, me encontré con un sistema que devoraba CPU y RAM, obligándome a escalar los nodos del clúster no por tráfico, sino por ineficienciam situación muy distintas a las Apps de node que tenemos. Las imágenes de Docker rozaban los 1.2GB y los OOMKills acechaban en cada pico de actividad. Aunque había seguido al pie de la letra tutoriales y guías prácticas, además de apoyarme en la IA, no era el diseño limpio que había imaginado ni me habían prometido. En ese momento era lo que el conocimiento y el tiempo me permitían alcanzar. Así, cada tanto, aprovechando los espacios entre proyectos, volvía a la arquitectura para pulir, con nuevas herramientas y más perspectiva, cada pieza que generaba fricción.

Sin embargo, antes de saltar a la infraestructura del clúster, hay una realidad ineludible. Ningún orquestador, por potente que sea, puede rescatar un código ineficiente. La optimización real empieza en casa, limpiando el propio WordPress. Esto significa auditar el theme de verdad, deshacerse de esos plugins “basura” que hoy saturan el ecosistema y analizar las queries que asfixian la base de datos. En este terreno, la configuración del caché es decisiva. Mi experiencia me ha demostrado que, mientras soluciones como WP Rocket resultan casi inútiles bajo la lógica de Kubernetes, W3 Total Cache (W3TC) sigue siendo el estándar de oro por su simplicidad y su capacidad de integrarse quirúrgicamente en arquitecturas de alto rendimiento.

Este aprendizaje me llevó a la segunda gran revelación de este viaje, que fue la necesidad de romper con la mentalidad monolítica. Estamos acostumbrados a que WordPress lo gestione todo —desde el envío de correos hasta la seguridad— dentro de un mismo proceso. En Kubernetes, ese enfoque es una receta para el desastre. El verdadero cambio de paradigma ocurrió cuando dejé de ver a WordPress como el centro del universo y empecé a tratarlo como un servicio más que debe delegar tareas pesadas a otros componentes especializados. Entender que el CMS no tiene por qué saber cómo procesar una imagen o cómo filtrar un ataque de inyección SQL fue lo que finalmente permitió que mis deploys de WordPress dejaran de sufrir por picos de carga mal gestionados.

En este sentido, es imposible no hacer una mención a Wordfence. Sé que para muchos desarrolladores es una herramienta indispensable, casi la única alternativa para sentirse protegidos, pero en un entorno de Kubernetes es, sencillamente, un suicidio técnico. Su desorbitado uso de recursos y su constante escaneo del sistema de archivos chocan frontalmente con la lógica de contenedores ligeros e inmutables. Wordfence es el síntoma más claro de un WordPress que intenta resolverlo todo desde dentro, pagando un precio altísimo en CPU y memoria que, en un Pod con límites estrictos, termina por asfixiar al sistema.

Encontrar la causa de esta asfixia se convirtió en mi leitmotiv. Cuál perito forense, realicé una auditoría profunda de los logs y me apoyé en xhprof y xhgui para exponer a los verdaderos culpables. El código descuidado, los plugins ineficientes y esa marea incesante de bots devoraban los recursos mucho antes de procesar peticiones reales.

El patrón en cascada y de sidecars

Para explicarlo de forma sencilla, un sidecar es un contenedor secundario que corre junto al principal dentro del mismo Pod, compartiendo recursos y ciclo de vida para extender sus capacidades sin ensuciar la lógica de la aplicación. Bajo este concepto, hablo de un patrón en cascada porque el tráfico no llega directamente al núcleo, sino que debe atravesar capas de servicios secuenciales donde cada una cumple un propósito específico de limpieza o aceleración.

En la primera capa, implementé un Pod Frontal compuesto por dos contenedores. El primero corre Nginx con ModSecurity para resolver el blindaje a nivel de WAF, mientras que el segundo tiene Varnish como un escudo de caché. Este pod filtra y detiene el ruido de forma externa mucho antes de que el tráfico viaje hacia la aplicación en una segunda capa.

La segunda capa es el Pod de Aplicación, el cual también cuenta con un esquema de sidecar. Aquí, un Nginx actúa como proxy hacia el contenedor de PHP-FPM 8.4. Esta separación interna es clave, ya que PHP-FPM solo se despierta para ejecutar código, mientras que el Nginx del pod gestiona la entrega de recursos con una latencia mínima al compartir el mismo volumen de datos. Gracias a este aislamiento, logré que mis imágenes bajaran de peso drásticamente (60MB de base) y que el sistema fuera predecible, ágil y capaz de escalar sin arrastrar el lastre de un monolito.

Diagrama de Arquitectura (Cascade & Sidecar)

Adiós al almacenamiento pesado. Sharp y el procesamiento On-the-fly

Desde el primer minuto, la gestión de medios fue un auténtico dolor de cabeza. La lentitud extrema en las subidas y los constantes timeouts al interactuar con los buckets de Google Cloud Storage (GCS) marcaron el inicio del proyecto. WordPress, por defecto, genera una latencia de red agotadora al intentar procesar y escribir múltiples versiones de cada imagen (una por cada _add_imagesize configurado) directamente en el almacenamiento persistente.

Para solucionar este cuello de botella, implementé el SHARP SVC un microservicio basado en Fastify y Sharp que actúa como un proxy inteligente para GCS. Lo interesante de este diseño es que el servicio de imágenes no está aislado, sino que se sitúa también detrás del mismo Varnish del Pod Frontal. Esto permite que una imagen procesada se cachee inmediatamente en el borde, evitando ejecuciones redundantes de Node.js.

El flujo es ahora mucho más limpio:

  • WordPress se desentiende de las miniaturas. Mediante filtros en el core y aprovechando las opciones de CDN de W3 Total Cache, el CMS simplemente sube la imagen original y apunta las URLs de medios hacia el endpoint del servicio.
  • Cuando un usuario solicita una imagen, el SHARP SVC la genera al vuelo desde el original en GCS si no existe en caché, y Varnish se encarga de servirla de forma permanente desde ese momento.

Este ajuste no solo eliminó el bloqueo de I/O en la administración y los timeouts, sino que borró la necesidad de recurrir a costosos y complejos sistemas de archivos compartidos (RWX).

W3 Total Cache y Valkey para la gestión del estado

En otra de esas vueltas al proyecto para seguir puliendo detalles, configuré W3 Total Cache utilizando Valkey como backend fundamental para la gestión del estado. Aunque el estándar suele ser Redis, el cambio a Valkey me permitió manejar entornos efímeros con una eficiencia superior y un consumo de recursos mucho menor. Al conectar W3TC a este motor, el Object Cache y la gestión de sesiones empezaron a volar, liberando a la base de datos de miles de consultas redundantes que antes asfixiaban el rendimiento.

La potencia real del sistema reside en la orquestación entre W3TC y Varnish. Al delegar el almacenamiento de objetos a Valkey y el cacheo de páginas al escudo frontal, el volumen de peticiones que finalmente impactan en PHP y el backend se reduce a niveles mínimos. Esta arquitectura se complementa con la directiva stale-while-revalidate en Varnish, una pieza fundamental para asegurar respuestas instantáneas. Bajo este esquema, si un elemento en caché ha expirado, el sistema sirve la versión antigua al usuario mientras actualiza el contenido en segundo plano sin bloquear la navegación.

Este enfoque permite que el sistema de WordPress opere casi exclusivamente en memoria, logrando que la infraestructura sea mucho más estable ante picos inesperados sin tener que subir la cuota de recursos constantemente.

GitOps e Inmutabilidad

Hace un tiempo enfrentamos un requerimiento para actualizar un WordPress en Kubernetes que funcionaba bajo la lógica de archivos persistidos en un PVC. El problema de ese enfoque es que, por regla general, esos volúmenes terminan siendo ReadWriteOnce (RWO), quedando atados al primer nodo que los reclama. Es una contradicción absoluta en Kubernetes que impide el escalado horizontal y rompe la naturaleza efímera del clúster. Por eso, nosotros decidimos mantener el camino de la inmutabilidad total aprovechando las herramientas de GitLab.

Este flujo se apoya en dos pilares tecnológicos fundamentales:

  • GitLab Package Registry: Aquí es donde reside la inteligencia modular de nuestros sitios. Tratamos cada plugin y tema personalizado como un paquete versionado de Composer. En lugar de subir el código directamente al repositorio del sitio, lo requerimos como una dependencia externa. Esto nos permite mantener un núcleo limpio y asegurar que cada despliegue utilice la versión exacta y probada de cada componente, eliminando el riesgo de inconsistencias entre entornos.
  • GitLab Container Registry: Es el destino final de nuestro pipeline de CI/CD. Una vez que el código se ensambla mediante Composer, Kaniko construye la imagen final del contenedor (PHP-FPM y Nginx) y la envía a este registro. Al centralizar todo en el ecosistema de GitLab, simplificamos la autenticación del clúster y aceleramos la descarga de imágenes en cada nodo.

Al trabajar así, ya no existe la modificación de archivos en caliente ni la dependencia de un disco compartido para el código. Cada cambio genera un “install” limpio desde cero que empaqueta todo el sitio en una imagen atómica. Si un plugin causa problemas, el rollback es inmediato: simplemente desplegamos la imagen anterior desde el registro de contenedores. Esta inmutabilidad es la que garantiza que el clúster pueda escalar horizontalmente sin fricción, sabiendo que el estado del servidor coincide siempre con lo definido en Git.

Guía rápida para replicar esta arquitectura

Si quieres implementar este stack, he preparado un boilerplate público con las configuraciones base de Kubernetes (Helm charts), el microservicio Sharp en Fastify y el pipeline de GitLab CI.

¡Echa un ojo al código!

He subido una base técnica a GitLab para que no tengas que picar piedra desde cero. Úsala como referencia, ajusta las piezas de infraestructura y lánzate a probarlo.

Boilerplate en GitLab: git.idastage.com/labs/stack-wp-k8s

Échale un vistazo rápido al README.md para ver cómo conectar los cables y al DISCLAIMER.md (ya sabes, para que estemos todos tranquilos antes de pasar a producción).

Este repositorio incluye los filtros de WordPress necesarios para anular la generación de miniaturas y redirigir el tráfico de medios al SHARP SVC de forma automática.

Conclusión y el orgullo del diseño propio

Hoy, la infraestructura se siente finalmente ordenada. Lo que empezó como una lucha contra la pesadez de los archivos y los costos de cómputo se ha transformado, iteración tras iteración, en un sistema donde la seguridad, la optimización y la simpleza conviven en armonía.

No ha sido un plan maestro ejecutado de un solo tirón, sino el resultado de muchas iteraciones, investigación profunda, ensayo, prueba y error. Ha sido un proceso de lecturas constantes, aprovechando las ayudas y optimizaciones de la IA. Es esa satisfacción de haber diseñado una maquinaria propia, el orgullo del made by yourself, logrando que WordPress fluya con una ligereza que en sitios de alta complejidad, en su forma tradicional, nunca podría alcanzar.

Acerca del Autor

Maximiliano Villegas - Director de Desarrollo

Director de Desarrollo

Investigo lo último en tecnología web, para ofrecer soluciones innovadoras en los proyectos. Encargado de resolver problemas de integración en diversas API's, servicios y plataformas que operamos. Me gustan los proyectos perfectamente terminados, con código bien estructurado, simple y legible.

Agregar un comentario