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:
Antes de iniciar a demonstração real, realizamos estes pré-requisitos:
Instalou o plano de controle NGINX Server Mesh no cluster Kubernetes e configurou o mTLS e a política estrita
para o service mesh .
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.
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
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 ...
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
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
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:
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
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."