Usar el disco persistente con WordPress y MySQL

En este instructivo se muestra cómo configurar una implementación WordPress de réplica única y una base de datos de MySQL de réplica única en tu clúster. Ambas aplicaciones usan PersistentVolumes (PV) y PersistentVolumeClaims (PVC) para almacenar datos.

Un PersistentVolume es una representación de almacenamiento en el clúster que ha sido aprovisionado manualmente por un administrador, o dinámicamente por Kubernetes usando un StorageClass. Una PersistentVolumeClaim es una solicitud de almacenamiento por parte de un usuario que puede llevarse a cabo mediante un PersistentVolume. Los PersistentVolumes y las PersistentVolumeClaims son independientes de los ciclos de vida de los pod y preservan los datos mediante el reinicio, la reprogramación y hasta la eliminación de los pod. Ambas aplicaciones usarán discos persistentes como almacenamiento para respaldar los Volúmenes continuos.

Contexto

WordPress es una herramienta de blog que usa MySQL como su base de datos con el objetivo de almacenar los artículos del blog; y el sistema de archivos local para almacenar recursos, como imágenes de una entrada de blog o extensiones. En este instructivo se usan las imágenes de contenedor oficiales de MySQL y WordPress de Docker Hub.

En general, el sistema de archivos raíz de un contenedor no es adecuado para almacenar datos persistentes. Los contenedores que ejecutas en GKE suelen ser entidades desechables; y el administrador del clúster puede borrar, expulsar o reprogramar cualquier contenedor que deje de estar disponible debido a una falla en el nodo, o bien a otras causas. En tal caso, todos los datos guardados en el sistema de archivos raíz de tu contenedor se pierden.

Usar los Volúmenes continuos respaldados por discos persistentes te permite almacenar datos para las aplicaciones WordPress y MySQL fuera de los contenedores. De esta manera, tus datos se mantienen constantes, incluso si se borran los contenedores.

MySQL y Wordpress requieren un PersistentVolume para almacenar datos. Para este instructivo, usarás la clase de almacenamiento predeterminada que crea discos persistentes de manera dinámica y crearás dos PersistentVolumeClaims, una para cada implementación.

Luego, crearás dos implementaciones: una para MySQL y otra para WordPress. Ambas ejecutan una sola réplica de cada pod.

Luego, debes crear dos servicios, uno para el contenedor de WordPress, que se comunicará con el contenedor de MySQL; otro para exponer la implementación de WordPress a Internet en una dirección IP externa con un balanceador de cargas.

Antes de comenzar

Sigue los pasos que se indican a continuación para habilitar la API de Kubernetes Engine:
  1. Visita la página de Kubernetes Engine en Google Cloud Platform Console.
  2. Crea o selecciona un proyecto.
  3. Espera a que la API y los servicios relacionados se habiliten. Esto puede tardar varios minutos.
  4. Comprueba que la facturación esté habilitada en tu proyecto.

    Descubre cómo puedes habilitar la facturación

Instala las siguientes herramientas de línea de comandos que se usan en este instructivo:

  • gcloud se usa para crear y borrar clústeres de Kubernetes Engine. gcloud se incluye en el SDK de Google Cloud.
  • kubectl se usa para administrar Kubernetes, el sistema de organización de clústeres que utiliza Kubernetes Engine. Puedes instalar kubectl mediante gcloud:
    gcloud components install kubectl

Establecer valores predeterminados para la herramienta de línea de comandos de gcloud

Para ahorrar tiempo en escribir las opciones de tu ID del proyecto y de la zona de Compute Engine en la herramienta de línea de comandos de gcloud, puedes establecer los valores predeterminados:
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone us-central1-b

Descargar los manifiestos de la aplicación

Para este instructivo, creas los objetos de Kubernetes necesarios usando archivos de manifiesto en formato YAML.

Este enfoque se denomina administración de objeto declarativo. Estos archivos son para ti. Si quieres descargar los archivos de manifiesto del repositorio de GitHub, ejecuta los siguientes comandos en una terminal:

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/wordpress-persistent-disks

(Si no tienes git instalado en tu sistema, puedes descargarlos usando los vínculos que se encuentran a continuación).

