Crie um controlador de entrada não gerenciado

Um controlador de entrada é uma parte do software que fornece proxy reverso, roteamento de tráfego configurável e terminação TLS para serviços de Kubernetes. Os recursos de entrada de Kubernetes são usados para configurar as regras de entrada e as rotas para os serviços de Kubernetes individuais. Quando você usa um controlador de entrada e regras de ingresso, só pode usar um único endereço IP para rotear o tráfego para vários serviços em um cluster do Kubernetes.

Este artigo mostra como implantar o controlador de ingresso NGINX em um Cluster do Serviço de Kubernetes do Azure (AKS0) Dois aplicativos são então executados no cluster do AKS, cada um dos quais é acessível pelo endereço IP único.

Importante

O complemento de roteamento de aplicativos é recomendado para entrada no AKS. Para obter mais informações, consulte Entrada do nginx gerenciada com o complemento de roteamento de aplicativo.

Observação

Há dois controladores de entrada de código aberto para Kubernetes com base no Nginx: um mantido pela comunidade do Kubernetes (kubernetes/ingress-nginx) e outro mantido pela NGINX, Inc. (nginxinc/kubernetes-ingress). Este artigo estará usando o controlador de entrada da comunidade do 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 usar a versão mais recente do Helm e de ter acesso ao repositório ingress-nginx do Helm. As etapas descritas neste artigo podem não ser compatíveis com versões anteriores do gráfico do Helm, do controlador de entrada NGINX ou do Kubernetes.
  • Este artigo pressupõe que você tenha um cluster do AKS com um ACR (Registro de Contêiner do Azure) integrado. Para saber como criar um cluster do AKS com um ACR integrado, confira Autenticar-se com o Registro de Contêiner do Azure no Serviço de Kubernetes do Azure.
  • O ponto de extremidade de integridade da API do Kubernetes healthz foi preterido no Kubernetes v1.16. Como alternativa, você pode substituí-lo pelos pontos de extremidade livez e readyz. Consulte Pontos de extremidade da API do Kubernetes para verificar integridade para determinar qual ponto de extremidade usar para seu cenário.
  • Se você estiver usando a CLI do Azure, este artigo exigirá que você esteja executando a CLI do Azure versão 2.0.64 ou posterior. Execute az --version para encontrar a versão. Se você precisa instalar ou atualizar, consulte Instalar a CLI do Azure.
  • Se você estiver usando Azure PowerShell, este artigo exigirá que você esteja executando o Azure PowerShell versão 5.9.0 ou posterior. Execute Get-InstalledModule -Name Az para encontrar a versão. Se precisar instalar ou atualizar, consulte Instalar o Azure PowerShell.

Configuração básica

Para criar um controlador de entrada NGINX básico sem personalizar os padrões, use o Helm. A configuração a seguir usa a configuração padrão para fins de simplificação. É possível adicionar parâmetros para personalizar a implantação, por exemplo, --set controller.replicaCount=3.

Observação

Se você quiser habilitar a preservação de IP de origem do cliente para solicitações a contêineres em seu cluster, adicione --set controller.service.externalTrafficPolicy=Local ao comando de instalação do Helm. O IP de origem do cliente é armazenado no cabeçalho da solicitação em X-Forwarded-For. Se você usar 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

Observação

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 para /healthz não for 200, todo o controlador de entrada ficará inoperante. Você pode modificar o valor para outro URI em seu próprio cenário. Não é possível excluir essa parte ou remover a definição do valor, ou o controlador de entrada ainda estará inativo. O pacote ingress-nginx usado neste tutorial, fornecido pelo Kubernetes oficial, sempre retornará o 200 código de resposta se solicitar /healthz, pois ele é projetado como back-end padrão para que os usuários tenham um início rápido, a menos que esteja sendo substituído pelas 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.

Importar as imagens usadas pelo gráfico do Helm em seu ACR

Para controlar as versões de imagem, importe-as para seu próprio Registro de Contêiner do Azure. O gráfico do Helm do controlador de entrada NGINX se baseia em três imagens de contêiner. Use az acr import para importar essas imagens no 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

Observação

Além de importar imagens de contêiner no ACR, você também pode importar gráficos do Helm no ACR. Para saber mais, confira Enviar por push e efetuar pull de gráficos do Helm para o Registro de Contêiner do Azure.

Criar um controlador de entrada

Para criar o controlador de entrada, use o Helm para instalarnginx-ingress. O controlador de entrada precisa ser agendado em um nó do Linux. Os nós do Windows Server não devem executar o controlador de entrada. Um seletor de nó é especificado usando o parâmetro --set nodeSelector para instruir o agendador do Kubernetes a executar o controlador de entrada NGINX em um nó baseado em Linux.

