Recibe eventos de Pub/Sub en un extremo HTTP privado en un clúster de GKE privado


En este instructivo, se muestra cómo crear un extremo HTTP privado en un clúster privado de Google Kubernetes Engine (GKE) que recibe eventos de mensajes de Pub/Sub con Eventarc. Para obtener más información sobre este destino del evento, consulta Enruta eventos a un extremo HTTP interno en una red de VPC.

Los clústeres de GKE privados son un tipo de clúster nativo de la nube privada virtual (VPC) en el que los nodos solo tienen direcciones IP internas, lo que significa que los nodos y los Pods están aislados de los Internet de forma predeterminada. Puedes optar por no tener acceso de cliente, tener acceso limitado o tener acceso ilimitado al plano de control. No puedes convertir un clúster público existente en un clúster privado. Para obtener más información, consulta Acerca de los clústeres privados.

Puedes ejecutar los siguientes comandos con Google Cloud CLI en la terminal o en Cloud Shell.

Objetivos

En este instructivo, podrás:

  1. Crea una subred de solo proxy en la red de VPC predeterminada y una regla de firewall de VPC.
  2. Crear un clúster privado de GKE Autopilot sin acceso de clientes al extremo público.
  3. Crear una instancia de máquina virtual (VM) de Compute Engine en una subred específica de la red de VPC
  4. Establece una conexión SSH a la instancia de VM e implementa un servicio de receptor de eventos en la instancia de VM.
  5. Implementa una puerta de enlace en tu clúster y un manifiesto HTTPRoute para configurar el enrutamiento de tráfico en Kubernetes a los backends de aplicaciones.
  6. Crear un adjunto de red que permita a una red de VPC del productor iniciar conexiones a una red de VPC del consumidor.
  7. Crear un activador de Eventarc que enrute los eventos de Pub/Sub al receptor de eventos en tu instancia de VM.
  8. Publicar un mensaje en un tema de Pub/Sub para generar un evento y visualizar el cuerpo del evento en los registros del Pod de la aplicación.

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.

Antes de comenzar

  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. Actualiza los componentes de Google Cloud CLI:
    gcloud components update
  13. Accede con tu cuenta:
    gcloud auth login
  14. Si eres el creador del proyecto, se te otorga el rol de propietario básico (roles/owner). De forma predeterminada, este rol de Identity and Access Management (IAM) incluye los permisos necesarios para obtener acceso completo a la mayoría de los recursos de Google Cloud, pero puedes omitir este paso.

    Si no eres el creador del proyecto, se deben otorgar los permisos necesarios en el proyecto a la principal correspondiente. Por ejemplo, una principal puede ser una Cuenta de Google (para usuarios finales) o una cuenta de servicio (para aplicaciones y cargas de trabajo de procesamiento). Para obtener más información, consulta la página Roles y permisos para el destino del evento.

    Permisos necesarios

    Si quieres obtener los permisos que necesitas para completar esta guía de inicio rápido, pídele a tu administrador que te otorgue los siguientes roles de IAM en tu proyecto:

    Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

    También puedes obtener los permisos necesarios mediante roles personalizados o cualquier otro rol predefinido.

  15. Toma nota del recurso Compute Engine predeterminada, ya que la conectarás a un activador de Eventarc para representar la identidad del activador con fines de prueba. Esta cuenta de servicio se crea automáticamente después de habilitar o usar un servicio de Google Cloud que use Compute Engine, y con la siguiente formato de correo electrónico:

    PROJECT_NUMBER-compute@developer.gserviceaccount.com

    Reemplaza PROJECT_NUMBER por el número de proyecto de Google Cloud. Para encontrar el número del proyecto, ve a la página de bienvenida de la consola de Google Cloud o ejecuta el siguiente comando:

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

    Para entornos de producción, recomendamos crear una cuenta de servicio nueva y otorgarle una o más funciones de IAM que contengan los permisos mínimos requeridos y seguir el principio de privilegio mínimo.

  16. Si habilitaste el agente de servicio de Cloud Pub/Sub el 8 de abril de 2021 o antes de esa fecha, para admitir las solicitudes de envío de Pub/Sub autenticadas, otorga el rol de creador de tokens de cuenta de servicio (roles/iam.serviceAccountTokenCreator) al agente de servicio. De lo contrario, este rol se otorga de forma predeterminada:
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:service-PROJECT_NUMBER@gcp-sa-pubsub.iam.gserviceaccount.com \
        --role=roles/iam.serviceAccountTokenCreator

