Proteger o tráfego para o Ingress do GKE

Nesta página, mostramos como proteger e otimizar o tráfego para Entrada do Google Kubernetes Engine (GKE). É possível configurar certificados SSL entre o cliente e o balanceador de carga e proteger o tráfego entre o balanceador de carga e o aplicativo de back-end. Antes de continuar, familiarize-se com a forma como o GKE protege a Entrada com HTTPS.

Esta página é destinada a especialistas em redes que projetam e arquitetam a rede para a organização e instalam, configuram e oferecem suporte a equipamentos de rede. Para saber mais sobre papéis comuns e tarefas de exemplo que mencionamos no conteúdo doGoogle Cloud , consulte Funções e tarefas comuns do usuário do GKE.

Proteja e otimize o tráfego entre o cliente e o balanceador de carga

Para aceitar solicitações HTTPS dos seus clientes, o balanceador de carga precisa ter um certificado para provar a identidade dele aos clientes. Além disso, ele precisa ter uma chave privada para concluir o handshake HTTPS. Para saber mais sobre como fornecer certificados SSL a um balanceador de carga HTTP(S), consulte Configurar TLS entre o cliente e o balanceador de carga.

Usar certificados gerenciados pelo Google

Para configurar um ou mais certificados SSL gerenciados pelo Google e associá-los a uma Entrada, é necessário:

  • Crie um ou mais objetos ManagedCertificate no mesmo namespace que o Entrada. É possível especificar até 15 certificados para o balanceador de carga.
  • Associe os objetos ManagedCertificate a uma Entrada adicionando a anotação networking.gke.io/managed-certificates à Entrada. Essa anotação é uma lista separada por vírgulas de objetos ManagedCertificate.

Limitações

Esta seção descreve as limitações dos certificados gerenciados pelo Google. Se você precisar de certificados autogerenciados ou se já tiver certificados SSL que gostaria de configurar na Entrada, consulte Como configurar o HTTPS (TLS) entre o cliente e o balanceador de carga.

  • Os certificados gerenciados pelo Google são menos flexíveis do que os certificados conseguidos e gerenciados por você. Os certificados gerenciados pelo Google aceitam até 100 domínios não curingas. Ao contrário dos certificados autogerenciados, os gerenciados pelo Google não são compatíveis com domínios com caracteres curinga.

  • O número e o tipo de certificados compatíveis com uma Entrada são definidos pelos limites dos certificados SSL gerenciados pelo Google.

  • Não há suporte para atualizações em certificados gerenciados pelo Google. Para mais informações, consulte Como atualizar manualmente um certificado gerenciado pelo Google.

  • Se o certificado for revogado diretamente pela autoridade certificadora, o Google não fará a rotação automaticamente. Você precisa excluir o ManagedCertificate e criar um novo.

  • O GKE Ingress não aceita certificados gerenciados pelo Certificate Manager. Para usar certificados gerenciados pelo Gerenciador de certificados, use a API Gateway.

Pré-requisitos

  • É preciso ser proprietário do nome de domínio. O nome do domínio não pode ter mais de 63 caracteres. É possível usar qualquer registrador de nomes de domínio para conseguir um nome de domínio.

  • Se você usa um cluster padrão do GKE, o complemento HttpLoadBalancing precisa estar ativado.

  • O manifesto do Ingress precisa incluir a anotação kubernetes.io/ingress.class: "gce". O campo ingressClassName não é compatível.

  • Aplique recursos Ingress e ManagedCertificate no mesmo projeto e namespace.

  • Crie um endereço IP externo reservado (estático). Reservar um endereço IP estático garante que ele continue sendo seu, mesmo que você exclua a Entrada. Se você não reservar um endereço IP, ele poderá ser alterado, exigindo que você reconfigure os registros DNS do domínio. Use a Google Cloud CLI ou o console Google Cloud para criar um endereço IP reservado.

    gcloud

    Para criar um endereço IP reservado, execute o comando a seguir:

    gcloud compute addresses create ADDRESS_NAME --global
    

    Substitua ADDRESS_NAME pelo nome do endereço IP reservado que você está criando.

    Para encontrar o endereço IP estático que você criou, execute o seguinte comando:

    gcloud compute addresses describe ADDRESS_NAME --global
    

    A saída será assim:

    address: 203.0.113.32
    ...
    

    Console

    Para criar um endereço IP reservado, siga estas etapas:

    1. Acesse a página Endereços IP externos no console do Google Cloud .

      Acesse Endereços IP externos

    2. Especifique um nome para o endereço IP (por exemplo, example-ip-address).

    3. Especifique se você quer um endereço IPv4 ou IPv6.

    4. Selecione a opção Global para Tipo.

    5. Clique em Reservar. O endereço IP é listado na coluna Endereço externo.

    Config Connector

    Observação: esta etapa requer o Config Connector. Siga estas instruções para instalar o Config Connector no cluster.

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    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
    

