Criar um controlador de entrada não gerenciado
Um controlador de entrada é um software que fornece proxy reverso, roteamento de tráfego configurável e terminação TLS para serviços Kubernetes. Os recursos de entrada do Kubernetes são utilizados para configurar regras e rotas de entrada para serviços individuais do Kubernetes. Quando utiliza um controlador de entradas e regras de entradas, um único endereço IP pode ser utilizado para encaminhar o tráfego para vários serviços num cluster do Kubernetes.
Este artigo mostra como implantar o controlador de entrada NGINX em um cluster do Serviço Kubernetes do Azure (AKS). Duas aplicações são então executadas no cluster AKS, cada uma das quais é acessível através do único endereço IP.
Importante
O complemento de roteamento de aplicativos é recomendado para entrada no AKS. Para obter mais informações, consulte Managed nginx Ingress with the application routing add-on.
Nota
Existem dois controladores de entrada de código aberto para Kubernetes baseados em Nginx: um é mantido pela comunidade Kubernetes (kubernetes/ingress-nginx), e um é mantido pela NGINX, Inc. Este artigo usará o controlador de entrada da comunidade Kubernetes.
Antes de começar
- Este artigo usa o Helm 3 para instalar o controlador de entrada NGINX em uma versão suportada do Kubernetes. Certifique-se de que você está usando a versão mais recente do Helm e tenha acesso ao repositório ingress-nginx Helm. As etapas descritas neste artigo podem não ser compatíveis com versões anteriores do gráfico Helm, controlador de entrada NGINX ou Kubernetes.
- Este artigo pressupõe que você tenha um cluster AKS existente com um Registro de Contêiner do Azure (ACR) integrado. Para obter mais informações sobre como criar um cluster AKS com um ACR integrado, consulte Autenticar com o Registro de Contêiner do Azure do Serviço Kubernetes do Azure.
- O ponto
healthz
de extremidade de integridade da API do Kubernetes foi preterido no Kubernetes v1.16. Em vez disso,livez
você pode substituir esse ponto de extremidade pelos pontos de extremidade ereadyz
. Consulte Pontos de extremidade da API do Kubernetes para integridade para determinar qual ponto de extremidade usar para seu cenário. - Se você estiver usando a CLI do Azure, este artigo requer que você esteja executando a CLI do Azure versão 2.0.64 ou posterior. Executar
az --version
para localizar a versão. Se precisar de instalar ou atualizar, veja Install Azure CLI (Instalar o Azure CLI). - Se você estiver usando o Azure PowerShell, este artigo requer que você esteja executando o Azure PowerShell versão 5.9.0 ou posterior. Executar
Get-InstalledModule -Name Az
para localizar a versão. Se precisar de instalar ou atualizar, veja Install Azure PowerShell(Instalar o Azure PowerShell).
Configuração básica
Para criar um controlador de entrada NGINX básico sem personalizar os padrões, você usará o Helm. A configuração a seguir usa a configuração padrão para simplificar. Você pode adicionar parâmetros para personalizar a implantação, como --set controller.replicaCount=3
.
Nota
Se você quiser habilitar a preservação do IP de origem do cliente para solicitações a contêineres em seu cluster, adicione --set controller.service.externalTrafficPolicy=Local
ao comando Helm install. O IP de origem do cliente é armazenado no cabeçalho da solicitação em X-Forwarded-For. Quando você estiver usando um controlador de entrada com a preservação de IP de origem do cliente habilitada, a passagem TLS não funcionará.
NAMESPACE=ingress-basic
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx \
--create-namespace \
--namespace $NAMESPACE \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
--set controller.service.externalTrafficPolicy=Local
Nota
Neste tutorial, service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path
está sendo definido como /healthz
. Isso significa que, se o código de resposta das solicitações não /healthz
for 200
, todo o controlador de entrada estará inativo. Você pode modificar o valor para outro URI em seu próprio cenário. Não é possível excluir essa parte ou desdefinir o valor, ou o controlador de entrada ainda estará inativo.
O pacote ingress-nginx
usado neste tutorial, que é fornecido pelo oficial do Kubernetes, sempre retornará 200
o código de resposta se solicitar/healthz
, pois é projetado como back-end padrão para que os usuários tenham um início rápido, a menos que esteja sendo substituído por regras de entrada.
Configuração personalizada
Como alternativa à configuração básica apresentada na seção acima, o próximo conjunto de etapas mostrará como implantar um controlador de entrada personalizado. Você terá a opção de usar um endereço IP estático interno ou um endereço IP público dinâmico.
Importe as imagens usadas pelo gráfico Helm para o ACR
Para controlar as versões de imagem, convém importá-las para seu próprio Registro de Contêiner do Azure. O gráfico Helm do controlador de ingresso NGINX depende de três imagens de contêiner. Use az acr import
para importar essas imagens para o seu ACR.
REGISTRY_NAME=<REGISTRY_NAME>
SOURCE_REGISTRY=registry.k8s.io
CONTROLLER_IMAGE=ingress-nginx/controller
CONTROLLER_TAG=v1.8.1
PATCH_IMAGE=ingress-nginx/kube-webhook-certgen
PATCH_TAG=v20230407
DEFAULTBACKEND_IMAGE=defaultbackend-amd64
DEFAULTBACKEND_TAG=1.5
az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$CONTROLLER_IMAGE:$CONTROLLER_TAG --image $CONTROLLER_IMAGE:$CONTROLLER_TAG
az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$PATCH_IMAGE:$PATCH_TAG --image $PATCH_IMAGE:$PATCH_TAG
az acr import --name $REGISTRY_NAME --source $SOURCE_REGISTRY/$DEFAULTBACKEND_IMAGE:$DEFAULTBACKEND_TAG --image $DEFAULTBACKEND_IMAGE:$DEFAULTBACKEND_TAG
Nota
Além de importar imagens de contêiner para seu ACR, você também pode importar gráficos Helm para seu ACR. Para obter mais informações, consulte Enviar e puxar gráficos de leme para um Registro de Contêiner do Azure.
Criar um controlador de entrada
Para criar o controlador de entrada, use Helm para instalar o ingress-nginx. O controlador de entrada precisa ser agendado em um nó Linux. Os nós do Windows Server não devem executar o controlador de entrada. É especificado um seletor de nós com o parâmetro --set nodeSelector
para indicar ao agendador do Kubernetes que execute o controlador de entrada do NGINX num nó baseado no Linux.
Para uma maior redundância, são implementadas duas réplicas dos controladores de entrada do NGINX com o parâmetro --set controller.replicaCount
. Para se beneficiar totalmente da execução de réplicas do controlador de entrada, certifique-se de que há mais de um nó em seu cluster AKS.
O exemplo a seguir cria um namespace Kubernetes para os recursos de entrada chamados ingress-basic e destina-se a funcionar dentro desse namespace. Especifique um namespace para seu próprio ambiente, conforme necessário. Se o cluster AKS não estiver habilitado para o controle de acesso baseado em função do Kubernetes, adicione --set rbac.create=false
aos comandos Helm.
Nota
Se você quiser habilitar a preservação do IP de origem do cliente para solicitações a contêineres em seu cluster, adicione --set controller.service.externalTrafficPolicy=Local
ao comando Helm install. O IP de origem do cliente é armazenado no cabeçalho da solicitação em X-Forwarded-For. Quando você estiver usando um controlador de entrada com a preservação de IP de origem do cliente habilitada, a passagem TLS não funcionará.
# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# Set variable for ACR location to use for pulling images
ACR_LOGIN_SERVER=<REGISTRY_LOGIN_SERVER>
# Use Helm to deploy an NGINX ingress controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
--version 4.7.1 \
--namespace ingress-basic \
--create-namespace \
--set controller.replicaCount=2 \
--set controller.nodeSelector."kubernetes\.io/os"=linux \
--set controller.image.registry=$ACR_LOGIN_SERVER \
--set controller.image.image=$CONTROLLER_IMAGE \
--set controller.image.tag=$CONTROLLER_TAG \
--set controller.image.digest="" \
--set controller.admissionWebhooks.patch.nodeSelector."kubernetes\.io/os"=linux \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
--set controller.service.externalTrafficPolicy=Local \
--set controller.admissionWebhooks.patch.image.registry=$ACR_LOGIN_SERVER \
--set controller.admissionWebhooks.patch.image.image=$PATCH_IMAGE \
--set controller.admissionWebhooks.patch.image.tag=$PATCH_TAG \
--set controller.admissionWebhooks.patch.image.digest="" \
--set defaultBackend.nodeSelector."kubernetes\.io/os"=linux \
--set defaultBackend.image.registry=$ACR_LOGIN_SERVER \
--set defaultBackend.image.image=$DEFAULTBACKEND_IMAGE \
--set defaultBackend.image.tag=$DEFAULTBACKEND_TAG \
--set defaultBackend.image.digest=""
Criar um controlador de entrada usando um endereço IP interno
Por padrão, um controlador de entrada NGINX é criado com uma atribuição de endereço IP público dinâmico. Um requisito de configuração comum é usar uma rede interna, privada e um endereço IP. Essa abordagem permite que você restrinja o acesso aos seus serviços a usuários internos, sem acesso externo.
Use os --set controller.service.loadBalancerIP
parâmetros e --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-internal"=true
para atribuir um endereço IP interno ao seu controlador de entrada. Forneça seu próprio endereço IP interno para uso com o controlador de entrada. Certifique-se de que este endereço IP ainda não está a ser utilizado na sua rede virtual. Se você estiver usando uma rede virtual e uma sub-rede existentes, deverá configurar seu cluster AKS com as permissões corretas para gerenciar a rede virtual e a sub-rede. Para obter mais informações, consulte Usar rede kubenet com seus próprios intervalos de endereços IP no Serviço Kubernetes do Azure (AKS) ou Configurar a rede CNI do Azure no Serviço Kubernetes do Azure (AKS).
# Add the ingress-nginx repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# Set variable for ACR location to use for pulling images
ACR_LOGIN_SERVER=<REGISTRY_LOGIN_SERVER>
# Use Helm to deploy an NGINX ingress controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
--version 4.7.1 \
--namespace ingress-basic \
--create-namespace \
--set controller.replicaCount=2 \
--set controller.nodeSelector."kubernetes\.io/os"=linux \
--set controller.image.registry=$ACR_LOGIN_SERVER \
--set controller.image.image=$CONTROLLER_IMAGE \
--set controller.image.tag=$CONTROLLER_TAG \
--set controller.image.digest="" \
--set controller.admissionWebhooks.patch.nodeSelector."kubernetes\.io/os"=linux \
--set controller.service.loadBalancerIP=10.224.0.42 \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-internal"=true \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
--set controller.admissionWebhooks.patch.image.registry=$ACR_LOGIN_SERVER \
--set controller.admissionWebhooks.patch.image.image=$PATCH_IMAGE \
--set controller.admissionWebhooks.patch.image.tag=$PATCH_TAG \
--set controller.admissionWebhooks.patch.image.digest="" \
--set defaultBackend.nodeSelector."kubernetes\.io/os"=linux \
--set defaultBackend.image.registry=$ACR_LOGIN_SERVER \
--set defaultBackend.image.image=$DEFAULTBACKEND_IMAGE \
--set defaultBackend.image.tag=$DEFAULTBACKEND_TAG \
--set defaultBackend.image.digest=""
Verifique o serviço do balanceador de carga
Verifique o serviço do balanceador de carga usando kubectl get services
.
kubectl get services --namespace ingress-basic -o wide -w ingress-nginx-controller
Quando o serviço de balanceador de carga do Kubernetes é criado para o controlador de entrada NGINX, um endereço IP é atribuído em EXTERNAL-IP, conforme mostrado na saída de exemplo a seguir:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
ingress-nginx-controller LoadBalancer 10.0.65.205 EXTERNAL-IP 80:30957/TCP,443:32414/TCP 1m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
Se você navegar até o endereço IP externo neste estágio, verá uma página 404 exibida. Isso ocorre porque você ainda precisa configurar a conexão com o IP externo, o que é feito nas próximas seções.
Executar aplicativos de demonstração
Para ver o controlador de entrada em ação, execute dois aplicativos de demonstração em seu cluster AKS. Neste exemplo, você usa kubectl apply
para implantar duas instâncias de um aplicativo Hello world simples.
Crie um
aks-helloworld-one.yaml
arquivo e copie no exemplo a seguir YAML:apiVersion: apps/v1 kind: Deployment metadata: name: aks-helloworld-one spec: replicas: 1 selector: matchLabels: app: aks-helloworld-one template: metadata: labels: app: aks-helloworld-one spec: containers: - name: aks-helloworld-one image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 ports: - containerPort: 80 env: - name: TITLE value: "Welcome to Azure Kubernetes Service (AKS)" --- apiVersion: v1 kind: Service metadata: name: aks-helloworld-one spec: type: ClusterIP ports: - port: 80 selector: app: aks-helloworld-one
Crie um
aks-helloworld-two.yaml
arquivo e copie no exemplo a seguir YAML:apiVersion: apps/v1 kind: Deployment metadata: name: aks-helloworld-two spec: replicas: 1 selector: matchLabels: app: aks-helloworld-two template: metadata: labels: app: aks-helloworld-two spec: containers: - name: aks-helloworld-two image: mcr.microsoft.com/azuredocs/aks-helloworld:v1 ports: - containerPort: 80 env: - name: TITLE value: "AKS Ingress Demo" --- apiVersion: v1 kind: Service metadata: name: aks-helloworld-two spec: type: ClusterIP ports: - port: 80 selector: app: aks-helloworld-two
Execute os dois aplicativos de demonstração usando
kubectl apply
:kubectl apply -f aks-helloworld-one.yaml --namespace ingress-basic kubectl apply -f aks-helloworld-two.yaml --namespace ingress-basic
Criar uma rota de entrada
Ambos os aplicativos agora estão sendo executados em seu cluster Kubernetes. Para rotear o tráfego para cada aplicativo, crie um recurso de entrada do Kubernetes. O recurso de entrada configura as regras que encaminham o tráfego para um dos dois aplicativos.
No exemplo a seguir, o tráfego para EXTERNAL_IP/hello-world-one é roteado para o serviço chamado aks-helloworld-one
. O tráfego para EXTERNAL_IP/hello-world-two é encaminhado para o aks-helloworld-two
serviço. O tráfego para EXTERNAL_IP/static é roteado para o serviço nomeado aks-helloworld-one
para ativos estáticos.
Crie um arquivo nomeado
hello-world-ingress.yaml
e copie no seguinte exemplo YAML:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: hello-world-ingress annotations: nginx.ingress.kubernetes.io/ssl-redirect: "false" nginx.ingress.kubernetes.io/use-regex: "true" nginx.ingress.kubernetes.io/rewrite-target: /$2 spec: ingressClassName: nginx rules: - http: paths: - path: /hello-world-one(/|$)(.*) pathType: Prefix backend: service: name: aks-helloworld-one port: number: 80 - path: /hello-world-two(/|$)(.*) pathType: Prefix backend: service: name: aks-helloworld-two port: number: 80 - path: /(.*) pathType: Prefix backend: service: name: aks-helloworld-one port: number: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: hello-world-ingress-static annotations: nginx.ingress.kubernetes.io/ssl-redirect: "false" nginx.ingress.kubernetes.io/rewrite-target: /static/$2 spec: ingressClassName: nginx rules: - http: paths: - path: /static(/|$)(.*) pathType: Prefix backend: service: name: aks-helloworld-one port: number: 80
Crie o recurso de entrada usando o
kubectl apply
comando.kubectl apply -f hello-world-ingress.yaml --namespace ingress-basic
Teste o controlador de ingresso
Para testar as rotas para o controlador de entrada, navegue até os dois aplicativos. Abra um navegador da Web para o endereço IP do seu controlador de entrada NGINX, como EXTERNAL_IP. O primeiro aplicativo de demonstração é exibido no navegador da Web, como mostrado no exemplo a seguir:
Agora, adicione o caminho /hello-world-two ao endereço IP, como EXTERNAL_IP/hello-world-two. O segundo aplicativo de demonstração com o título personalizado é exibido:
Testar um endereço IP interno
Crie um pod de teste e anexe uma sessão de terminal a ele.
kubectl run -it --rm aks-ingress-test --image=mcr.microsoft.com/dotnet/runtime-deps:6.0 --namespace ingress-basic
Instale
curl
no pod usandoapt-get
.apt-get update && apt-get install -y curl
Acesse o endereço do seu controlador de entrada do Kubernetes usando
curl
, como http://10.224.0.42. Forneça seu próprio endereço IP interno especificado quando você implantou o controlador de entrada.curl -L http://10.224.0.42
Nenhum caminho foi fornecido com o endereço, portanto, o controlador de entrada assume como padrão a / rota. O primeiro aplicativo de demonstração é retornado, como mostrado na seguinte saída de exemplo condensado:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <link rel="stylesheet" type="text/css" href="/static/default.css"> <title>Welcome to Azure Kubernetes Service (AKS)</title> [...]
Adicione o caminho /hello-world-two ao endereço, como http://10.224.0.42/hello-world-two.
curl -L -k http://10.224.0.42/hello-world-two
O segundo aplicativo de demonstração com o título personalizado é retornado, conforme mostrado na seguinte saída de exemplo condensado:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <link rel="stylesheet" type="text/css" href="/static/default.css"> <title>AKS Ingress Demo</title> [...]
Clean up resources (Limpar recursos)
Este artigo usou o Helm para instalar os componentes de entrada e os aplicativos de exemplo. Quando você implanta um gráfico Helm, muitos recursos do Kubernetes são criados. Esses recursos incluem pods, implantações e serviços. Para limpar esses recursos, você pode excluir todo o namespace de exemplo ou os recursos individuais.
Excluir o namespace de exemplo e todos os recursos
Para excluir todo o namespace de exemplo, use o comando e especifique o nome do kubectl delete
namespace. Todos os recursos no namespace são excluídos.
kubectl delete namespace ingress-basic
Excluir recursos individualmente
Como alternativa, uma abordagem mais granular é excluir os recursos individuais criados.
Liste as liberações do Helm com o
helm list
comando.helm list --namespace ingress-basic
Procure gráficos chamados ingress-nginx e aks-helloworld, conforme mostrado na saída de exemplo a seguir:
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION ingress-nginx ingress-basic 1 2020-01-06 19:55:46.358275 -0600 CST deployed nginx-ingress-1.27.1 0.26.1
Desinstale as versões com o
helm uninstall
comando.helm uninstall ingress-nginx --namespace ingress-basic
Remova os dois aplicativos de exemplo.
kubectl delete -f aks-helloworld-one.yaml --namespace ingress-basic kubectl delete -f aks-helloworld-two.yaml --namespace ingress-basic
Remova a rota de entrada que direcionou o tráfego para os aplicativos de exemplo.
kubectl delete -f hello-world-ingress.yaml
Exclua o namespace usando o comando e especificando o nome do
kubectl delete
namespace.kubectl delete namespace ingress-basic
Próximos passos
Para configurar o TLS com seus componentes de entrada existentes, consulte Usar TLS com um controlador de entrada.
Para configurar seu cluster AKS para usar o roteamento de aplicativos HTTP, consulte Habilitar o complemento de roteamento de aplicativos HTTP.
Este artigo incluiu alguns componentes externos ao AKS. Para saber mais sobre esses componentes, consulte as seguintes páginas do projeto: