Tests de charge distribués à l'aide de Google Kubernetes Engine

Ce tutoriel explique comment utiliser Google Kubernetes Engine (GKE) afin de déployer un framework de tests de charge distribués qui crée du trafic pour une API REST simple à l'aide de plusieurs conteneurs. Ce tutoriel teste la charge d'une application Web déployée sur App Engine qui expose les points de terminaison de type REST pour enregistrer les requêtes HTTP POST entrantes.

Vous pouvez utiliser ce même modèle afin de créer des frameworks de tests de charge pour un éventail de scénarios et d'applications, tels que des systèmes de messagerie, des systèmes de gestion de flux de données et des systèmes de base de données.

Objectifs

  • Définir des variables d'environnement pour contrôler la configuration du déploiement
  • Créer un cluster GKE
  • Effectuer des tests de charge
  • (Facultatif) Augmenter le nombre d'utilisateurs ou étendre le modèle à d'autres cas d'utilisation

Coûts

Ce tutoriel utilise les composants facturables suivants de Google Cloud :

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

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Avant de commencer

  1. Connectez-vous à votre compte Google.

    Si vous n'en possédez pas déjà un, vous devez en créer un.

  2. Dans Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Cloud.

    Accéder à la page de sélection du projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud. Découvrez comment vérifier que la facturation est activée pour votre projet.

  4. Activer les API Cloud Build, Compute Engine, Container Analysis, and Container Registry.

    Activer les API

Une fois que vous avez terminé ce tutoriel, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Consultez la page Effectuer un nettoyage pour en savoir plus.

Exemple de charge de travail

Le schéma suivant montre un exemple de charge de travail où les requêtes passent d'un client à une application.

Requêtes passant d'un client à une application.

Pour modéliser cette interaction, vous pouvez utiliser Locust, un outil de tests de charge distribués basé sur Python, capable de distribuer des requêtes sur plusieurs chemins d'accès cibles. Par exemple, Locust peut distribuer des requêtes sur les chemins d'accès cibles /login et /metrics. La charge de travail est modélisée en tant qu'ensemble de tâches dans Locust.

Architecture

Cette architecture implique deux composants principaux :

  • L'image de conteneur Docker Locust
  • Le mécanisme de gestion et d'orchestration de conteneurs

L'image de conteneur Docker Locust contient le logiciel Locust. Le Dockerfile, que vous obtenez lorsque vous clonez le dépôt GitHub, fourni avec ce tutoriel, utilise une image Python de base et inclut des scripts pour démarrer le service Locust et exécuter les tâches. Pour se rapprocher des clients du monde réel, chaque tâche Locust est pondérée. Par exemple, l'enregistrement se produit tous les milliers de requêtes client.

GKE fournit une gestion et une orchestration des conteneurs. Avec GKE, vous pouvez spécifier le nombre de nœuds de conteneur qui constituent la base de votre framework de tests de charge. Vous pouvez également organiser vos nœuds de calcul de tests de charge en pods, et spécifier le nombre de pods que GKE doit continuer à exécuter.

Pour déployer les tâches de tests de charge, procédez comme suit :

  1. Déployez un nœud maître de tests de charge.
  2. Déployez un groupe de nœuds de calcul de tests de charge. Grâce à ces derniers, vous pouvez créer une quantité de trafic importante à des fins de test.

Le schéma ci-dessous illustre le contenu des nœuds maîtres et des nœuds de calcul.

Le nœud maître contient le serveur d'API, le programmeur et le gestionnaire. Les deux nœuds contiennent chacun Kublet, un proxy et une image Docker comprenant quatre pods.

À propos du nœud maître de tests de charge

Le nœud maître Locust constitue le point d'entrée pour l'exécution des tâches de tests de charge. Sa configuration spécifie plusieurs éléments, y compris les ports que le conteneur doit exposer :

  • 8089 pour l'interface Web
  • 5557 et 5558 pour la communication avec les nœuds de calcul

Ces informations servent ensuite à la configuration des nœuds de calcul Locust.