Como configurar um certificado gerenciado pelo Google

  1. Criar um objeto ManagedCertificate. Este recurso especifica o domínio do certificado SSL. Domínios com caracteres curinga sem suporte.

    O manifesto a seguir descreve um objeto ManagedCertificate. Salve o manifesto como managed-cert.yaml.

    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: FIRST_CERT_NAME
    spec:
      domains:
        - FIRST_DOMAIN
    ---
    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: SECOND_CERT_NAME
    spec:
      domains:
        - SECOND_DOMAIN
    

    Substitua:

    • FIRST_CERT_NAME: o nome do primeiro objeto ManagedCertificate.
    • FIRST_DOMAIN: o primeiro domínio que pertence a você.
    • SECOND_CERT_NAME: o nome do segundo objeto ManagedCertificate.
    • SECOND_DOMAIN: o segundo domínio que pertence a você.

    Os nomes dos objetos ManagedCertificate são diferentes dos nomes dos certificados reais que eles criam. Você só precisará saber os nomes dos objetos ManagedCertificate para usá-los na Entrada.

  2. Aplique o manifesto ao cluster:

    kubectl apply -f managed-cert.yaml
    
  3. Siga as instruções para criar uma implantação e um serviço para expor seu aplicativo na Internet.

  4. Para que esse objeto ManagedCertificate se torne Active, anexe-o ao Entrada usando a anotação networking.gke.io/managed-certificates, como no exemplo a seguir. O ManagedCertificate ainda não precisa ser Active para ser anexado a uma Entrada.

     apiVersion: networking.k8s.io/v1
     kind: Ingress
     metadata:
       name: my-gmc-ingress
       annotations:
         networking.gke.io/managed-certificates: "FIRST_CERT_NAME,SECOND_CERT_NAME"
     spec:
       rules:
       - host: FIRST_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60001
       - host: SECOND_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60002
     ```
    
    Replace <code><var>FIRST_DOMAIN</var></code> and
    <code><var>SECOND_DOMAIN</var></code> with your domain names.
    
    This manifest describes an Ingress that lists pre-shared certificate
    resources in an annotation.
    
    Note: It might take several hours for Google Cloud to provision the load
    balancer and the managed certificates, and for the load balancer to begin
    using the new certificates. For more information, see
    [Deploy a Google-managed certificate with load balancer authorization](/certificate-manager/docs/deploy-google-managed-lb-auth#wait_until_the_certificate_has_been_activated).
    
  5. Aguarde a conclusão do provisionamento dos certificados gerenciados pelo Google. Isso pode levar até 60 minutos. Verifique o status dos certificados usando o seguinte comando:

    kubectl describe managedcertificate managed-cert
    

    O resultado será o seguinte:

    Name:         managed-cert
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         ManagedCertificate
    (...)
    Spec:
     Domains:
       FQDN_1
       FQDN_2
    Status:
     CertificateStatus: Active
    (...)
    

    O valor do campo Status.CertificateStatus indica que o certificado é provisionado. Se Status.CertificateStatus não for Active, o certificado ainda não será provisionado.

  6. Acesse seus domínios usando o prefixo https:// para verificar se o SSL está funcionando. O navegador indica que a conexão é segura e é possível ver os detalhes do certificado.

Como migrar para certificados gerenciados pelo Google com base em certificados autogerenciados

Ao migrar uma Entrada, fazendo a transição de certificados SSL autogerenciados para certificados SSL gerenciados pelo Google, não exclua nenhum certificado SSL autogerenciado antes que os certificados SSL gerenciados pelo Google estejam ativos. Após o provisionamento bem-sucedido dos certificados SSL gerenciados pelo Google, eles ficarão automaticamente ativos. Depois que os certificados SSL gerenciados pelo Google estiverem ativos, será possível excluir os certificados SSL autogerenciados.

Use estas instruções para migrar de certificados autogerenciados para certificados SSL gerenciados pelo Google.

  1. Adicione um novo certificado gerenciado pelo Google ao Entrada, conforme descrito na seção anterior.
  2. Aguarde até que o status do recurso de certificado gerenciado pelo Google seja Active. Use o comando a seguir para verificar o status do certificado:

    kubectl describe managedcertificate managed-cert
    
  3. Quando o status estiver Active, atualize a Entrada para remover as referências ao certificado autogerenciado.

Como remover um certificado gerenciado pelo Google

Para remover um certificado gerenciado pelo Google do cluster, é necessário excluir o objeto ManagedCertificate e remover a anotação da Entrada que se refere a ele.

  1. Exclua o objeto ManagedCertificate:

    kubectl delete -f managed-cert.yaml
    

    A saída será assim:

    managedcertificate.networking.gke.io "managed-cert" deleted
    
  2. Remova a anotação da Entrada:

    kubectl annotate ingress managed-cert-ingress networking.gke.io/managed-certificates-
    

    Observe o sinal de menos - no final do comando.

  3. Libere o endereço IP estático que você reservou para o balanceador de carga.

    Use a Google Cloud CLI, o console do Google Cloud ou o Config Connector para liberar um endereço IP reservado.

    gcloud

    Use o seguinte comando para liberar o endereço IP reservado:

    gcloud compute addresses delete ADDRESS_NAME --global
    

    Substitua ADDRESS_NAME pelo nome do endereço IP.

    Console

    Para liberar o endereço IP reservado, siga estas etapas:

    1. Acesse a página Endereços IP externos no console do Google Cloud .

      Acesse Endereços IP externos

    2. Marque a caixa de seleção ao lado do endereço IP que você quer liberar.

    3. Clique em Liberar endereço IP.

    Config Connector

    Observação: esta etapa requer o Config Connector. Siga estas instruções para instalar o Config Connector no cluster.

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      name: example-ip-address
    spec:
      location: global

    Para implantar esse manifesto, faça o download dele para sua máquina como compute-address.yaml e execute:

    kubectl delete -f compute-address.yaml
    

Criar certificados e chaves

Para usar certificados pré-compartilhados ou secrets do Kubernetes, primeiro você precisa de um ou mais certificados com as chaves privadas correspondentes. Cada certificado precisa ter um Nome comum (CN) que seja igual a um nome de domínio que você tem. Se você já tiver dois arquivos de certificado com os valores apropriados para o nome comum, avance para a próxima seção.

  1. Crie a primeira chave:

    openssl genrsa -out test-ingress-1.key 2048
    
  2. Crie a primeira solicitação de assinatura de certificado:

    openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \
        -subj "/CN=FIRST_DOMAIN"
    

    Substitua FIRST_DOMAIN por um nome de domínio de sua propriedade, como example.com.

  3. Crie o primeiro certificado:

    openssl x509 -req -days 365 -in test-ingress-1.csr -signkey test-ingress-1.key \
        -out test-ingress-1.crt
    
  4. Crie a segunda chave:

    openssl genrsa -out test-ingress-2.key 2048
    
  5. Crie a segunda solicitação de assinatura de certificado:

    openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \
        -subj "/CN=SECOND_DOMAIN"
    

    Substitua SECOND_DOMAIN por outro nome de domínio de sua propriedade, como examplepetstore.com.

  6. Crie o segundo certificado:

    openssl x509 -req -days 365 -in test-ingress-2.csr -signkey test-ingress-2.key \
        -out test-ingress-2.crt
    

Para mais informações sobre certificados e chaves, consulte a Visão geral dos certificados SSL.

Agora você tem dois arquivos de certificado e dois arquivos de chaves.

As demais tarefas usam os seguintes marcadores para referir-se aos seus domínios, certificados e chaves:

  • FIRST_CERT_FILE: o caminho para o primeiro arquivo de certificado.
  • FIRST_KEY_FILE: o caminho para o arquivo de chave que acompanha o primeiro certificado.
  • FIRST_DOMAIN: um nome de domínio que pertence a você.
  • FIRST_SECRET_NAME: o nome do secret que contém o primeiro certificado e chave.
  • SECOND_CERT_FILE: o caminho para o segundo arquivo de certificado.
  • SECOND_KEY_FILE: o caminho para o arquivo de chave que acompanha o segundo certificado.
  • SECOND_DOMAIN: um segundo nome de domínio que você tem.
  • SECOND_SECRET_NAME: o nome do secret que contém o segundo certificado e chave.

Usar certificados pré-compartilhados

É possível usar certificados SSL autogerenciados que você envia para seu projeto do Google Cloud . Eles são chamados de certificados pré-compartilhados. É possível especificar um ou mais certificados pré-compartilhados para um Entrada.

Para usar vários certificados pré-compartilhados, siga estas etapas:

  1. Para cada par de certificado e chave, crie um recurso de certificado SSL visível publicamente em Google Cloud.

     gcloud compute ssl-certificates create FIRST_CERT_NAME \
         --certificate=FIRST_CERT_FILE \
         --private-key=FIRST_KEY_FILE
     ```
    
    ```sh
     gcloud compute ssl-certificates create SECOND_CERT_NAME \
         --certificate=SECOND_CERT_FILE \
         --private-key=SECOND_KEY_FILE
     ```
    
    Replace the following:
    
    • FIRST_CERT_NAME, SECOND_CERT_NAME: os nomes do primeiro e do segundo certificado.
    • FIRST_CERT_FILE, SECOND_CERT_FILE: o primeiro e o segundo arquivos de certificado.
    • FIRST_KEY_FILE:, SECOND_KEY_FILE o primeiro e o segundo arquivos de chave.
  2. No manifesto do Entrada, adicione a anotação ingress.gcp.kubernetes.io/pre-shared-cert. O valor da anotação é uma lista separada por vírgulas dos nomes dos seus certificados. Além disso, na seção spec.rules, inclua os campos host para especificar os domínios dos seus serviços.

     apiVersion: networking.k8s.io/v1
     kind: Ingress
     metadata:
       name: my-psc-ingress
       annotations:
         ingress.gcp.kubernetes.io/pre-shared-cert: "FIRST_CERT_NAME,SECOND_CERT_NAME"
     spec:
       rules:
       - host: FIRST_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60001
       - host: SECOND_DOMAIN
         http:
           paths:
           - pathType: ImplementationSpecific
             backend:
               service:
                 name: my-mc-service
                 port:
                   number: 60002
     ```
    
    Replace <code><var>FIRST_DOMAIN</var></code> and
    <code><var>SECOND_DOMAIN</var></code> with your domain names.
    
    This manifest describes an Ingress that lists pre-shared certificate
    resources in an annotation.
    

Usar secrets do Kubernetes

Para fornecer um balanceador de carga HTTP(S) com certificados e chaves que você mesmo criou, crie um ou mais objetos secret do Kubernetes. Cada secret contém um certificado e uma chave. Adicione os secrets ao campo tls do manifesto Ingress. O balanceador de carga usa a indicação de nome do servidor (SNI, na sigla em inglês) para determinar qual certificado precisa ser apresentado ao cliente com base no nome de domínio no handshake de TLS.

Para usar vários certificados, siga estas etapas:

  1. Crie um secret para cada par de certificado e chave:

     kubectl create secret tls FIRST_SECRET_NAME \
         --cert=FIRST_CERT_FILE \
         --key=FIRST_KEY_FILE
     ```
    
    ```sh
     kubectl create secret tls SECOND_SECRET_NAME \
         --cert=SECOND_CERT_FILE \
         --key=SECOND_KEY_FILE
     ```
    
  2. No manifesto da Entrada, na seção spec.tls, liste os secrets que você criou. Além disso, na seção spec.rules, inclua os campos host para especificar os domínios dos seus serviços.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-mc-ingress
    spec:
      tls:
      - secretName: FIRST_SECRET_NAME
      - secretName: SECOND_SECRET_NAME
      rules:
      - host: FIRST_DOMAIN
        http:
          paths:
          - pathType: ImplementationSpecific
            backend:
              service:
                name: my-mc-service
                port:
                  number: 60001
      - host: SECOND_DOMAIN
        http:
          paths:
          - pathType: ImplementationSpecific
            backend:
              service:
                name: my-mc-service
                port:
                  number: 60002
    

    Substitua FIRST_DOMAIN e SECOND_DOMAIN pelos seus nomes de domínio, por exemplo, example.com e examplepetstore.com.

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 proteger a Entrada criptografada por HTTPS para seus clusters do GKE, consulte o exemplo de Entrada segura.

