BLOG | NGINX

Tutoriel NGINX : Réduisez la latence de Kubernetes grâce à la mise à l'échelle automatique

Vignette de Daniele Polencic
Danièle Polencic
Publié le 15 mars 2022

Ce tutoriel est l'un des quatre qui mettent en pratique les concepts de Microservices de mars 2022 : Réseau Kubernetes :

Vous souhaitez des conseils détaillés sur l’utilisation de NGINX pour encore plus de cas d’utilisation de réseau Kubernetes ? Téléchargez notre eBook gratuit, Gérer le trafic Kubernetes avec NGINX : Un guide pratique .

Votre organisation a créé une application dans Kubernetes et elle devient désormais populaire ! Vous êtes passé de quelques visiteurs à des centaines (et parfois des milliers) par jour. Mais il y a un problème… l’augmentation du trafic atteint un goulot d’étranglement, ce qui entraîne des temps de latence et des délais d’attente pour vos clients. Si vous ne pouvez pas améliorer l’expérience, les gens arrêteront d’utiliser l’application.

Vous – l’ingénieur Kubernetes audacieux – avez une solution. Vous déployez un contrôleur Ingress pour diriger le trafic et mettez en place une politique d’autoscaling pour que le nombre de pods contrôleur Ingress augmente ou diminue instantanément selon les fluctuations du trafic. Vos pods contrôleur Ingress gèrent désormais les pics de trafic sans accroc – « Adieu la latence ! » – puis se réduisent automatiquement pour économiser les ressources quand le trafic baisse – « Bonjour les économies ! » Bravo.

Présentation du laboratoire et du didacticiel

Ce blog accompagne le laboratoire de l'unité 1 de Microservices de mars 2022 - Architecture de clusters Kubernetes pour les sites Web à fort trafic , montrant comment utiliser NGINX Ingress Controller pour exposer une application, puis mettre à l'échelle automatiquement les pods du contrôleur Ingress en réponse à un trafic élevé.

Pour exécuter le tutoriel, vous avez besoin d'une machine avec :

  • 2 CPU ou plus
  • 2 Go de mémoire libre
  • 20 Go d'espace disque libre
  • Connexion Internet
  • Gestionnaire de conteneurs ou de machines virtuelles, tel que Docker, Hyperkit, Hyper‑V, KVM, Parallels, Podman, VirtualBox ou VMware Fusion/Workstation
  • minikube installé
  • Casque installé
  • Une configuration qui vous permet de lancer une fenêtre de navigateur. Si cela n’est pas possible, vous devez trouver comment accéder aux services concernés via un navigateur.

Pour tirer le meilleur parti du laboratoire et du tutoriel, nous vous recommandons, avant de commencer, de :

Ce tutoriel utilise ces technologies :

Les instructions pour chaque défi incluent le texte complet des fichiers YAML utilisés pour configurer les applications. Vous pouvez également copier le texte depuis notre dépôt GitHub . Un lien vers GitHub est fourni avec le texte de chaque fichier YAML.

Ce tutoriel comprend quatre défis :

  1. Configurer une application simple sur un cluster Kubernetes
  2. Utilisez NGINX Ingress Controller pour acheminer le trafic vers l'application
  3. Générer et surveiller le trafic
  4. Contrôleur d'entrée NGINX Autoscale

Défi 1 : Configurer une application simple sur un cluster Kubernetes

Dans ce défi, vous créez un cluster minikube et installez Podinfo en tant qu'exemple d'application.

Créer un cluster Minikube

Créez un cluster minikube . Après quelques secondes, un message confirme que le déploiement a réussi.

$ minikube start 🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default 

Installer l'application Podinfo

Podinfo est une « application Web réalisée avec Go qui présente les meilleures pratiques d'exécution de microservices dans Kubernetes ». Nous l'utilisons comme exemple d'application en raison de son faible encombrement.

  1. À l’aide de l’éditeur de texte de votre choix, créez un fichier YAML appelé 1-deployment.yaml avec le contenu suivant (ou copiez-le depuis GitHub ). Il définit un déploiement avec une seule réplique et un service.

    apiVersion: apps/v1 kind: Deployment 
    metadata: 
      name: podinfo 
    spec: 
      selector: 
        matchLabels: 
          app: podinfo 
      template: 
        metadata: 
          labels: 
            app: podinfo 
        spec: 
          containers: 
          - name: podinfo 
            image: stefanprodan/podinfo 
            ports: 
            - containerPort: 9898 
    --- 
    apiVersion: v1 
    kind: Service 
    metadata: 
      name: podinfo 
    spec: 
      ports: 
        - port: 80 
          targetPort: 9898 
          nodePort: 30001 
      selector: 
        app: podinfo 
      type: LoadBalancer 
    
  2. Déployer l'application :

    $ kubectl apply -f 1-deployment.yaml deployment.apps/podinfo created 
    service/podinfo created
    
  3. Confirmez que le pod Podinfo est déployé, comme indiqué par la valeur En cours d'exécution dans la colonne STATUS .

    $ kubectl get podsNAME                       READY   STATUS   RESTARTS   AGE 
    podinfo-5d76864686-rd2s5   1/1     Running  0          3m38s
    
  4. Ouvrez Podinfo dans un navigateur. Les salutations de la page podinfo indiquent que Podinfo est en cours d'exécution.

    $ minikube service podinfo
    

