Como configurar o balanceamento de carga HTTP(S) com a entrada

Neste tutorial, mostramos como executar um aplicativo da Web por trás de um balanceador de carga HTTP(S) externo configurando o recurso de entrada.

Segundo plano

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 conexões HTTP ou respostas e solicitações HTTP individuais. Outra característica importante é que as solicitações não são encaminhadas por proxy ao destino.

  • Ao especificar kind:Ingress no manifesto do recurso, você instrui o GKE a criar um recurso de entrada. Ao incluir anotações e oferecer suporte a cargas de trabalho e Serviços, você consegue criar um controlador de Entrada 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, onde cada serviço corresponde a um Serviço do GKE do tipo NodePort, conforme mencionado no Ingress. Os back-ends para cada serviço de back-end 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 da Entrada. 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 do GKE correspondente.

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

Antes de começar

Siga estas etapas para ativar a API do 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 o faturamento está ativado para seu projeto na nuvem. Saiba como confirmar se o faturamento está ativado para o 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-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 uma implantação usando a imagem de amostra do contêiner de aplicativo da Web para detectar em um servidor HTTP na porta 8080:

  1. Faça o download do manifesto web-deployment.yaml.
  2. Aplique o recurso ao cluster:

    kubectl apply -f web-deployment.yaml
    

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

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

  1. Faça o download do manifesto web-service.yaml.
  2. 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.

  3. Verifique se o serviço foi criado e se uma porta de nó foi alocada:

    kubectl get service web
    
    Saída:
    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, note que 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, criar esse 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 de entrada.

Etapa 3: criar um recurso de entrada

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

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

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

O arquivo de configuração a seguir define um recurso de entrada que direciona o tráfego para seu serviço web:

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

Para implantar esse recurso de entrada:

  1. Faça o download do manifesto basic-ingress.yaml.
  2. Aplique o recurso ao cluster:

    kubectl apply -f basic-ingress.yaml
    

Depois que você implanta esse manifesto, o Kubernetes cria um recurso Ingress no cluster. O controlador de entrada do GKE cria e configura um balanceador de carga HTTP(S) de acordo com as informações na entrada, roteando todo o tráfego HTTP externo (na porta 80) para o 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 disponibiliza o aplicativo, execute:

kubectl get ingress basic-ingress
Saída:
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 da entrada.

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 que não seja alterado.

Por padrão, o GKE aloca endereços IP externos temporários de aplicativos HTTP expostos por meio de uma entrada. 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.

Note que, depois de configurar um IP estático para o recurso do Ingress, a exclusão do Ingress não excluirá 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 uma entrada implementada, é possível converter o endereço IP atual temporário do aplicativo para estático reservado sem alterar o endereço IP externo. Basta acessar a seção Endereços IP externos no Console do Cloud.

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

  1. 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 as instruções para instalar o Config Connector no seu 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

  2. Configure o recurso de entrada existente para usar o endereço IP reservado. Substitua o manifesto basic-ingress.yaml usado anteriormente pelo seguinte manifesto:

    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 na entrada para usar o recurso de IP estático chamado web-static-ip.

  3. Aplique esta modificação à entrada existente:

    kubectl apply -f basic-ingress.yaml
    
  4. Verifique o endereço IP externo:

    kubectl get ingress basic-ingress
    

    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 de entrada atual, a reconfiguração do balanceador de carga e a propagação das regras de balanceamento de carga em todo o mundo podem demorar alguns minutos. Após a conclusão da operação, o GKE libera o endereço IP temporário anteriormente 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 na entrada. Com a hospedagem de vários serviços na mesma entrada, você evita a criação de mais balanceadores de carga, que são recursos faturáveis, para cada serviço publicado na Internet.

Crie outra implantação 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 a Implantação do 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 a entrada for implantada, 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 é 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 é encaminhada para o serviço web2)

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

Etapa 7: (opcional) monitorar a disponibilidade e a latência do serviço

As verificações de tempo de atividade do Google Cloud realizam o monitoramento de aplicativos do Blackbox do ponto de vista do usuário, determinando a latência e a disponibilidade de vários IPs externos para o endereço IP do balanceador de carga. Em comparação, as verificações de integridade do Google Cloud realizam uma verificação interna em relação aos IPs do pod, determinando a disponibilidade no nível da instância. Eles são complementares e fornecem uma visão holística da integridade do aplicativo.