Como desativar o HTTP

Se quiser que todo o tráfego entre o cliente e o balanceador de carga use HTTPS, é possível desativar o HTTP incluindo a anotação kubernetes.io/ingress.allow-http no seu manifesto da entrada. Defina o valor da anotação como "false".

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress-2
  annotations:
    kubernetes.io/ingress.allow-http: "false"
spec:
  tls:
  - secretName: SECRET_NAME
  ...

Esse manifesto inclui o SECRET_NAME, que é o nome do secret que você criou.

HTTP/2 entre o cliente e o balanceador de carga

Os clientes podem usar HTTP/2 para enviar solicitações ao balanceador de carga. Nenhuma configuração é necessária.

Proteger e otimizar o tráfego entre o balanceador de carga e o aplicativo

É possível configurar o protocolo usado para a comunicação entre o balanceador de carga e os pods de aplicativo para garantir a segurança de ponta a ponta ou otimizar o desempenho do tráfego interno. Embora o balanceador de carga use o HTTP/1.1 não criptografado por padrão para conexões de back-end, é possível ativar o HTTPS ou o HTTP/2 para atender aos requisitos específicos do aplicativo.

HTTPS entre o balanceador de carga e o aplicativo

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 mais informações, consulte HTTPS (TLS) entre o balanceador de carga e 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 serviço. Esse manifesto de Serviço precisa incluir type: NodePort, a menos que você esteja usando o balanceamento de carga nativo do contêiner. Se você usa o balanceamento de carga nativo de contêiner, use o type: ClusterIP.

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