Déployez un service pour vous assurer que les autres pods du cluster peuvent accéder aux ports exposés via hostname:port. Les ports exposés peuvent également être référencés via un nom de port descriptif.

Utilisez un service pour permettre aux nœuds de calcul Locust de découvrir facilement le nœud maître et de communiquer de manière fiable avec lui, même si celui-ci tombe en panne et que le déploiement le remplace par un nouveau pod. Le service comprend également une instruction permettant de créer une règle de transfert externe au niveau du cluster, afin que le trafic externe puisse accéder aux ressources du cluster.

Après avoir déployé le nœud maître Locust, vous pouvez ouvrir l'interface Web à l'aide de l'adresse IP publique de la règle de transfert externe. Après avoir déployé les nœuds de calcul Locust, vous pouvez démarrer la simulation et consulter des statistiques globales via l'interface Web Locust.

À propos des nœuds de calcul de tests de charge

Les nœuds de calcul Locust exécutent les tâches de tests de charge. Vous utilisez un seul déploiement pour créer plusieurs pods. Les pods sont répartis dans le cluster Kubernetes. Chaque pod utilise des variables d'environnement afin de contrôler des informations de configuration, telles que le nom d'hôte du système soumis aux tests et le nom d'hôte du nœud maître Locust.

Le schéma suivant illustre la relation entre le nœud maître Locust et les nœuds de calcul Locust.

Le nœud maître Locust est en haut de la hiérarchie, et plusieurs nœuds de calcul se trouvent en dessous.

Initialiser des variables communes

Vous devez définir plusieurs variables qui contrôlent l'emplacement où sont déployés les éléments de l'infrastructure.

  1. Ouvrez Cloud Shell.

    Ouvrir Cloud Shell

    Dans ce tutoriel, vous allez exécuter toutes les commandes de terminal à partir de Cloud Shell.

  2. Définissez les variables d'environnement :

    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. Définissez la zone et l'ID du projet par défaut afin de ne pas avoir à spécifier ces valeurs dans chacune des commandes suivantes :

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

Configurer l'environnement

  1. Clonez l'exemple de dépôt depuis GitHub :

    git clone https://github.com/GoogleCloudPlatform/distributed-load-testing-using-kubernetes
    
  2. Changez votre répertoire de travail dans le dépôt cloné :

    cd distributed-load-testing-using-kubernetes
    

Créer le cluster GKE

  1. Créez le cluster 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. Connectez-vous au cluster GKE :

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

Créer l'image Docker

  1. Créez l'image Docker et stockez-la dans le registre Container Registry de votre projet.

    gcloud builds submit \
        --tag gcr.io/$PROJECT/locust-tasks:latest docker-image
    
  2. Vérifiez que l'image Docker se trouve dans le dépôt de conteneurs de votre projet :

    gcloud container images list | grep locust-tasks
    

    Le résultat ressemble à ceci :

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

Déployer l'exemple d'application

  • Déployez l'exemple d'application sur App Engine :

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

    Le résultat doit ressembler à ceci :

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

Déployer les nœuds maîtres et les nœuds de calcul Locust

  1. Remplacez l'hôte cible et l'ID du projet par le point de terminaison déployé et l'ID du projet dans les fichiers locust-master-controller.yaml et 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. Déployez les nœuds maîtres et les nœuds de calcul 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. Vérifiez les déploiements Locust :

    kubectl get pods -o wide
    

    Le résultat ressemble à ceci :

    Les nœuds maîtres et de calcul Locust sont déployés.
  4. Vérifiez les services :

    kubectl get services
    

    Le résultat ressemble à ceci :

    Les services sont déployés.
  5. Exécutez une boucle de contrôle lorsqu'une adresse IP externe est attribuée au service de nœud maître Locust :

    kubectl get svc locust-master --watch
    
  6. Appuyez sur Ctrl+C pour quitter la boucle de contrôle, puis exécutez la commande suivante pour noter l'adresse IP externe :

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

Tester la charge

