Recevoir des événements Pub/Sub sur un point de terminaison HTTP privé dans un cluster GKE privé

Ce tutoriel explique comment créer un point de terminaison HTTP privé dans un cluster privé Google Kubernetes Engine (GKE) qui reçoit des événements de messages Pub/Sub à l'aide d'Eventarc. Pour en savoir plus sur cette destination d'événement, consultez la page Acheminer des événements vers un point de terminaison HTTP interne dans un réseau VPC.

Les clusters GKE privés sont un type de cluster de cloud privé virtuel (VPC) natif dans lequel les nœuds ne disposent que d'adresses IP internes, ce qui signifie que les nœuds et les pods sont isolés d'Internet par défaut. Vous pouvez choisir de ne pas disposer d'un accès client, d'un accès limité ou d'un accès illimité au plan de contrôle. Vous ne pouvez pas convertir un cluster non privé existant en cluster privé. Pour plus d'informations, consultez la page À propos des clusters privés.

Vous pouvez exécuter les commandes suivantes à l'aide de Google Cloud CLI dans votre terminal ou Cloud Shell.

Créer un sous-réseau proxy réservé

Sauf si vous créez une règle d'administration qui l'interdit, les nouveaux projets démarrent avec un réseau par défaut (un réseau VPC en mode automatique) qui possède un sous-réseau dans chaque région. Chaque réseau VPC est constitué d'une ou de plusieurs plages d'adresses IP appelées sous-réseaux. Les sous-réseaux sont des ressources régionales auxquelles sont associées des plages d'adresses IP.

  1. Utilisez la commande gcloud compute networks subnets create pour créer un sous-réseau proxy réservé dans le réseau par défaut.

    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
    

    Notez qu'un sous-réseau avec purpose=REGIONAL_MANAGED_PROXY est réservé aux équilibreurs de charge basés sur Envoy et que range doit fournir au moins 64 adresses IP.

  2. Créez une règle de pare-feu correspondant à la plage du sous-réseau proxy réservé et qui autorise le trafic sur le port TCP 8080.

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

Créer un cluster GKE privé

Exécutez la commande gcloud container clusters create-auto pour créer un cluster GKE privé en mode Autopilot avec des nœuds privés et sans accès client au point de terminaison public.

L'exemple suivant crée un cluster GKE privé nommé private-cluster et crée également un sous-réseau nommé 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

Veuillez noter les points suivants :

  • --enable-master-authorized-networks spécifie que l'accès au point de terminaison public est limité aux plages d'adresses IP que vous autorisez.
  • --enable-private-nodes indique que les nœuds du cluster ne possèdent pas d'adresses IP externes.
  • --enable-private-endpoint indique que le cluster est géré à l'aide de l'adresse IP interne du point de terminaison de l'API du plan de contrôle.

La création du cluster peut prendre plusieurs minutes. Une fois le cluster créé, le résultat doit indiquer que son état est RUNNING.

Créer une instance de VM dans un sous-réseau spécifique

Une instance de VM Compute Engine est une machine virtuelle hébergée sur l'infrastructure de Google. Les termes instance Compute Engine, instance de VM et VM sont synonymes et sont utilisés de manière interchangeable. Les instances de VM incluent des clusters GKE, des instances de l'environnement flexible App Engine et d'autres produits Google Cloud basés sur des VM Compute Engine.

Exécutez la commande gcloud compute instances create pour créer une instance de VM Compute Engine dans le sous-réseau que vous avez créé précédemment. Associez un compte de service et définissez le niveau d'accès de la VM sur 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

Pour en savoir plus, consultez la page Créer et démarrer une instance de VM.

Déployer un récepteur d'événements sur la VM

