Tras haber preparado nuestra infraestructura con almacenamiento persistente y gestión automatizada, ha llegado el momento de desplegar una aplicación real de arquitectura Stateful (con estado).
En esta fase vamos a desplegar un WordPress respaldado por una base de datos MySQL. Para garantizar la Alta Disponibilidad (HA) y que los datos no se pierdan si los contenedores se destruyen, conectaremos ambos servicios a nuestro servidor NFS. Finalmente, expondremos la web al exterior utilizando nuestro Ingress Controller.
En Kubernetes, es una buena práctica agrupar los recursos de un mismo proyecto en un entorno aislado llamado Namespace para no mezclar configuraciones.
Ejecutamos el siguiente comando para crear el namespace wp-proyecto directamente desde nuestro repositorio:
kubectl apply -f https://raw.githubusercontent.com/jobopaK/ProyectoIntegradoASIR/refs/heads/main/kubernetes/manifests/apps/wordpress/namespace-wordpress.yml
Para verificar que se ha creado correctamente, listamos todos los namespaces del clúster:
kubectl get namespaces

[!IMPORTANT] A partir de ahora, como nuestros recursos vivirán en este “cajón”, debemos añadir la etiqueta
-n wp-proyectoal final de cualquier comando para que Kubernetes sepa dónde buscar.
Nunca debemos exponer contraseñas en texto plano. Utilizamos el recurso Secret de Kubernetes para inyectar de forma segura la contraseña root y la del usuario de nuestra base de datos MySQL.
kubectl apply -f https://raw.githubusercontent.com/jobopaK/ProyectoIntegradoASIR/refs/heads/main/kubernetes/manifests/apps/wordpress/secrets-wordpress.yml
Comprobamos que el secreto se ha generado correctamente:
kubectl get secrets -n wp-proyecto

Para que los datos sobrevivan a reinicios de los Pods, creamos Volúmenes Persistentes (PV) y “Peticiones de Volumen” (PVC) enlazados a nuestro servidor NFS.
kubectl apply -f https://raw.githubusercontent.com/jobopaK/ProyectoIntegradoASIR/refs/heads/main/kubernetes/manifests/apps/wordpress/storage-wordpress.yml
Verificamos que Kubernetes ha conseguido enlazar el almacenamiento con el servidor físico NFS:
kubectl get pv,pvc -n wp-proyecto
[!NOTE] El estado
Boundconfirma que la reclamación de espacio ha sido un éxito.

Lanzamos el motor de base de datos. Este manifiesto crea el Deployment (los Pods) y el Service (el puente de red interno) para que WordPress pueda comunicarse con MySQL.
kubectl apply -f https://raw.githubusercontent.com/jobopaK/ProyectoIntegradoASIR/refs/heads/main/kubernetes/manifests/apps/wordpress/mysql-wordpress.yml
Esperamos unos segundos y verificamos que el Pod de MySQL está corriendo (Running):
kubectl get pods -n wp-proyecto

Desplegamos el contenedor de WordPress. Este utilizará la base de datos previa y guardará los archivos (temas, imágenes) directamente en el NFS montado en la ruta /var/www/html.
kubectl apply -f https://raw.githubusercontent.com/jobopaK/ProyectoIntegradoASIR/refs/heads/main/kubernetes/manifests/apps/wordpress/wordpress.yml
Comprobamos que ambos pods están vivos y completamente listos (1/1):
kubectl get pods -n wp-proyecto

Aunque la web funciona, está aislada en la red interna del clúster. Configuramos una regla de Ingress para conectar el exterior con el servicio mediante un nombre de dominio amigable.
kubectl apply -f https://raw.githubusercontent.com/jobopaK/ProyectoIntegradoASIR/refs/heads/main/kubernetes/manifests/apps/wordpress/ingress-wordpress.yml
Revisamos que el Ingress Controller ha asignado la IP correcta (proveída por MetalLB) a nuestro dominio wordpress.asir.local:
kubectl get ingress -n wp-proyecto

Al usar volúmenes compartidos NFS, es común enfrentarse a problemas de permisos o errores “502 Bad Gateway”. Esto ocurre porque el usuario interno del contenedor Apache (www-data, ID 33) no tiene permisos de escritura sobre la carpeta creada como root en nuestro servidor NFS físico.
1. En el Servidor NFS (Consola física/SSH a la VM de NFS): Cedemos la propiedad de la carpeta al usuario web:
sudo chown -R 33:33 /srv/nfs/wp-data
sudo chmod -R 775 /srv/nfs/wp-data
2. En el Nodo Master de Kubernetes: Forzamos a Kubernetes a destruir el Pod actual para que genere uno nuevo que ya reconocerá los permisos correctos:
Primero obtenemos el nombre exacto del Pod:
kubectl get pods -n wp-proyecto
(Copiamos el nombre que empiece por wordpress-, por ejemplo: wordpress-5bb7bd84d8-gcn5b)
Lo eliminamos:
kubectl delete pod wordpress-TU-ID-AQUI -n wp-proyecto
Para engañar a nuestro navegador y que sepa traducir el dominio wordpress.asir.local a la IP de nuestro Ingress, debemos editar el archivo hosts en nuestro equipo de trabajo personal (el portátil).
En Linux:
sudo nano /etc/hosts
Añadimos la línea con la IP que nos devolvió el Ingress en el Paso 7:
192.168.1.200 wordpress.asir.local
Finalmente, introducimos http://wordpress.asir.local en nuestro navegador. Nos recibirá el instalador de WordPress, demostrando que la persistencia, la red y los contenedores trabajan en perfecta sintonía.

Siguiente Paso: Fase 9: Monitorización con Prometheus y Grafana
Proyecto Integrado de Grado Superior ASIR
© 2026 - jobopaK