Para redundância adicional, duas réplicas dos controladores de entrada NGINX são implementadas com o parâmetro --set controller.replicaCount. Para se beneficiar totalmente da execução de réplicas do controlador de entrada, verifique se 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 tem como objetivo funcionar nesse namespace. Especifique um namespace para seu próprio ambiente, conforme necessário. Se o cluster do AKS não for habilitado para o RBAC do Kubernetes, adicione --set rbac.create=false aos comandos do Helm.

Observação

Se você quiser habilitar a preservação de IP de origem do cliente para solicitações a contêineres em seu cluster, adicione --set controller.service.externalTrafficPolicy=Local ao comando de instalação do Helm. O IP de origem do cliente é armazenado no cabeçalho da solicitação em X-Forwarded-For. Se você usar 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=""

Crie um controlador de entrada usando um endereço IP interno

Por padrão, um controlador de entrada NGINX é criado com uma atribuição dinâmica de endereço IP público. Um requisito de configuração comum é usar um endereço IP e uma rede privada interna. Essa abordagem permite restringir o acesso a seus serviços a usuários internos, sem acesso externo.

Use os parâmetros --set controller.service.loadBalancerIP e --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-internal"=true para atribuir um endereço IP interno ao controlador de entrada. Forneça seu próprio endereço IP interno para uso com o controlador de entrada. Certifique-se de que esse endereço IP não esteja em uso em sua rede virtual. Se você estiver usando uma rede virtual e uma sub-rede existentes, configure o cluster do AKS com as permissões corretas para gerenciá-las. Para saber mais, confira Usar a rede kubenet com seus próprios intervalos de endereços IP no AKS (Serviço de Kubernetes do Azure) ou Configurar a rede CNI do Azure no AKS (Serviço de Kubernetes do Azure).

# 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="" 

Criar um serviço de balanceador de carga

Verifique o serviço de 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 seguinte saída de exemplo:

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, executaremos dois aplicativos de demonstração no cluster do AKS. Neste exemplo, você usa o kubectl apply para implantar duas instâncias de um aplicativo Hello world simples.

  1. Crie um arquivo aks-helloworld-one.yaml e copie-o no seguinte YAML de exemplo:

    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 arquivo aks-helloworld-two.yaml e copie-o no seguinte YAML de exemplo:

    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 rota de entrada

Ambos os aplicativos agora estão em execução no cluster do Kubernetes. Para rotear o tráfego para cada aplicativo, crie um recurso de entrada do Kubernetes. O recurso de entrada configura as regras que roteiam 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 é roteado para o serviço aks-helloworld-two. O tráfego para EXTERNAL_IP/static é roteado para o serviço chamado aks-helloworld-one para ativos estáticos.

  1. Crie um arquivo chamado hello-world-ingress.yaml e copie no exemplo YAML a seguir:

    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
    

Testar o controlador de entrada

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 controlador de entrada NGINX, como EXTERNAL_IP. O primeiro aplicativo de demonstração é exibido no navegador da Web, conforme mostrado no seguinte exemplo:

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 é mostrado:

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 de 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
    

    Como nenhum caminho foi fornecido com o endereço, o controlador de entrada aceita o padrão da rota /. O primeiro aplicativo de demonstração é retornado, conforme mostrado na saída de exemplo condensada a seguir:

    <!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 um título personalizado é retornado, conforme mostrado na saída de exemplo condensada a seguir:

    <!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>
    [...]
    

Limpar os recursos

Este artigo usou o Helm para instalar os componentes de ingresso e os aplicativos de amostra. Quando você implanta um gráfico do Helm, vários recursos do Kubernetes são criados. Esses recursos incluem pods, implantações e serviços. Para limpar esses recursos, você poderá excluir o namespace inteiro de exemplo ou os recursos individuais.

Excluir o namespace de exemplo e todos os recursos

Para excluir o namespace inteiro de exemplo, use o comando kubectl delete e especifique o nome do 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 versões do Helm com o comando helm list.

    helm list --namespace ingress-basic
    

    Procure gráficos nomeados ingress-nginx e aks-helloworld, conforme mostrado na saída do 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 comando helm uninstall.

    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 direcionava o tráfego para os aplicativos de exemplo.

    kubectl delete -f hello-world-ingress.yaml
    
  5. Exclua o namespace usando o comando kubectl delete e especificando o nome do namespace.

    kubectl delete namespace ingress-basic
    

Próximas etapas

Para configurar o TLS com seus componentes de entrada existentes, confira Usar o TLS com um controlador de entrada.

Para configurar o cluster do AKS para usar o roteamento de aplicativo HTTP, confira Habilitar o complemento de roteamento de aplicativo HTTP.

Este artigo incluído alguns componentes externos no AKS. Para saber mais sobre esses componentes, consulte as seguintes páginas do projeto: