Entrada para balanceamento de carga de HTTP(S) interno

Nesta página, mostramos como configurar e usar o Ingress para balanceamento de carga HTTP(S) interno no Google Kubernetes Engine (GKE). O Ingress para balanceamento de carga de HTTP(S) interno fornece suporte nativo por meio do controlador Ingress do GKE.

Para saber mais sobre quais recursos são compatíveis com o Ingress do balanceamento de carga interno HTTP(S), consulte esta página. Saiba mais sobre como o Ingress para balanceamento de carga HTTP(S) interno funciona em Ingress para balanceamento de carga HTTP(S) interno.

Antes de começar

Antes de implantar os recursos do balanceador de carga por meio da API Entrada do Kubernetes, você precisa preparar seu ambiente de rede para que os proxies do balanceador de carga possam ser implantados em uma determinada região. Para saber como implantar a sub-rede somente proxy, consulte como configurar a rede e as sub-redes.

É preciso concluir esta etapa antes de implantar a entrada para balanceamento de carga HTTP(S) interno.

Para saber mais sobre por que a entrada do balanceamento de carga interno HTTP(S) requer o uso de uma sub-rede somente proxy, consulte Ambiente de rede obrigatório.

Requisitos

O Ingress para balanceamento de carga HTTP(S) interno tem os requisitos a seguir:

  • Seu cluster precisa usar uma versão do GKE posterior a 1.16.5-gke.10.
  • Seu cluster precisa ser executado no modo nativo de VPC (IP do alias). Para mais informações, consulte Clusters nativos de VPC.
  • Seu cluster precisa ter o complemento de balanceamento de carga HTTP ativado. Os clusters têm o balanceamento de carga HTTP ativado por padrão. Não desative o complemento.
  • Você precisa usar grupos de endpoints de rede (NEGs, na sigla em inglês) como back-ends para o serviço.

Como implantar o Ingress para balanceamento de carga HTTP(S) interno

Os exercícios a seguir mostram como implantar o Ingress para balanceamento de carga HTTP(S) interno:

  1. Crie um cluster.
  2. Implementar um aplicativo.
  3. Implantar um Service.
  4. Implante o Ingress.
  5. Validar a implantação.
  6. Excluir recursos de Entrada

Como criar um cluster

Nesta seção, você cria um cluster que pode ser usado com o Ingress para balanceamento de carga HTTP(S) interno. É possível criar esse cluster usando a ferramenta de linha de comando gcloud ou o Console do Google Cloud.

gcloud

Crie um cluster com os seguintes campos:

gcloud container clusters create CLUSTER_NAME \
    --cluster-version=VERSION_NUMBER \
    --enable-ip-alias \
    --zone=ZONE \
    --network=NETWORK

Substitua:

  • CLUSTER_NAME: adicione um nome para o cluster.
  • VERSION_NUMBER: adiciona uma versão posterior à 1.16.5-gke.10. Também é possível usar a sinalização --release-channel para selecionar um canal de lançamento com uma versão padrão posterior a 1.16.5-gke.10.
  • --enable-ip-alias ativa o IP do alias. Os clusters que usam o Ingress para balanceamento de carga HTTP(S) interno precisam ser executados no modo nativo de VPC (IP do alias). Para mais informações, consulte Como criar um cluster nativo de VPC.
  • ZONE: adicione uma zona para criar o cluster. Escolha uma zona na mesma região que a sub-rede proxy criada para seu balanceador de carga HTTP(S) interno em Como configurar a rede e as sub-redes;
  • NETWORK: adicione o nome da rede em que você quer que o cluster seja criado. Essa rede precisa estar na mesma rede VPC que a sub-rede do proxy.

Console

  1. Acesse o menu do Google Kubernetes Engine no Console do Cloud.

    Acesse o menu do Google Kubernetes Engine

  2. Clique em Criar.

  3. Na seção Princípios básicos do cluster, conclua o seguinte:

    1. Insira o Nome do cluster.
    2. Em Tipo de local, selecione uma zona para o cluster. Escolha uma zona na mesma região que a sub-rede proxy criada para o balanceador de carga HTTP(S) interno em como configurar a rede e as sub-redes;
    3. Em Versão principal, selecione uma Versão estática posterior a 1.16.5-gke.10 ou selecione um Canal de lançamento com uma versão padrão posterior a 1.16.5-gke.10.
  4. No painel de navegação, em Cluster, clique em Rede.

    1. Na lista suspensa Rede, selecione a rede em que você quer criar o cluster. Essa rede precisa estar na mesma rede VPC que a sub-rede do proxy.
    2. Em Opções de rede avançadas, verifique se as opções Ativar roteamento de tráfego nativo de VPC (usa IP do alias) e Ativar balanceamento de carga HTTP estão selecionada.
  5. Clique em Criar.

