BLOG | NGINX

Tutorial do NGINX: Reduza a latência do Kubernetes com dimensionamento automático

Miniatura de Daniele Polencic
Daniele Polencic
Publicado em 15 de março de 2022

Este tutorial é um dos quatro que colocam em prática conceitos do Microservices de março de 2022: Rede Kubernetes :

Quer orientação detalhada sobre como usar o NGINX para ainda mais casos de uso de rede Kubernetes? Baixe nosso e-book gratuito, Gerenciando o tráfego do Kubernetes com NGINX: Um guia prático .

Sua organização criou um aplicativo no Kubernetes e agora ele está se tornando popular! Você passou de apenas alguns visitantes para centenas (e às vezes milhares) por dia. Mas há um problema... o aumento do tráfego está atingindo um gargalo, causando latência e tempos limite para seus clientes. Se você não puder melhorar a experiência, as pessoas deixarão de usar o aplicativo.

Você – o corajoso engenheiro do Kubernetes – tem uma solução. Você implanta um controlador Ingress para rotear o tráfego e configura uma política de dimensionamento automático para que o número de pods do controlador Ingress se expanda e contraia instantaneamente para corresponder às flutuações do tráfego. Agora, seus pods controladores do Ingress lidam perfeitamente com picos de tráfego – “Adeus, latência!” – e reduzem a escala para conservar recursos quando o tráfego diminui – “Olá, economia de custos!” Muito bem, você.

Visão geral do laboratório e do tutorial

Este blog acompanha o laboratório da Unidade 1 de Microsserviços de março de 2022 – Arquitetura de clusters do Kubernetes para sites de alto tráfego , demonstrando como usar o NGINX Ingress Controller para expor um aplicativo e, em seguida, dimensionar automaticamente os pods do Ingress Controller em resposta ao alto tráfego.

Para executar o tutorial, você precisa de uma máquina com:

  • 2 CPUs ou mais
  • 2 GB de memória livre
  • 20 GB de espaço livre em disco
  • Conexão de internet
  • Gerenciador de contêiner ou máquina virtual, como Docker, Hyperkit, Hyper‑V, KVM, Parallels, Podman, VirtualBox ou VMware Fusion/Workstation
  • minikube instalado
  • Leme instalado
  • Uma configuração que permite iniciar uma janela do navegador. Se isso não for possível, você precisa descobrir como acessar os serviços relevantes por meio de um navegador.

Para aproveitar ao máximo o laboratório e o tutorial, recomendamos que antes de começar você:

Este tutorial usa estas tecnologias:

As instruções para cada desafio incluem o texto completo dos arquivos YAML usados para configurar os aplicativos. Você também pode copiar o texto do nosso repositório GitHub . Um link para o GitHub é fornecido junto com o texto de cada arquivo YAML.

Este tutorial inclui quatro desafios:

  1. Configurar um aplicativo simples em um cluster Kubernetes
  2. Use o NGINX Ingress Controller para rotear o tráfego para o aplicativo
  3. Gerar e monitorar tráfego
  4. Controlador de entrada NGINX de dimensionamento automático

Desafio 1: Configurar um aplicativo simples em um cluster Kubernetes

Neste desafio, você cria um cluster minikube e instala o Podinfo como um aplicativo de exemplo.

Crie um cluster Minikube

Crie um cluster minikube . Após alguns segundos, uma mensagem confirma que a implantação foi bem-sucedida.

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

Instale o aplicativo Podinfo

Podinfo é um “aplicativo web feito com Go que demonstra as melhores práticas de execução de microsserviços no Kubernetes”. Estamos usando-o como um aplicativo de exemplo devido ao seu tamanho reduzido.

  1. Usando o editor de texto de sua escolha, crie um arquivo YAML chamado 1-deployment.yaml com o seguinte conteúdo (ou copie do GitHub ). Ele define uma implantação com uma única réplica e um serviço.

    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. Implante o aplicativo:

    $ kubectl apply -f 1-deployment.yaml deployment.apps/podinfo created 
    service/podinfo created
    
  3. Confirme se o pod Podinfo foi implantado, conforme indicado pelo valor Em execução na coluna STATUS .

    $ kubectl get podsNAME                       READY   STATUS   RESTARTS   AGE 
    podinfo-5d76864686-rd2s5   1/1     Running  0          3m38s
    
  4. Abra o Podinfo em um navegador. As saudações da página podinfo indicam que o Podinfo está em execução.

    $ minikube service podinfo
    

Desafio 2: Use o NGINX Ingress Controller para rotear o tráfego para o aplicativo

Neste desafio, você implanta o NGINX Ingress Controller e o configura para rotear o tráfego para o aplicativo Podinfo .

Implantar o NGINX Ingress Controller

A maneira mais rápida de instalar o NGINX Ingress Controller é com o Helm .

  1. Adicione o repositório NGINX ao Helm:

    $ helm repo add nginx-stable https://helm.nginx.com/stable 
    
  2. Baixe e instale o NGINX Open Source‑based NGINX Ingress Controller , que é mantido pela F5 NGINX. A linha final de saída confirma a instalação bem-sucedida.

    $ 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. Confirme se o pod do NGINX Ingress Controller foi implantado, conforme indicado pelo valor Em execução na coluna STATUS (para legibilidade, a saída é distribuída em duas linhas).

    $ 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
    

Direcione o tráfego para seu aplicativo

  1. Usando o editor de texto de sua escolha, crie um arquivo YAML chamado 2-ingress.yaml com o seguinte conteúdo (ou copie do GitHub ). Ele define o manifesto do Ingress necessário para rotear o tráfego para o 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. Implante o recurso Ingress:

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

Desafio 3: Gerar e monitorar tráfego

Neste desafio, você observa o desempenho do NGINX Ingress Controller sob diferentes cargas de tráfego. Como etapas preparatórias, você lista as métricas disponíveis no NGINX Ingress Controller, implanta o Prometheus e instala o Locust . Em seguida, use o Locust para simular um aumento no tráfego e monitorar o efeito no desempenho no Prometheus.

Como você já descobriu, um controlador Ingress é um pod comum do Kubernetes que agrupa um proxy reverso (no nosso caso, NGINX) com algum código para integração com o Kubernetes. Se seu aplicativo receber muito tráfego, provavelmente você precisará aumentar o número de réplicas de pod do NGINX Ingress Controller para evitar a latência causada quando o NGINX Ingress Controller fica sobrecarregado.

Listar as métricas disponíveis

Para saber quando e quanto dimensionar, você precisa de informações precisas sobre o desempenho do NGINX Ingress Controller. Neste tutorial, a métrica NGINX usada para determinar quando dimensionar é o número de conexões ativas ( nginx_connections_active ). Aqui você verifica se o seu NGINX Ingress Controller rastreia essa métrica.

O NGINX Ingress Controller expõe várias métricas : 8 métricas com o modelo baseado em NGINX Open Source que estamos usando neste tutorial e mais de 80 métricas com o modelo baseado em NGINX Plus .

  1. Obtenha o endereço IP do pod do NGINX Ingress Controller para que você possa consultar sua lista de métricas. O endereço aparece no campo IP e aqui está172.17.0.4 . (Para legibilidade, as colunas RESTARTS e AGE são omitidas e a saída é distribuída em duas linhas.)

    $ 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. Crie um pod BusyBox temporário com um shell em um host dentro do cluster Kubernetes:

    $ kubectl run -ti --rm=true busybox --image=busyboxIf you don't see a command prompt, try pressing enter. 
    / # 
    
  3. Liste as métricas geradas pelo seu NGINX Ingress Controller e verifique se ele inclui nginx_connections_active . Para <endereço_IP> substitua o valor do Passo 1.

    /# wget -qO- <IP_address>:9113/metrics
    
  4. Saia do shell para retornar ao servidor Kubernetes.

    /# exit 
    