Défi 2 : Utilisez NGINX Ingress Controller pour acheminer le trafic vers l'application

Dans ce défi, vous déployez NGINX Ingress Controller et le configurez pour acheminer le trafic vers l'application Podinfo .

Déployer le contrôleur d'entrée NGINX

Le moyen le plus rapide d'installer NGINX Ingress Controller est d'utiliser Helm .

  1. Ajoutez le référentiel NGINX à Helm :

    $ helm repo add nginx-stable https://helm.nginx.com/stable 
    
  2. Téléchargez et installez le contrôleur d'entrée NGINX Open Source NGINX , qui est géré par F5 NGINX. La dernière ligne de sortie confirme la réussite de l'installation.

    $ helm install main nginx-stable/nginx-ingress \ --set controller.watchIngressWithoutClass=true \
    --set controller.service.type=NodePort \ 
    --set controller.service.httpPort.nodePort=30005 
    NAME: main 
    LAST DEPLOYED: Tue Mar 15 09:49:17 2022 
    NAMESPACE: default 
    STATUS: deployed 
    REVISION: 1 
    TEST SUITE: None 
    NOTES: The NGINX Ingress Controller has been installed.
    
  3. Confirmez que le pod NGINX Ingress Controller est déployé, comme indiqué par la valeur En cours d'exécution dans la colonne STATUS (pour plus de lisibilité, la sortie est répartie sur deux lignes).

    $ kubectl get podsNAME                                   READY   STATUS    ...
    main-nginx-ingress-779b74bb8b-mtdkr    1/1     Running   ...
    podinfo-5d76864686-fjncl               1/1     Running   ...
    
           ... RESTARTS   AGE
           ... 0          18s 
           ... 0        2m36s
    

Dirigez le trafic vers votre application

  1. À l’aide de l’éditeur de texte de votre choix, créez un fichier YAML appelé 2-ingress.yaml avec le contenu suivant (ou copiez-le depuis GitHub ). Il définit le manifeste Ingress requis pour acheminer le trafic vers Podinfo.

    apiVersion: networking.k8s.io/v1 kind: Ingress 
    metadata: 
      name: podinfo 
    spec: 
      ingressClassName: nginx 
      rules: 
        - host: "example.com" 
          http: 
            paths: 
              - backend: 
                  service: 
                    name: podinfo 
                    port: 
                      number: 80 
                path: / 
                pathType: Prefix 
    
  2. Déployez la ressource Ingress :

    $ kubectl apply -f 2-ingress.yaml ingress.networking.k8s.io/podinfo created 
    

Défi 3 : Générer et surveiller le trafic

Dans ce défi, vous observez les performances du contrôleur d'entrée NGINX sous différentes charges de trafic. En guise d’étapes préparatoires, vous répertoriez les métriques disponibles auprès de NGINX Ingress Controller, déployez Prometheus et installez Locust . Vous utilisez ensuite Locust pour simuler une augmentation du trafic et suivre l’effet sur les performances dans Prometheus.

Comme vous l’avez déjà découvert, un contrôleur Ingress est un pod Kubernetes classique qui regroupe un proxy inverse (dans notre cas, NGINX) avec du code pour l’intégration avec Kubernetes. Si votre application reçoit beaucoup de trafic, vous devrez probablement augmenter le nombre de répliques de pod NGINX Ingress Controller pour éviter la latence provoquée lorsque NGINX Ingress Controller est surchargé.

Lister les métriques disponibles

Pour savoir quand et dans quelle mesure évoluer, vous avez besoin d'informations précises sur les performances du contrôleur d'entrée NGINX. Dans ce didacticiel, la métrique NGINX utilisée pour déterminer quand effectuer une mise à l’échelle est le nombre de connexions actives ( nginx_connections_active ). Ici, vous vérifiez que votre contrôleur d’entrée NGINX suit cette métrique.

