Pruebas de carga distribuidas mediante Google Kubernetes Engine

En este instructivo, se explica cómo usar Google Kubernetes Engine (GKE) con el fin de implementar un framework de prueba de carga distribuida que use varios contenedores a fin de crear tráfico para una sola API basada en REST. En este instructivo, se realizan pruebas de carga de una aplicación web implementada en App Engine que expone extremos de estilo REST para capturar solicitudes POST HTTP entrantes.

Puedes usar este mismo patrón con el fin de frameworks de pruebas de carga para una variedad de situaciones y aplicaciones, como los sistemas de mensajería, los sistemas de administración de flujos de datos y los sistemas de bases de datos.

Objetivos

  • Definir variables de entorno para controlar la configuración de implementación
  • Crear un clúster de GKE
  • Realizar pruebas de carga
  • Escalar la cantidad de usuarios o extender el patrón para otros casos prácticos, opcionalmente

Costos

En este instructivo, se usan los siguientes componentes facturables de Google Cloud:

  • Google Kubernetes Engine
  • App Engine
  • Cloud Build
  • Cloud Storage

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 sean aptos para obtener una prueba gratuita.

Antes de comenzar

  1. Accede a tu Cuenta de Google.

    Si todavía no tienes una cuenta, regístrate para obtener una nueva.

  2. En la página de selección de proyectos de Cloud Console, selecciona o crea un proyecto de Cloud.

    Ir a la página Selector de proyectos

  3. Comprueba que la facturación esté habilitada en tu proyecto.

    Descubre cómo puedes habilitar la facturación

  4. Habilita las API de Cloud Build, Compute Engine, Container Analysis, and Container Registry.

    Habilita las API

Cuando finalices este instructivo, podrás borrar los recursos creados para evitar que se te siga facturando. Para obtener más información, consulta cómo hacer una limpieza.

Carga de trabajo de ejemplo

En el siguiente diagrama, se muestra una carga de trabajo de ejemplo en la que las solicitudes van del cliente a la aplicación.

Solicitudes que van del cliente a la aplicación.

Para modelar esta interacción, puedes usar Locust, una herramienta de prueba de carga distribuida basada en Python que puede distribuir solicitudes a través de varias rutas de destino. Por ejemplo, Locust puede distribuir solicitudes a las rutas de destino /login y /metrics. La carga de trabajo se modela como un conjunto de tareas en Locust.

Arquitectura

Esta arquitectura incluye dos componentes principales:

  • La imagen de contenedor de Locust Docker
  • El mecanismo de organización y administración de contenedores

La imagen de contenedor de Locust Docker contiene el software de Locust. El Dockerfile, que se obtiene después de clonar el repositorio de GitHub que acompaña a este instructivo, utiliza una imagen de Python básica y también incluye secuencias de comandos para iniciar el servicio de Locust y ejecutar las tareas. Para aproximarse a los clientes del mundo real, cada tarea de Locust está ponderada. Por ejemplo, el registro se realiza una vez por cada mil solicitudes totales de clientes.

GKE proporciona organización y administración de contenedores. Con GKE, puedes especificar el número de nodos de contenedor que proporcionan la base para tu marco de trabajo de pruebas de carga. También puedes organizar tus trabajadores de pruebas de carga en pods y especificar cuántos pods deseas que GKE siga ejecutando.

Para implementar las tareas de prueba de carga, haz lo siguiente:

  1. Implementa un principal de la prueba de carga.
  2. Implementa un grupo de trabajadores de pruebas de carga. Con estos trabajadores de pruebas de carga, puedes crear una cantidad sustancial de tráfico para fines de prueba.

En el siguiente diagrama, se muestran los contenidos del nodo principal y los nodos trabajadores.

El nodo principal contiene el servidor de la API, el programador y el administrador. Cada uno de los 2 nodos contiene Kublet, un proxy y una imagen de Docker con 4 Pods.

Información acerca del principal de pruebas de carga

El principal de Locust es el punto de entrada para ejecutar las tareas de prueba de carga. La configuración del principal de Locust especifica varios elementos, incluidos los puertos que el contenedor debe exponer:

  • 8089 para la interfaz web
  • 5557 y 5558 para comunicarse con los trabajadores

Esta información se usa más tarde para configurar los trabajadores de Locust.

Implementa un servicio para asegurarte de que otros Pods dentro del clúster puedan acceder a los puertos expuestos a través de hostname:port. También se puede hacer referencia a los puertos expuestos por medio de un nombre de puerto descriptivo.

Utilizas un servicio para permitir que los trabajadores de Locust detecten fácilmente y se comuniquen de manera confiable con el principal, incluso si el principal falla y la implementación lo reemplaza por un nuevo pod. El servicio también incluye una directiva para crear una regla de reenvío externa al nivel de clúster, que proporciona la capacidad al tráfico externo de acceder a los recursos del clúster.