Crea una subred de solo proxy

A menos que crees una política de la organización que la prohíba, los proyectos nuevos comienzan con una red predeterminada (una red de VPC en modo automático) que tiene una subred en cada región. Cada red de VPC consta de uno o más rangos de direcciones IP llamados subredes. Las subredes son recursos regionales y tienen rangos de direcciones IP asociados.

  1. Usa el comando gcloud compute networks subnets createpara crear una subred de solo proxy en la red predeterminada.

    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
    

    Ten en cuenta que una subred con purpose=REGIONAL_MANAGED_PROXY está reservada para los balanceadores de cargas basados en Envoy y que range debe proporcionar 64 direcciones IP o más.

  2. Crea una regla de firewall que coincida con el rango de la subred de solo proxy y que permita el tráfico en el puerto TCP 8080.

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

Crea un clúster de GKE privado

Usa el comando gcloud container clusters create-auto para crear un clúster de GKE privado en modo Autopilot que tenga nodos privados y que no tenga acceso de clientes en el extremo público.

En el siguiente ejemplo, se crea un clúster de GKE privado llamado private-cluster y también se crea una subred llamada 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

Ten en cuenta lo siguiente:

  • --enable-master-authorized-networks especifica que el acceso al extremo público está restringido a los rangos de direcciones IP que autorices.
  • --enable-private-nodes indica que los nodos del clúster no tienen direcciones IP externas.
  • --enable-private-endpoint indica que el clúster se administra con la dirección IP interna del extremo de API del plano de control.

La creación del clúster puede tardar varios minutos en completarse. Una vez que se crea el clúster, el resultado debe indicar que el estado del clúster es RUNNING.

Crea una instancia de VM en una subred específica

Una instancia de VM de Compute Engine es una máquina virtual alojada en la infraestructura de Google. Los términos instancia de Compute Engine, instancia de VM y VM son sinónimos y se usan de manera intercambiable. Las instancias de VM incluyen clústeres de GKE, instancias del entorno flexible de App Engine y otros productos de Google Cloud compilados en VMs de Compute Engine.

Usa el comando gcloud compute instances create para crear una instancia de VM de Compute Engine en la subred que creaste antes. Conecta una cuenta de servicio y configura el permiso de acceso de la VM en 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 obtener más información, consulta Crea y, luego, inicia una instancia de VM.

Implementa un receptor de eventos en la VM

Con una imagen compilada previamente, us-docker.pkg.dev/cloudrun/container/hello, implementa un servicio en tu VM que escuche en el puerto 80 y que reciba y registre eventos.

  1. Establece una conexión SSH a tu instancia de VM mediante la ejecución del siguiente comando:

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

    Después de establecer una conexión al servidor SSH, ejecuta los comandos restantes en tu instancia de VM.

  2. Si es necesario, instala kubectl y cualquier complemento necesario.

  3. Desde tu instancia de VM, usa el comando get-credentials para habilitar kubectl de modo de que funcione con el clúster que creaste.

    gcloud container clusters get-credentials private-cluster \
        --region=us-central1 \
        --internal-ip
    
  4. Usa un comando de Kubernetes, kubectl create deployment, para implementar una aplicación en el clúster.

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

    Esto crea un objeto Deployment llamado hello-app. El pod del Deployment ejecuta la imagen del contenedor hello.

  5. Después de implementar la aplicación, puedes exponerla al tráfico con la creación de un Service de Kubernetes. Ejecuta el siguiente comando kubectl expose:

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

    Deberías ver service/hello-app exposed en el resultado.

    Puedes ignorar cualquier mensaje similar al siguiente:

    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
    

Configura el enrutamiento de tráfico de Kubernetes

Un recurso de puerta de enlace representa un plano de datos que enruta el tráfico en Kubernetes. Una puerta de enlace puede representar muchos tipos diferentes de balanceo de cargas y enrutamiento según la GatewayClass de la que deriva. Para obtener más información, consulta Implementa puertas de enlace. Se implementa un manifiesto HTTPRoute para crear rutas y enviar tráfico a los backends de aplicaciones.

  1. Implementa una Gateway en tu clúster.

    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
    

    Ten en cuenta lo siguiente:

    • gatewayClassName: gke-l7-rilb especifica la GatewayClass de la que deriva esta puerta de enlace. gke-l7-rilb corresponde al balanceador de cargas de aplicaciones interno.
    • port: 80 especifica que la puerta de enlace expone solo el puerto 80 para escuchar el tráfico HTTP.
  2. Verifica que la puerta de enlace se haya implementado de forma correcta. La implementación de todos sus recursos puede llevar unos minutos.

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

    El resultado es similar al siguiente:

    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. Implementa un manifiesto HTTPRoute para enrutar el tráfico HTTP al servicio hello-app en el puerto 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
    

Crea un adjunto de red

Un adjunto de red es un recurso que permite que una red de VPC del productor inicie conexiones a una red de VPC del consumidor a través de una interfaz de Private Service Connect.

Para publicar eventos, Eventarc usa el adjunto de red para establecer una conexión con el extremo HTTP interno alojado en una red de VPC.

Puedes crear un adjunto de red que acepte conexiones de forma automática desde cualquier interfaz de Private Service Connect que haga referencia al adjunto de red. Crea el adjunto de red en la misma red y región que contiene el servicio de destino HTTP.

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

Para obtener más información, consulta Acerca de los adjuntos de red.

Crea un activador de Eventarc

Crea un activador de Eventarc que cree un nuevo tema de Pub/Sub y enrute eventos al receptor de eventos implementado en la VM cuando se publique un mensaje en el tema de Pub/Sub.

  1. Recupera la dirección de la puerta de enlace.

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

    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
    

    Reemplaza PROJECT_NUMBER por el número de proyecto de Google Cloud. Para encontrar el número del proyecto, ve a la página de bienvenida de la consola de Google Cloud o ejecuta el siguiente comando:

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

Para obtener más información sobre cómo configurar el activador, consulta Enruta eventos a un extremo HTTP interno en una red de VPC.

Genera y visualiza un evento de tema de Pub/Sub

Puedes generar un evento si publicas un mensaje en un tema de Pub/Sub.

  1. Busca y establece el tema Pub/Sub como una variable de entorno.

    export MY_TOPIC=$(gcloud eventarc triggers describe my-trigger \
        --location=us-central1 \
        --format='value(transport.pubsub.topic)')
    
  2. Publicar un mensaje en el tema de Pub/Sub para generar un evento.

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

    El activador de Eventarc enruta el evento al extremo HTTP interno en el clúster de GKE privado.

  3. Comprueba los registros del Pod de la aplicación y verifica la entrega de los eventos.

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

    El cuerpo del evento debe ser similar al siguiente:

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

Implementaste un servicio del receptor de eventos en un extremo HTTP interno en un clúster privado de GKE de forma correcta, creaste un activador de Eventarc, generaste un evento de Pub/Sub y confirmaste que el activador enrutó el evento al extremo objetivo según lo esperado.

Realiza una limpieza

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

Borra el proyecto

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

Borra los recursos individuales

  1. Borrar el activador de Eventarc:
      gcloud eventarc triggers delete my-trigger --location=us-central1
  2. Sal de la VM y, luego, borra la instancia de VM:
      gcloud compute instances delete my-vm --zone=us-central1-a
  3. Borra el adjunto de red:
      gcloud compute network-attachments delete my-network-attachment --region=us-central1
  4. Borra la regla de firewall:
      gcloud compute firewall-rules delete allow-proxy-connection
  5. Borra el clúster:
      gcloud container clusters delete private-cluster --region=us-central1
      
  6. Delete the subnet:
      gcloud compute networks subnets delete proxy-only-subnet --region=us-central1

¿Qué sigue?