O manifesto do serviço precisa incluir um valor name na anotação da porta. Só é possível editar a porta do Serviço fazendo referência ao name atribuído, e não ao valor targetPort.

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

Usar HTTP/2 entre o balanceador de carga e o aplicativo

Se o aplicativo em execução em um pod do GKE for capaz de receber solicitações HTTP/2, configure o balanceador de carga para usar HTTP/2 ao encaminhar solicitações para o aplicativo.

Para ativar o HTTP/2, use a anotação cloud.google.com/app-protocols no manifesto de serviço do Kubernetes. Essa anotação especifica o protocolo que o balanceador de carga usa para se comunicar com seu aplicativo. Para garantir que o balanceador de carga faça uma solicitação HTTP/2 correta para o back-end, ele precisa ser configurado com SSL.

Confira abaixo um exemplo de manifesto de serviço configurado para HTTP/2:

apiVersion: v1
kind: Service
metadata:
  name: my-http2-service
  annotations:
    cloud.google.com/app-protocols: '{"my-port":"HTTP2"}'
spec:
  type: NodePort
  selector:
    app: my-app
  ports:
  - name: my-port
    protocol: TCP
    port: 443
    targetPort: 8443

Observe o seguinte:

  • A anotação cloud.google.com/app-protocols é definida como '{"my-port":"HTTP2"}', o que instrui o balanceador de carga a usar HTTP/2 para o tráfego enviado à porta chamada my-port.
  • A porta é definida como 443 e direciona o tráfego para pods em targetPort 8443.