Como implantar um aplicativo da Web

Nesta seção, você cria uma implantação.

Para criar uma implantação:

  1. Copie e salve o seguinte recurso de implantação em um arquivo chamado web-deployment.yaml:

    # web-deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: hostname
      name: hostname-server
    spec:
      selector:
        matchLabels:
          app: hostname
      minReadySeconds: 60
      replicas: 3
      template:
        metadata:
          labels:
            app: hostname
        spec:
          containers:
          - image: k8s.gcr.io/serve_hostname:v1.4
            name: hostname-server
            ports:
            - containerPort: 9376
              protocol: TCP
          terminationGracePeriodSeconds: 90
    

    Esse arquivo de implantação usa uma imagem de contêiner que detecta um servidor HTTPS na porta 9376. Esse Deployment gerencia os pods do aplicativo. Cada pod executa um contêiner de aplicativo com um servidor HTTPS que retorna o nome do host do servidor de aplicativos como a resposta. O nome do host padrão de um pod é o nome do pod. O contêiner também processa o encerramento correto.

  2. Depois de criar o Deployment, aplique o recurso ao cluster.

    kubectl apply -f web-deployment.yaml
    

Como implantar um serviço como um grupo de endpoints de rede (NEG)

Nesta seção, você cria um recurso Serviço. O Serviço seleciona os contêineres de back-end pelos rótulos para que o controlador Ingress possa programá-los como endpoints de back-end. O Ingress para balanceamento de carga HTTP(S) interno exige que você use NEGs como back-ends. O recurso não é compatível com grupos de instâncias como back-ends. Como os back-ends de NEG são necessários, a seguinte anotação de NEG é necessária ao implantar serviços que são expostos por meio do Ingress:

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

Seu serviço é anotado automaticamente com cloud.google.com/neg: '{"ingress": true}' quando todas as condições a seguir são verdadeiras:

  • Você criou o serviço nos clusters do GKE 1.17.6-gke.7 e posteriores.
  • Você está usando clusters nativos de VPC.
  • Se você não estiver usando uma VPC compartilhada.
  • Se você não estiver usando a política de rede do GKE.

O uso de NEGs permite que o controlador Ingress execute o balanceamento de carga nativo do contêiner. O tráfego é balanceado por carga do proxy do Ingress diretamente para o IP do pod, em vez de transferir o IP do nó ou 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 verificações de prontidão e atividade do Kubernetes. Os portões de prontidão do pod garantem que o tráfego não seja interrompido durante eventos do ciclo de vida, como inicialização do pod, perda do pod ou perda de nó.

Se você não incluir uma anotação NEG, receberá um aviso no objeto Ingress que impede a configuração do balanceador de carga HTTP(S) interno. Um evento do Kubernetes também será gerado no Ingress se a anotação NEG não estiver incluída. A mensagem a seguir é um exemplo da mensagem de evento:

Message
-------
error while evaluating the ingress spec: could not find port "8080" in service "default/no-neg-svc"

Um NEG não é criado até que um Ingress faça referência ao Serviço. O NEG não aparece no Compute Engine até que o Ingress e o respectivo Serviço referenciado existam. Os NEGs são um recurso zonal e, para clusters com várias zonas, um é criado por Serviço por zona.

Para criar um Service:

  1. Copie e salve o seguinte recurso Service em um arquivo chamado web-service.yaml:

    # web-service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: hostname
      namespace: default
      annotations:
        cloud.google.com/neg: '{"ingress": true}'
    spec:
      ports:
      - name: host1
        port: 80
        protocol: TCP
        targetPort: 9376
      selector:
        app: hostname
      type: NodePort
    
  2. Depois de criar o arquivo de serviço, aplique o recurso ao cluster:

    kubectl apply -f  web-service.yaml
    

Como implantar o Ingress

Nesta etapa, você cria um recurso Ingress que aciona a implantação do balanceamento de carga do Compute Engine por meio do controlador Ingress. Uma Entrada para balanceamento de carga HTTP(S) interno requer a seguinte anotação:

annotations:
    kubernetes.io/ingress.class: "gce-internal"

Para criar um Ingress:

  1. Copie e salve o seguinte recurso Ingress em um arquivo chamado internal-ingress.yaml:

    # internal-ingress.yaml
    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: ilb-demo-ingress
      namespace: default
      annotations:
        kubernetes.io/ingress.class: "gce-internal"
    spec:
      backend:
        serviceName: hostname
        servicePort: 80
    
  2. Depois de criar o arquivo Ingress, aplique o recurso ao cluster:

    kubectl apply -f internal-ingress.yaml
    

