BLOG | NGINX

Como simplificar o gerenciamento de tráfego de entrada e saída do Kubernetes

NGINX-Parte-de-F5-horiz-preto-tipo-RGB
Miniatura de Kate Osborn
Kate Osborn
Publicado em 28 de junho de 2021

Uma das maneiras pelas quais uma malha de serviço pode realmente tornar mais complicado o gerenciamento de um ambiente Kubernetes é quando ela deve ser configurada separadamente do controlador Ingress . Configurações separadas não são apenas demoradas. Eles aumentam a probabilidade de erros de configuração que podem impedir o roteamento adequado do tráfego e até mesmo levar a vulnerabilidades de segurança (como agentes mal-intencionados obtendo acesso a aplicativos restritos) e experiências ruins (como clientes não conseguindo acessar aplicativos para os quais estão autorizados). Além do tempo que leva para executar configurações separadas, você acaba gastando mais tempo solucionando erros.

Você pode evitar esses problemas – e economizar tempo – integrando o NGINX Ingress Controller baseado no NGINX Plus com o NGINX Service Mesh para controlar o tráfego mTLS de entrada e saída. Nesta demonstração em vídeo, abordamos todas as etapas.

A documentação de suporte é referenciada nas seguintes seções:

Pré-requisitos (0:18)

Antes de iniciar a demonstração real, realizamos estes pré-requisitos:

  1. Instalou o plano de controle NGINX Server Mesh no cluster Kubernetes e configurou o mTLS e a política estrita para o service mesh .

  2. Instalou o NGINX Ingress Controller baseado no NGINX Plus como uma implantação (em vez de um DaemonSet) no cluster Kubernetes, habilitou o egress e o expôs como um serviço do tipo LoadBalancer .

    Observação:  A demonstração não funciona com o NGINX Ingress Controller baseado em código aberto NGINX. Para facilitar a leitura, nos referimos ao NGINX Ingress Controller baseado no NGINX Plus simplesmente como “NGINX Ingress Controller” no restante deste blog.

  3. Siga nossas instruções para baixar o aplicativo de exemplo bookinfo , injetar o sidecar do NGINX Service Mesh e implantar o aplicativo.

Como resultado da política rigorosa criada na Etapa 1, solicitações ao aplicativo bookinfo de clientes fora da malha são negadas no sidecar. Ilustramos isso na demonstração executando primeiro o seguinte comando para configurar o encaminhamento de porta:

> kubectl port-forward svc/product-page 9080 Encaminhamento de 127.0.0.1:9080 -> 9080 Encaminhamento de [::1]:9080 -> 9080 Manipulando conexão para 9080

Quando tentamos acessar o aplicativo, obtemos o código de status503 porque nossa máquina local não faz parte da malha de serviço:

> enrolar localhost:9080503

Implantando o NGINX Ingress Controller com o NGINX Service Mesh (1:50)

O primeiro estágio no processo de exposição de um aplicativo é implantar uma instância do NGINX Ingress Controller. Instruções correspondentes são fornecidas em nosso tutorial, Implantar com o NGINX Plus Ingress Controller para Kubernetes .

O NGINX fornece manifestos de implantação e DaemonSet para essa finalidade. Na demonstração, usamos o manifesto de implantação, nginx-plus-ingress.yaml . Inclui anotações para rotear o tráfego de entrada e saída pela mesma instância do NGINX Ingress Controller:

O manifesto permite a integração direta do NGINX Ingress Controller com o Spire, a autoridade de certificação (CA) do NGINX Service Mesh, eliminando a necessidade de injetar o sidecar do NGINX Service Mesh no NGINX Ingress Controller. Em vez disso, o NGINX Ingress Controller busca certificados e chaves diretamente do Spire CA para usar no mTLS com os pods na malha. O manifesto especifica o endereço do agente Spire:

e monta o soquete UNIX do agente Spire no pod do NGINX Ingress Controller:

A última coisa a ser observada sobre o manifesto é o argumento CLI -enable-internal-routes , que nos permite rotear para serviços de saída:

