Entrada do GKE para balanceamento de carga HTTP(S)

Nesta página, fornecemos uma visão geral do funcionamento do Entrada no balanceamento de carga HTTP(S). O Google Kubernetes Engine (GKE) fornece um controlador de entrada gerenciado e integrado chamado Entrada do GKE. Ele implementa recursos do 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 de serviço, e cada um deles está associado a um conjunto de pods.

Ao criar um objeto Entrada, o controlador do Entrada do GKE gera um balanceador de carga HTTP(S) do Google Cloud e o configura de acordo com as informações no Entrada e nos serviços associados.

Para usar o Entrada, é preciso ativar o complemento de balanceamento de carga HTTP. Os clusters do GKE têm o balanceamento de carga HTTP ativado por padrão. Não o desative.

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. Um objeto Entrada define como o tráfego chega aos seus objetos de Serviço e como ele é roteado para seu aplicativo. Além disso, um 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
  • Suporte para vários certificados TLS. Um Entrada pode especificar o uso de vários certificados TLS para o encerramento da solicitação.

Para uma lista mais completa, consulte Recursos do Entrada.

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 endpoints da rede (NEGs).

Ao usar grupos de instâncias, os balanceadores de carga do Compute Engine enviam tráfego para IPs de VM como back-ends. Ao executar contêineres em VMs, eles compartilharão a mesma interface de host. Isso introduz algumas limitações:

  • Há dois saltos de balanceamento de carga: um do balanceador de carga para a VM NodePort e outro pelo roteamento do kube-proxy para o IP do pod (que pode residir em uma VM diferente).
  • Saltos extras aumentam a latência e tornam o caminho de tráfego mais complexo.
  • 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.
  • Eventos de ambiente, como perda de VM ou de pod, têm maior probabilidade de causar perda intermitente de tráfego devido ao salto de tráfego duplo.

Com os NEGs, o tráfego é balanceado pelo balanceador de carga diretamente para o IP do pod, em vez de cruzar o IP da VM e a rede kube-proxy. Além disso, os portões de prontidão do pod são implementados para determinar a integridade dos pods da perspectiva do balanceador de carga, e não apenas das sondagens de integridade no cluster do Kubernetes. Isso melhora a estabilidade geral do tráfego, fazendo com que a infraestrutura do balanceador de carga reconheça eventos de ciclo de vida, como a inicialização do pod, a perda do pod ou a perda da VM. Esses recursos resolvem as limitações acima e resultam em uma rede estável e com melhor desempenho.

O balanceamento de carga nativo de contêiner é ativado por padrão nos Serviços quando todas as condições a seguir são verdadeiras:

  • Para Serviços criados nos clusters do GKE 1.17.6-gke.7 e superiores
  • Como usar clusters nativos de VPC
  • Não usar uma VPC compartilhada
  • Política de rede do GKE não está em uso

Nessas condições, os Serviços serão anotados automaticamente com cloud.google.com/neg: '{"ingress": true}', indicando que um NEG precisa ser criado para espelhar os IPs do pod no Serviço. O NEG é o que permite que os balanceadores de carga do Compute Engine se comuniquem diretamente com os pods. Os Serviços existentes criados antes do GKE 1.17.6-gke.7 não serão anotados automaticamente pelo controlador do Serviço.

Para clusters do GKE 1.17.6-gke.7 e superiores em que a anotação NEG é automática, será possível desativar os NEGs e forçar o balanceador de carga do Compute Engine a usar um grupo de instâncias como back-ends, se necessário. Isso pode ser feito anotando explicitamente os Serviços com cloud.google.com/neg: '{"ingress": false}'.

Para clusters em que os NEGs não são o padrão, ainda é altamente recomendado usar o balanceamento de carga nativo de contêiner, mas ele precisa ser ativado explicitamente em cada Serviço. A anotação deve ser aplicada aos Serviços da seguinte maneira:

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

Vários serviços de back-end

Cada balanceador de carga HTTP(S) externo ou interno usa um mapa de URLs único que se refere a um ou mais serviços de back-end. Um serviço de back-end corresponde a cada Serviço referenciado pelo Entrada.

Por exemplo, você pode configurar o balanceador de carga para rotear 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 de serviço, e cada um deles associado a um conjunto de pods.

Veja um manifesto para uma Entrada chamado my-ingress:

apiVersion: networking.k8s.io/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 o Entrada, o controlador de entrada do GKE cria e configura um balanceador de carga HTTP(S) externo ou interno de acordo com as informações no 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, essa é 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 * 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, use type: NodePort a menos que esteja usando o balanceamento de carga nativo do contêiner. Se estiver usando o balanceamento de carga nativo de contêiner, use o type: ClusterIP.

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: networking.k8s.io/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:

  • Uma regra de encaminhamento e um endereço IP.
  • Regras de firewall do Compute Engine que permitem tráfego para verificações de integridade do balanceador de carga e tráfego de aplicativos dos proxies do Google Front End ou Envoy.
  • Um proxy HTTP de destino e um proxy HTTPS de destino, se você tiver configurado o TLS.
  • Um mapa de URLs que, com uma única regra de host, refere-se a uma única correspondência de caminho. A correspondência de caminho tem duas regras de caminho, uma para /* e outra para /discounted. Cada regra de caminho mapeia um serviço de back-end exclusivo.
  • 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 do Entrada no 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 a um balanceador de carga HTTP(S):

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 são compatíveis com domínios curinga.
Certificados autogerenciados compartilhados com o Google Cloud
É possível provisionar seu próprio certificado SSL e criar um recurso de certificado em seu 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

Quando você expõe um ou mais Serviços por meio de um Entrada usando o controlador padrão, o GKE cria um balanceador de carga HTTP(S) externo ou interno do Google Cloud. Esses dois balanceadores de carga são compatíveis com vários serviços de back-end em um único mapa de URLs. Cada um dos serviços de back-end corresponde a um serviço do Kubernetes, e cada serviço de back-end precisa fazer referência a uma verificação de integridade do Google Cloud. Essa verificação de integridade é diferente de uma sondagem de atividade ou prontidão do Kubernetes porque a verificação de integridade é implementada fora do cluster.

O GKE usa o procedimento a seguir para criar uma verificação de integridade para cada serviço de back-end correspondente a um serviço do Kubernetes:

  • Se o serviço referir-se a uma CRD BackendConfig com informações de healthCheck, o GKE usará isso para criar a verificação de integridade. O controlador de entrada do Anthos e o controlador de entrada do GKE são compatíveis com esse tipo de criação de verificações de integridade.

  • Se o Serviço não referenciar um CRD BackendConfig:

    • O GKE poderá inferir alguns ou todos os parâmetros de uma verificação de integridade. Para isso, os pods de exibição precisam usar um modelo com um contêiner em que a sondagem de prontidão tenha atributos que possam ser interpretados como parâmetros de verificação de integridade. Consulte Parâmetros de uma sondagem de prontidão para ver detalhes de implementação e Parâmetros padrão e inferidos para ver uma lista de atributos que podem ser usados para criar parâmetros de verificações de integridade. Somente o controlador de entrada do GKE é compatível com a inferência de parâmetros de uma sondagem de prontidão.

    • Se o modelo dos pods de exibição do Serviço não tiver um contêiner com uma sondagem de prontidão que tenha atributos que possam ser interpretados como parâmetros de verificação de integridade, os valores padrão serão usados para criar a verificação de integridade. O controlador de entrada do Anthos e o controlador de entrada do GKE podem criar uma verificação de integridade usando apenas os valores padrão.

Parâmetros padrão e inferidos

Os parâmetros a seguir são usados quando você não especificar os parâmetros da verificação de integridade do Serviço correspondente com um CRD BackendConfig.

Parâmetro de verificação de integridade Valor padrão Valor inferido da sondagem de prontidão
Protocolo HTTP se estiver presente no spec do pod de exibição:
containers[].readinessProbe.httpGet.scheme
Caminho da solicitação / se estiver presente no pod de exibição spec:
containers[].readinessProbe.httpGet.path
Cabeçalho do host da solicitação Host: backend-ip-address se estiver presente no pod de exibição spec:
containers[].readinessProbe.httpGet.httpHeaders
Resposta esperada HTTP 200 (OK) HTTP 200 (OK)
não pode ser alterado
Intervalo de verificação
  • para NEGs zonais: 15 segundos
  • para grupos de instâncias: 60 segundos
se estiver presente no pod de exibição spec:
  • para NEGs zonais:
    containers[].readinessProbe.periodSeconds
  • para grupos de instâncias:
    containers[].readinessProbe.periodSeconds + 60 seconds
Tempo limite da verificação 5 segundos se estiver presente no pod de exibição spec:
containers[].readinessProbe.timeoutSeconds
Limite íntegro 1 1
não pode ser alterado
Limite não íntegro
  • para NEGs zonais: 2
  • para grupos de instâncias: 10
o mesmo que o padrão:
  • para NEGs zonais: 2
  • para grupos de instâncias: 10
Porta
especificada por número
  • para NEGs zonais: o port do Serviço
  • para grupos de instâncias: o nodePort do Serviço
Se o backend.servicePort do objeto Entrada fizer referência ao port de um Serviço, essa porta será usada, desde que também seja definido o seguinte:
  • A sondagem de prontidão do pod de exibição precisa especificar uma porta:
    spec.containers[].readinessProbe.httpGet.port
  • O targetPort do Serviço faz referência ao containers[].spec.ports.containerPort do pod de exibição
Endereço IP de destino
  • para NEGs zonais: o endereço IP do pod
  • para grupos de instâncias: o endereço IP do nó
o mesmo que o padrão:
  • para NEGs zonais: o endereço IP do pod
  • para grupos de instâncias: o endereço IP do nó

Parâmetros de uma sondagem de prontidão

Quando o GKE cria a verificação de integridade para o serviço de back-end do Serviço, ele pode copiar determinados parâmetros da sondagem de prontidão de um contêiner usada pelos pods de exibição desse Serviço. Essa opção é compatível somente com o controlador de entrada do GKE.

Os atributos de sondagem de prontidão compatíveis que podem ser interpretados como parâmetros de verificação de integridade são listados com os valores padrão em Parâmetros padrão e inferidos. Os valores padrão serão usados para quaisquer atributos não especificados na sondagem de prontidão ou se você não especificar nenhuma sondagem.

Se os pods de veiculação do Serviço contiverem vários contêineres ou se você estiver usando o controlador de entrada do Anthos, use um CRD BackendConfig para definir parâmetros de verificação de integridade. Para mais informações, consulte Quando usar um CRD BackendConfig.

Quando usar os CRDs BackendConfig

Em vez de depender de parâmetros das sondagens de prontidão do pod, defina explicitamente os parâmetros de verificação de integridade em um serviço de back-end. Para isso, crie um CRD BackendConfig para o Serviço nestas situações:

  • Se você estiver usando o Anthos: o controlador de entrada do Anthos não é compatível com a obtenção de parâmetros de verificação de integridade a partir das sondagens de prontidão de pods de exibição. Só é possível criar verificações de integridade por meio e parâmetros implícitos ou definidos em um CRD BackendConfig.

  • Se os pods de exibição tiverem vários contêineres com sondagens de prontidão exclusivas: se os pods de exibição de um Serviço tiverem mais de um contêiner, e cada contêiner tiver configurações de sondagem de prontidão diferentes, defina a verificação de integridade do serviço de back-end correspondente. Para isso, faça referência a um CRD BackendConfig no Serviço correspondente. O GKE não permite que você escolha uma sondagem de prontidão específica de onde inferirá parâmetros de verificação de integridade caso várias sondagens de prontidão estejam presentes em um pod de exibição.

  • Se você precisar de controle sobre a porta usada para as verificações de integridade do balanceador de carga: o GKE só usará o containers[].readinessProbe.httpGet.port da sondagem de prontidão para a verificação de integridade do serviço de back-end quando essa porta corresponder à porta de serviço no Serviço mencionado no Entrada spec.rules[].http.paths[].backend.servicePort.

Parâmetros de um CRD BackendConfig

É possível especificar os parâmetros da verificação de integridade do serviço de back-end usando o parâmetro healthCheck de um CRD BackendConfig referenciado pelo Serviço correspondente. Isso proporciona mais flexibilidade e controle sobre as verificações de integridade de um balanceador de carga HTTP(S) externo ou interno do Google Cloud criado por um Entrada. Consulte Recursos do Entrada para ver a compatibilidade da versão do GKE.

Este exemplo e CRD BackendConfig define o protocolo de verificação de integridade (tipo), um caminho de solicitação, uma porta e um intervalo de verificação no atributo spec.healthCheck:

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: http-hc-config
spec:
  healthCheck:
    checkIntervalSec: 5
    port: 15020
    type: https
    requestPath: /healthz

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. Existe uma forte relação entre os dois, mas o relacionamento 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 do GKE atue de forma anormal. Para mais informações, veja este problema (em inglês) no GitHub.

  • Cotas para mapas de URL são aplicáveis.

  • 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.

  • Um balanceador de carga HTTP(S) externo 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 exposto por meio de um Serviço do GKE do tipo LoadBalancer e encerre o TLS nos back-ends localizados em regiões adequadas às suas necessidades.

  • Não há suporte para combinar vários recursos do Entrada em um único balanceador de carga do Google Cloud.

A seguir