NGINX Ingress Controller expose plusieurs métriques : 8 métriques avec le modèle basé sur NGINX Open Source que nous utilisons dans ce tutoriel et plus de 80 métriques avec le modèle basé sur NGINX Plus .

  1. Obtenez l’adresse IP du pod NGINX Ingress Controller afin de pouvoir interroger sa liste de métriques. L'adresse apparaît dans le champ IP et la voici172.17.0.4 . (Pour plus de lisibilité, les colonnes RESTARTS et AGE sont omises et la sortie est répartie sur deux lignes.)

    $ kubectl get pods -o wide NAME                                  READY   STATUS    ...
    main-nginx-ingress-779b74bb8b-6hdwx   1/1     Running   ...
    podinfo-5d76864686-nl8ws              1/1     Running   ...
    
        ... IP           NODE       NOMINATED NODE  READINESS GATES 
        ... 172.17.0.4   minikube   <none>          <none> 
        ... 172.17.0.3   minikube   <none>          <none>
    
  2. Créez un pod BusyBox temporaire avec un shell sur un hôte à l'intérieur du cluster Kubernetes :

    $ kubectl run -ti --rm=true busybox --image=busyboxIf you don't see a command prompt, try pressing enter. 
    / # 
    
  3. Répertoriez les métriques générées par votre contrôleur d’entrée NGINX et vérifiez qu’il inclut nginx_connections_active . Pour <adresse_IP> remplacez la valeur de l’étape 1.

    /# wget -qO- <IP_address>:9113/metrics
    
  4. Quittez le shell pour revenir au serveur Kubernetes.

    /# exit 
    

Déployer Prometheus

Maintenant que vous savez que votre contrôleur d’entrée NGINX suit la métrique nginx_connections_active , vous avez besoin d’un outil pour collecter (« scrape ») les métriques – ce tutoriel utilise Prometheus .

Quant à NGINX Ingress Controller, Helm est le moyen le plus rapide d'installer Prometheus.

  1. Ajoutez le référentiel Prometheus à Helm :

    $ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
    
  2. Téléchargez et installez Prometheus :

    $ helm install prometheus prometheus-community/prometheus \ 
    --set server.service.type=NodePort --set server.service.nodePort=30010
    
  3. Vérifiez l’installation, qui prend généralement jusqu’à 60 secondes. Dans l'exemple de sortie suivant, la commande de vérification a été exécutée quelques secondes seulement après la commande helm install et nous voyons donc l'installation en cours, avec ContainerCreating signalé dans le champ STATUS pour certains pods Prometheus. L'installation est terminée lorsque tous les pods ont le statut En cours d'exécution . (La sortie est répartie sur deux lignes pour plus de lisibilité.)

    $ kubectl get podsNAME                                           READY  ...
    main-nginx-ingress-779b74bb8b-mtdkr            1/1    ...
    podinfo-5d76864686-fjncl                       1/1    ...
    prometheus-alertmanager-d6d94cf4b-85ww5        0/2    ...
    prometheus-kube-state-metrics-7cd8f95cb-86hhs  0/1    ...
    prometheus-node-exporter-gqxfz                 1/1    ...
    prometheus-pushgateway-56745d8d8b-qnwcb        0/1    ...
    prometheus-server-b78c9449f-kwhzp              0/2    ...
    
          ... STATUS             RESTARTS  AGE 
          ... Running            0         3m23s 
          ... Running            0         5m41s 
          ... ContainerCreating  0         7s
          ... Running            0         7s
          ... Running            0         7s
          ... ContainerCreating  0         7s
          ... ContainerCreating  0         7s
    
  4. Ouvrez Prométhée. Dans un environnement minikube, exécutez la commande suivante, qui ouvre le tableau de bord Prometheus dans votre navigateur par défaut.

    $ minikube service prometheus-server
    

    Une page comme celle-ci confirme que le serveur fonctionne.

  5. Tapez nginx_ingress_nginx_connections_active dans la barre de recherche pour voir la valeur actuelle de la métrique des connexions actives. Vous voyez une connexion active, ce qui est logique car vous avez déployé un pod NGINX Ingress Controller.

Installer Locust