Antes de iniciar a demonstração, executamos o comando kubectl apply -f nginx-plus-ingress.yaml para instalar o NGINX Ingress Controller e, neste ponto, inspecionamos a implantação no namespace nginx-ingress . Conforme mostrado na coluna READY da saída a seguir, há apenas um contêiner para o pod do NGINX Ingress Controller, porque não o injetamos com um sidecar do NGINX Service Mesh.

Também implantamos um serviço do tipo LoadBalancer para expor o endereço IP externo do NGINX Ingress Controller (aqui, 35.233.133.188) fora do cluster. Acessaremos o aplicativo bookinfo de exemplo nesse endereço IP.

> kubectl get pods --namespace=nginx-ingress NOME PRONTO STATUS REINÍCIOS IDADE pod/nginx-ingress-867f954b8f0fzdrm 1/1 Em execução 0 3d3h NOME TIPO CLUSTER-IP EXTERNO-IP ... service-nginx-ingress LoadBalancer 10.31.245.207 35.233.133.188 ... ... IDADE DO(S) PORTO(S) ... 80:31469/TCP,443:32481/TCP 4d2h ...

Usando um recurso de entrada padrão do Kubernetes para expor o aplicativo (3:55)

Agora expomos o aplicativo bookinfo na malha, usando um recurso padrão do Kubernetes Ingress, conforme definido em bookinfo-ingress.yaml . Instruções correspondentes são fornecidas em nosso tutorial, Expor um aplicativo com o NGINX Plus Ingress Controller .

O recurso faz referência a um segredo do Kubernetes para o aplicativo bookinfo na linha 10 e inclui uma regra de roteamento que especifica que as solicitações para bookinfo.example.com são enviadas ao serviço productpage ( linhas 11–18 ). O Segredo é definido em bookinfo-secret.yaml :

Executamos este comando para carregar a chave e o certificado, que na demonstração é autoassinado:

> kubectl apply -f bookinfo-secret.yaml secret/bookinfo-secret inalterado

Ativamos o recurso Ingress:

> kubectl apply -f bookinfo-ingress.yaml ingress.networking.k8s.io/bookinfo-ingress excluído

e verifique se o Ingress Controller adicionou a rota definida no recurso, conforme confirmado pelo evento no final da saída:

> kubectl descreve ingress bookinfo-ingress ...
Eventos:
  Tipo Motivo Idade De Mensagem ---- ------ ---- ---- ------- Normal Adicionado ou Atualizado 5s nginx-ingress-controller Configuração para ... ...default/bookinfo-ingress foi adicionado ou atualizado

Na demonstração, agora usamos um navegador para acessar o aplicativo bookinfo em https://bookinfo.example.com/ . (Adicionamos anteriormente um mapeamento no arquivo local /etc/hosts entre o endereço IP do serviço Ingress Controller – 35.233.133.188 na demonstração, conforme observado acima – e bookinfo.example.com . Para obter instruções, consulte a documentação .) As informações na seção Resenhas de livros da página mudam periodicamente conforme as solicitações passam pelas três versões do serviço de resenhas definido em bookinfo.yaml ( download ).

Em seguida, inspecionamos o tráfego de entrada nos clusters. Executamos o script generate-traffic.sh para fazer solicitações ao serviço productpage por meio do endereço IP público do NGINX Ingress Controller e, em seguida, executamos o comando nginx-meshctl top para monitorar o tráfego:

> nginxmesh-ctl top deploy/productpage-v1 Direção da implantação Recurso Taxa de sucesso P99 P90 P50 ... productpage-v1 Para detalhes-v1 100,00% 3 ms 3 ms 2 ms Para avaliações-v2 100,00% 99 ms 90 ms 20 ms Para avaliações-v3 100,00% 99 ms 85 ms 18 ms Para avaliações-v1 100,00% 20 ms 17 ms 9 ms De nginx-ingress 100,00% 192 ms 120 ms 38 ms ... NumRequests ... 14 ... 5 ... 5 ... 12