À l'aide d'une image prédéfinie, us-docker.pkg.dev/cloudrun/container/hello, déployez un service sur votre VM qui écoute sur le port 80, et reçoit et consigne les événements.

  1. Établissez une connexion SSH avec votre instance de VM en exécutant la commande suivante:

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

    Une fois la connexion au serveur SSH établie, exécutez les commandes restantes sur votre instance de VM.

  2. Si nécessaire, installez kubectl et tous les plug-ins requis.

  3. À partir de votre instance de VM, exécutez la commande get-credentials pour activer kubectl afin de pouvoir l'utiliser avec le cluster que vous venez de créer.

    gcloud container clusters get-credentials private-cluster \
        --region=us-central1 \
        --internal-ip
    
  4. Exécutez une commande Kubernetes kubectl create deployment pour déployer une application sur le cluster.

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

    Cela crée un déploiement nommé hello-app. Le pod de ce déploiement exécute l'image de conteneur hello.

  5. Après avoir déployé l'application, vous pouvez l'exposer au trafic en créant un service Kubernetes. Exécutez la commande kubectl exposeci-dessous :

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

    Vous devriez voir service/hello-app exposed dans le résultat.

    Vous pouvez ignorer tous les messages semblables à celui-ci:

    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
    

Configurer le routage du trafic Kubernetes

Une ressource Gateway représente un plan de données qui achemine le trafic dans Kubernetes. Une ressource Gateway peut représenter de nombreux types d'équilibrage de charge et de routage différents en fonction de la ressource GatewayClass dont elle est dérivée. Pour en savoir plus, consultez la section Déployer des passerelles. Un fichier manifeste HTTPRoute est déployé pour créer des routes et envoyer le trafic aux backends d'application.

  1. Déployez une ressource Gateway dans votre 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
    

    Veuillez noter les points suivants :

    • gatewayClassName: gke-l7-rilb spécifie la ressource GatewayClass à partir de laquelle cette ressource Gateway est dérivée. gke-l7-rilb correspond à l'équilibreur de charge d'application interne.
    • port: 80 indique que la ressource Gateway n'expose que le port 80 pour l'écoute du trafic HTTP.
  2. Confirmez que la ressource Gateway a été correctement déployée. Le déploiement de toutes ses ressources peut prendre quelques minutes.

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

    Le résultat ressemble à ce qui suit :

    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. Déployez un fichier manifeste HTTPRoute pour acheminer le trafic HTTP vers le service hello-app sur le port 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
    

Créer un rattachement de réseau

Un rattachement de réseau est une ressource qui permet à un réseau VPC producteur d'établir des connexions à un réseau VPC consommateur via une interface Private Service Connect.

Pour publier des événements, Eventarc utilise le rattachement de réseau pour établir une connexion au point de terminaison HTTP interne hébergé dans un réseau VPC.

Vous pouvez créer un rattachement de réseau qui accepte automatiquement les connexions de n'importe quelle interface Private Service Connect qui fait référence au rattachement de réseau. Créez le rattachement de réseau dans le même réseau et la même région que ceux contenant le service de destination HTTP.

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

Pour en savoir plus, consultez la page À propos des rattachements de réseau.

Créer un déclencheur Eventarc

Créez un déclencheur Eventarc qui crée un sujet Pub/Sub et achemine les événements vers le récepteur d'événements déployé sur la VM lorsqu'un message est publié dans le sujet Pub/Sub.

  1. Récupérez l'adresse de la ressource Gateway.

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

    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
    

    Remplacez PROJECT_NUMBER par votre numéro de projet Google Cloud. Vous pouvez trouver le numéro de votre projet sur la page Bienvenue de la console Google Cloud ou en exécutant la commande suivante :

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

Pour plus d'informations sur la configuration du déclencheur, consultez la section Router des événements vers un point de terminaison HTTP interne dans un réseau VPC.

Générer et afficher un événement de type sujet Pub/Sub.

Vous pouvez générer un événement en publiant un message dans un sujet Pub/Sub.

  1. Recherchez et définissez le sujet Pub/Sub en tant que variable d'environnement.

    export MY_TOPIC=$(gcloud eventarc triggers describe my-trigger \
        --location=us-central1 \
        --format='value(transport.pubsub.topic)')
    
  2. Envoyer un message au sujet Pub/Sub pour générer un événement.

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

    Le déclencheur Eventarc achemine l'événement vers le point de terminaison HTTP interne du cluster GKE privé.

  3. Consultez les journaux du pod de l'application et vérifiez la diffusion des événements.

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

    Le corps de l'événement doit se présenter comme suit :

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

Vous venez de déployer un service récepteur d'événements sur un point de terminaison HTTP interne d'un cluster GKE privé, de créer un déclencheur Eventarc, de générer un événement à partir de Pub/Sub et de confirmer que l'événement a été acheminé comme prévu par le déclencheur vers le point de terminaison cible.