Crear un Guestbook con Redis y PHP

En este instructivo, se muestra cómo compilar una aplicación web de varios niveles con Google Kubernetes Engine (GKE). La aplicación del instructivo es un libro de visitas que les permite a los visitantes ingresar texto en un registro y ver las entradas más recientes en él.

En el instructivo, se muestra cómo configurar el servicio web del libro de visitas en una IP externa con un balanceador de cargas y cómo ejecutar un clúster de Redis con una sola instancia principal (líder) y varias réplicas (seguidores)..

En este ejemplo, se destacan varios conceptos importantes de GKE, como los siguientes:

Objetivos

Para implementar y ejecutar la aplicación del libro de visitas en GKE, haz lo siguiente:

  1. Configura el líder de Redis.
  2. Configura dos seguidores de Redis.
  3. Configura el frontend web del libro de visitas.
  4. Visita el sitio web del libro de visitas.
  5. Escala el frontend web del libro de visitas.

En el siguiente diagrama, se muestra una descripción general de la arquitectura de clúster que crearás cuando completes estos objetivos: Diagrama de GKE del libro de visitas

Antes de comenzar

Sigue los pasos que se indican a continuación para habilitar la API de Kubernetes Engine:
  1. Consulta la página de Kubernetes Engine en Google Cloud 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. Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Descubre cómo confirmar que tienes habilitada la facturación en un proyecto.

Instala las siguientes herramientas de línea de comandos de 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 emplea Kubernetes Engine. Puedes instalar kubectl mediante gcloud:
    gcloud components install kubectl

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

Para ahorrar tiempo en la escritura de las opciones del ID del proyecto y de la zona o región de Compute Engine en la herramienta de gcloud, puedes establecer los valores predeterminados:
gcloud config set project project-id

Según el modo de operación que elijas usar en GKE, especifica una zona o región de procesamiento predeterminada. Si usas el modo estándar, tu clúster es zonal (para este instructivo), por lo que debes establecer tu zona de procesamiento predeterminada. Si usas el modo Autopilot, tu clúster es regional, así que configura la región predeterminada de procesamiento.

Estándar

Ejecuta el siguiente comando y reemplaza compute-zone por la zona de procesamiento, como us-west1-a:

gcloud config set compute/zone compute-zone

Autopilot

Ejecuta el siguiente comando y reemplaza compute-region por tu región de procesamiento, como us-west1:

gcloud config set compute/region compute-region

Cree un clúster de GKE

El primer paso es crear un clúster de GKE en el que deberás ejecutar la aplicación de libro de visitas y el servicio de Redis.

Crea un clúster de GKE llamado guestbook:

Estándar

gcloud container clusters create guestbook --num-nodes=4

Autopilot

 gcloud container clusters create-auto guestbook

Puedes enumerar los clústeres que se ejecutan en tu proyecto con los siguientes comandos:

gcloud container clusters list
gcloud container clusters describe guestbook

Configura el líder de Redis

La aplicación de libro de visita usa Redis para almacenar sus datos. La aplicación escribe sus datos en una instancia del líder de Redis y lee los datos de varias instancias de seguidores de Redis. El primer paso es implementar un líder de Redis.

Primero, clona los manifiestos de muestra:

git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
cd kubernetes-engine-samples/guestbook
git checkout abbb383

Usa el archivo de manifiesto llamado redis-leader-deployment para implementar el líder de Redis. En este archivo de manifiesto, se especifica un Deployment de Kubernetes que ejecuta una sola réplica del Pod líder de Redis:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-leader
  labels:
    app: redis
    role: leader
    tier: backend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
        role: leader
        tier: backend
    spec:
      containers:
      - name: leader
        image: "docker.io/redis:6.0.5"
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379

Ejecuta el siguiente comando para implementar el líder de Redis:

kubectl apply -f redis-leader-deployment.yaml

Verifica que el Pod líder de Redis esté en ejecución:

kubectl get pods
Salida:
NAME                           READY     STATUS    RESTARTS   AGE
redis-leader-343230949-qfvrq   1/1       Running   0          43s

Ejecuta el siguiente comando para ver los registros del pod del líder de Redis:

kubectl logs deployment/redis-leader

Salida:

1:M 24 Jun 2020 14:48:20.917 * Ready to accept connections

Crea el servicio de líder de Redis

La aplicación del libro de visitas necesita comunicarse con el líder de Redis para escribir sus datos. Puedes crear un Service para poder usar un proxy en el tráfico hacia el pod del líder de Redis.

Un Service es una abstracción de Kubernetes que define un conjunto lógico de pods y una política para acceder a ellos. El Service es efectivamente un balanceador de cargas con nombre que actúa como proxy para el tráfico hacia uno o más pods. Cuando configuras un Service, describe en qué pods actuar como proxy en función de las etiquetas de los pods.

Mira el archivo de manifiesto redis-leader-service.yaml, en el que se describe un recurso de un Service para el líder de Redis:

apiVersion: v1
kind: Service
metadata:
  name: redis-leader
  labels:
    app: redis
    role: leader
    tier: backend
