Balanceamento de carga de HTTP(s) com o Ingress

No Google Kubernetes Engine, um objeto Entrada define regras para rotear o tráfego HTTP(S) externo para aplicativos em execução no cluster. Um objeto Entrada está associado a um ou mais objetos de serviço, e cada um deles associado a um conjunto de pods.

Quando você cria um objeto Ingress, o controlador de entrada do GKE (em inglês) gera um balanceador de carga HTTP(S) do Google Cloud Platform e o configura de acordo com as informações no Ingress e nos respectivos serviços associados.

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 GCP
Um Ingress pode configurar recursos do GCP, como certificados SSL gerenciados pelo Google (Beta), o Cloud Armor, o Cloud CDN e o 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.

Para saber mais sobre esses recursos, consulte os Conceitos de balanceamento de carga HTTP(S).

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 GCP
É possível provisionar seu próprio certificado SSL e criar um recurso de certificado em seu projeto do GCP. 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.

Limitações

  • O tamanho total do namespace e o nome de um Ingress 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, consulte este problema.

  • 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ê usar o controlador de entrada do GKE, seu cluster poderá ter no máximo 1000 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 o Ingress 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 onde 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 backends localizados em regiões apropriadas para suas necessidades.

Vários serviços de back-end

Um balanceador de carga HTTP(S) fornece um endereço IP estável 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 de serviço, e cada um deles associado a um conjunto de pods.