Como validar uma implantação bem-sucedida do Ingress

Nesta seção, você validará se a implantação foi bem-sucedida.

Pode levar vários minutos para que o recurso Ingress seja totalmente provisionado. Durante esse período, o controlador Ingress cria itens como regras de encaminhamento, serviços de back-end, mapas de URL e NEGs.

Para recuperar o status do recurso Ingress criado na seção anterior, execute o seguinte comando:

kubectl get ingress ilb-demo-ingress

O resultado será semelhante a:

NAME               HOSTS    ADDRESS            PORTS     AGE
ilb-demo-ingress   *        10.128.0.58        80        59s

Quando o campo ADDRESS é preenchido, o Ingress está pronto. O uso de um endereço RFC 1918 nesse campo indica um IP interno na VPC.

Como o balanceador de carga HTTP(S) interno é um balanceador de carga regional, o IP virtual (VIP, na sigla em inglês) só pode ser acessado por um cliente dentro da mesma região e VPC. Depois de recuperar o VIP do balanceador de carga, use ferramentas (por exemplo, curl) para emitir chamadas HTTP GET para o VIP de dentro da VPC.

Para emitir uma chamada HTTP GET, siga estas

  1. Para alcançar o VIP do Ingress de dentro da VPC, implante uma VM na mesma região e rede do cluster.

    Por exemplo, se você seguiu as etapas anteriores para criar sua implantação, serviço e entrada e criou seu cluster na rede padrão e na zona us-central1-a, poderia use o seguinte comando:

    gcloud compute instances create l7-ilb-client-us-central1-a \
        --image-family=debian-9 \
        --image-project=debian-cloud \
        --network=default \
        --subnet=default \
        --zone=us-central1-a \
        --tags=allow-ssh
    

    Para saber mais sobre como criar instâncias, consulte Como criar e iniciar uma instância de VM.

  2. Para acessar o VIP interno de dentro da VM, use curl:

    1. Use SSH para acessar a VM criada na etapa anterior:

      gcloud compute ssh l7-ilb-client-us-central1-a \
         --zone=us-central1-a
      
    2. Use curl para acessar o VIP do aplicativo interno:

      curl 10.128.0.58
      hostname-server-6696cf5fc8-z4788
      

      A resposta HTTP e o nome do host de um dos contêineres de back-end indicam que o caminho de balanceamento de carga completo está funcionando corretamente.

Como excluir recursos de Entrada

A remoção dos recursos Ingress e Serviço também remove os recursos do balanceador de carga do Compute Engine associados a eles. Para evitar o vazamento de recursos, garanta que os recursos Ingress sejam eliminados quando você não precisar mais deles. Também é preciso excluir os recursos Ingress e Serviço antes de excluir clusters ou outros recursos de balanceamento de carga do Compute Engine serem órfãos.

Para remover uma Entrada, conclua as seguintes etapas:

  1. Exclua o Ingress: Por exemplo, para excluir a entrada criada nesta página, execute o seguinte comando:

    kubectl delete ingress ilb-demo-ingress
    

    A exclusão do Ingress remove as regras de encaminhamento, os serviços de back-end e os mapas de URL associados a esse recurso Ingress.

  2. Exclua o serviço: Por exemplo, para excluir o serviço criado nesta página, execute o seguinte comando:

    kubectl delete service hostname
    

    A exclusão do Serviço remove o NEG associado a ele.

Endereços IP estáticos

Os recursos de entrada interna são compatíveis com os endereços IP estático e temporário. Se um endereço IP não for especificado, um endereço IP disponível será alocado automaticamente da sub-rede do nó do GKE. No entanto, o recurso Ingress não provisiona endereços IP da sub-rede somente proxy, porque essa sub-rede é usada apenas para consumo interno de proxy. Esses endereços IP temporários são alocados ao Ingress somente pelo ciclo de vida do recurso interno do Ingress. 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.

Se você quiser um endereço IP permanente que seja independente do ciclo de vida do recurso Ingress interno, reserve um endereço IP interno estático regional. Em seguida, especifique um endereço IP estático usando a anotação kubernetes.io/ingress.regional-static-ip-name no recurso de entrada.

O exemplo a seguir mostra como adicionar essa anotação:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.regional-static-ip-name: STATIC_IP_NAME
    kubernetes.io/ingress.class: "gce-internal"

