Como configurar o balanceamento de carga HTTP(S) com o Ingress

Neste tutorial, mostramos como executar um aplicativo da Web protegido por um balanceador de carga HTTP(S) externo http-lb configurando o recurso Ingress.

Contexto

O Google Kubernetes Engine (GKE) oferece suporte integrado a dois tipos de Cloud Load Balancing para um aplicativo acessível ao público:

  • Quando você especifica type:LoadBalancer no manifesto do recurso, o GKE cria um Serviço do tipo LoadBalancer. O GKE faz chamadas apropriadas à API do Google Cloud para criar um balanceador de carga de rede externo ou um balanceador de carga TCP/UDP interno. O GKE cria um balanceador de carga TCP/UDP interno quando você adiciona a anotação cloud.google.com/load-balancer-type: "Internal". Caso contrário, o GKE criará um balanceador de carga de rede externo.

    É possível usar um desses tipos de balanceador de carga para o tráfego HTTP(S), mas eles operam nas camadas OSI 3/4 e não reconhecem as conexões HTTP ou as respostas e solicitações HTTP individuais. Outra característica importante é que as solicitações não são enviadas por proxy ao destino.

  • Ao especificar type:Ingress no manifesto do recurso, você instrui o GKE a criar um recurso Ingress. Ao incluir anotações e oferecer suporte a cargas de trabalho e Serviços, você cria um controlador Ingress personalizado. Caso contrário, o GKE faz chamadas apropriadas à API do Google Cloud para criar um balanceador de carga HTTP(S) externo. As regras de host e as correspondências de caminho do mapa de URLs do balanceador de carga se referem a um ou mais serviços de back-end, em que cada serviço corresponde a um Serviço do GKE do tipo NodePort, conforme mencionado no Ingress. Os back-ends de cada serviço são grupos de instâncias ou de endpoints de rede (NEGs, na sigla em inglês). Os NEGs são criados quando você define o balanceamento de carga nativo de contêiner como parte da configuração do Ingress. Para cada serviço de back-end, o GKE cria uma verificação de integridade do Google Cloud com base nas configurações de sondagem de prontidão da carga de trabalho referenciada pelo Serviço (em inglês) correspondente do GKE.

    Se você está expondo um serviço HTTP(S) hospedado no GKE, o balanceamento de carga HTTP(S) é o método recomendado nesse caso.

Antes de começar

Siga estas etapas para ativar a API Kubernetes Engine:
  1. Acesse a página do Kubernetes Engine no Console do Google Cloud.
  2. Crie ou selecione um projeto.
  3. Aguarde a ativação da API e dos serviços relacionados. Isso pode levar alguns minutos.
  4. Verifique se a cobrança está ativada para o seu projeto do Google Cloud. Saiba como confirmar se a cobrança está ativada para o seu projeto.

Instale as ferramentas de linha de comando a seguir usadas neste tutorial:

  • gcloud é usado para criar e excluir clusters do Kubernetes Engine. gcloud está incluído no SDK do Google Cloud.
  • O kubectl é usado para gerenciar o Kubernetes, o sistema de orquestração de cluster usado pelo Kubernetes Engine. É possível instalar kubectl usando gcloud:
    gcloud components install kubectl

Definir padrões para a ferramenta de linha de comando gcloud

Para poupar tempo, em vez de digitar o ID do projeto e as opções de zona do Compute Engine na ferramenta de linha de comando gcloud, defina os padrões:
    gcloud config set project [PROJECT_ID]
    gcloud config set compute/zone [COMPUTE_ENGINE_ZONE]

Criar um cluster de contêiner

Crie um cluster de contêiner chamado loadbalancedcluster executando:

    gcloud container clusters create loadbalancedcluster
    

Etapa 1: implantar um aplicativo da Web

Crie um Deployment usando a imagem de amostra do contêiner do aplicativo da Web para escuta em um servidor HTTP na porta 8080:

Para criar a implantação, faça o download do web-deployment.yaml e aplique o recurso ao cluster:

    kubectl apply -f web-deployment.yaml
    

Etapa 2: publicar a implantação internamente como um serviço

Crie um recurso Serviço para tornar a implantação de web acessível no cluster de contêiner.

Para criar a implantação, faça o download do web-service.yaml e aplique o recurso ao cluster:

    kubectl apply -f web-service.yaml
    

Quando você cria um Serviço do tipo NodePort com esse comando, o GKE o disponibiliza em um número de porta alto selecionado aleatoriamente (por exemplo, 32640) em todos os nós do cluster.

Verifique se o Serviço foi criado e se uma porta do nó foi alocada:

    kubectl get service web
    