Veja aqui o manifesto de uma Entrada.

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 é encaminhada para um serviço do Kubernetes chamado my-products na porta 60000. Quando um cliente envia uma solicitação para "your-store.example/discounted", ela é encaminhada 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, mas *,/foo/bar* e /foo/*/bar não são.

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 seria assim:

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 o type é NodePort. Esse é o tipo necessário para uma Entrada usada para configurar um balanceador de carga HTTP(S).

O campo selector no manifesto de serviço informa que qualquer pod que tenha os rótulos app: products e department: sales é um membro desse 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.

Observe que cada pod de membro precisa ter um contêiner escutando a porta TCP 50000.

O manifesto do serviço my-discounted-products seria assim:

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

O campo selector no manifesto de serviço informa que qualquer pod que tenha os rótulos app: discounted-products e department: sales é um membro desse 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.

Observe que cada pod de 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 de 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, as solicitações que não corresponderem a / ou /discounted serão 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.

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.

Service do Kubernetes em comparação com o serviço de back-end do GCP

Um Service (em inglês) do Kubernetes e um serviço de back-end do GCP 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 GCP para cada par de (serviceName, servicePort) em um manifesto da Entrada. Portanto, é possível que um objeto do serviço do Kubernetes esteja relacionado a vários serviços de back-end do GCP.

Suporte para recursos do GCP

Use um BackendConfig para configurar um balanceador de carga HTTP(S) e usar recursos como o Google Cloud Armor, o Cloud CDN, e o Cloud IAP.

O BackendConfig é um recurso personalizado que contém informações de configuração dos recursos do GCP.

Os manifestos da Entrada se referem a um serviço, e o manifesto do serviço se refere a um BackendConfig com uma anotação beta.cloud.google.com/backend-config.

...
kind: Ingress
...
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: my-service
          servicePort: 80
...

kind: Service
metadata:
  name: my-service
  ...
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"80":"my-backend-config"}}'
spec:
  type: NodePort
  ...
 

Suporte para WebSocket

O protocolo WebSocket funciona idealmente com o balanceamento de carga HTTP(S). Nenhuma configuração é necessária.

Se você pretende usar o protocolo WebSocket, use um valor de tempo limite maior que o padrão de 30 segundos. Para definir o valor de tempo limite para um serviço de back-end configurado por meio da Entrada, crie um objeto BackendConfig e use a anotação beta.cloud.google.com/backend-config no manifesto do serviço.

Para mais informações, consulte Como configurar um serviço de back-end por meio da Entrada.

Endereços IP estáticos para balanceadores de carga HTTP(S)

Ao criar um objeto Entrada, você recebe um endereço IP externo estável que os clientes podem usar para acessar seus serviços e, por sua vez, os contêineres em execução. O endereço IP é estável porque ele dura por toda a vida útil do objeto Entrada. Se você excluir a Entrada e criar uma nova no mesmo arquivo de manifesto, pode ser que não receba o mesmo endereço IP externo.

Caso queira um endereço IP permanente que se mantenha o mesmo depois de excluir a Entrada e criar uma nova, reserve um endereço IP externo estático global. Em seguida, no manifesto da Entrada, inclua uma anotação que forneça o nome do endereço IP estático reservado.

Por exemplo, suponha que você tenha reservado um endereço IP externo estático global chamado my-static-address. No manifesto da Entrada, inclua uma anotação kubernetes.io/ingress.global-static-ip-name, como mostrado aqui:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: my-static-address

Para mais informações sobre como criar um endereço IP externo e estático para um Ingress, consulte Como configurar um endereço IP estático e Configurar nomes de domínio com endereços IP estáticos.

Como configurar o HTTPS (TLS) entre o cliente e o balanceador de carga

Um balanceador de carga HTTP(S) atua como um proxy entre seus clientes e o aplicativo. Se você quiser aceitar solicitações HTTPS dos seus clientes, o balanceador de carga precisará ter um certificado para provar sua identidade a eles. Além disso, ele precisa ter uma chave privada para concluir o handshake HTTPS.

Quando o balanceador de carga aceita uma solicitação HTTPS de um cliente, o tráfego entre o cliente e o balanceador de carga é criptografado com TLS. No entanto, o balanceador de carga encerra a criptografia TLS e encaminha a solicitação sem criptografia para o aplicativo. Para informações sobre como criptografar o tráfego entre o balanceador de carga e o aplicativo, consulte HTTPS entre o balanceador de carga e seu aplicativo.

É possível usar certificados SSL gerenciados pelo Google (Beta) ou usar certificados gerenciados por você mesmo. Para mais informações sobre como criar uma Entrada que use certificados gerenciados pelo Google, consulte Como usar certificados SSL gerenciados pelo Google (Beta).

Para fornecer um balanceador de carga HTTP(S) com um certificado e uma chave que você mesmo criou, especifique o nome de um secret do Kubernetes no campo tls do seu manifesto de Ingress. O secret, que você criou anteriormente, contém o certificado e a chave.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress-2
spec:
  tls:
  - secretName: my-secret
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-metrics
          servicePort: 60000

As alterações nos secrets são coletadas periodicamente. Por isso, se você modificar os dados do secret, levará no máximo 10 minutos para que essas alterações sejam aplicadas ao balanceador de carga.

Para mais informações sobre o uso de chaves secretas para fornecer certificados ao balanceador de carga, consulte Como usar vários certificados SSL no balanceamento de carga HTTP(S) com a Entrada.

Como desativar o HTTP

Se você quiser que todo o tráfego entre o cliente e o balanceador de carga HTTP(S) use HTTPS, desative o HTTP. Basta incluir a anotação kubernetes.io/ingress.allow-http no manifesto da Entrada. Defina o valor da anotação como "false".

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-ingress-2
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: my-secret
  ...

Certificados pré-compartilhados para balanceadores de carga

Como alternativa ao uso das chaves secretas do Kubernetes para fornecer certificados ao balanceador de carga para o encerramento do HTTP(S), é possível usar os certificados enviados anteriormente ao projeto do GCP. Para mais informações, consulte Como usar certificados pré-compartilhados e Como usar vários certificados SSL no balanceamento de carga HTTP(S) com o Ingress.

HTTPS (TLS) entre o balanceador de carga e o aplicativo

Um balanceador de carga HTTP(S) atua como um proxy entre seus clientes e o aplicativo. Os clientes podem usar HTTP ou HTTPS para a comunicação com o proxy do balanceador de carga. Porém, a conexão entre o proxy do balanceador de carga e o aplicativo usa o HTTP por padrão. Se o aplicativo em execução em um pod do GKE for capaz de receber solicitações HTTPS, configure o balanceador de carga para usar HTTPS quando encaminhar solicitações para o aplicativo.

Para configurar o protocolo usado entre o balanceador de carga e o aplicativo, use a anotação cloud.google.com/app-protocols no manifesto de seu serviço.

O manifesto do serviço a seguir especifica duas portas. A anotação informa que, quando um balanceador de carga HTTP(S) aponta para a porta 80 do serviço, ele deve usar HTTP. E, quando o balanceador de carga aponta para a porta 443 do serviço, ele deve usar HTTPS.

apiVersion: v1
kind: Service
metadata:
  name: my-service-3
  annotations:
    cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
spec:
  type: NodePort
  selector:
    app: metrics
    department: sales
  ports:
  - name: my-https-port
    port: 443
    targetPort: 8443
  - name: my-http-port
    port: 80
    targetPort: 50001

A anotação cloud.google.com/app-protocols tem a mesma finalidade que a anotação service.alpha.kubernetes.io/app-protocols mais antiga. Os nomes de anotações novas e antigas podem coexistir, como mostrado no manifesto do serviço a seguir. Quando as duas anotações são exibidas no mesmo manifesto do serviço, service.alpha.kubernetes.io/app-protocols tem precedência.

apiVersion: v1
kind: Service
metadata:
  name: my-service-3
  annotations:
    cloud.google.com/app-protocols: '{"my-https-port":"HTTPS","my-http-port":"HTTP"}'
    service.alpha.kubernetes.io/app-protocols: '{"my-first-port":"HTTPS","my-second-port":"HTTP"}'
spec:
  type: NodePort
  selector:
    app: metrics
    department: sales
  ports:
  - name: my-first-port
    port: 443
    targetPort: 8443
  - name: my-second-port
    port: 80
    targetPort: 50001

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.

A seguir

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…

Documentação do Kubernetes Engine