BLOG | NGINX

Tutorial do NGINX: Proteja as APIs do Kubernetes com limitação de taxa

NGINX-Parte-de-F5-horiz-preto-tipo-RGB
Miniatura de Daniele Polencic
Daniele Polencic
Publicado em 21 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 acaba de lançar seu primeiro aplicativo e API no Kubernetes. Foi dito para você esperar altos volumes de tráfego (e o dimensionamento automático já foi implementado para garantir que o NGINX Ingress Controller possa rotear o tráfego rapidamente), mas há preocupações de que a API possa ser alvo de um ataque malicioso. Se a API receber um alto volume de solicitações HTTP – uma possibilidade com tentativas de adivinhação de senha por força bruta ou ataques DDoS – tanto a API quanto o aplicativo podem ficar sobrecarregados ou até mesmo travar.

Mas você está com sorte! A técnica de controle de tráfego chamada limitação de taxa é um caso de uso de gateway de API que limita a taxa de solicitações de entrada a um valor típico para usuários reais. Você configura o NGINX Ingress Controller para implementar uma política de limitação de taxa, o que evita que o aplicativo e a API sejam sobrecarregados por muitas solicitações. Bom trabalho!

Visão geral do laboratório e do tutorial

Este blog acompanha o laboratório da Unidade 2 de Microsserviços de março de 2022 – Expondo APIs no Kubernetes , demonstrando como combinar vários controladores de entrada NGINX com limitação de taxa para evitar que aplicativos e APIs fiquem sobrecarregados.

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 três desafios:

  1. Implantar um cluster, aplicativo, API e controlador de entrada
  2. Sobrecarregue seu aplicativo e API
  3. Salve seu aplicativo e API com controladores de entrada dupla e limitação de taxa

Desafio 1: Implantar um cluster, aplicativo, API e controlador de entrada

Neste desafio, você implanta um cluster minikube e instala o Podinfo como um aplicativo de amostra e API. Em seguida, você implanta o NGINX Ingress Controller , configura o roteamento de tráfego e testa a configuração do Ingress .

Crie um cluster Minikube

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

$ minikube start 🏄 Pronto! O kubectl agora está configurado para usar o cluster "minikube" e o namespace "default" por padrão 

Instale o aplicativo Podinfo e a API 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 e API devido ao seu tamanho reduzido.

  1. Usando o editor de texto de sua escolha, crie um arquivo YAML chamado 1-apps.yaml com o seguinte conteúdo (ou copie do GitHub ). Ele define uma Implantação que inclui:

    • Um aplicativo da web (vamos chamá-lo de Podinfo Frontend ) que renderiza uma página HTML
    • Uma API ( Podinfo API ) que retorna uma carga útil JSON
    apiVersão: apps/v1 
    tipo: Implantação
    metadados: 
    nome: api 
    especificação: 
    seletor: 
    matchLabels: 
    aplicativo: api 
    modelo: 
    metadados: 
    rótulos: 
    aplicativo: api 
    especificação: 
    contêineres: 
    -nome: api 
    imagem: stefanprodan/podinfo 
    portas: 
    -containerPort: 9898 
    --- 
    apiVersão: v1 
    tipo: Serviço
    metadados:
    nome: api
    especificação:
    portas:
    - porta: 80 
    targetPort: 9898 
    nóPorta: 30001 
    seletor: 
    aplicativo: api 
    tipo: Balanceador de carga
    --- 
    apiVersion: apps/v1 
    tipo: Implantação
    metadados: 
    nome: frontend
    especificação: 
    seletor: 
    matchLabels: 
    aplicativo: frontend
    modelo: 
    metadados: 
    rótulos: 
    aplicativo: frontend
    especificação: 
    contêineres: 
    -nome: frontend
    imagem: stefanprodan/podinfo
    portas: 
    -containerPort: 9898 
    --- 
    apiVersão: v1 
    tipo: Serviço
    metadados:
    nome: frontend
    especificação:
    portas:
    - porta: 80 
    targetPort: 9898 
    nóPorta: 30002 
    seletor: 
    aplicativo: frontend 
    tipo: Balanceador de carga
    
  2. Implante o aplicativo e a API:

    $ kubectl apply -f 1-apps.yaml deployment.apps/api criado service/api criado deployment.apps/frontend criado service/frontend criado 
    
  3. Confirme se os pods para a API do Podinfo e o Frontend do Podinfo foram implantados com sucesso, conforme indicado pelo valor Em execução na coluna STATUS .

    $ kubectl get pods NOME PRONTO STATUS REINÍCIOS IDADE api-7574cf7568-c6tr6 1/1 Em execução 0 87s frontend-6688d86fc6-78qn7 1/1 Em execução 0 87s 
    
    
    

