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 e readyz . 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.

  1. 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
    
  2. 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
    
  3. 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.

  1. 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
    
  2. 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:

First app running behind the ingress controller

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:

Second app running behind the ingress controller

Testar um endereço IP interno

  1. 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
    
  2. Instale curl no pod usando apt-get.

    apt-get update && apt-get install -y curl
    
  3. 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>
    [...]
    
  4. 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.

  1. 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  
    
  2. Desinstale as versões com o helm uninstall comando.

    helm uninstall ingress-nginx --namespace ingress-basic
    
  3. 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
    
  4. Remova a rota de entrada que direcionou o tráfego para os aplicativos de exemplo.

    kubectl delete -f hello-world-ingress.yaml
    
  5. 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: