Receber eventos do Pub/Sub em um endpoint HTTP particular em um cluster particular do GKE


Neste tutorial, mostramos como criar um endpoint HTTP particular em um cluster particular do Google Kubernetes Engine (GKE) para receber eventos de mensagens do Pub/Sub usando o Eventarc. Para saber mais sobre esse destino de evento, consulte Rotear eventos para um endpoint HTTP interno em uma rede VPC.

Os clusters particulares do GKE são um tipo de cluster nativo de nuvem privada virtual (VPC) em que os nós têm apenas endereços IP internos, o que significa que nós e pods estão isolados da Internet por padrão. Você pode optar por não ter acesso de cliente, acesso limitado ou acesso irrestrito ao plano de controle. Não é possível converter um cluster não particular atual em um cluster particular. Para mais informações, consulte Sobre clusters particulares.

É possível executar os comandos a seguir usando a CLI do Google Cloud no terminal ou no Cloud Shell.

Objetivos

Com este tutorial, você vai:

  1. Criar uma sub-rede somente proxy na rede VPC padrão e criar uma regra de firewall da VPC.
  2. Criar um cluster particular do GKE Autopilot sem acesso do cliente ao endpoint público.
  3. Criar uma instância de máquina virtual (VM) do Compute Engine em uma sub-rede especificada da rede VPC.
  4. Estabelecer uma conexão SSH com a instância de VM e implantar um serviço receptor de eventos na instância de VM.
  5. Implantar um gateway no cluster e um manifesto HTTPRoute para configurar o roteamento de tráfego no Kubernetes para back-ends de aplicativos.
  6. Crie um anexo de rede que permita que uma rede VPC produtora inicie conexões com uma rede VPC consumidora.
  7. Crie um gatilho do Eventarc que direcione eventos do Pub/Sub para o receptor de eventos na instância de VM.
  8. Publicar uma mensagem em um tópico do Pub/Sub para gerar um evento e exibir o corpo do evento nos registros do pod do aplicativo.

Custos

Neste documento, você vai usar os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços.

Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.

Antes de começar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. Se você estiver usando um provedor de identidade externo (IdP), primeiro faça login na CLI gcloud com sua identidade federada.

  4. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  5. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Cloud Resource Manager, Compute Engine, Eventarc, GKE, and Pub/Sub APIs:

    gcloud services enable compute.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com eventarc.googleapis.com pubsub.googleapis.com
  8. Install the Google Cloud CLI.

  9. Se você estiver usando um provedor de identidade externo (IdP), primeiro faça login na CLI gcloud com sua identidade federada.

  10. Para inicializar a CLI gcloud, execute o seguinte comando:

    gcloud init
  11. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Verify that billing is enabled for your Google Cloud project.

  13. Enable the Cloud Resource Manager, Compute Engine, Eventarc, GKE, and Pub/Sub APIs:

    gcloud services enable compute.googleapis.com container.googleapis.com cloudresourcemanager.googleapis.com eventarc.googleapis.com pubsub.googleapis.com
  14. Atualize os componentes da CLI do Google Cloud:
    gcloud components update
  15. Faça login usando sua conta:
    gcloud auth login
  16. Se você for o criador do projeto, vai receber o papel de proprietário básico (roles/owner). Por padrão, esse papel do Identity and Access Management (IAM) inclui as permissões necessárias para acesso total à maioria dos recursos do Google Cloud, e você pode pular esta etapa.

    Se você não é o criador do projeto, as permissões necessárias precisam ser concedidas ao principal apropriado. Por exemplo, um principal pode ser uma Conta do Google (para usuários finais) ou uma conta de serviço (para aplicativos e cargas de trabalho de computação). Para mais informações, consulte a página Papéis e permissões do destino do evento.

    Permissões necessárias

    Para conseguir as permissões necessárias a fim de concluir o guia de início rápido, peça ao administrador para conceder a você os seguintes papéis do IAM no projeto:

    Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

    Também é possível conseguir as permissões necessárias por meio de papéis personalizados ou de outros papéis predefinidos.

  17. Anote as propriedades da conta de serviço padrão do Compute Engine, porque você vai anexá-la a um gatilho do Eventarc para representar a identidade do acionador para fins de teste. Essa conta de serviço é criada automaticamente depois de ativar ou usar um serviço do Google Cloud que usa o Compute Engine e com o seguinte formato de e-mail:

    PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Substitua PROJECT_NUMBER pelo número do seu projeto Google Cloud. Encontre o número do projeto na página Boas-vindas do console do Google Cloud ou executando o seguinte comando:

    gcloud projects describe PROJECT_ID --format='value(projectNumber)'

    Para ambientes de produção, é altamente recomendável criar uma nova conta de serviço, conceder a ela um ou mais papéis do IAM que contenham as permissões mínimas necessárias, bem como seguir o princípio de privilégio mínimo.

  18. Se você ativou o agente de serviço do Cloud Pub/Sub até 8 de abril de 2021, para oferecer compatibilidade com solicitações push autenticadas do Pub/Sub, conceda o papel de Criador de token da conta de serviço (roles/iam.serviceAccountTokenCreator) ao agente de serviço. Caso contrário, esse papel é concedido por padrão:
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
        --role=roles/iam.serviceAccountTokenCreator
  19. Criar uma sub-rede somente proxy

    A menos que você crie uma política organizacional que proíba isso, os novos projetos começam com uma rede padrão (uma rede VPC de modo automático) que tem uma sub-rede em cada região. Cada rede VPC consiste em um ou mais intervalos de endereços IP chamados sub-redes. As sub-redes são recursos regionais e têm intervalos de endereços IP associados a elas.

    1. Use o comando gcloud compute networks subnets create para criar uma sub-rede somente proxy na rede padrão.

      gcloud compute networks subnets create proxy-only-subnet \
          --purpose=REGIONAL_MANAGED_PROXY \
          --role=ACTIVE \
          --region=us-central1 \
          --network=default \
          --range=10.10.10.0/24
      

      Observe que uma sub-rede com purpose=REGIONAL_MANAGED_PROXY é reservada para balanceadores de carga baseados em Envoy e que o range precisa fornecer 64 ou mais endereços IP.

    2. Crie uma regra de firewall que corresponda ao intervalo da sub-rede somente proxy e que permita o tráfego na porta TCP 8080.

      gcloud compute firewall-rules create allow-proxy-connection \
          --allow tcp:8080 \
          --source-ranges 10.10.10.0/24 \
          --network=default
      

    Criar um cluster do GKE particular

    Use o comando gcloud container clusters create-auto para criar um cluster particular do GKE no modo Autopilot que tenha nós particulares e não tenha acesso de cliente no endpoint público.

    O seguinte exemplo cria um cluster particular do GKE chamado private-cluster e também uma sub-rede chamada my-subnet:

    gcloud container clusters create-auto private-cluster \
        --create-subnetwork name=my-subnet \
        --enable-master-authorized-networks \
        --enable-private-nodes \
        --enable-private-endpoint \
        --region=us-central1
    

    Observações:

    • --enable-master-authorized-networks especifica que o acesso ao endpoint público é restrito aos intervalos de endereços IP que você autorizar;
    • --enable-private-nodes indica que os nós do cluster não têm endereços IP externos.
    • --enable-private-endpoint indica que o cluster é gerenciado usando o endereço IP interno do endpoint da API do plano de controle.

    A criação do cluster pode levar vários minutos para ser concluída. Depois da criação do cluster, a saída deve indicar que o status dele é RUNNING.

    Criar uma instância de VM em uma sub-rede específica

    Uma instância de VM do Compute Engine é uma máquina virtual hospedada na infraestrutura do Google. Os termos instância do Compute Engine, instância de VM e VM são sinônimos. As instâncias de VM incluem clusters do GKE, instâncias de ambiente flexível do App Engine e outros produtos do Google Cloud criados em VMs do Compute Engine.

    Use o comando gcloud compute instances create para criar uma instância de VM do Compute Engine na sub-rede criada anteriormente. Anexe uma conta de serviço e defina o escopo de acesso da VM como cloud-platform.

    gcloud compute instances create my-vm \
        --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com \
        --scopes=https://www.googleapis.com/auth/cloud-platform \
        --zone=us-central1-a \
        --subnet=my-subnet
    

    Para mais informações, consulte Criar e iniciar uma instância de VM.

    Implantar um receptor de eventos na VM

    Usando uma imagem pré-criada, us-docker.pkg.dev/cloudrun/container/hello, implante um serviço na VM que detecte na porta 80 e receba e registre eventos.

    1. Execute o seguinte comando para estabelecer uma conexão SSH com a instância de VM:

      gcloud compute ssh my-vm --project=PROJECT_ID --zone=us-central1-a
      

      Depois que uma conexão com o servidor SSH for estabelecida, execute os comandos restantes na instância de VM.

    2. Se necessário, instale kubectl e os plug-ins necessários.

    3. Na instância de VM, use o comando get-credentials para permitir que kubectl funcione com o cluster criado.

      gcloud container clusters get-credentials private-cluster \
          --region=us-central1 \
          --internal-ip
      
    4. Use um comando do Kubernetes, kubectl create deployment, para implantar um aplicativo no cluster.

      kubectl create deployment hello-app \
          --image=us-docker.pkg.dev/cloudrun/container/hello
      

      Isso cria uma implantação chamada hello-app. O pod da implantação executa a imagem de contêiner hello.

    5. Depois da implantação, é possível expor o aplicativo ao tráfego criando um serviço do Kubernetes. Execute este comando kubectl expose:

      kubectl expose deployment hello-app \
          --type ClusterIP \
          --port 80 \
          --target-port 8080
      

      O resultado vai mostrar service/hello-app exposed.

      Você pode ignorar qualquer mensagem semelhante a esta:

      E0418 14:15:33.970933    1129 memcache.go:287] couldn't get resource list for metrics.k8s.io/v1beta1: the server is currently unable to handle the request
      

    Configurar o roteamento de tráfego do Kubernetes

    Um recurso de gateway representa um plano de dados que roteia o tráfego no Kubernetes. Um Gateway pode representar vários tipos diferentes de balanceamento de carga e roteamento, dependendo do GatewayClass que o deriva. Para mais informações, consulte Como implantar gateways. Um manifesto HTTPRoute é implantado para criar rotas e enviar tráfego para back-ends de aplicativos.

    1. Implante um gateway no cluster.

      kubectl apply -f - <<EOF
      kind: Gateway
      apiVersion: gateway.networking.k8s.io/v1beta1
      metadata:
        name: internal-http
      spec:
        gatewayClassName: gke-l7-rilb
        listeners:
        - name: http
          protocol: HTTP
          port: 80
      EOF
      

      Observações:

      • gatewayClassName: gke-l7-rilb especifica o GatewayClass que deriva este gateway. gke-l7-rilb corresponde ao balanceador de carga de aplicativo interno.
      • port: 80 especifica que o gateway expõe apenas a porta 80 para detectar o tráfego HTTP.
    2. Verifique se o gateway foi implantado corretamente. Pode levar alguns minutos para implantar todos os recursos.

      kubectl describe gateways.gateway.networking.k8s.io internal-http
      

      O resultado será assim:

      Name:         internal-http
      Namespace:    default
      ...
      API Version:  gateway.networking.k8s.io/v1beta1
      Kind:         Gateway
      ...
      Spec:
        Gateway Class Name:  gke-l7-rilb
        Listeners:
          Allowed Routes:
            Namespaces:
              From:  Same
          Name:      http
          Port:      80
          Protocol:  HTTP
      Status:
        Addresses:
          Type:   IPAddress
          Value:  10.36.172.5
      ...
      Events:
        Type    Reason  Age                From                   Message
        ----    ------  ----               ----                   -------
        Normal  ADD     80s                sc-gateway-controller  default/internal-http
        Normal  UPDATE  20s (x3 over 80s)  sc-gateway-controller  default/internal-http
        Normal  SYNC    20s                sc-gateway-controller  SYNC on default/internal-http was a success
      
    3. Implante um manifesto HTTPRoute para rotear o tráfego HTTP para o serviço hello-app na porta 80.

      kubectl apply -f - <<EOF
      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1beta1
      metadata:
        name: hello-app-route
      spec:
        parentRefs:
        - kind: Gateway
          name: internal-http
        rules:
        - backendRefs:
          - name: hello-app
            port: 80
      EOF
      

    Criar um anexo de rede

    Um anexo de rede é um recurso que permite que uma rede VPC produtora inicie conexões com uma rede VPC consumidora por uma interface do Private Service Connect.

    Para publicar eventos, o Eventarc usa o anexo de rede para estabelecer uma conexão com o endpoint HTTP interno hospedado em uma rede VPC.

    É possível criar um anexo de rede que aceite automaticamente conexões de qualquer interface do Private Service Connect que se refira ao anexo de rede. Crie o anexo de rede na mesma rede e região que contém o serviço de destino HTTP.

    gcloud compute network-attachments create my-network-attachment \
        --region=us-central1 \
        --subnets=my-subnet\
        --connection-preference=ACCEPT_AUTOMATIC

    Para mais informações, consulte Sobre anexos de rede.

    Criar um gatilho do Eventarc

    Crie um gatilho do Eventarc que crie um novo tópico do Pub/Sub e encaminhe eventos para o receptor de eventos implantado na VM quando uma mensagem for publicada no tópico do Pub/Sub.

    1. Recupere o endereço do gateway.

      GATEWAY_ADDRESS=$(kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}")
      
    2. Crie um gatilho.

      gcloud eventarc triggers create my-trigger \
          --location=us-central1 \
          --destination-http-endpoint-uri="http://$GATEWAY_ADDRESS:80/" \
          --network-attachment="projects/PROJECT_ID/regions/us-central1/networkAttachments/my-network-attachment" \
          --event-filters="type=google.cloud.pubsub.topic.v1.messagePublished" \
          --service-account=PROJECT_NUMBER-compute@developer.gserviceaccount.com
      

      Substitua PROJECT_NUMBER pelo número do seu projeto Google Cloud. Encontre o número do projeto na página Boas-vindas do console do Google Cloud ou executando o seguinte comando:

      gcloud projects describe PROJECT_ID --format='value(projectNumber)'
      

    Para mais informações sobre como configurar seu gatilho, consulte Rotear eventos para um endpoint HTTP interno em uma rede VPC.

    Gerar e visualizar um evento de tópico do Pub/Sub.

    É possível gerar um evento publicando uma mensagem em um tópico do Pub/Sub.

    1. Encontre e defina o tópico do Pub/Sub como uma variável de ambiente:

      export MY_TOPIC=$(gcloud eventarc triggers describe my-trigger \
          --location=us-central1 \
          --format='value(transport.pubsub.topic)')
      
    2. Publique uma mensagem para o tópico do Pub/Sub a fim de gerar um evento.

      gcloud pubsub topics publish $MY_TOPIC --message "Hello World"
      

      O gatilho do Eventarc encaminha o evento para o endpoint HTTP interno no cluster particular do GKE.

    3. Verifique os registros do pod do aplicativo e a entrega do evento.

      POD_NAME=$(kubectl get pod --selector app=hello-app --output=name)
      kubectl logs $POD_NAME
      

      O corpo do evento será semelhante a este:

      2024/04/18 20:31:43 Hello from Cloud Run! The container started successfully and is listening for HTTP requests on $PORT
      {"severity":"INFO","eventType":"google.cloud.pubsub.topic.v1.messagePublished","message":"Received event of type google.cloud.pubsub.topic.v1.messagePublished.
      Event data: Hello World","event":{"specversion":"1.0","id":"10935738681111260","source":"//pubsub.googleapis.com/projects/my-project/topics/eventarc-us-central1-my-trigger-224","type":"google.cloud.pubsub.topic.v1.messagePublished","datacontenttype":"application/json","time":"2024-04-18T20:40:03Z","data":
      {"message":{"data":"SGVsbG8gV29ybGQ=","messageId":"10935738681111260","publishTime":"2024-04-18T20:40:03Z"}}}}
      

    Você implantou com sucesso um serviço de receptor de eventos em um endpoint HTTP interno em um cluster particular do GKE, criou um gatilho do Eventarc, gerou um evento do Pub/Sub e confirmou que o evento foi roteado conforme esperado pelo gatilho para o endpoint de destino.

    Limpar

    Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

    Excluir o projeto

      Delete a Google Cloud project:

      gcloud projects delete PROJECT_ID

    Excluir recursos individuais

    1. Exclua o gatilho do Eventarc:
        gcloud eventarc triggers delete my-trigger --location=us-central1
    2. Saia da VM e exclua a instância:
        gcloud compute instances delete my-vm --zone=us-central1-a
    3. Exclua o anexo de rede:
        gcloud compute network-attachments delete my-network-attachment --region=us-central1
    4. Exclua a regra do firewall:
        gcloud compute firewall-rules delete allow-proxy-connection
    5. Exclua o cluster:
        gcloud container clusters delete private-cluster --region=us-central1
        
    6. Delete the subnet:
        gcloud compute networks subnets delete proxy-only-subnet --region=us-central1

    A seguir