Entrada do GKE para balanceamento de carga HTTP(S)

Nesta página, fornecemos uma visão geral do funcionamento da entrada para balanceamento de carga HTTP(S). O Google Kubernetes Engine (GKE) fornece um controlador de entrada gerenciado e integrado chamado GKE Ingress. Ele implementa recursos de entrada como balanceadores de carga do Google Cloud para cargas de trabalho HTTP(S) no GKE.

Visão geral

No GKE, um objeto Entrada define regras para rotear tráfego HTTP(S) para aplicativos executados em um cluster. Um objeto "Entrada" está associado a um ou mais objetos Serviço, e cada um deles está associado a um conjunto de pods.

Ao criar um objeto "Entrada", o controlador da entrada do GKE (em inglês) gera um balanceador de carga HTTP(S) do Google Cloud e o configura de acordo com as informações na entrada e nos respectivos serviços associados.

Entrada para tráfego externo e interno

Os recursos da Entrada do GKE vêm em dois tipos:

Recursos do balanceamento de carga HTTP(S)

O balanceamento de carga HTTP(S), configurado pela Entrada, inclui os seguintes recursos:

Configuração flexível para serviços
Uma Entrada define como o tráfego chega aos seus serviços e como ele é roteado para seu aplicativo. Além disso, uma Entrada pode fornecer um único endereço IP para vários Serviços no cluster.
Integração com serviços de rede do Google Cloud
Uma entrada pode configurar recursos do Google Cloud, como certificados SSL gerenciados pelo Google (Beta), Google Cloud Armor, Cloud CDN e Cloud Identity-Aware Proxy.
Suporte para vários certificados TLS
Uma Entrada pode especificar o uso de vários certificados TLS para o encerramento da solicitação.

Balanceamento de carga nativo de contêiner

O balanceamento de carga nativo do contêiner é a prática do balanceamento de carga diretamente para os endpoints do pod no GKE usando grupos de endpoint da rede (NEGs).

Antes dos NEGs, os balanceadores de carga do Compute Engine enviavam tráfego para grupos de instâncias usando IPs de nós como back-ends. Esse método tem várias limitações:

  • Incorre dois saltos de balanceamento de carga.
  • Adiciona latência.
  • O balanceador de carga do Compute Engine não tem visibilidade direta para os pods, resultando em um equilíbrio de tráfego abaixo do ideal.

Com NEGs, o tráfego é balanceado por carga da entrada do proxy diretamente para o IP do pod em vez de atravessar o IP do nó ou a rede kube-proxy. Além disso, os portfólios de prontidão do conjunto são implementados para determinar a integridade dos pods a partir da perspectiva do balanceador de carga e não apenas das verificações de prontidão e atividade do Kubernetes. Isso garante que o tráfego não seja interrompido durante eventos do ciclo de vida, como a inicialização do pod, a perda do pod ou a perda do nó.

Potencializar o balanceamento de carga nativo do contêiner implantando a Entrada com NEGs é altamente recomendado e pode ser usado sempre que possível. Ele não é o modo padrão dos Serviços e precisa ser aplicado explicitamente com a anotação cloud.google.com/neg aos Serviços que são back-ends para uma regra de Entrada:

kind: Service
    ...
      annotations:
        cloud.google.com/neg: '{"ingress": true}'
    ...
    

Vários serviços de back-end

Um balanceador de carga HTTP(S) fornece um endereço IP estável que pode ser usado para rotear solicitações para diversos serviços de back-end.

Por exemplo, é possível configurar o balanceador de carga para encaminhar solicitações para diferentes serviços de back-end dependendo do caminho do URL. As solicitações enviadas para your-store.example podem ser encaminhadas para um serviço de back-end que exibe itens com preço integral. Já as enviadas para your-store.example/discounted podem ser encaminhadas para um serviço de back-end que exibe itens com desconto.

Também é possível configurar o balanceador de carga para encaminhar solicitações de acordo com o nome do host. As solicitações enviadas para your-store.example poderiam ir para um serviço de back-end e as enviadas para your-experimental-store.example para outro.

Para criar e configurar um balanceador de carga HTTP(S), crie um objeto Entrada do Kubernetes em um cluster do GKE. O objeto Entrada precisa estar associado a um ou mais objetos Serviço, e cada um deles associado a um conjunto de Pods.