É possível criar uma verificação de tempo de atividade usando o Console do Google Cloud, a API Cloud Monitoring ou as bibliotecas de cliente do Cloud Monitoring. Para mais informações, consulte Como gerenciar verificações de tempo de atividade. Se você quiser criar uma verificação de tempo de atividade usando o Console do Google Cloud, faça o seguinte:

  1. No Console do Google Cloud, selecione Monitoramento ou clique no botão a seguir:

    Acessar o Monitoring

  2. No painel de navegação Monitoramento, selecione Verificações de tempo de atividade e clique em Criar verificação de tempo de atividade.

  3. Para o destino da verificação de tempo de atividade, defina os seguintes campos:

    • Selecione o tipo de protocolo como TCP.
    • Em Tipo de recurso, selecione URL.
    • Em Nome do host, insira o endereço IP do balanceador de carga.
    • Digite o número da porta do balanceador de carga no campo Porta.

    Para ter acesso à documentação completa de todos os campos em uma verificação de tempo de atividade, consulte Como criar uma verificação de tempo de atividade.

Para monitorar uma verificação de tempo de atividade, você pode criar uma política de alertas ou ver o painel de verificação de tempo de atividade. Uma política de alertas pode notificar você por e-mail ou por meio de um canal diferente se a verificação de tempo de atividade falhar. Para informações gerais sobre políticas de alertas, consulte Introdução a alertas.

Comentários

Por padrão, a entrada executa uma verificação de integridade periódica. Para fazer isso, 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 diferente, poderá usar um caminho de verificação de integridade personalizado.

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

  • Hospedagem virtual baseada em nome: use a entrada para reaproveitar o balanceador de carga em vários nomes de domínio, subdomínios e para expor vários serviços em um único endereço IP e balanceador de carga. Confira os exemplos de fanout simples e hospedagem virtual baseada em nome para saber como configurar a entrada para essas tarefas.

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

Quando uma entrada é excluída, os recursos associados são limpos automaticamente pelo controlador dela, com exceção dos endereços IP estáticos reservados.

Como limpar

Para evitar cobranças dos recursos usados neste tutorial na conta do Google Cloud Platform:

  1. Excluir as regras de encaminhamento criadas manualmente e os proxies de destino que fazem referência à entrada:

    Um proxy de destino pendente que se referir a um mapa de URL gerenciado do controlador da entrada fará com que a exclusão da entrada falhe nas versões 1.15.4-gke.22 e posteriores do GKE. O recurso da entrada pode ser inspecionado para encontrar um evento com uma mensagem de erro semelhante a esta:

     Error during GC: error running load balancer garbage collection routine: googleapi: Error 400: The url_map resource 'projects/project-id/global/urlMaps/k8s2-um-tlw9rhgp-default-my-ingress-9ifnni82' is already being used by 'projects/project-id/global/targetHttpsProxies/k8s2-um-tlw9rhgp-default-my82-target-proxy', resourceInUseByAnotherResource
     

    No exemplo da mensagem de erro acima, k8s2-um-tlw9rhgp-default-my82-target-proxy é um proxy https de destino criado manualmente que ainda faz referência ao mapa de URL k8s2-um-tlw9rhgp-default-my-ingress-9ifnni82 que foi criado e gerenciado pelo controlador de entrada.

    Portanto, esses recursos de front-end criados manualmente (regra de encaminhamento e proxy de destino) precisam ser excluídos antes de prosseguir com a exclusão da entrada.

  2. Exclua a entrada: 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 a entrada. Basta executar:

    kubectl delete ingress fanout-ingress

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

    • Se você tiver seguido 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ê tiver seguido "Opção 2" na Etapa 5, execute o comando a seguir para excluir o endereço IP estático:

      gcloud compute addresses delete web-static-ip --global
  4. Exclua o cluster: assim são excluídos os nós do Compute do cluster de contêiner e outros recursos, como as implantações:

    gcloud container clusters delete loadbalancedcluster

A seguir