Implantar Prometheus

Agora que você sabe que seu NGINX Ingress Controller rastreia a métrica nginx_connections_active , você precisa de uma ferramenta para coletar (“raspar”) as métricas – este tutorial usa o Prometheus .

Quanto ao NGINX Ingress Controller, o Helm é a maneira mais rápida de instalar o Prometheus.

  1. Adicione o repositório Prometheus ao Helm:

    $ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
    
  2. Baixe e instale o Prometheus:

    $ helm install prometheus prometheus-community/prometheus \ 
    --set server.service.type=NodePort --set server.service.nodePort=30010
    
  3. Verifique a instalação, que geralmente leva até 60 segundos para ser concluída. No exemplo de saída a seguir, o comando de verificação foi executado apenas alguns segundos após o comando helm install e, portanto, vemos a instalação em andamento, com ContainerCreating relatado no campo STATUS para alguns pods do Prometheus. A instalação estará concluída quando todos os pods tiverem o status Em execução . (A saída é distribuída em duas linhas para maior legibilidade.)

    $ 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. Abra o Prometheus. Em um ambiente minikube, execute o seguinte comando, que abre o painel do Prometheus no seu navegador padrão.

    $ minikube service prometheus-server
    

    Uma página como a seguinte confirma que o servidor está funcionando.

  5. Digite nginx_ingress_nginx_connections_active na barra de pesquisa para ver o valor atual da métrica de conexões ativas. Você vê uma conexão ativa, o que faz sentido porque você implantou um pod do NGINX Ingress Controller.

Instalar Locust

Na próxima seção, você usará o Locust , uma ferramenta de teste de carga de código aberto, para simular um aumento de tráfego e poder observar o desempenho do NGINX Ingress Controller no Prometheus. Aqui você implanta o Locust.

  1. Usando o editor de texto de sua escolha, crie um arquivo YAML chamado 3-locust.yaml com o seguinte conteúdo (ou copie do GitHub ). Os objetos de implantação e serviço definem o pod Locust. O objeto ConfigMap define um script chamado locustfile.py que gera solicitações a serem enviadas ao pod, completas com os cabeçalhos corretos.

    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. Implantar Locust:

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

Simule um aumento de tráfego e observe o efeito no desempenho

  1. Abra o Locust em um navegador.

    $ minikube service locust
    

  2. Insira os seguintes valores nos campos:

    • Número de usuários – 1000
    • Taxa de spawn – 10
    • Anfitrião – http://main-nginx-ingress
  3. Clique no botão Iniciar swarming para enviar tráfego para o aplicativo Podinfo.

  4. Retorne ao painel do Prometheus para ver como o NGINX Ingress Controller responde. Talvez seja necessário executar uma nova consulta para nginx_ingress_nginx_connections_active para ver alguma alteração.

    Conforme mostrado na saída de tela a seguir, o pod único do NGINX Ingress Controller tem dificuldade para processar o tráfego aumentado sem latência, pois um grande número de conexões é estabelecido. O gráfico do Prometheus revela que cerca de 100 conexões ativas por pod do NGINX Ingress Controller é o ponto crítico para um pico de latência. Você pode usar essas informações para determinar quando precisa aumentar o número de pods do NGINX Ingress Controller para evitar aumento de latência.

Desafio 4: Controlador de entrada NGINX de dimensionamento automático

No desafio final, você cria uma configuração que dimensiona automaticamente os recursos conforme o volume de tráfego aumenta. O tutorial usa o KEDA para dimensionamento automático, então primeiro você o instala e cria uma política que define quando e como o dimensionamento ocorre. Assim como no Desafio 3, você usa o Locust para simular um aumento de tráfego e o Prometheus para observar o desempenho do NGINX Ingress Controller quando o dimensionamento automático está habilitado.

Instalar KEDA

KEDA , um autoescalador orientado a eventos do Kubernetes, integra um servidor de métricas (o componente que armazena e transforma métricas para o Kubernetes) e pode consumir métricas diretamente do Prometheus (assim como de outras ferramentas). Ele cria um Horizontal Pod Autoscaler (HPA) com essas métricas, conecta as métricas coletadas pelo Prometheus e as envia ao Kubernetes.

Assim como no NGINX Ingress Controller e no Prometheus, o tutorial usa o Helm para instalar o KEDA.

  1. Adicione KEDA ao repositório Helm:

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

    $ helm install keda kedacore/keda NAME: keda 
    NAMESPACE: default 
    STATUS: deployed 
    REVISION: 1 
    TEST SUITE: None
    
  3. Verifique se o KEDA está sendo executado como dois pods. (Para maior legibilidade, alguns valores na coluna NOME foram encurtados. Além disso, a coluna RESTARTS é omitida; o valor é0 para todos os pods.)

    $ 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
    

Crie uma política de dimensionamento automático

Agora use a definição de recurso personalizado (CRD) do KEDA ScaledObject para definir os parâmetros que determinam como o NGINX Ingress Controller é dimensionado. A seguinte configuração:

  • Aciona o dimensionamento automático com base no valor da métrica nginx_connections_active coletada pelo Prometheus
  • Implanta um novo pod quando os pods existentes atingem 100 conexões ativas cada
  • Dimensiona automaticamente os pods do NGINX Ingress Controller de um único pod para até 20 pods

Execute os seguintes passos:

  1. Usando o editor de texto de sua escolha, crie um arquivo YAML chamado 4-scaled-object.yaml com o seguinte conteúdo (ou copie do GitHub ). Ele define um 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. Implante o ScaledObject :

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

Simule um aumento de tráfego e observe o efeito do dimensionamento automático no desempenho

Para realmente testar a eficácia do dimensionamento automático, você dobra o número de conexões em comparação ao Desafio 3.

  1. Retorne ao servidor Locust no seu navegador. Insira os seguintes valores nos campos e clique no botão Iniciar enxameação :

    • Número de usuários – 2000
    • Taxa de spawn – 10
    • Anfitrião – http://main-nginx-ingress
  2. Retorne aos painéis do Prometheus e do Locust. A caixa rosa abaixo do gráfico do Prometheus representa o número de pods do NGINX Ingress Controller aumentando e diminuindo.

  3. Retorne ao seu terminal e inspecione manualmente o KEDA HPA. O campo REPLICAS na saída mostra o número atual de réplicas de pod implantadas. (A saída é distribuída em duas linhas para maior legibilidade.)

    $ 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
    

Próximos passos

Há uma limitação potencial quando você baseia o dimensionamento automático apenas no número de conexões ativas. Se (mesmo com dimensionamento) o NGINX Ingress Controller ficar tão ocupado que precise descartar conexões, o dimensionador automático verá menos conexões ativas, interpretará isso como um sinal de que as solicitações foram recusadas e reduzirá o número de réplicas. Isso pode piorar o desempenho, mas aproveitar uma combinação de métricas pode garantir que isso não aconteça. Por exemplo, nginxplus_connections_dropped (disponível com o NGINX Ingress Controller baseado no NGINX Plus) rastreia essas conexões de cliente descartadas.

Para experimentar o NGINX Ingress Controller com NGINX Plus e NGINX App Protect, comece seu teste gratuito de 30 dias hoje mesmo ou entre em contato conosco para discutir seus casos de uso .

Para testar o NGINX Ingress Controller com o NGINX Open Source, você pode obter o código-fonte da versão ou baixar um contêiner pré-criado do DockerHub .


"Esta postagem do blog pode fazer referência a produtos que não estão mais disponíveis e/ou não têm mais suporte. Para obter as informações mais atualizadas sobre os produtos e soluções F5 NGINX disponíveis, explore nossa família de produtos NGINX . O NGINX agora faz parte do F5. Todos os links anteriores do NGINX.com redirecionarão para conteúdo semelhante do NGINX no F5.com."