Veja um manifesto para uma Entrada chamado my-ingress:

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: my-ingress
    spec:
      rules:
      - http:
          paths:
          - path: /*
            backend:
              serviceName: my-products
              servicePort: 60000
          - path: /discounted
            backend:
              serviceName: my-discounted-products
              servicePort: 80
    

Quando você cria a Entrada, o controlador de entrada do GKE cria e configura um balanceador de carga HTTP(S) de acordo com as informações na Entrada e nos serviços associados. Além disso, o balanceador de carga recebe um endereço IP estável que pode ser associado a um nome de domínio.

No exemplo anterior, imagine que você associou o endereço IP do balanceador de carga ao nome de domínio your-store.example. Quando um cliente envia uma solicitação para your-store.example, ela é roteada para um serviço do Kubernetes chamado my-products na porta 60000. E quando um cliente envia uma solicitação para your-store.example/discounted, ela é roteada para um serviço do Kubernetes chamado my-discounted-products na porta 80.

O único caractere curinga aceito no campo path de uma entrada é *. O caractere * precisa vir depois de uma barra (/) e ser o último caractere no padrão. Por exemplo, /*, /foo/* e /foo/bar/* são padrões válidos, ao contrário de *, /foo/bar*, e /foo/*/bar.

Um padrão mais específico tem precedência sobre um menos específico. Se você tiver os padrões /foo/* e /foo/bar/*, /foo/bar/bat será usado na correspondência com /foo/bar/*.

Para mais informações sobre limitações de caminho e correspondência de padrões, consulte a documentação dos mapas de URL.

O manifesto do serviço my-products ficaria da seguinte maneira:

    apiVersion: v1
    kind: Service
    metadata:
      name: my-products
    spec:
      type: NodePort
      selector:
        app: products
        department: sales
      ports:
      - protocol: TCP
        port: 60000
        targetPort: 50000
    

No manifesto do serviço, observe que type é NodePort. Esse é o tipo necessário para uma Entrada usada para configurar um balanceador de carga HTTP(S).

No manifesto do serviço, o campo selector diz que qualquer pod que tenha os rótulos app: products e department: sales é membro deste serviço.

Quando uma solicitação chega ao serviço na porta 60000, ela é roteada para um dos pods de membro na porta TCP 50000.

Cada pod de membro precisa ter um contêiner escutando a porta TCP 50000.

O manifesto do serviço my-discounted-products ficaria da seguinte maneira:

    apiVersion: v1
    kind: Service
    metadata:
      name: my-discounted-products
    spec:
      type: NodePort
      selector:
        app: discounted-products
        department: sales
      ports:
      - protocol: TCP
        port: 80
        targetPort: 8080
    

No manifesto do serviço, o campo selector diz que qualquer pod que tenha os rótulos app: discounted-products e department: sales é membro deste serviço.

Quando uma solicitação chega ao serviço na porta 80, ela é roteada para um dos pods de membro na porta TCP 8080.

Todo pod membro precisa ter um contêiner escutando a porta TCP 8080.

Back-end padrão

Especifique um back-end padrão fornecendo um campo backend no manifesto da entrada. As solicitações que não corresponderem aos caminhos no campo rules serão enviadas ao serviço e à porta especificada no campo backend. Por exemplo, na entrada a seguir, todas as solicitações que não correspondem / ou /discounted foram enviadas para um serviço chamado my-products na porta 60001.

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: my-ingress
    spec:
      backend:
        serviceName: my-products
        servicePort: 60001
      rules:
      - http:
          paths:
          - path: /
            backend:
              serviceName: my-products
              servicePort: 60000
          - path: /discounted
            backend:
              serviceName: my-discounted-products
              servicePort: 80
    

Se você não especificar um back-end padrão, o GKE fornecerá um back-end padrão que retorna 404.

Entrada para os mapeamentos de recursos do Compute Engine

O controlador de entrada do GKE implanta e gerencia os recursos do balanceador de carga do Compute Engine com base nos recursos da Entrada implantados no cluster. O mapeamento dos recursos do Compute Engine depende da estrutura do recurso Entrada. O conhecimento desses mapeamentos de recursos ajuda no planejamento, no design e na solução de problemas.

O manifesto my-ingress mostrado na seção Vários serviços de back-end especifica um recurso externo da Entrada com duas correspondências de caminho do URL que referenciam dois serviços diferentes do Kubernetes. Veja alguns dos recursos do Compute Engine criados em nome de my-ingress:

  • Um VIP público correspondente a um forwardingRule.
  • Regras de firewall do Compute Engine que permitem o tráfego para verificações de integridade e tráfego de aplicativos.
  • Um proxy HTTP de destino. Se o TLS foi configurado, isso resultaria em um proxy HTTPS adicional.
  • Um mapa de URL que tem hostRule, pathMatchers únicos para /* e /descontado. Isso aponta para backendServices correspondentes.
  • NEGs que contêm uma lista de IPs de pod de cada Serviço como endpoints. Eles são criados como resultado dos serviços my-discounted-products e my-products. O diagrama a seguir fornece uma visão geral dos mapeamentos de recursos da Entrada para o Compute Engine.

Entrada no diagrama de mapeamento de recursos do Compute Engine

Opções para fornecer certificados SSL

Existem três maneiras de fornecer certificados SSL para um balanceador de carga HTTPS:

Certificados gerenciados pelo Google
Os certificados SSL gerenciados pelo Google são provisionados, implantados, renovados e gerenciados para seus domínios. Os certificados gerenciados não oferecem suporte a domínios com caractere curinga ou a vários nomes alternativos do assunto (SANs, na sigla em inglês).
Certificados autogerenciados compartilhados com o Google Cloud
É possível provisionar seu próprio certificado SSL e criar um recurso de certificado no projeto do Google Cloud. Em seguida, liste o recurso de certificado em uma anotação em uma Entrada para criar um balanceador de carga HTTP(S) que use o certificado. Consulte as instruções para certificados pré-compartilhados para mais informações.
Certificados autogerenciados como recursos de secret
É possível provisionar seu próprio certificado SSL e criar um Secret para mantê-lo. Em seguida, consulte o secret em uma especificação da Entrada para criar um balanceador de carga HTTP(S) que use o certificado. Para mais informações, consulte as instruções para usar certificados em secrets.

Verificações de integridade

Um serviço exposto por meio de uma Entrada precisa responder a verificações de integridade do balanceador de carga. Qualquer contêiner que seja o destino final do tráfego com carga balanceada precisa seguir um destes procedimentos para indicar que está íntegro:

  • Veicular uma resposta com o status HTTP 200 para solicitações GET no caminho /.

  • Configurar uma sondagem de preparo do HTTP. Exibir uma resposta com o status HTTP 200 para solicitações GET no path especificado pela sondagem de preparo. O serviço exposto por meio de uma entrada precisa apontar para a mesma porta de contêiner em que a sondagem está ativada.

    Por exemplo, imagine que um contêiner especifica a seguinte sondagem de preparo:

    ...
        readinessProbe:
          httpGet:
            path: /healthy
        

    Em seguida, se o gerenciador do caminho /healthy do contêiner retornar um status HTTP 200, o balanceador de carga considerará o contêiner como ativo e íntegro.

Como usar vários certificados TLS

Suponha que você queira que um balanceador de carga HTTP(S) atenda ao conteúdo de dois nomes de host: your-store.example e your-experimental-store.example. Além disso, você quer que o balanceador de carga use um certificado para your-store.example e outro para your-experimental-store.example.

É possível especificar vários certificados em um manifesto de entrada. O balanceador de carga escolherá um certificado se o nome comum (CN, na sigla em inglês) no certificado corresponder ao nome do host usado na solicitação. Para informações detalhadas sobre como configurar vários certificados, consulte Como usar vários certificados SSL no balanceamento de carga HTTP(S) com a Entrada.

Serviço do Kubernetes em comparação com o serviço de back-end do Google Cloud

Um serviço (em inglês) do Kubernetes e um serviço de back-end do Google Cloud são coisas diferentes. Há uma forte relação entre os dois, mas ela não é necessariamente de um para um. O controlador de entrada do GKE cria um serviço de back-end do Google Cloud para cada par (serviceName, servicePort) em um manifesto de entrada. Dessa forma, é possível que um objeto de serviço do Kubernetes esteja relacionado a vários serviços de back-end do Google Cloud.

Limitações

  • O tamanho total do namespace e o nome de uma entrada não pode exceder 40 caracteres. O não cumprimento desta diretriz pode fazer com que o controlador de entrada GKE atue de forma anormal. Para mais informações, veja este problema (em inglês) no GitHub.

  • O número máximo de regras para um mapa de URL é 50. Isso significa que é possível especificar no máximo 50 regras em uma Entrada.

  • Se você não estiver usando NEGs com o controlador de entrada do GKE, os clusters do GKE terão um limite de 1.000 nós. Quando os serviços são implantados com NEGs, não há limite de nós do GKE. Todos os Serviços não NEG expostos por meio da Entrada não funcionam corretamente em clusters com mais de 1.000 nós.

  • Para que o controlador de entrada do GKE use os readinessProbes como verificação de integridade, os pods de uma entrada precisam existir no momento da criação dela. Se as réplicas forem dimensionadas para 0, a verificação de integridade padrão será aplicada. Para mais informações, veja esses comentários sobre o problema.

  • As alterações no readinessProbe de um Pod não afetam a entrada após a criação.

  • O balanceador de carga HTTPS encerra o TLS em locais que são distribuídos globalmente, de modo a minimizar a latência entre os clientes e o balanceador de carga. Se você precisar de controle geográfico sobre o local em que o TLS é encerrado, use um controlador de entrada personalizado (em inglês) e um balanceador de carga de rede do GCP e encerre o TLS em back-ends localizados em regiões apropriadas para suas necessidades.

A seguir