Paso 1: crear un clúster de GKE

El primer paso es crear un clúster de GKE que aloje tus contenedores de la aplicación WordPress y MySQL. El siguiente comando crea un clúster denominado persistent-disk-tutorial con 3 nodos:

gcloud container clusters create persistent-disk-tutorial --num-nodes=3

Paso 2: crear tus PersistentVolumes y PersistentVolumeClaims

A fin de crear el almacenamiento necesario para MySQL y Wordpress, el primer paso es crear PersistentVolumeClaims. Cuando se crea una PersistentVolumeClaim, si no existe un PersistentVolume con el que pueda enlazarse, se aprovisiona de forma dinámica un PersistentVolume nuevo según la configuración de StorageClass.

GKE tiene un StorageClass predeterminado instalado que te permitirá aprovisionar de forma dinámica PersistentVolumes respaldados por discos persistentes. Cuando no se especifica un StorageClass en la PersistentVolumeClaim, se utiliza el StorageClass predeterminado del clúster.

Usarás los archivos mysql-volumeclaim.yaml y wordpress-volumeclaim.yaml a fin de crear las PersistentVolumeClaims requeridas para las implementaciones. El archivo mysql-volumeclaim.yaml se ve así:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mysql-volumeclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 200Gi

y el archivo wordpress-volumeclaim.yaml se ve así:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: wordpress-volumeclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 200Gi

Estos manifiestos describen las PersistentVolumeClaims que cada solicitud de 200 Gi formateó con un sistema de archivos. Ten en cuenta que no se especificó un StorageClass, por lo tanto, estas PersistentVolumeClaims usarán el StorageClass predeterminado que aprovisionará los PersistentVolumes respaldados por discos persistentes.

Para implementar estos manifiestos, ejecuta lo siguiente:

kubectl apply -f mysql-volumeclaim.yaml
kubectl apply -f wordpress-volumeclaim.yaml

Ejecuta el siguiente comando para verificar si las reclamaciones se vinculan. Es posible que aprovisionar los PersistentVolumes respaldados por un disco persistente y vincularlos a tus PersistentVolumeClaims tome un par de segundos.

kubectl get pvc
Resultado:
NAME                    STATUS    VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mysql-volumeclaim       Bound     pvc-864bf3d6-3c44-11e8-80a6-42010a800002   200G       RWO            standard       11s
wordpress-volumeclaim   Bound     pvc-89d49350-3c44-11e8-80a6-42010a800002   200G       RWO            standard       5s

Paso 3: configurar MySQL

Implementar MySQL

El primer paso para implementar MySQL es crear un secreto de Kubernetes con el objetivo de almacenar la contraseña de la base de datos. Para crear un Secreto denominado mysql, ejecuta el siguiente comando (y reemplaza YOUR_PASSWORD con una frase de contraseña de tu elección):

kubectl create secret generic mysql --from-literal=password=YOUR_PASSWORD

Luego, usarás el archivo de manifiesto mysql.yaml para implementar la aplicación de MySQL de una sola instancia que se ejecuta en el puerto 3306. El archivo mysql.yaml se ve así:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - image: mysql:5.6
          name: mysql
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql
                  key: password
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts:
            - name: mysql-persistent-storage
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql-persistent-storage
          persistentVolumeClaim:
            claimName: mysql-volumeclaim

En este manifiesto se describe una implementación con un pod de MySQL de una sola instancia que tendrá la variable de entorno MYSQL_ROOT_PASSWORD, cuyo valor se establece a partir del secreto creado. El contenedor mysql usará la PersistentVolumeClaim y activará el disco persistente en /var/lib/mysql dentro del contenedor.

Para implementar este archivo de manifiesto, ejecuta lo siguiente:

kubectl create -f mysql.yaml

Comprueba que el pod se esté ejecutando. La transición del pod al estado Running puede tomar algunos minutos, ya que vincular el disco persistente al nodo de procesamiento lleva tiempo:

kubectl get pod -l app=mysql
Resultado:
NAME                 READY     STATUS    RESTARTS   AGE
mysql-259040-flmqh   1/1       Running   0          3m

Crear el servicio MySQL

