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ê 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. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. 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.

  5. Make sure that billing is enabled for your Google Cloud project.

  6. 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
  7. Install the Google Cloud CLI.
  8. To initialize the gcloud CLI, run the following command:

    gcloud init
  9. 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.

  10. Make sure that billing is enabled for your Google Cloud project.

  11. 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
  12. Atualize os componentes da CLI do Google Cloud:
    gcloud components update
  13. Faça login usando sua conta:
    gcloud auth login
  14. Se você for o criador do projeto, receberá o papel de proprietário básico (roles/owner). Por padrão, esse papel do gerenciamento de identidade e acesso (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 para concluir o guia de início rápido, peça ao administrador para conceder a você os seguintes papéis do IAM no seu projeto:

    Para mais informações sobre como conceder papéis, consulte Gerenciar acesso.

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

  15. A conta de serviço padrão do Compute Engine é criada automaticamente depois de ativar ou usar um serviço do Google Cloud que usa o Compute Engine.

    Para fins de teste, é possível anexar essa conta de serviço a um gatilho do Eventarc para representar a identidade do gatilho. Observe o formato de e-mail a ser usado ao criar um acionador:

    PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Substitua PROJECT_NUMBER pelo número do projeto do 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)'

    A conta de serviço do Compute Engine recebe o papel básico de Editor (roles/editor) de modo automático no projeto. No entanto, se as concessões automáticas de papéis tiverem sido desativadas, consulte as instruções aplicáveis em Papéis e permissões para criar uma nova conta de serviço e conceder os papéis necessários.

  16. Se você ativou o agente de serviço do Cloud Pub/Sub até 8 de abril de 2021, para oferecer suporte a solicitações push autenticadas do Pub/Sub, conceda o papel Criador de token da conta de serviço. (roles/iam.serviceAccountTokenCreator) à conta de serviço gerenciada pelo Google. 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

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 o seguinte 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 projeto do 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.

Exclua 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. Exclua a sub-rede:
      gcloud compute networks subnets delete proxy-only-subnet --region=us-central1

A seguir