Dans la section suivante, vous allez utiliser Locust, un outil libre de test de charge, pour simuler une montée en charge et observer les performances du contrôleur NGINX Ingress dans Prometheus. Voici comment déployer Locust.

  1. À l’aide de l’éditeur de texte de votre choix, créez un fichier YAML appelé 3-locust.yaml avec le contenu suivant (ou copiez-le depuis GitHub ). Les objets Déploiement et Service définissent le pod Locust. L'objet ConfigMap définit un script appelé locustfile.py qui génère des requêtes à envoyer au pod, avec les en-têtes corrects.

    apiVersion: v1 
    kind: ConfigMap 
    metadata: 
      name: locust-script 
    data: 
      locustfile.py: |- 
        from locust import HttpUser, task, between 
    
        class QuickstartUser(HttpUser): 
            wait_time = between(0.7, 1.3) 
    
            @task 
            def hello_world(self): 
                self.client.get("/", headers={"Host": "example.com"}) 
    --- 
    apiVersion: apps/v1 
    kind: Deployment 
    metadata: 
      name: locust 
    spec: 
      selector: 
        matchLabels: 
          app: locust 
      template: 
        metadata: 
          labels: 
            app: locust 
        spec: 
          containers: 
            - name: locust 
              image: locustio/locust 
              ports: 
                - containerPort: 8089 
              volumeMounts: 
                - mountPath: /home/locust 
                  name: locust-script 
          volumes: 
            - name: locust-script 
              configMap: 
                name: locust-script 
    --- 
    apiVersion: v1 
    kind: Service 
    metadata: 
      name: locust 
    spec: 
      ports: 
        - port: 8089 
          targetPort: 8089 
          nodePort: 30015 
      selector: 
        app: locust 
      type: LoadBalancer 
    
  2. Déployer Locust :

    $ kubectl apply -f 3-locust.yaml configmap/locust-script created 
    deployment.apps/locust created 
    service/locust created 
    

Simulez une augmentation du trafic et observez l'effet sur les performances

  1. Ouvrez Locust dans un navigateur.

    $ minikube service locust
    

  2. Saisissez les valeurs suivantes dans les champs :

    • Nombre d'utilisateurs – 1000
    • Taux d'apparition – 10
    • Hôte – http://main-nginx-ingress
  3. Cliquez sur le bouton Démarrer l’essaimage pour envoyer le trafic vers l’application Podinfo.

  4. Revenez au tableau de bord Prometheus pour voir comment NGINX Ingress Controller réagit. Vous devrez peut-être effectuer une nouvelle requête pour nginx_ingress_nginx_connections_active pour voir un changement.

    Comme le montre la sortie d’écran suivante, le pod unique du contrôleur d’entrée NGINX a du mal à traiter l’augmentation du trafic sans latence lorsqu’un grand nombre de connexions sont établies. Le graphique Prometheus révèle qu'environ 100 connexions actives par pod NGINX Ingress Controller constituent le point de basculement pour un pic de latence. Vous pouvez utiliser ces informations pour déterminer quand vous devez augmenter le nombre de pods NGINX Ingress Controller pour éviter une latence accrue.

Défi 4 : Contrôleur d'entrée NGINX Autoscale

Dans ce dernier défi, vous créez une configuration qui ajuste automatiquement les ressources au fur et à mesure que le volume de trafic augmente. Le tutoriel utilise KEDA pour l’autoscaling, commencez donc par l’installer puis définir une politique précisant quand et comment l’ajustement s’effectue. Comme dans le Défi 3, vous utilisez ensuite Locust pour simuler un pic de trafic et Prometheus pour analyser les performances du contrôleur NGINX Ingress lorsque l’autoscaling est actif.

Installer KEDA