Vous pouvez utiliser l'interface Web du nœud maître Locust pour exécuter les tâches de tests de charge sur le système soumis aux tests.

  1. Obtenez l'adresse IP externe du système :

    echo $EXTERNAL_IP
    

  2. Ouvrez votre navigateur, puis ouvrez l'interface Web du nœud maître Locust. Dans l'URL suivante, remplacez [EXTERNAL_IP] par l'adresse IP que vous avez obtenue à l'étape précédente : http://[EXTERNAL_IP]:8089.

    L'interface Web du nœud maître Locust fournit une boîte de dialogue permettant de démarrer un nouvel essaim et de spécifier le nombre d'utilisateurs et le taux d'apparition.

  3. Dans le champ Number of users to simulate (Nombre d'utilisateurs à simuler), indiquez 10 en tant que valeur totale. Dans le champ Hatch rate (Taux d'apparition), soit la fréquence à laquelle les utilisateurs doivent être générés, indiquez 5 utilisateurs par seconde.

  4. Cliquez ensuite sur Start swarming (Démarrer le travail en essaim) pour commencer la simulation.

    Une fois que le travail en essaim des requêtes a commencé, les métriques de simulation (nombre de requêtes, nombre de requêtes par seconde, etc.) s'affinent, car les statistiques commencent à s'agréger, comme illustré dans l'image suivante :

    L'interface Web Locust montre que les statistiques commencent à s'agréger.
  5. Cliquez sur Stop pour mettre fin au test.

Vous pouvez afficher le service déployé et d'autres métriques depuis la console Google Cloud.

Le tableau de bord d'App Engine affiche un graphique représentant une heure de requêtes par type.

Augmenter le nombre d'utilisateurs (facultatif)

Si vous souhaitez tester une charge accrue sur l'application, vous pouvez ajouter des utilisateurs simulés. Avant cela, vous devez vous assurer qu'il y a suffisamment de ressources pour permettre l'augmentation de la charge. Avec Google Cloud, vous pouvez ajouter des pods de nœuds de calcul Locust au déploiement sans redéployer les pods existants, à condition que les ressources de VM sous-jacentes acceptent un nombre accru de pods. Le cluster GKE initial commence avec trois nœuds et peut procéder à un autoscaling jusqu'à 10 nœuds.

  • Faites passer le pool de pods de nœuds de calcul Locust à 20.

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

    Le déploiement et le démarrage des nouveaux pods prennent quelques minutes.

Si vous voyez s'afficher une erreur PodUnschedulable, vous devez ajouter plus de nœuds au cluster. Pour en savoir plus, consultez la page Redimensionner un cluster GKE.

Une fois les pods démarrés, revenez à l'interface Web du nœud maître Locust et relancez les tests de charge

Étendre le modèle

Pour étendre ce modèle, vous pouvez créer des tâches Locust ou même basculer vers un framework de tests de charge différent.

Vous pouvez personnaliser les métriques que vous collectez. Par exemple, vous pouvez mesurer le nombre de requêtes par seconde ou surveiller le temps de latence des réponses lorsque la charge augmente, ou encore vérifier les taux d'échec des réponses et les types d'erreurs.

Pour en savoir plus, consultez la documentation de Cloud Monitoring.

Effectuer un nettoyage

Une fois que vous avez terminé le tutoriel, vous pouvez effacer les ressources que vous avez créées sur GCP afin qu'elles ne vous soient plus facturées.

Supprimer le projet

Le moyen le plus simple d'empêcher la facturation est de supprimer le projet que vous avez créé pour ce tutoriel.

Pour supprimer le projet :

  1. Dans Cloud Console, accédez à la page Gérer les ressources.

    Accéder à la page Gérer les ressources

  2. Dans la liste des projets, sélectionnez le projet que vous souhaitez supprimer, puis cliquez sur Supprimer .
  3. Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur Arrêter pour supprimer le projet.

Supprimer le cluster GKE

Si vous ne souhaitez pas supprimer l'ensemble du projet, exécutez la commande suivante pour supprimer le cluster GKE :

   gcloud container clusters delete $CLUSTER --zone $ZONE
   

Étapes suivantes