Resposta:
    NAME      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
    web       NodePort   10.35.245.219   <none>        8080:32640/TCP   5m
    

Na saída de exemplo acima, a porta do nó para o serviço do web é 32640. Além disso, não há IP externo alocado para esse Serviço. Como os nós do GKE não podem ser acessados externamente por padrão, a criação desse Serviço não faz com que o aplicativo possa ser acessado pela Internet.

Para que o aplicativo de servidor da Web HTTP(S) possa ser acessado publicamente, crie um recurso Ingress.

Etapa 3: criar um recurso Ingress

O Ingress é um recurso do Kubernetes que encapsula um conjunto de regras e configurações para encaminhar o tráfego HTTP(S) externo aos serviços internos.

No GKE, o Ingress é implementado usando o Cloud Load Balancing. Quando você cria um Ingress no cluster, o GKE gera um balanceador de carga HTTP(S) e o configura para encaminhar o tráfego ao aplicativo.

O Kubernetes Ingress é um recurso Beta. Isso significa que a forma como você descreve o objeto Ingress está sujeita a alterações, mas os balanceadores de carga do Cloud provisionados pelo GKE para implementar o Ingress estão prontos para produção.

O arquivo de configuração a seguir define um recurso Ingress que direciona o tráfego ao Serviço web:

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: basic-ingress
    spec:
      backend:
        serviceName: web
        servicePort: 8080
    

Para implantar esse recurso Ingress, faça o download de basic-ingress.yaml e execute:

    kubectl apply -f basic-ingress.yaml
    

Depois que você implanta esse manifesto, o Kubernetes cria um recurso Ingress no cluster. O controlador Ingress em execução no cluster é responsável por criar um balanceador de carga HTTP(S) para encaminhar todo o tráfego HTTP externo (na porta 80) ao Serviço NodePort web que você expôs.

Etapa 4: acessar o aplicativo

Para descobrir o endereço IP externo do balanceador de carga que processa o aplicativo, execute:

    kubectl get ingress basic-ingress
    
Resposta:
    NAME            HOSTS     ADDRESS         PORTS     AGE
    basic-ingress   *         203.0.113.12    80        2m
    

Aponte seu navegador para o endereço IP externo do aplicativo e veja uma resposta HTTP de texto simples como esta:

Hello, world!
    Version: 1.0.0
    Hostname: web-6498765b79-fq5q5

Acesse Balanceamento de carga no Console do Cloud e verifique os recursos de rede criados pelo controlador Ingress.

Etapa 5: configurar um endereço IP estático (opcional)

Quando você expõe um servidor da Web em um nome de domínio, precisa que o endereço IP externo de um aplicativo seja um IP estático (inalterado).

Por padrão, o GKE aloca endereços IP externos temporários para aplicativos HTTP expostos por meio de um Ingress. Endereços temporários estão sujeitos a alterações. Para um aplicativo da Web que você está planejando há bastante tempo, use um endereço IP externo estático.

Depois de configurar um IP estático para o recurso Ingress, a exclusão do Ingress não removerá o endereço IP estático associado a ele. Certifique-se de limpar os endereços IP estáticos configurados se você não planeja usá-los novamente.

Opção 1: converter endereços IP atuais temporários em estáticos

Se você já tem um Ingress implementado, é possível converter o endereço IP atual temporário do aplicativo em estático reservado sem alterar o endereço IP externo. Para isso, acesse a seção Endereços IP externos no Console do Cloud.

Opção 2: reservar um novo endereço IP estático

Reserve um endereço IP externo estático nomeado web-static-ip.

gcloud

    gcloud compute addresses create web-static-ip --global
    

Config Connector

Observação: esta etapa requer o Config Connector. Siga estas instruções para instalar o Config Connector no cluster.

apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: web-static-ip
    spec:
      location: global
Para implantar esse manifesto, faça o download dele para sua máquina como compute-address.yaml e execute:
kubectl apply -f compute-address.yaml

Agora configure o recurso Ingress atual para usar o endereço IP reservado. Substitua o conteúdo do manifesto basic-ingress.yaml pelo manifesto a seguir:

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: basic-ingress
      annotations:
        kubernetes.io/ingress.global-static-ip-name: "web-static-ip"
    spec:
      backend:
        serviceName: web
        servicePort: 8080
    

Essa alteração adiciona uma anotação ao Ingress para usar o recurso de IP estático chamado web-static-ip. Para aplicar essa modificação ao Ingress atual, execute o comando a seguir:

    kubectl apply -f basic-ingress.yaml
    

Execute kubectl get ingress basic-ingress e aguarde até que o endereço IP do seu aplicativo seja alterado para usar o endereço IP reservado do recurso web-static-ip.