Implantar o NGINX Ingress Controller

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

Instale o NGINX Ingress Controller em um namespace separado ( nginx ) usando o Helm.

  1. Crie o namespace:

    $ kubectl criar namespace nginx 
    
  2. Adicione o repositório NGINX ao Helm:

    $ helm repo adicionar nginx-stable https://helm.nginx.com/stable 
    
  3. Baixe e instale o NGINX Ingress Controller no seu cluster:

    $ helm install main nginx-stable/nginx-ingress \ --set controller.watchIngressWithoutClass=true \ --set controller.ingressClass=nginx \ --set controller.service.type=NodePort \ --set controller.service.httpPort.nodePort=30010 \ --set controller.enablePreviewPolicies=true \ --namespace nginx 
    
  4. 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 pods -namespace nginx NOME PRONTO STATUS ... main-nginx-ingress-779b74bb8b-d4qtc 1/1 Executando ... ... RECOMEÇA IDADE ... 0 92s 
    

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 aplicativo e a API.
  2. apiVersão: networking.k8s.io/v1 
    tipo: Ingress
    metadados:
    nome: primeiro
    especificação:
    ingressClassName: nginx
    regras:
    - host: "example.com"
    http:
    caminhos:
    - backend:
    serviço:
    nome: frontend
    porta:
    número: 80 
    caminho: / 
    caminhoType: Prefixo 
    - host: "api.example.com" 
    http: 
    paths: 
    - backend: 
    service: 
    name: api 
    port: 
    number: 80 
    caminho: / 
    caminhoType: Prefixo
    
  3. Implante o recurso Ingress:
  4. $ kubectl apply -f 2-ingress.yaml ingress.networking.k8s.io/primeiro criado 
    

Teste a configuração do Ingress

  1. Para garantir que sua configuração do Ingress esteja funcionando conforme o esperado, teste-a usando um pod temporário. Inicie um pod BusyBox descartável no cluster:

    $ kubectl run -ti --rm=true busybox --image=busybox Se você não vir um prompt de comando, tente pressionar enter. / #
    
  2. Teste a API do Podinfo emitindo uma solicitação ao pod do NGINX Ingress Controller com o nome de host api.example.com . A saída mostrada indica que a API está recebendo tráfego.

    / # wget --header="Host: api.example.com" -qO- main-nginx-ingress.nginx { "nome do host": "api-687fd448f8-t7hqk", "versão": "6.0.3", "revisão": "", "cor": "#34577c", "logotipo": "https://raw.githubusercontent.com/stefanprodan/podinfo/gh-pages/cuddle_clap.gif", "mensagem": "saudações do podinfo v6.0.3", "goos": "linux", "goarch": "arm64", "tempo de execução": "go1.16.9", "num_goroutine": "6", "num_cpu": "4" } 
    
  3. Teste o Podinfo Frontend emitindo o seguinte comando no mesmo pod BusyBox para simular um navegador da web e recuperar a página da web. A saída mostrada é o código HTML para o início da página da web.
    / # wget --header="Host: example.com" --header="Agente do Usuário: Mozilla" -qO- main-nginx-ingress.nginx <!DOCTYPE html> 
    <html> 
    <cabeçalho> 
    <título>frontend-596d5c9ff4-xkbdc</título> 
    # ...
    
  4. Em outro terminal, abra o Podinfo em um navegador. As saudações da página podinfo indicam que o Podinfo está em execução.

    $ minikube serviço podinfo
    

    Parabéns! O NGINX Ingress Controller está recebendo solicitações e as encaminhando para o aplicativo e a API.

  5. No terminal original, encerre a sessão do BusyBox:

    / # sair $
    

Desafio 2: Sobrecarregue seu aplicativo e API

Neste desafio, você instala o Locust , uma ferramenta de geração de carga de código aberto, e a usa para simular um aumento de tráfego que sobrecarrega a API e faz com que o aplicativo trave.

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

    O objeto ConfigMap define um script chamado locustfile.py que gera solicitações a serem enviadas ao pod, completas com os cabeçalhos corretos. O tráfego não é distribuído uniformemente entre o aplicativo e a API – as solicitações são direcionadas para a API do Podinfo , com apenas 1 em cada 5 solicitações indo para o Podinfo Frontend .

    Os objetos de implantação e serviço definem o pod Locust.

    apiVersão: v1 
    tipo: ConfigMap
    metadados:
    nome: script-locust
    dados:
    locustfile.py: |-
    de locust importar HttpUser, tarefa, entre
    
    classe QuickstartUser(HttpUser):
    tempo_de_espera = entre(0.7, 1.3)
    
    @tarefa(1)
    def visit_website(self):
    com self.client.get("/", headers={"Host": "exemplo.com", "Agente-do-usuário": "Mozilla"}, timeout=0.2, catch_response=True) como resposta: 
    if response.request_meta["response_time"] > 200: 
    response.failure("Falha no frontend") 
    else: 
    response.success() 
    
    @task(5) 
    def visit_api(self): 
    with self.client.get("/", headers={"Host": "api.example.com"}, timeout=0.2) como resposta: 
    if response.request_meta["response_time"] > 200: 
    response.failure("Falha na API") 
    else: 
    response.success() 
    --- 
    apiVersion: apps/v1 
    kind: Implantação
    metadados: 
    nome: gafanhoto
    especificação: 
    seletor: 
    matchLabels: 
    aplicativo: gafanhoto
    modelo: 
    metadados: 
    rótulos: 
    aplicativo: gafanhoto
    especificação: 
    contêineres: 
    -nome: gafanhoto
    imagem: locustio/gafanhoto
    portas: 
    -containerPort: 8089 
    volumeMounts: 
    - mountPath: /home/locust 
    nome: locust-script 
    volumes: 
    -nome: locust-script 
    configMap: 
    nome: locust-script 
    --- 
    apiVersion: v1 
    tipo: Serviço
    metadados:
    nome: locust
    especificação:
    portas:
    - porta: 8089 
    targetPort: 8089 
    nóPorta: 30015 
    seletor: 
    aplicativo: gafanhoto 
    tipo: Balanceador de carga
    
  2. Implantar Locust:

    $ kubectl apply -f 3-locust.yaml configmap/locust-script criado deployment.apps/locust criado serviço/locust criado 
    
  3. Verifique a implantação do Locust. No exemplo de saída a seguir, o comando de verificação foi executado apenas alguns segundos após o comando kubectl apply e, portanto, a instalação ainda está em andamento, conforme indicado pelo valor ContainerCreating para o pod Locust no campo STATUS . Aguarde até que o valor esteja em execução antes de prosseguir para a próxima seção. (A saída é distribuída em duas linhas para maior legibilidade.)
    $ kubectl get pods NOME PRONTO STATUS ... api-7574cf7568-c6tr6 1/1 Em execução ... frontend-6688d86fc6-78qn7 1/1 Em execução ... locust-77c699c94d-hc76t 0/1 ContainerCreating ... ... RECOMEÇA IDADE ... 0 33m ... 0 33m ... 0 4s
    

Simule um aumento de tráfego

  1. Abra o Locust em um navegador.

    $ serviço minikube gafanhoto
    
  2. Insira os seguintes valores nos campos:

    • Número de usuários1000
    • Taxa de spawn30
    • Anfitriãohttp://main-nginx-ingress
  3. Clique no botão Iniciar swarming para enviar tráfego para a API do Podinfo e o Frontend do Podinfo . Observe os padrões de tráfego nas guias Locust Charts e Failures :

    • Gráfico – À medida que o número de solicitações de API aumenta, os tempos de resposta da API do Podinfo pioram.
    • Falhas – Como a API do Podinfo e o Frontend do Podinfo compartilham um controlador Ingress, o número crescente de solicitações de API logo faz com que o aplicativo da web comece a retornar erros.

Isso é problemático porque um único agente mal-intencionado usando a API pode derrubar não apenas a API, mas todos os aplicativos atendidos pelo NGINX Ingress Controller!

Desafio 3: Salve seu aplicativo e API com controladores de entrada dupla e limitação de taxa

No desafio final, você implanta dois NGINX Ingress Controllers para eliminar as limitações da implantação anterior, criando um namespace separado para cada um, instalando instâncias separadas do NGINX Ingress Controller para o Podinfo Frontend e o Podinfo API , reconfigura o Locust para direcionar o tráfego do aplicativo e da API para seus respectivos NGINX Ingress Controllers e verifica se a limitação de taxa é eficaz . Primeiro, vamos ver como abordar o problema arquitetônico. No desafio anterior, você sobrecarregou o NGINX Ingress Controller com solicitações de API, o que também impactou o aplicativo. Isso aconteceu porque um único Ingress controller era responsável por rotear o tráfego para o aplicativo da web ( Podinfo Frontend ) e para a API ( Podinfo API ).