KEDA , un autoscaler piloté par événements Kubernetes, intègre un serveur de métriques (le composant qui stocke et transforme les métriques pour Kubernetes) et peut consommer des métriques directement depuis Prometheus (ainsi que d'autres outils). Il crée un Horizontal Pod Autoscaler (HPA) avec ces métriques, relie les métriques collectées par Prometheus et les transmet à Kubernetes.

Comme avec NGINX Ingress Controller et Prometheus, le tutoriel utilise Helm pour installer KEDA.

  1. Ajoutez KEDA au référentiel Helm :

    $ helm repo add kedacore https://kedacore.github.io/charts 
    "kedacore" has been added to your repositories 
    
  2. Installer KEDA :

    $ helm install keda kedacore/keda NAME: keda 
    NAMESPACE: default 
    STATUS: deployed 
    REVISION: 1 
    TEST SUITE: None
    
  3. Vérifiez que KEDA fonctionne comme deux pods. (Pour plus de lisibilité, certaines valeurs de la colonne NOM sont raccourcies. De plus, la colonne RESTARTS est omise ; la valeur est0 pour tous les modules.)

    $ kubectl get pods NAME                                    READY  STATUS     AGE 
    keda-operator-8644dcdb79-492x5          1/1    Running    59s 
    keda-operator-metrics-apiserver-66d...  1/1    Running    59s 
    locust-77c699c94d-dvb5n                 1/1    Running  8m59s 
    main-nginx-ingress-779b74bb8b-v7ggw     1/1    Running    48m 
    podinfo-5d76864686-c98rb                1/1    Running    50m 
    prometheus-alertmanager-d6d94cf4b-8...  2/2    Running    37m 
    prometheus-kube-state-metrics-7cd8f...  1/1    Running    37m 
    prometheus-node-exporter-j4qf4          1/1    Running    37m 
    prometheus-pushgateway-56745d8d8b-9n4nl 1/1    Running    37m 
    prometheus-server-b78c9449f-6ktn9       2/2    Running    37m
    

Créer une politique de mise à l'échelle automatique

Utilisez désormais la définition de ressource personnalisée (CRD) KEDA ScaledObject pour préciser les paramètres qui guident la montée en charge du contrôleur NGINX Ingress. La configuration suivante :

  • Déclenche la mise à l'échelle automatique en fonction de la valeur de la métrique nginx_connections_active collectée par Prometheus
  • Déploie un nouveau pod lorsque les pods existants atteignent 100 connexions actives chacun
  • Mise à l'échelle automatique des pods du contrôleur d'entrée NGINX d'un seul pod jusqu'à 20 pods

Procédez comme suit :

  1. À l’aide de l’éditeur de texte de votre choix, créez un fichier YAML appelé 4-scaled-object.yaml avec le contenu suivant (ou copiez-le depuis GitHub ). Il définit un KEDA ScaledObject .

    apiVersion: keda.sh/v1alpha1 kind: ScaledObject 
    metadata: 
     name: nginx-scale 
    spec: 
     scaleTargetRef: 
       kind: Deployment 
       name: main-nginx-ingress 
    minReplicaCount: 1 
    maxReplicaCount: 20 
    cooldownPeriod: 30 
    pollingInterval: 1 
    triggers: 
    - type: prometheus 
      metadata: 
        serverAddress: http://prometheus-server 
        metricName: nginx_connections_active_keda 
        query: | 
          sum(avg_over_time(nginx_ingress_nginx_connections_active{app="main-nginx-ingress"}[1m])) 
        threshold: "100" 
    
  2. Déployer le ScaledObject :

    $ kubectl apply -f 4-scaled-object.yaml scaledobject.keda.sh/nginx-scale created 
    

Simulez une augmentation du trafic et observez l'effet de la mise à l'échelle automatique sur les performances

Pour tester réellement l’efficacité de la mise à l’échelle automatique, vous doublez le nombre de connexions par rapport au défi 3.

  1. Retournez au serveur Locust dans votre navigateur. Saisissez les valeurs suivantes dans les champs et cliquez sur le bouton Démarrer l'essaimage :

    • Nombre d'utilisateurs – 2000
    • Taux d'apparition – 10
    • Hôte – http://main-nginx-ingress
  2. Retournez aux tableaux de bord Prometheus et Locust. La case rose sous le graphique Prometheus représente le nombre de pods NGINX Ingress Controller qui augmentent et diminuent.

  3. Revenez à votre terminal et inspectez manuellement le KEDA HPA. Le champ RÉPLIQUES dans la sortie affiche le nombre actuel de répliques de pod déployées. (La sortie est répartie sur deux lignes pour plus de lisibilité.)

    $ kubectl get hpa
    NAME                  REFERENCE                      ... 
    keda-hpa-nginx-scale  Deployment/main-nginx-ingress  ... 
    
        ... TARGETS           MINPODS   MAXPODS   REPLICAS   AGE 
        ... 101500m/100 (avg) 1         20        10         2m45s
    

Prochaines étapes

Il existe une limitation potentielle lorsque vous basez la mise à l'échelle automatique uniquement sur le nombre de connexions actives. Si (même avec mise à l'échelle) NGINX Ingress Controller est si occupé qu'il doit abandonner des connexions, l'autoscaler voit moins de connexions actives, interprète cela comme signifiant que les demandes ont diminué et réduit le nombre de répliques. Cela peut aggraver les performances, mais l'utilisation d'une combinaison de mesures peut garantir que cela ne se produise pas. Par exemple, nginxplus_connections_dropped (disponible avec le contrôleur d'entrée NGINX basé sur NGINX Plus) garde une trace de ces connexions client abandonnées.

Pour essayer NGINX Ingress Controller avec NGINX Plus et NGINX App Protect, démarrez votre essai gratuit de 30 jours dès aujourd'hui ou contactez-nous pour discuter de vos cas d'utilisation .

Pour essayer NGINX Ingress Controller avec NGINX Open Source, vous pouvez obtenir le code source de la version ou télécharger un conteneur préassemblé depuis DockerHub.


« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."