Usando um recurso NGINX VirtualServer para expor o aplicativo (6:45)

A seguir, mostramos uma maneira alternativa de expor um aplicativo, usando um recurso NGINX VirtualServer . É um recurso personalizado do NGINX Ingress Controller que oferece suporte ao tratamento de tráfego mais complexo, como divisão de tráfego e roteamento baseado em conteúdo.

Primeiro, excluímos o recurso padrão do Ingress:

> kubectl delete -f bookinfo-ingress.yaml ingress.networking.k8s.io "bookinfo-ingress" excluído

Nosso arquivo bookinfo-vs.yaml configura o mTLS com o mesmo segredo do bookinfo-ingress.yaml ( linhas 7–8 ). As linhas 9 a 12 definem o serviço productpage como upstream, e as linhas 13 a 24, uma rota que envia todas as solicitações GET feitas em bookinfo.example.com para esse upstream. Para métodos HTTP diferentes de GET , ele retorna o código de status405 .

Aplicamos o recurso:

> kubectl apply -f bookinfo-vs.yaml virtualserver.kubernetes.nginx.org/bookinfo-vs criado

Em seguida, realizamos as mesmas etapas do recurso Ingress: executando o comando kubectl describe para confirmar a implantação correta e acessar o aplicativo em um navegador. Outra confirmação de que o aplicativo está funcionando corretamente é que ele rejeita o método POST :

> curl -k -X POST https://bookinfo.example.com/ Método não permitido

Configurando uma rota de saída segura com o NGINX Ingress Controller (8:44)

Agora mostraremos como rotear o tráfego de saída por meio do NGINX Ingress Controller. Nosso tutorial Configurar uma rota de saída segura com o NGINX Plus Ingress Controller aborda o processo usando diferentes aplicativos de exemplo.

Já definimos um pod bash simples em bash.yaml e o implantamos no namespace padrão de onde estamos enviando solicitações. Conforme mostrado na coluna PRONTO desta saída, ele foi injetado com o sidecar do NGINX Service Mesh.

> kubectl obter tudoNOME PRONTO STATUS REINICIA IDADE
pod/bash-6ccb678958-zsgm7 2/2 Em execução 0 77s

NOME TIPO CLUSTER-IP EXTERNO-IP PORTA(S) IDADE
service/kubernetes ClusterIP 10.31.240.1 <nenhum> 443/TCP 4d2h
...

Há vários casos de uso em que você pode querer habilitar solicitações de dentro do pod para um serviço de saída , que é qualquer entidade que não faça parte do NGINX Service Mesh. Exemplos são serviços implantados:

  • Fora do cluster
  • Em outro cluster
  • No mesmo cluster, mas não injetado com o sidecar NGINX Service Mesh

Na demonstração, estamos considerando o caso de uso final. Temos um aplicativo implantado no namespace legado , que não é controlado pelo NGINX Service Mesh e onde a injeção automática do sidecar do NGINX Service Mesh está desabilitada. Há apenas um pod em execução para o aplicativo.

> kubectl obter todos --namespaces=legacyNOME PRONTO STATUS REINÍCIOS IDADE
pod/target-5f7bcb96c6-km9lz 1/1 Em execução 0 27m

NOME TIPO CLUSTER-IP EXTERNO-IP PORTA(S) IDADE
service/target-svc ClusterIP 10.31.245.213 <nenhum> 80/TCP,443/TCP 27m
...

Lembre-se de que configuramos uma política mTLS rigorosa para o NGINX Service Mesh; como resultado, não podemos enviar solicitações diretamente do pod bash para o serviço de destino, porque os dois não podem se autenticar um com o outro. Quando tentamos, obtemos o código de status503 conforme ilustrado aqui:

> kubectl exec -it bash-6ccb678958-zsgm7 -c bash -- curl target-svc.legacy curl: (56) Falha de recebimento: redefinição de conexão pelo comando peer 503 encerrada com código de saída 56

A solução é permitir que o pod bash envie tráfego de saída por meio do NGINX Ingress Controller. Descomentamos a anotação nas linhas 14–15 de bash.yaml :