Executar um pod NGINX Ingress Controller separado para cada um dos seus serviços evita que seu aplicativo seja afetado por muitas solicitações de API. Isso não é necessariamente necessário para todos os casos de uso, mas em nossa simulação é fácil ver os benefícios de executar vários controladores NGINX Ingress.

A segunda parte da solução, que evita que a API do Podinfo fique sobrecarregada, é implementar a limitação de taxa usando o NGINX Ingress Controller como um gateway de API.

 

O que é limitação de taxa?

A limitação de taxa restringe o número de solicitações que um usuário pode fazer em um determinado período de tempo. Para mitigar um ataque DDoS, por exemplo, você pode usar a limitação de taxa para limitar a taxa de solicitações de entrada a um valor típico para usuários reais. Quando a limitação de taxa é implementada com o NGINX, os clientes que enviam muitas solicitações são redirecionados para uma página de erro para que não possam impactar negativamente a API. Saiba como isso funciona na documentação do NGINX Ingress Controller .

O que é um gateway de API?

Um gateway de API roteia solicitações de API de clientes para os serviços apropriados. Um grande erro de interpretação dessa definição simples é que um gateway de API é uma peça única de tecnologia. Não é. Em vez disso, “gateway de API” descreve um conjunto de casos de uso que podem ser implementados por meio de diferentes tipos de proxies – mais comumente um ADC ou balanceador de carga e proxy reverso e, cada vez mais, um controlador Ingress ou malha de serviço. A limitação de taxa é um caso de uso comum para implantar um gateway de API. Saiba mais sobre casos de uso de gateway de API no Kubernetes em Como escolher? Gateway de API vs. Controlador de entrada vs. Service Mesh em nosso blog.

Prepare seu cluster

Antes de implementar a nova arquitetura e a limitação de taxa, você deve excluir a configuração anterior do NGINX Ingress Controller.

  1. Exclua a configuração do NGINX Ingress Controller:

     

    $ kubectl delete -f 2-ingress.yaml ingress.networking.k8s.io "primeiro" excluído 
    
    
    
  2. Crie um namespace chamado nginx‑web para o Podinfo Frontend :

    $ kubectl criar namespace nginx-web namespace/nginx-web criado 
    
    
    
  3. Crie um namespace chamado nginx‑api para a API do Podinfo :

    $ kubectl criar namespace nginx-api namespace/nginx-api criado 
    
    
    

Instalar o NGINX Ingress Controller para o Podinfo Frontend

  1. Instalar o NGINX Ingress Controller:

    $ helm install web nginx-stable/nginx-ingress --set controller.ingressClass=nginx-web \ --set controller.service.type=NodePort \ --set controller.service.httpPort.nodePort=30020 \ --namespace nginx-web
    
    
    
  2. Crie um manifesto do Ingress chamado 4-ingress-web.yaml para o Podinfo Frontend (ou copie do GitHub ).

    apiVersion: k8s.nginx.org/v1 tipo: Metadados da política: nome: especificação da política de limite de taxa: rateLimit: taxa: Chave 10r/s: ${binary_remote_addr} zoneSize: 10M --- apiVersão: k8s.nginx.org/v1 tipo: Metadados do VirtualServer: nome: api-vs spec: ingressClassName: nginx-api host: api.example.com políticas: - nome: rate-limit-policy upstreams: - nome: api service: api port: 80 rotas: - caminho: / ação: senha: api
  3. Implante o novo manifesto:

    $ kubectl apply -f 4-ingress-web.yaml ingress.networking.k8s.io/frontend criado  
    
    
    

Reconfigurar Locust

Agora, reconfigure o Locust e verifique se:

  • A API do Podinfo não fica sobrecarregada.
  • Não importa quantas solicitações sejam enviadas para a API do Podinfo , não há impacto no frontend do Podinfo .