El próximo paso es crear un servicio para exponer el contenedor de MySQL y hacerlo accesible desde el contenedor wordpress que vas a crear.

Usarás el manifiesto de servicio definido en mysql-service.yaml, que se ve así:

apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  type: ClusterIP
  ports:
    - port: 3306
  selector:
    app: mysql

En este manifiesto se describe un servicio que crea un IP del clúster en el puerto 3306 para los pod que coinciden con la etiqueta app: mysql. El contenedor mysql implementado en el paso anterior tiene esta etiqueta. En este caso, usas type:ClusterIP para el servicio, ya que este valor permite que el servicio esté accesible solo desde el clúster.

La IP del clúster creado enruta el tráfico al contenedor de MySQL desde todos los nodos de procesamiento en el clúster y no está accesible a los clientes fuera del clúster. Una vez que se crea el servicio, el contenedor wordpress puede usar el nombre del DNS del contenedor mysql para comunicarse, aunque no estén en el mismo nodo de procesamiento.

Para implementar este archivo de manifiesto, ejecuta lo siguiente:

kubectl create -f mysql-service.yaml

Verifica si se creó el servicio:

kubectl get service mysql
Resultado:
NAME      CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
mysql     10.51.240.175   <none>        3306/TCP   4m

¡Has terminado de configurar la base de datos para tu nuevo blog de WordPress!

Paso 4: configurar WordPress

Implementar WordPress

El próximo paso es implementar tu contenedor de WordPress en el clúster de contenedores. Usarás el archivo de manifiesto wordpress.yaml para implementar un contenedor de WordPress de una sola instancia.

wordpress.yaml se ve así:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      containers:
        - image: wordpress
          name: wordpress
          env:
          - name: WORDPRESS_DB_HOST
            value: mysql:3306
          - name: WORDPRESS_DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: mysql
                key: password
          ports:
            - containerPort: 80
              name: wordpress
          volumeMounts:
            - name: wordpress-persistent-storage
              mountPath: /var/www/html
      volumes:
        - name: wordpress-persistent-storage
          persistentVolumeClaim:
            claimName: wordpress-volumeclaim

En este manifiesto se describe una implementación con un pod de WordPress de una sola instancia. Este contenedor lee la variable del entorno WORDPRESS_DB_PASSWORD de la contraseña de la base de datos que creaste anteriormente.

En este manifiesto también se configura el contenedor de WordPress para comunicar MySQL con la dirección del host mysql:3306. Este valor se establece en la variable del entorno WORDPRESS_DB_HOST. Puedes referirte a la base de datos como mysql, ya que el DNS de Kubernetes permite que los pod se comuniquen con un servicio por su nombre

Para implementar este archivo de manifiesto, ejecuta lo siguiente:

kubectl create -f wordpress.yaml

Comprueba que el pod se esté ejecutando. La transición del pod al estado Running puede tomar algunos minutos, ya que vincular el disco persistente al nodo de procesamiento lleva tiempo:

kubectl get pod -l app=wordpress
Resultado:
NAME                     READY     STATUS    RESTARTS   AGE
wordpress-387015-02xxb   1/1       Running   0          9h

Exponer el servicio WordPress

En el paso anterior, implementaste un contenedor de WordPress que no es accesible actualmente desde fuera de tu clúster, ya que no tiene una dirección IP externa.

Para exponer tu aplicación WordPress al tráfico de Internet mediante un balanceador de cargas (sujeto a facturación), necesitas un servicio con type:LoadBalancer.

El archivo wordpress-service.yaml contiene el manifiesto de este servicio y se ve así:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: wordpress
  name: wordpress
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    app: wordpress

Para implementar este archivo de manifiesto, ejecuta lo siguiente:

kubectl create -f wordpress-service.yaml

Implementar este manifiesto creará un balanceador de cargas, lo cual puede tomar algunos minutos. Ejecuta el siguiente comando para descubrir la dirección IP externa de tu blog:

kubectl get svc -l app=wordpress
Resultado:
NAME        CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
wordpress   10.51.243.233   203.0.113.3    80:32418/TCP   1m

En el resultado anterior, la columna EXTERNAL-IP muestra la dirección IP pública creada para tu blog. Guarda esta dirección IP para el próximo paso.