Substitua STATIC_IP_NAME por um nome de IP estático que atenda aos seguintes critérios:

  • Crie o IP estático antes de implantar o Ingress. Um balanceador de carga não é implantado até que o IP estático exista, e a referência a um recurso de endereço IP inexistente não cria um IP estático.
  • Faça referência ao recurso de endereço IP do Google Cloud pelo nome, e não pelo endereço IP.
  • O endereço IP precisa ser de uma sub-rede na mesma região que o cluster do GKE. Use qualquer sub-rede privada disponível na região (exceto sub-rede somente proxy). Diferentes recursos de Entrada também podem ter endereços de sub-redes diferentes.

HTTPS entre o cliente e o balanceador de carga

O Ingress para balanceamento de carga interno permite a exibição de certificados TLS para clientes. É possível exibir certificados TLS por meio de secrets do Kubernetes ou de certificados SSL regionais pré-compartilhados no Google Cloud. Também é possível especificar vários certificados por recurso Ingress.

Nas etapas a seguir, detalhamos como criar um certificado no Google Cloud e exibi-lo para clientes internos por meio do Ingress.

  1. Crie o certificado regional:

    gcloud compute ssl-certificates create CERT_NAME \
        --certificate CERT_FILE_PATH \
        --private-key KEY_FILE_PATH \
        --region REGION
    

    Substitua:

    • CERT_NAME: adicione um nome para seu certificado.
    • CERT_FILE_PATH: adicione o caminho para o arquivo de certificado local a fim de criar um certificado autogerenciado. O certificado precisa estar no formato PEM.
    • KEY_FILE_PATH: adicione o caminho para um arquivo de chave privada local. A chave privada precisa estar no formato PEM e usar a criptografia RSA ou ECDSA.
    • REGION: adicione uma região para seu certificado.
  2. Crie um Ingress. O seguinte arquivo YAML, denominado ingress-pre-shared-cert.yaml, é um exemplo do recurso Ingress que você precisa criar:

    # ingress-pre-shared-cert.yaml
    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: ilb-demo-ing
      namespace: default
      annotations:
        ingress.gcp.kubernetes.io/pre-shared-cert: "CERT_NAME"
        kubernetes.io/ingress.class: "gce-internal"
        kubernetes.io/ingress.allow-http: "false"
    spec:
      rules:
      - host: DOMAIN
        http:
          paths:
          - backend:
              serviceName: SERVICE_NAME
              servicePort: 80
    

    Substitua:

    • DOMAIN: adicione seu domínio.
    • CERT_NAME: adicione o nome do certificado criado na seção anterior.
    • SERVICE_NAME: adicione o nome do seu serviço.
  3. Depois de criar o Serviço, aplique o recurso ao cluster.

    kubectl apply -f ingress-pre-shared-cert.yaml
    

Resumo das anotações internas do Ingress

As tabelas a seguir mostram as anotações que podem ser adicionadas ao criar recursos de Entrada e Serviço para Ingress para balanceamento de carga HTTP(S) interno.

Anotações do Ingress

Anotação Descrição
kubernetes.io/ingress.class Especificado como "gce-internal" para o Ingress interno. Se a classe não for especificada, um recurso Ingress será interpretado, por padrão, como externo
kubernetes.io/ingress.allow-http Especifica se o tráfego HTTP será permitido entre o cliente e o balanceador de carga HTTP(S). Os valores possíveis são true e false. O valor padrão é true, mas você precisa definir essa anotação como false se estiver usando HTTPS para balanceamento de carga interno. Para mais informações, consulte Como desativar o HTTP.
ingress.gcp.kubernetes.io/pre-shared-cert É possível fazer upload de certificados e chaves para seu projeto do Google Cloud. Use essa anotação para fazer referência aos certificados e chaves. Para mais informações, consulte Como usar vários certificados SSL no balanceamento de carga HTTP(S).
Anotação Descrição
cloud.google.com/backend-config Use essa anotação para configurar o serviço de back-end associado a um servicePort. Para mais informações, consulte Recursos de Entrada.
cloud.google.com/neg Use essa anotação para especificar que o balanceador de carga usará grupos de endpoint de rede. Para mais informações, consulte Como usar balanceamento de carga nativo de contêiner.

Solução de problemas

Entender e observar o estado do Ingress geralmente envolve a inspeção dos recursos associados. Os tipos de problemas encontrados geralmente incluem recursos de balanceamento de carga que não estão sendo criados corretamente, tráfego que não alcança back-ends ou back-ends que não aparecem íntegros.