Em seguida aplicamos a nova configuração:

> kubectl apply -f bash.yaml deployment.apps/bash configurado

e verifique se um novo pod bash foi iniciado:

> kubectl get pods NOME PRONTO STATUS REINÍCIOS IDADE bash-678c8b4579-7sfml 2/2 Em execução 0 6s bash-6ccb678958-zsgm7 2/2 Terminando 0 3m28s

Agora, quando executamos o mesmo comando kubectl exec de antes, para enviar uma solicitação do pod bash para o serviço de destino, obtemos o código de status404 em vez de503 . Isso indica que o pod bash enviou com sucesso a solicitação ao NGINX Ingress Controller, mas este não sabe para onde encaminhá-la porque nenhuma rota está definida.

Criamos a rota necessária com a seguinte definição de recurso Ingress em legacy-route.yaml . A anotação de rota interna na linha 7 significa que o serviço de destino não é exposto à Internet, mas apenas às cargas de trabalho no NGINX Service Mesh.

Ativamos o novo recurso e confirmamos que o NGINX Ingress Controller adicionou a rota definida no recurso:

> kubectl apply -f legacy-route.yaml ingress.networking.k8s.io/target-internal-route criado > kubectl describe ingress target-internal-route -n legacy ...
Eventos:
  Tipo Motivo Idade De Mensagem ---- ------ ---- ---- ------- Normal Adicionado ou Atualizado 6s nginx-ingress-controller Configuração para ... ...legacy/target-internal-route foi adicionado ou atualizado

Agora, quando executamos o comando kubectl exec , alcançamos o serviço de destino:

{"req": {"método": "OBTER" "url": "/",
"host": "target-svc.legacy",
"remoteAddr": "10.28.2.76:56086"}}

Uma vantagem de rotear o tráfego de saída por meio do NGINX Ingress Controller é que você pode controlar exatamente quais serviços externos podem ser acessados de dentro do cluster – são apenas aqueles para os quais você define uma rota.

Uma última coisa que mostramos na demonstração é como monitorar o tráfego de saída. Executamos o comando kubectl exec para enviar várias solicitações e, em seguida, executamos este comando:

> nginxmesh-ctl top deploy/nginx-ingress -n nginx-ingress Direção de implantação Recurso Taxa de sucesso P99 P90 P50 NumRequests nginx-ingress Para o destino 100,00% 1 ms 1 ms 1 ms 9 De bash 100,00% 0 ms 0 ms 0 ms 9

Diga “Não” à Latência – Experimente o NGINX Service Mesh com o NGINX Ingress Controller

Muitas malhas de serviço oferecem opções de gateway de entrada e saída, mas achamos que você apreciará um benefício adicional da integração com o NGINX: menor latência. A maioria das malhas exige que um sidecar seja injetado no controlador Ingress, o que exige que o tráfego faça um salto extra em seu caminho para seus aplicativos. Os segundos são importantes, e esse salto extra que torna suas experiências digitais mais lentas pode fazer com que os clientes procurem outro lugar. O NGINX Service Mesh não adiciona latência desnecessária porque não injeta um sidecar no NGINX Ingress Controller. Em vez disso, ao integrar-se diretamente com o Spire, a CA da malha, o NGINX Ingress Controller se torna parte do NGINX Service Mesh. O NGINX Ingress Controller simplesmente busca certificados e chaves do agente Spire e os usa para participar da troca de certificados mTLS com pods em malha.

Existem duas versões do NGINX Ingress Controller para Kubernetes: NGINX Open Source e NGINX Plus. Para implantar o NGINX Ingress Controller com o NGINX Service Mesh conforme descrito neste blog, você deve usar a versão NGINX Plus, que está disponível para um teste gratuito de 30 dias .

O NGINX Service Mesh é totalmente gratuito e está disponível para download imediato , podendo ser implantado em menos de 10 minutos! Para começar, confira a documentação e nos conte como foi via GitHub .


"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."