A atualização do recurso Ingress atual, a reconfiguração do balanceador de carga e a propagação das regras de balanceamento de carga globalmente podem levar alguns minutos. Após a conclusão da operação, o GKE libera o endereço IP temporário já alocado ao aplicativo.

Etapa 6: processar vários aplicativos em um balanceador de carga (opcional)

Execute vários serviços em um único balanceador de carga e IP público configurando regras de encaminhamento no Ingress. Com a hospedagem de vários serviços no mesmo Ingress, você evita a criação de mais balanceadores de carga, que são recursos faturáveis, para cada Serviço exposto na Internet.

Crie outro Deployment de servidor da Web com a versão 2.0 do mesmo aplicativo da Web.

Faça o download do web-deployment-v2.yaml e aplique o recurso ao cluster:

    kubectl apply -f web-deployment-v2.yaml
    

Em seguida, exponha o Deployment de web2 internamente ao cluster em um Serviço NodePort chamado web2.

Faça o download do web-service-v2.yaml e aplique o recurso ao cluster:

    kubectl apply -f web-service-v2.yaml
    

O manifesto a seguir descreve um recurso de entrada que:

  • roteia as solicitações com o caminho começando com /v2/ para o serviço web2
  • encaminha todas as outras solicitações para o serviço web
    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: fanout-ingress
    spec:
      rules:
      - http:
          paths:
          - path: /*
            backend:
              serviceName: web
              servicePort: 8080
          - path: /v2/*
            backend:
              serviceName: web2
              servicePort: 8080
    

Para implantar esse manifesto, salve-o em um fanout-ingress.yaml e execute:

    kubectl create -f fanout-ingress.yaml
    

Quando o Ingress for implantado, execute kubectl get ingress fanout-ingress para descobrir o endereço IP público do cluster.

Em seguida, acesse o endereço IP para ver se os dois aplicativos podem ser acessados no mesmo balanceador de carga:

  • Acesse http://<IP_ADDRESS>/ e observe que a resposta contém Version: 1.0.0, já que a solicitação foi encaminhada para o Serviço web.
  • Acesse http://<IP_ADDRESS>/v2/ e observe que a resposta contém Version: 2.0.0, já que a solicitação foi encaminhada para o Serviço web2.

A única correspondência de padrão de caractere curinga permitida no campo path no Ingress do GKE é por meio do caractere *. Por exemplo, é possível ter regras com campos path como /* ou /foo/bar/*. Consulte a documentação de mapas de URL para ver as limitações de path.

Comentários

Por padrão, o Ingress executa uma verificação de integridade periódica. Para fazer isso, ele realiza uma solicitação GET no caminho / para determinar a integridade do aplicativo. A resposta esperada é HTTP 200. Se você quiser verificar um caminho diferente ou esperar um código de resposta distinto, use um caminho de verificação de integridade personalizado.

O Ingress é compatível com casos de uso mais avançados, como os abaixo:

  • Hospedagem virtual baseada em nome: use o Ingress para reaproveitar o balanceador de carga em vários nomes de domínio e subdomínios e para expor diversos Serviços em um único endereço IP e balanceador de carga. Confira os exemplos de fanout simples e hospedagem virtual baseada em nome (links em inglês) para saber como configurar o Ingress para essas tarefas.

  • Encerramento de HTTPS: é possível configurar o Ingress para encerrar o tráfego HTTPS usando o Cloud Load Balancer.

Quando um Ingress é excluído, os recursos associados são limpos automaticamente pelo controlador dele, com exceção dos endereços IP estáticos reservados.

Limpeza

Para evitar que os recursos usados neste tutorial sejam cobrados na conta do Google Cloud Platform:

  1. Exclua o Ingress: com essa opção, o endereço IP externo temporário e os recursos de balanceamento de carga associados ao aplicativo são desalocados:

    kubectl delete ingress basic-ingress

    Se você seguiu a "Etapa 6", exclua o Ingress executando:

    kubectl delete ingress fanout-ingress

  2. Exclua o endereço IP estático: execute apenas se tiver seguido a Etapa 5.

    • Se você seguiu a "Opção 1" na Etapa 5 para converter um endereço IP temporário atual em IP estático, acesse o Console do Cloud para excluir o IP estático.

    • Se você seguiu a "Opção 2" na Etapa 5, execute o comando abaixo para excluir o endereço IP estático:

      gcloud compute addresses delete web-static-ip --global
  3. Exclua o cluster: esse procedimento exclui os nós do Compute do cluster de contêiner e outros recursos, como os Deployments:

    gcloud container clusters delete loadbalancedcluster

A seguir