Algumas etapas comuns de solução de problemas incluem:

  • Verificação de que o tráfego do cliente é derivado da mesma região e VPC que o balanceador de carga.
  • Verificação de que os pods e back-ends estão íntegros.
  • Validação do caminho de tráfego para o VIP e das verificações de integridade do Compute Engine para garantir que ele não seja bloqueado por regras de firewall.
  • Verificação de erros nos eventos do recurso Ingress.
  • Descrição do recurso Ingress para ver o mapeamento para recursos do Compute Engine.
  • Validação de que os recursos de balanceamento de carga do Compute Engine existem, têm as configurações corretas e não têm erros relatados.

Como filtrar eventos do Ingress

A consulta a seguir filtra erros em todos os eventos do Ingress no cluster.

kubectl get events --all-namespaces --field-selector involvedObject.kind=Ingress

Também é possível filtrar por objetos ou nomes de objetos:

kubectl get events --field-selector involvedObject.kind=Ingress,involvedObject.name=hostname-internal-ingress

No seguinte erro, veja que o Serviço referenciado pelo Ingress não existe:

LAST SEEN   TYPE      REASON      OBJECT                              MESSAGE
0s          Warning   Translate   ingress/hostname-internal-ingress   error while evaluating the ingress spec: could not find service "default/hostname-invalid"

Como inspecionar recursos do balanceador de carga do Compute Engine

O comando a seguir exibe a saída completa do recurso Ingress para que você veja os mapeamentos para os recursos do Compute Engine criados pelo controlador Ingress:

kubectl get ing INGRESS_FILENAME -o yaml

Substitua INGRESS_FILENAME pelo nome de arquivo do recurso Ingress.

O resultado será semelhante a:

apiVersion: v1
items:
- apiVersion: networking.k8s.io/v1beta1
  kind: Ingress
  metadata:
    annotations:
      ingress.kubernetes.io/backends: '{"k8s1-241a2b5c-default-hostname-80-29269aa5":"HEALTHY"}'
      ingress.kubernetes.io/forwarding-rule: k8s-fw-default-ilb-demo-ingress--241a2b5c94b353ec
      ingress.kubernetes.io/target-proxy: k8s-tp-default-ilb-demo-ingress--241a2b5c94b353ec
      ingress.kubernetes.io/url-map: k8s-um-default-ilb-demo-ingress--241a2b5c94b353ec
      kubectl.kubernetes.io/last-applied-configuration: |
       {"apiVersion":"networking.k8s.io/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"gce-internal"},"name":"ilb-demo-ingress","namespace":"default"},"spec":{"backend":{"serviceName":"hostname","servicePort":80}}}
      kubernetes.io/ingress.class: gce-internal
    creationTimestamp: "2019-10-15T02:16:18Z"
    finalizers:
    - networking.gke.io/ingress-finalizer
    generation: 1
    name: ilb-demo-ingress
    namespace: default
    resourceVersion: "1538072"
    selfLink: /apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/ilb-demo-ingress
    uid: 0ef024fe-6aea-4ee0-85f6-c2578f554975
  spec:
    backend:
      serviceName: hostname
      servicePort: 80
  status:
    loadBalancer:
      ingress:
      - ip: 10.128.0.127
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

As anotações ingress.kubernetes.io/backends listam os back-ends e os status. Verifique se os back-ends estão listados como HEALTHY.

Os recursos do Compute Engine criados pelo Ingress podem ser consultados diretamente para entender o status e a configuração deles. A execução dessas consultas também pode ser útil para a solução de problemas.

Para listar todas as regras de encaminhamento do Compute Engine:

gcloud compute forwarding-rules list

Exemplo de saída:

NAME                                                        REGION       IP_ADDRESS      IP_PROTOCOL  TARGET
k8s-fw-default-hostname-internal-ingress--42084f6a534c335b  us-central1  10.128.15.225   TCP          us-central1/targetHttpProxies/k8s-tp-default-hostname-internal-ingress--42084f6a534c335b

Para listar a integridade de um serviço de back-end, primeiro liste os serviços de back-end e faça uma cópia do nome do serviço de back-end que você quer inspecionar:

gcloud compute backend-services list

Exemplo de saída:

NAME                                         BACKENDS                                                                       PROTOCOL
k8s1-42084f6a-default-hostname-80-98cbc1c1   us-central1-a/networkEndpointGroups/k8s1-42084f6a-default-hostname-80-98cbc1c1 HTTP

Agora você pode usar o nome do serviço de back-end para consultar a integridade dele:

gcloud compute backend-services get-health k8s1-42084f6a-default-hostname-80-98cbc1c1 \
    --region us-central1

Exemplo de saída:

backend: https://www.googleapis.com/compute/v1/projects/user1-243723/zones/us-central1-a/networkEndpointGroups/k8s1-42084f6a-default-hostname-80-98cbc1c1
status:
  healthStatus:
  - healthState: HEALTHY

A seguir