spec:
  ports:
  - port: 6379
    targetPort: 6379
  selector:
    app: redis
    role: leader
    tier: backend

Con este archivo de manifiesto, se crea un servicio llamado redis-leader con un conjunto de selectores de etiquetas. Estas coinciden con el conjunto de etiquetas implementado en el paso anterior. Por lo tanto, este Service enruta el tráfico de la red al pod líder de Redis que creaste en un paso anterior.

En la sección ports del manifiesto, se declara el mapa de un solo puerto. En este caso, el servicio enrutará el tráfico del port: 6379 al targetPort: 6379 de los contenedores que coincidan con las etiquetas selector especificadas. Ten en cuenta que el containerPort del Deployment debe coincidir con el targetPort a fin de enrutar el tráfico al Deployment.

Para iniciar el Service del líder de Redis, ejecuta lo siguiente:

kubectl apply -f redis-leader-service.yaml

Verifica que se haya creado el servicio con el siguiente comando:

kubectl get service
Salida:
NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     10.51.240.1     <none>        443/TCP    42s
redis-leader   10.51.242.233   <none>        6379/TCP   12s

Configura los seguidores de Redis

Si bien el líder de Redis es un solo Pod, puedes hacer que tenga alta disponibilidad y cumplir con las demandas de tráfico si agregas algunos seguidores de Redis, o réplicas.

Observa el archivo de manifiesto redis-follower-deployment.yaml, en el que se describe una implementación para los pods de los seguidores de Redis:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-follower
  labels:
    app: redis
    role: follower
    tier: backend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
        role: follower
        tier: backend
    spec:
      containers:
      - name: follower
        image: gcr.io/google_samples/gb-redis-follower:v2
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379

Para crear el Deployment de seguidores de Redis, ejecuta lo siguiente:

kubectl apply -f redis-follower-deployment.yaml

Consulta la lista de Pods para verificar que las dos réplicas de seguidores de Redis estén en ejecución:

kubectl get pods
Resultado:
NAME                              READY   STATUS    RESTARTS   AGE
redis-follower-76588f55b7-bnsq6   1/1     Running   0          27s
redis-follower-76588f55b7-qvtws   1/1     Running   0          27s
redis-leader-dd446dc55-kl7nl      1/1     Running   0          119s

Obtén los registros del Pod para uno de los seguidores de Redis.

kubectl logs deployment/redis-follower
Resultado:
1:M 24 Jun 2020 14:50:43.617 * Background saving terminated with success
1:M 24 Jun 2020 14:50:43.617 * Synchronization with replica 10.12.3.4:6379 succeeded

Crea el servicio de seguidores de Redis

La aplicación de libro de visitas debe comunicarse con los seguidores de Redis para leer los datos. Para que los seguidores de Redis sean detectables, debes configurar otro Service.

redis-follower-service.yaml define la configuración de Service para los seguidores de Redis:

apiVersion: v1
kind: Service
metadata:
  name: redis-follower
  labels:
    app: redis
    role: follower
    tier: backend
spec:
  ports:
    # the port that this service should serve on
  - port: 6379
  selector:
    app: redis
    role: follower
    tier: backend

Con este archivo, se define un Service llamado redis-follower que se ejecuta en el puerto 6379. Ten en cuenta que el campo selector del Service coincide con los Pods seguidores de Redis creados en el paso anterior.

Para crear el servicio redis-follower, ejecuta el siguiente comando:

kubectl apply -f redis-follower-service.yaml

Verifica que se haya creado el servicio con el siguiente comando:

kubectl get service
Salida:
NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     10.51.240.1     <none>        443/TCP    1m
redis-leader   10.51.242.233   <none>        6379/TCP   49s
redis-follower 10.51.247.238   <none>        6379/TCP   3s

Configura el frontend web del libro de visitas

Ahora que el almacenamiento de Redis del libro de visitas está listo para usarlo, inicia sus servidores web. Al igual que los seguidores de Redis, el frontend se implementa mediante un Deployment de Kubernetes.

La aplicación de libro de visitas usa un frontend PHP. Se configura para comunicarse con los Services de los seguidores o del líder de Redis, según si la solicitud es de lectura o de escritura. El frontend expone una interfaz JSON y entrega una UX basada en jQuery-Ajax.

Visualiza el archivo de manifiesto frontend-deployment.yaml que describe el Deployment para el servidor web del libro de visitas:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
        app: guestbook
        tier: frontend
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google_samples/gb-frontend:v5
        env:
        - name: GET_HOSTS_FROM
          value: "dns"
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 80

Para crear el Deployment del frontend web del libro de visitas, ejecuta el siguiente comando:

kubectl apply -f frontend-deployment.yaml

Consulta la lista de etiquetas que identifican el frontend web para verificar que las tres réplicas estén en ejecución:

kubectl get pods -l app=guestbook -l tier=frontend
Salida:
NAME                        READY   STATUS    RESTARTS   AGE
frontend-7b78458576-8kp8s   1/1     Running   0          37s
frontend-7b78458576-gg86q   1/1     Running   0          37s
frontend-7b78458576-hz87g   1/1     Running   0          37s

En el archivo de manifiesto, se especifica la variable de entorno GET_HOSTS_FROM=dns. Cuando proporcionas la configuración a la aplicación del frontend web del libro de visitas, la aplicación del frontend usa los nombres de host redis-follower y redis-leader para realizar una búsqueda de DNS. Mediante la búsqueda de DNS, se obtienen las direcciones IP de los Service respectivos que creaste en los pasos anteriores. Este concepto se llama descubrimiento de servicios de DNS.

Expón el frontend en una dirección IP externa

Los Service redis-follower y redis-leader que creaste en los pasos anteriores solo son accesibles en el clúster de GKE, porque el tipo predeterminado para un Service es ClusterIP. Con ClusterIP, se proporciona una sola dirección IP para el conjunto de Pods al que se direcciona el Service. Solo se puede acceder a esta dirección IP en el clúster.

Sin embargo, el Service del frontend web del libro de visitas debe ser visible de manera externa. Es decir, quieres que un cliente pueda solicitar el Service desde fuera del clúster de GKE. Para realizar esta solicitud, puedes especificar type: LoadBalancer o type: NodePort en la configuración del Service, según tus requisitos. En este ejemplo, usarás type: LoadBalancer. El archivo de manifiesto frontend-service.yaml en el que se especifica esta configuración tiene el siguiente aspecto:

apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  type: LoadBalancer
  ports:
    # the port that this service should serve on
  - port: 80
  selector:
    app: guestbook
    tier: frontend

Cuando se crea el servicio frontend, GKE crea un balanceador de cargas y una dirección IP externa. Ten en cuenta que estos recursos están sujetos a facturación. En la declaración del puerto en la sección ports, se especifica port: 80, pero no se especifica targetPort. Cuando omites la propiedad targetPort, su valor predeterminado es el valor del campo port. En este caso, este Service enrutará el tráfico externo del puerto 80 al puerto 80 de los contenedores del Deployment frontend.

Para crear el Service, ejecuta el siguiente comando:

kubectl apply -f frontend-service.yaml

Visita el sitio web del libro de visitas

Para acceder al Service del libro de visitas, ejecuta el siguiente comando a fin de buscar la IP externa del Service que configuraste:

kubectl get service frontend
Salida:
NAME       CLUSTER-IP      EXTERNAL-IP        PORT(S)        AGE
frontend   10.51.242.136   109.197.92.229     80:32372/TCP   1m

Copia la dirección IP de la columna EXTERNAL-IP y carga la página en el navegador:

Libro de visitas en ejecución en GKE

Prueba agregar algunas entradas del libro de visitas. Para ello, escribe un mensaje y haz clic en Enviar (Submit). El mensaje que escribiste aparece en el frontend. Este mensaje indica que los datos se agregaron a Redis de forma correcta a través de los Service que creaste antes.

Cómo escalar verticalmente el frontend web

Supongamos que tu aplicación de libro de visitas lleva un tiempo en ejecución y, de un momento a otro, se llena de publicidad. Entonces, decides que sería una buena idea agregar más servidores web a tu frontend. Esto es fácil de hacer, ya que tus servidores están definidos como un servicio que usa un controlador de implementación.

Para escalar verticalmente la cantidad de pods de frontend a cinco, ejecuta el siguiente comando:

kubectl scale deployment frontend --replicas=5

Salida:

deployment.extensions/frontend scaled

La configuración del Deployment se actualizará para indicar que debería haber cinco réplicas en ejecución. El Deployment ajusta la cantidad de pods que ejecuta para que coincidan con la configuración. Para verificar la cantidad de réplicas, ejecuta el siguiente comando:

kubectl get pods
Salida:
NAME                             READY     STATUS    RESTARTS   AGE
frontend-88237173-3s3sc          1/1       Running   0          1s
frontend-88237173-twgvn          1/1       Running   0          1s
frontend-88237173-5p257          1/1       Running   0          23m
frontend-88237173-84036          1/1       Running   0          23m
frontend-88237173-j3rvr          1/1       Running   0          23m
redis-leader-343230949-qfvrq     1/1       Running   0          54m
redis-follower-132015689-dp23k   1/1       Running   0          37m
redis-follower-132015689-xq9v0   1/1       Running   0          37m

Puedes reducir la cantidad de Pods de frontend con el mismo comando.

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

  1. Borra el Service: En este paso, se desasigna el balanceador de cargas de Cloud creado para el Service de frontend:

    kubectl delete service frontend

  2. Espera hasta que se haya borrado el balanceador de cargas aprovisionado para el Service de frontend: El balanceador de cargas se borra de forma asíncrona en segundo plano cuando ejecutas kubectl delete. Mira el resultado del siguiente comando y espera hasta que el balanceador de cargas se haya borrado:

    gcloud compute forwarding-rules list

  3. Borra el clúster de GKE: En este paso, se borran los recursos que conforman el clúster de GKE, como las instancias de procesamiento, los discos y los recursos de red.

    gcloud container clusters delete guestbook

¿Qué sigue?