Después de implementar el principal de Locust, puedes abrir la interfaz web con la dirección IP pública de la regla de reenvío externo. Después de implementar los trabajadores de Locust, puedes iniciar la simulación y ver estadísticas adicionales a través de la interfaz web de Locust.

Sobre los trabajadores de pruebas de carga

Los trabajadores de Locust ejecutan las tareas de prueba de carga. Usas una única implementación para crear múltiples pods. Los pods se extienden a través del clúster de Kubernetes. Cada pod usa variables de entorno para controlar la información de configuración, como el nombre de host del sistema a prueba y el nombre de host de la instancia principal de Locust.

En el siguiente diagrama, se muestra la relación entre el principal y los trabajadores de Locust.

El principal de Locust se encuentra en la parte superior de una jerarquía con varios trabajadores debajo.

Inicializa variables comunes

Debes definir muchas variables que controlen dónde se implementarán los elementos de la infraestructura.

  1. Abre Cloud Shell:

    Abrir Cloud Shell

    Ejecuta todos los comandos de terminal en este instructivo desde Cloud Shell.

  2. Configura las variables de entorno:

    REGION=us-central1
    ZONE=${REGION}-b
    PROJECT=$(gcloud config get-value project)
    CLUSTER=gke-load-test
    TARGET=${PROJECT}.appspot.com
    SCOPE="https://www.googleapis.com/auth/cloud-platform"
    
  3. Establece la zona predeterminada y el ID del proyecto para que no tengas que especificar estos valores en cada comando subsiguiente:

    gcloud config set compute/zone ${ZONE}
    gcloud config set project ${PROJECT}
    

Cómo configurar el entorno

  1. Clona el repositorio de muestra de GitHub:

    git clone https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes
    
  2. Cambia tu directorio de trabajo al repositorio clonado:

    cd distributed-load-testing-using-kubernetes
    

Cómo crear el clúster de GKE

  1. Crea el clúster de GKE:

    gcloud container clusters create $CLUSTER \
       --zone $ZONE \
       --scopes $SCOPE \
       --enable-autoscaling --min-nodes "3" --max-nodes "10" \
       --scopes=logging-write,storage-ro \
       --addons HorizontalPodAutoscaling,HttpLoadBalancing
    
  2. Conéctate al clúster de GKE:

    gcloud container clusters get-credentials $CLUSTER \
       --zone $ZONE \
       --project $PROJECT
    

Cómo compilar la imagen de Docker

  1. Crea la imagen de Docker y guárdala en el Container Registry de tu proyecto:

    gcloud builds submit \
        --tag gcr.io/$PROJECT/locust-tasks:latest docker-image
    
  2. Verifica que la imagen de Docker esté en el repositorio de contenedores de tu proyecto:

    gcloud container images list | grep locust-tasks
    

    El resultado debería ser similar a este:

    gcr.io/[PROJECT]/locust-tasks
    Only listing images in gcr.io/[PROJECT]. Use --repository to list images in other repositories.
    

