Receba eventos do Pub/Sub num ponto final HTTP privado num cluster do GKE privado

Este tutorial mostra como criar um ponto final HTTP privado num cluster privado do Google Kubernetes Engine (GKE) que recebe eventos de mensagens do Pub/Sub através do Eventarc. Para saber mais acerca deste destino de eventos, consulte o artigo Encaminhe eventos para um ponto final HTTP interno numa rede VPC.

Os clusters privados do GKE são um tipo de cluster nativo da nuvem privada virtual (VPC) em que os nós só têm endereços IP internos, o que significa que os nós e os pods estão isolados da Internet por predefinição. Pode optar por não ter acesso de cliente, ter acesso limitado ou ter acesso não restrito ao plano de controlo. Não pode converter um cluster existente não privado num cluster privado. Para mais informações, consulte Acerca dos clusters privados.

Pode executar os seguintes comandos através da CLI Google Cloud no seu terminal ou na Cloud Shell.

Crie uma sub-rede só de proxy

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

  1. Use o comando gcloud compute networks subnets create para criar uma sub-rede apenas de proxy na rede predefinida.

    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
    

    Tenha em atenção que uma sub-rede com purpose=REGIONAL_MANAGED_PROXY está reservada para balanceadores de carga baseados no Envoy e que a range tem de fornecer 64 ou mais endereços IP.

  2. Crie uma regra de firewall que corresponda ao intervalo da sub-rede só de 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
    

Crie um cluster privado do GKE

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

O exemplo seguinte cria um cluster do GKE privado com o nome private-cluster e também cria uma sub-rede com o nome 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

Tenha em conta o seguinte:

  • --enable-master-authorized-networks especifica que o acesso ao ponto final público está restrito a intervalos de endereços IP que autoriza.
  • --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 é gerido através do endereço IP interno do ponto final da API do plano de controlo.

A criação do cluster pode demorar vários minutos a ser concluída. Depois de criar o cluster, o resultado deve indicar que o estado do cluster é RUNNING.

Crie uma instância de VM numa sub-rede especificada

Uma instância de VM do Compute Engine é uma máquina virtual alojada na infraestrutura da Google. Os termos instância do Compute Engine, instância de VM e VM são sinónimos e são usados alternadamente. As instâncias de VM incluem clusters do GKE, instâncias do ambiente flexível do App Engine e outros Google Cloud produtos criados com base 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 que criou anteriormente. Anexe uma conta de serviço e defina o âmbito 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 o artigo Crie e inicie uma instância de VM.

Implemente um recetor de eventos na VM

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

  1. Estabeleça uma ligação SSH à sua instância de VM executando o seguinte comando:

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

    Depois de estabelecer uma ligação ao servidor SSH, execute os comandos restantes na instância da VM.

  2. Se necessário, instale kubectl e todos os plugins necessários.

  3. Na instância da VM, use o comando get-credentials para ativar o kubectl para funcionar com o cluster que criou.

    gcloud container clusters get-credentials private-cluster \
        --region=us-central1 \
        --internal-ip
    
  4. Use um comando do Kubernetes, kubectl create deployment, para implementar uma aplicação no cluster.

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

    Esta ação cria uma implementação denominada hello-app. O pod da implementação executa a imagem do contentor hello.

  5. Depois de implementar a aplicação, pode expô-la ao tráfego criando um serviço Kubernetes. Execute o seguinte comando: kubectl expose

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

    Deverá ver service/hello-app exposed no resultado.

    Pode ignorar mensagens semelhantes às seguintes:

    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
    

Configure o encaminhamento de tráfego do Kubernetes

Um recurso Gateway representa um plano de dados que encaminha o tráfego no Kubernetes. Um gateway pode representar muitos tipos diferentes de equilíbrio de carga e encaminhamento, dependendo da GatewayClass da qual deriva. Para mais informações, consulte o artigo Implementar gateways. É implementado um manifesto HTTPRoute para criar rotas e enviar tráfego para back-ends de aplicações.

  1. Implemente um Gateway no seu 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
    

    Tenha em conta o seguinte:

    • gatewayClassName: gke-l7-rilb especifica a GatewayClass a partir da qual este Gateway é derivado. gke-l7-rilb corresponde ao balanceador de carga de aplicações interno.
    • port: 80 especifica que o gateway expõe apenas a porta 80 para deteção de tráfego HTTP.
  2. Valide se o gateway foi implementado corretamente. A implementação de todos os recursos pode demorar alguns minutos.

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

    O resultado é semelhante ao seguinte:

    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. Implemente um manifesto HTTPRoute para encaminhar 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
    

Crie uma associação de rede

Uma associação de rede é um recurso que permite a uma rede da VPC do produtor iniciar ligações a uma rede da VPC do consumidor através de uma interface do Private Service Connect.

Para publicar eventos, o Eventarc usa a associação de rede para estabelecer uma ligação ao ponto final HTTP interno alojado numa rede VPC.

Pode criar uma associação de rede que aceite automaticamente ligações de qualquer interface do Private Service Connect que faça referência à associação de rede. Crie a associação 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 o artigo Acerca das associações de rede.

Crie um acionador do Eventarc

Crie um acionador do Eventarc que crie um novo tópico do Pub/Sub e encaminhe eventos para o recetor de eventos implementado na VM quando uma mensagem é publicada no tópico do Pub/Sub.

  1. Obtenha o endereço de gateway.

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

    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 seu Google Cloud número do projeto. Pode encontrar o número do projeto na página Boas-vindas da Google Cloud consola ou executando o seguinte comando:

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

Para mais informações sobre a configuração do acionador, consulte o artigo Encaminhe eventos para um ponto final HTTP interno numa rede VPC.

Gere e veja um evento de tópico Pub/Sub

Pode gerar um evento publicando uma mensagem num tópico do Pub/Sub.

  1. Encontre e defina o tópico 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 no tópico Pub/Sub para gerar um evento.

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

    O acionador do Eventarc encaminha o evento para o ponto final HTTP interno no cluster do GKE privado.

  3. Verifique os registos do pod da aplicação e valide a entrega de eventos.

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

    O corpo do evento deve ser semelhante ao seguinte:

    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"}}}}
    

Implementou com êxito um serviço de receção de eventos num ponto final HTTP interno num cluster privado do GKE, criou um acionador do Eventarc, gerou um evento a partir do Pub/Sub e confirmou que o evento foi encaminhado conforme esperado pelo acionador para o ponto final de destino.