Execute estas etapas:

  1. Altere o script do Locust para que:

    • Todas as solicitações para o Podinfo Frontend são direcionadas ao nginx‑web NGINX Ingress Controller em http://web-nginx-ingress.nginx-web
    • Todas as solicitações para a API Podinfo são direcionadas ao controlador de entrada NGINX nginx‑api em http://api-nginx-ingress.nginx-api

    Como o Locust suporta apenas uma única URL no painel, codifique o valor no script Python usando o arquivo YAML 6-locust.yaml com o seguinte conteúdo (ou copie do GitHub ). Anote os URLs em cada tarefa .

    
    apiVersion: v1 
    tipo: ConfigMap
    metadados:
    nome: script-locust
    dados:
    arquivo-locust.py: |-
    de locust importar HttpUser, tarefa, entre
    
    classe QuickstartUser(HttpUser):
    tempo_de_espera = entre(0.7, 1.3)
    
    @tarefa(1)
    def visitar_site(self):
    com self.client.get("http://web-nginx-ingress.nginx-web/", headers={"Host": "exemplo.com", "Agente-do-usuário": "Mozilla"}, timeout=0.2, catch_response=True) como resposta: 
    if response.request_meta["response_time"] > 200: 
    response.failure("Falha no frontend") 
    else: 
    response.success() 
    
    @task(5) 
    def visit_api(self): 
    with self.client.get("http://api-nginx-ingress.nginx-api/", headers={"Host": "api.example.com"}, timeout=0.2) como resposta: 
    if response.request_meta["response_time"] > 200: 
    response.failure("Falha na API") 
    else: 
    response.success() 
    --- 
    apiVersion: apps/v1 
    kind: Implantação
    metadados: 
    nome: gafanhoto
    especificação: 
    seletor: 
    matchLabels: 
    aplicativo: gafanhoto
    modelo: 
    metadados: 
    rótulos: 
    aplicativo: gafanhoto
    especificação: 
    contêineres: 
    -nome: gafanhoto
    imagem: locustio/gafanhoto
    portas: 
    -containerPort: 8089 
    volumeMounts: 
    - mountPath: /home/locust 
    nome: locust-script 
    volumes: 
    -nome: locust-script 
    configMap: 
    nome: locust-script 
    --- 
    apiVersion: v1 
    tipo: Serviço
    metadados:
    nome: locust
    especificação:
    portas:
    - porta: 8089 
    targetPort: 8089 
    nóPorta: 30015 
    seletor: 
    aplicativo: gafanhoto 
    tipo: Balanceador de carga 
    
    
    
  2. Implante a nova configuração do Locust. A saída confirma que o script mudou, mas os outros elementos permanecem inalterados.

    $ kubectl apply -f 6-locust.yaml configmap/locust-script configurado deployment.apps/locust inalterado service/locust inalterado
    
    
    
  3. Exclua o pod Locust para forçar o recarregamento do novo ConfigMap. Para identificar o pod a ser removido, o argumento para o comando kubectl delete pod é expresso como comandos canalizados que selecionam o pod Locust da lista de todos os pods.

    $ kubectl delete pod `kubectl obter pods | grep locust | awk {'imprimir $1'}` 
    
    
    
  4. Verifique se o Locust foi recarregado (o valor do pod Locust na coluna AGE é de apenas alguns segundos).

    $ kubectl get pods NOME PRONTO STATUS ... api-7574cf7568-jrlvd 1/1 Em execução ... frontend-6688d86fc6-vd856 1/1 Em execução ... locust-77c699c94d-6chsg 0/1 Em execução ... ... RECOMEÇA IDADE ... 0 9m57s ... 0 9m57s ... 0 6s
    
    
    

Verificar Limitação de Taxa

  1. Retorne ao Locust e altere os parâmetros nestes campos:

    • Número de usuários400
    • Taxa de spawn10
    • Anfitriãohttp://main-nginx-ingress
  2. Clique no botão Iniciar swarming para enviar tráfego para a API do Podinfo e o Frontend do Podinfo .

    Na barra de título do Locust, no canto superior esquerdo, observe como, à medida que o número de usuários aumenta na coluna STATUS , o mesmo ocorre com o valor na coluna FALHAS . No entanto, os erros não estão mais vindo do Podinfo Frontend, mas sim da Podinfo API, porque o limite de taxa definido para a API significa que solicitações excessivas estão sendo rejeitadas. No rastreamento no canto inferior direito você pode ver que o NGINX está retornando a mensagem503 Serviço Temporariamente Indisponível , que faz parte do recurso de limitação de taxa e pode ser personalizado. A API tem taxa limitada e o aplicativo web está sempre disponível. Bom trabalho!

PRÓXIMOS PASSOS

No mundo real, a limitação de taxa por si só não é suficiente para proteger seus aplicativos e APIs de agentes mal-intencionados. Você precisa implementar pelo menos um ou dois dos seguintes métodos para proteger aplicativos, APIs e infraestrutura do Kubernetes:

  • Autenticação e autorização
  • Firewall de aplicativo da Web e proteção DDoS
  • Criptografia de ponta a ponta e Zero Trust
  • Conformidade com os regulamentos da indústria

Abordamos esses tópicos e muito mais na Unidade 3 de Microservices de março de 2022 – Padrão de segurança de microsserviços no Kubernetes . Para experimentar o NGINX Ingress Controller para Kubernetes 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."