Cómo implementar la aplicación de ejemplo

  • Implementa la aplicación de muestra en App Engine:

    gcloud app deploy sample-webapp/app.yaml \
      --project=$PROJECT
    

    El resultado se verá de la siguiente manera:

    File upload done.
    Updating service [default]...done.
    Setting traffic split for service [default]...done.
    Deployed service [default] to [https://[PROJECT].appspot.com]
    

Implementa el nodo principal y los nodos trabajadores de Locust

  1. Reemplaza el host de destino y el ID del proyecto por el extremo implementado y el ID del proyecto en los archivos locust-master-controller.yaml y locust-worker-controller.yaml:

    sed -i -e "s/\[TARGET_HOST\]/$TARGET/g" kubernetes-config/locust-master-controller.yaml
    sed -i -e "s/\[TARGET_HOST\]/$TARGET/g" kubernetes-config/locust-worker-controller.yaml
    sed -i -e "s/\[PROJECT_ID\]/$PROJECT/g" kubernetes-config/locust-master-controller.yaml
    sed -i -e "s/\[PROJECT_ID\]/$PROJECT/g" kubernetes-config/locust-worker-controller.yaml
    
  2. Implementa el nodo principal y los nodos trabajadores de Locust:

    kubectl apply -f kubernetes-config/locust-master-controller.yaml
    kubectl apply -f kubernetes-config/locust-master-service.yaml
    kubectl apply -f kubernetes-config/locust-worker-controller.yaml
    
  3. Verifica las implementaciones de Locust:

    kubectl get pods -o wide
    

    El resultado presenta el siguiente aspecto:

    NAME                             READY   STATUS    RESTARTS   AGE   IP           NODE
    locust-master-87f8ffd56-pxmsk    1/1     Running   0          1m    10.32.2.6    gke-gke-load-test-default-pool-96a3f394
    locust-worker-58879b475c-279q9   1/1     Running   0          1m    10.32.1.5    gke-gke-load-test-default-pool-96a3f394
    locust-worker-58879b475c-9frbw   1/1     Running   0          1m    10.32.2.8    gke-gke-load-test-default-pool-96a3f394
    locust-worker-58879b475c-dppmz   1/1     Running   0          1m    10.32.2.7    gke-gke-load-test-default-pool-96a3f394
    locust-worker-58879b475c-g8tzf   1/1     Running   0          1m    10.32.0.11   gke-gke-load-test-default-pool-96a3f394
    locust-worker-58879b475c-qcscq   1/1     Running   0          1m    10.32.1.4    gke-gke-load-test-default-pool-96a3f394
    
  4. Verifica los servicios:

    kubectl get services
    

    El resultado presenta el siguiente aspecto:

    NAME            TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                                        AGE
    kubernetes      ClusterIP      10.35.240.1     <none>          443/TCP                                        12m
    locust-master   LoadBalancer   10.35.250.221   35.222.247.12   8089:30680/TCP,5557:30699/TCP,5558:31386/TCP   1m
    
  5. Ejecuta un bucle de observación mientras se asigna una dirección IP externa al servicio principal de Locust:

    kubectl get svc locust-master --watch
    
  6. Presiona Ctrl+C a fin de salir del bucle de observación y, luego, ejecuta el siguiente comando para anotar la dirección IP externa:

    EXTERNAL_IP=$(kubectl get svc locust-master -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
    

Prueba la carga

Puedes utilizar la interfaz web principal de Locust para ejecutar las tareas de prueba de carga en el sistema a prueba.

  1. Obtén la dirección IP externa del sistema:

    echo $EXTERNAL_IP
    

  2. Abre tu navegador y, luego, abre la interfaz web del principal de Locust. Para [EXTERNAL_IP] en la siguiente URL, sustituye la dirección IP que obtuviste en el paso anterior: http://[EXTERNAL_IP]:8089.

    En la interfaz web del principal de Locust, se proporciona un cuadro de diálogo para iniciar un nuevo conjunto y especificar la cantidad de usuarios y la tasa de generación.

  3. Especifica Number of users to simulate en 10 y Hatch rate (la tasa de generación en la que se deben activar los usuarios) en 5 usuarios por segundo.

  4. A continuación, haz clic en Comenzar a generar (Start swarming) para comenzar la simulación.

    Después de que las solicitudes comienzan a generarse, las estadísticas empiezan a agregarse para las métricas de simulación, como la cantidad de solicitudes y las solicitudes por segundo, como se muestra en la siguiente imagen:

    En la interfaz web de Locust, se muestra que las estadísticas comienzan a agregarse.
  5. Haz clic en Stop para terminar la prueba.

Puedes ver el servicio implementado y otras métricas desde Google Cloud Console.

En el panel de App Engine, se muestra un gráfico de una hora de solicitudes por tipo.

Escala verticalmente la cantidad de usuarios (opcional)

Si deseas probar una mayor carga en la aplicación, puedes agregar usuarios simulados. Para poder agregar usuarios simulados, debes asegurarte de que haya suficientes recursos a fin de admitir el aumento de la carga. Con Google Cloud, puedes agregar Pods de trabajadores de Locust a la implementación sin volver a implementar los Pods existentes, siempre que tengas los recursos de VM subyacentes para admitir una mayor cantidad de Pods. El clúster de GKE inicial comienza con 3 nodos y puede escalar de forma automática hasta 10 nodos.

  • Escala el grupo de pods trabajadores de Locust a 20.

    kubectl scale deployment/locust-worker --replicas=20
    

    Implementar e iniciar los Pods nuevos lleva unos minutos.

Si ves el error Pod Unschedulable, debes agregar más nodos al clúster. Para obtener más información, consulta Cambia el tamaño de un clúster de GKE.

Después de que se inicien los Pods, vuelve a la interfaz web del principal de Locust y reinicia las pruebas de carga.

Cómo extender el patrón

Para extender este patrón, puedes crear nuevas tareas de Locust o incluso cambiar a un marco de trabajo de pruebas de carga diferente.

Puedes personalizar las métricas que recopilas. Por ejemplo, es posible que desees medir las solicitudes por segundo, supervisar la latencia de las respuestas a medida que aumenta la carga o verificar las tasas de error de respuestas y los tipos de errores.

Para obtener más información, consulta la documentación de Cloud Monitoring.

Realiza una limpieza

Una vez completado el instructivo, puedes limpiar los recursos creados en GCP para que no se te facture por ellos en el futuro.

Cómo borrar el proyecto

La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

Para borrar el proyecto, sigue estos pasos:

  1. En Cloud Console, ve a la página Administrar recursos.

    Ir a la página Administrar recursos

  2. En la lista de proyectos, selecciona el proyecto que deseas borrar y haz clic en Borrar .
  3. En el cuadro de diálogo, escribe el ID del proyecto y haz clic en Cerrar para borrar el proyecto.

Borra el clúster de GKE

Si no quieres borrar todo el proyecto, ejecuta el comando siguiente para borrar el clúster de GKE:

   gcloud container clusters delete $CLUSTER --zone $ZONE
   

Próximos pasos