Crea una aplicación web de varios niveles con Redis y PHP


En este instructivo, se muestra cómo compilar una aplicación web de varios niveles con Google Kubernetes Engine (GKE).

En este instructivo, harás lo que se indica a continuación:

  • Configura una aplicación web con una dirección IP externa y un balanceador de cargas.
  • Crea un clúster de Redis con una sola instancia principal (líder) y varias réplicas (seguidores)..

En el ejemplo, se describen los siguientes conceptos de Kubernetes:

Objetivos

Para implementar y ejecutar la aplicación en GKE, haz lo siguiente:

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

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

Arquitectura del clúster de GKE

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.

Antes de comenzar

Cloud Shell tiene preinstalado el software que necesitas para este instructivo, incluidos kubectl y la CLI de gcloud. Si no usas Cloud Shell, debes instalar gcloud CLI.

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.
  3. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the GKE API:

    gcloud services enable container.googleapis.com
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  10. Make sure that billing is enabled for your Google Cloud project.

  11. Enable the GKE API:

    gcloud services enable container.googleapis.com

Prepare el entorno

Para configurar tu entorno, sigue estos pasos:

  1. Establece las variables de entorno:

    export PROJECT_ID=PROJECT_ID
    export COMPUTE_LOCATION=COMPUTE_LOCATION
    

    Reemplaza lo siguiente:

  2. Clona el repositorio de GitHub:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  3. Cambia al directorio de trabajo:

    cd kubernetes-engine-samples/quickstarts/guestbook/
    

Crea un clúster de GKE

Crea un Autopilot o Standard clúster de GKE:

Autopilot

gcloud container clusters create-auto guestbook \
    --location=${COMPUTE_LOCATION} \

Standard

gcloud container clusters create guestbook \
    --location=${COMPUTE_LOCATION} \
    --num-nodes=4

Conéctate al clúster

Configura kubectl para comunicarse con el clúster:

gcloud container clusters get-credentials guestbook \
    --location=${COMPUTE_LOCATION}

Configura el líder de Redis.

La aplicación 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.

  1. En el siguiente manifiesto, se describe una implementación de Kubernetes que ejecuta un Pod líder de Redis de una sola réplica:

    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

    Aplica el manifiesto al clúster:

    kubectl apply -f redis-leader-deployment.yaml
    
  2. Verifica que el Pod líder de Redis esté en ejecución:

    kubectl get pods
    

    El resultado es similar al siguiente:

    NAME                           READY     STATUS    RESTARTS   AGE
    redis-leader-343230949-qfvrq   1/1       Running   0          43s
    

    Es posible que STATUS tarde varios minutos en cambiar de Pending a Running.

Crea el servicio de líder de Redis

La aplicación web 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 habilitar el acceso a los Pods. Cuando creas un Service, describe en qué Pods actuar como proxy en función de las etiquetas de los pods.

  1. En el siguiente manifiesto, se describe 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

    Este manifiesto incluye 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. El Service enrutará el tráfico del port: 6379 al targetPort: 6379 de los contenedores que coincidan con las etiquetas selector especificadas. El containerPort que se usa en el Deployment debe coincidir con el targetPort para enrutar el tráfico al Deployment.

    Aplica el manifiesto al clúster:

    kubectl apply -f redis-leader-service.yaml
    
  2. Verifica que GKE haya creado el Service:

    kubectl get service
    

    El resultado es similar al siguiente:

    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 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.

  1. En el siguiente manifiesto, se describe un Deployment 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: us-docker.pkg.dev/google-samples/containers/gke/gb-redis-follower:v2
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 6379
  2. Aplica el manifiesto al clúster:

    kubectl apply -f redis-follower-deployment.yaml
    
  3. Verifica que las dos réplicas de seguidores de Redis estén en ejecución:

    kubectl get pods
    

    El resultado es similar al siguiente:

    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
    

    Es posible que STATUS tarde varios minutos en cambiar de Pending a Running.

Crea el Service de seguidores de Redis

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

  1. En el siguiente manifiesto, se describe un 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

    Este manifiesto especifica que el servicio se ejecuta en el puerto 6379. El campo selector del Service coincide con los Pods seguidores de Redis creados en el paso anterior.

    Aplica el manifiesto al clúster:

    kubectl apply -f redis-follower-service.yaml
    
  2. Verifica que GKE haya creado el servicio:

    kubectl get service
    

    El resultado es similar al siguiente:

    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 de la aplicación

Ahora que tienes el almacenamiento de Redis para tu aplicación, inicia los servidores web. Al igual que los seguidores de Redis, el frontend se implementa mediante un Deployment de Kubernetes.

La aplicación web usa un frontend de PHP, que se configura para comunicarse con los servicios de seguidores o líderes de Redis, según si la solicitud es de lectura o escritura. El frontend expone una interfaz JSON y entrega una IU basada en jQuery-Ajax.

  1. En el siguiente manifiesto, se describe una implementación para el servidor web:

    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: us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5
            env:
            - name: GET_HOSTS_FROM
              value: "dns"
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 80

    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, 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 Services que creaste en los pasos anteriores. Este concepto se llama descubrimiento de servicios de DNS.

    Aplica el manifiesto al clúster:

    kubectl apply -f frontend-deployment.yaml
    
  2. Verifica que las réplicas estén en ejecución:

    kubectl get pods -l app=guestbook -l tier=frontend
    

    El resultado es similar al siguiente:

    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
    

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

Con la configuración actual, solo se puede acceder a los Services redis-follower y redis-leader que creaste en los pasos anteriores dentro del clúster de GKE porque el tipo predeterminado para un Service es ClusterIP

Un servicio ClusterIP 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.

Para que el Service de frontend web sea de acceso externo, puedes especificar type: LoadBalancer o type: NodePort en la configuración del Service según tus requisitos.

El siguiente manifiesto describe un Service de tipo LoadBalancer:

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

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.

Aplica el manifiesto al clúster:

kubectl apply -f frontend-service.yaml

Cuando se crea el servicio frontend, GKE crea un balanceador de cargas y una dirección IP externa. Estos recursos están sujetos a facturación.

Visita el sitio web de la aplicación

Para acceder al sitio web de la aplicación, obtén la dirección IP externa del Service frontend:

kubectl get service frontend

El resultado es similar al siguiente:

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

Es posible que la columna EXTERNAL-IP muestre <pending> mientras se crea el balanceador de cargas. Esto podría llevar varios minutos. Si ves errores como Does not have minimum availability, espera unos minutos. Este error temporal se produce porque GKE vuelve a crear los nodos para realizar los cambios.

Copia la dirección IP y abre la página en tu navegador:

Aplicación web que se ejecuta en GKE

Prueba agregar algunas entradas. Para ello, escribe un mensaje y haz clic en Enviar. 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 Services que creaste.

Escala verticalmente el frontend web

Supongamos que tu aplicación 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. Para ello, aumenta la cantidad de Pods.

  1. Para aumentar la cantidad de Pods de frontend, ejecuta el siguiente comando:

    kubectl scale deployment frontend --replicas=5
    

    El resultado es similar al siguiente:

    deployment.extensions/frontend scaled
    
  2. Verifica la cantidad de réplicas que se están ejecutando:

    kubectl get pods
    

    El resultado es similar al siguiente:

    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. Para ello, reemplaza 5 por 1.

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.

Borra el proyecto

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

Borra los recursos individuales

Si usaste un proyecto existente y no quieres borrarlo, borra los recursos individuales.

  1. Borra el Service frontend:

    kubectl delete service frontend
    
  2. Borra el clúster de GKE:

    gcloud container clusters delete guestbook
    

¿Qué sigue?