¡Ya has terminado de implementar y exponer tu blog de WordPress!

Paso 5: visitar tu nuevo blog de WordPress

Luego de descubrir la dirección IP de tu blog, ve a esta dirección IP con tu navegador y verás la pantalla de instalación de WordPress, como se muestra a continuación:

Captura de pantalla de la pantalla de instalación de Wordpress

Una vez que finalices la configuración de WordPress, ve con tu navegador a la dirección IP de la aplicación WordPress nuevamente para visitar tu blog. Todo funciona como se esperaba.

Paso 6: (opcional) probar la persistencia de los datos en caso de error

Con los PersistentVolumes, tus datos se encuentran fuera del contenedor de la aplicación. Cuando tu contenedor deja de estar disponible y Kubernetes lo reprograme a otra instancia de procesamiento, GKE hará que el PersistentVolume esté disponible en la instancia que comenzó a ejecutar el pod.

kubectl get pods -o=wide
NAME                   ...  IP          NODE
mysql-259040-flmqh     ...  10.48.2.8   gke-persistent-disk-tutorial-default-pool-fe4fe9af-wcb4
wordpress-387483-02xxb ...  10.48.2.7   gke-persistent-disk-tutorial-default-pool-fe4fe9af-wcb4

Ahora, borra el pod mysql ejecutando lo siguiente:

kubectl delete pod -l app=mysql

Una vez que el pod mysql se haya borrado, el controlador de implementación notará que falta el pod y volverá a crearlo. Es probable que el nuevo pod mysql se inicie en un nodo distinto del que se estaba ejecutando antes.

Ejecuta el siguiente comando nuevamente y observa que el pod mysql esté programado en una instancia de procesamiento distinta a la de antes (si no, puedes borrar el pod nuevamente hasta que se ejecute en otro sitio).

kubectl get pods -o=wide
Resultado:
NAME                   ...  IP          NODE
mysql-259040-flmqh     ...  10.48.2.8   gke-persistent-disk-tutorial-default-pool-fe4fe9af-vg56
wordpress-387483-02xxb ...  10.48.2.7   gke-persistent-disk-tutorial-default-pool-fe4fe9af-wcb4

Vuelve a visitar tu blog para observar si el sitio web está funcionando correctamente y si los datos se conservan a pesar de que borraste tu pod y este está programado en otra instancia de tu clúster.

Paso 7: actualizar las imágenes de la aplicación

Es importante que el software implementado se actualice. Por ejemplo, las vulnerabilidades que requieren una actualización se pueden informar en WordPress. Para actualizar la imagen de contenedor de WordPress, busca la versión de la imagen más reciente en Docker Hub y actualiza el valor de la imagen en el archivo wordpress.yaml. Para aplicar la actualización, ejecuta lo siguiente:

kubectl apply -f wordpress.yaml

Limpieza

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud Platform por los recursos que usaste en este instructivo:

Después de completar este instructivo, sigue estos pasos para quitar los siguientes recursos y evitar que se apliquen cargos no deseados en tu cuenta:

  1. Borra el servicio: este paso desasigna el balanceador de cargas de Cloud creado para tu servicio wordpress:
kubectl delete service wordpress
  1. Espera a que el balanceador de cargas aprovisionado para el servicio wordpress se borre: el balanceador de cargas se borra de forma asíncrona en segundo plano cuando ejecutas kubectl delete. Espera hasta que el balanceador de cargas se haya borrado. Para ello, mira el resultado del siguiente comando:

    gcloud compute forwarding-rules list
  2. Borra las PersistentVolumeClaims para MySQL y WordPress: esto activará de forma automática la eliminación de los PersistentVolumes aprovisionados de manera dinámica y de los discos persistentes relacionados con estas PersistentVolumeClaims.

kubectl delete pvc wordpress-volumeclaim
kubectl delete pvc mysql-volumeclaim
  1. Borra el clúster del contenedor: este paso quitará los recursos que conforman el clúster del contenedor, como las instancias de procesamiento, los discos y los recursos de red.

    gcloud container clusters delete persistent-disk-tutorial

Qué sigue

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...

Instructivos de Kubernetes Engine