Configurer des services gRPC sans proxy basés sur des VM avec la gestion avancée du trafic

Ce document fournit des instructions de bout en bout pour configurer Traffic Director avec les fonctionnalités de routage suivantes :

  • Mise en correspondance des routes
  • Répartition du trafic

Pour obtenir des informations conceptuelles sur ces fonctionnalités, consultez la page sur la gestion avancée du trafic.

Pour illustrer ces fonctionnalités, vous devez déployer un exemple de portefeuille gRPC. Comme illustré dans le schéma ci-dessous, vous créez des services de backend pour wallet-service, stats-service et account-service.

Exemple de configuration de routage du trafic de portefeuille gRPC (cliquez pour agrandir)
Exemple de configuration de routage du trafic de portefeuille gRPC (cliquez pour agrandir)

Dans cet exemple, vous déployez plusieurs versions de chaque service pour illustrer le routage des requêtes en fonction des règles que vous configurez. Pour simuler la création et le déploiement de différentes versions d'un service, vous utilisez des options de serveur pour modifier le comportement des binaires que vous créez une seule fois.

  • L'option --port spécifie le port d'écoute du service sur la VM de backend.
  • L'option --hostname_suffix spécifie une valeur ajoutée au nom d'hôte de la VM qui répond à une requête. La valeur obtenue est ajoutée en tant que métadonnées hostname dans la réponse. Cela vous permet d'identifier l'instance d'un service de backend qui a répondu à la requête du client.
  • L'option --premium_only avec la valeur true indique que le service est une version premium du service stats.
  • L'option --v1_behavior avec la valeur true indique que le binaire du portefeuille se comporte comme une version v1.
Service Groupe d'instances Instance(s) Options de serveur
account account 2 --port=50053
--hostname_suffix="account"
stats stats 2 --port=50052
--hostname_suffix="stats"
--account_server="xds:///account.grpcwallet.io"
stats-premium stats-premium 2 --port=50052
--hostname_suffix="stats_premium"
--account_server="xds:///account.grpcwallet.io"
--premium_only=true
wallet-v1 wallet-v1 2 --port=50051
--hostname_suffix="wallet_v1"
--v1_behavior=true
--account_server="xds:///account.grpcwallet.io"
--stats_server="xds:///stats.grpcwallet.io"
wallet-v2 wallet-v2 2 --port=50051
--hostname_suffix "wallet_v2"
--account_server="xds:///account.grpcwallet.io"
--stats_server="xds:///stats.grpcwallet.io"

Configurez ensuite Traffic Director de manière à acheminer les requêtes vers ces services depuis un client de test, en fonction des règles de routage suivantes :

Hôte Règles de correspondance Action de routage
wallet.grpcwallet.io Par défaut wallet-v1
Chemin complet : /grpc.examples.wallet.Wallet/FetchBalance wallet-v1 : 40 %
wallet-v2 : 60 %
Préfixe de chemin d'accès : /grpc.examples.wallet.Wallet/ wallet-v2
stats.grpcwallet.io Par défaut stats
Préfixe de chemin d'accès : "/"
En-tête : {"membership": "premium"}
stats-premium
account.grpcwallet.io Par défaut account

Créer la vérification de l'état et la règle de pare-feu gRPC

Dans cette section, vous créez une vérification de l'état gRPC et une règle de pare-feu pour permettre aux requêtes de vérification de l'état gRPC d'atteindre votre réseau. Plus tard, la vérification de l'état gRPC est associée aux services de backend pour vérifier l'état des backends dans ces services de backend.

gcloud

  1. Créez la vérification de l'état.

    gcloud compute health-checks create grpc grpcwallet-health-check \
      --use-serving-port
    
  2. Créez la règle de pare-feu pour la vérification de l'état.

    gcloud compute firewall-rules create grpcwallet-allow-health-checks \
       --network default --action allow --direction INGRESS \
       --source-ranges 35.191.0.0/16,130.211.0.0/22 \
       --target-tags allow-health-checks \
       --rules tcp:50051-50053
    

Créer le modèle d'instance

Dans cette section, vous créez un modèle d'instance pour déployer le service gRPC account exposé sur le port 50053.

gcloud

  1. Créez le modèle d'instance.

    gcloud compute instance-templates create grpcwallet-account-template \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --tags=allow-health-checks \
      --image-family=debian-10 \
      --image-project=debian-cloud \
      --metadata-from-file=startup-script=<(echo '#! /bin/bash
    set -ex
    cd /root
    export HOME=/root
    sudo apt-get update -y
    curl -L https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples/archive/master.tar.gz | tar -xz
    cd traffic-director-grpc-examples-master/go/account_server/
    sudo apt-get install -y golang git
    go build .
    sudo systemd-run ./account_server --port 50053 --hostname_suffix account')
    

Créer un groupe d'instances géré

Les groupes d'instances gérés utilisent l'autoscaling pour créer des VM de backend en fonction des besoins. Dans cette section, vous créez un groupe d'instances géré à l'aide du modèle d'instance que vous avez créé à la section précédente.

gcloud

  1. Créez le groupe d'instances.

    gcloud compute instance-groups managed create grpcwallet-account-mig-us-central1 \
      --zone us-central1-a \
      --size=2 \
      --template=grpcwallet-account-template
    

Configurer le port nommé

Dans cette section, vous configurez le port nommé pour le service gRPC. Le port nommé est le port sur lequel le service gRPC écoute les requêtes. Dans cet exemple, le port nommé est le port 50053.

gcloud

  1. Créez le port nommé.

    gcloud compute instance-groups set-named-ports grpcwallet-account-mig-us-central1 \
      --named-ports=grpcwallet-account-port:50053 \
      --zone us-central1-a
    

Créer un service de backend

Dans cette section, vous créez un service de backend global avec un schéma d'équilibrage de charge INTERNAL_SELF_MANAGED et le protocole GRPC, puis vous associez la vérification de l'état et le groupe d'instances au service de backend. Dans cet exemple, vous utilisez le groupe d'instances géré que vous avez créé à la section Créer un groupe d'instances géré. Ce groupe d'instances géré exécute le service gRPC account. Le port de l'option --port-name est le port nommé que vous avez créé dans la section Configurer le port nommé.

gcloud

  1. Créez le service de backend et associez la vérification de l'état au nouveau service de backend.

    gcloud compute backend-services create grpcwallet-account-service \
        --global \
        --load-balancing-scheme=INTERNAL_SELF_MANAGED \
        --protocol=GRPC \
        --port-name=grpcwallet-account-port \
        --health-checks grpcwallet-health-check
    
  2. Ajoutez le groupe d'instances géré en tant que backend.

    gcloud compute backend-services add-backend grpcwallet-account-service \
      --instance-group grpcwallet-account-mig-us-central1 \
      --instance-group-zone us-central1-a \
      --global
    

La procédure de création des services de backend restants utilisés dans l'exemple de portefeuille gRPC est semblable à celle décrite ci-dessus. Pour créer les services restants, exécutez un script shell. Le script déploie les services de backend suivants :

  • stats
  • stats-premium
  • wallet-v1
  • wallet-v2

Exécutez le script shell qui crée les services de backend supplémentaires :

curl -O https://raw.githubusercontent.com/GoogleCloudPlatform/traffic-director-grpc-examples/master/scripts/create_service.sh
chmod +x ./create_service.sh

./create_service.sh go stats 50052 stats '--account_server="xds:///account.grpcwallet.io"'

./create_service.sh go stats 50052 stats-premium '--account_server="xds:///account.grpcwallet.io" --premium_only=true'

./create_service.sh java wallet 50051 wallet-v1 '--account_server="xds:///account.grpcwallet.io" --stats_server="xds:///stats.grpcwallet.io" --v1_behavior=true'

./create_service.sh java wallet 50051 wallet-v2 '--account_server="xds:///account.grpcwallet.io" --stats_server="xds:///stats.grpcwallet.io"'

Créer les règles de routage

Dans cette section, vous créez un mappage d'URL qui spécifie les noms d'hôte virtuel des services de cet exemple et les règles de routage associées. Pour plus d'informations, consultez la page sur les cartes des règles de routage.

Dans le mappage d'URL, hostRules spécifie les noms d'hôte virtuel des services de l'exemple. Il s'agit des noms qu'un client utilise dans l'URI du canal pour se connecter à un service spécifique. Par exemple, pour envoyer une requête au service account, un client utilise xds:///account.grpcwallet.io dans l'URI du canal. Vous devez configurer une entrée hosts avec la valeur account.grpcwallet.io dans hostRules.

Le paramètre pathMatcher associé à une entrée hosts spécifie le nom de la ressource pathMatcher contenant toutes les règles de routage de cet hôte virtuel. Une configuration pathMatcher se compose de règles de mise en correspondance et de règles d'action correspondantes. L'exemple donne la configuration suivante :

  • Lorsqu'une requête est envoyée à account.grpcwallet.io, envoyez la requête au service de backend grpcwallet-account-service.
  • Lorsqu'une requête est envoyée à stats.grpcwallet.io :
    • Si la requête contient l'en-tête membership avec la valeur premium, envoyez la requête au service de backend grpcwallet-stats-premium-service.
    • Sinon, envoyez la requête au service de backend par défaut grpcwallet-stats-service.
  • Lorsqu'une requête est envoyée à wallet.grpcwallet.io :

    • Si ServiceName/MethodName correspond à /grpc.examples.wallet.Wallet/FetchBalance, envoyez 40 % de ces requêtes au service de backend grpcwallet-wallet-v2-service, et les requêtes restantes au service de backend grpcwallet-wallet-v1-service.
    • Sinon, si ServiceName correspond à /grpc.examples.wallet.Wallet/, quelle que soit la méthode appelée, envoyez la requête au service de backend grpcwallet-wallet-v1-service.

gcloud

Exécutez la commande suivante pour créer le mappage d'URL :

export PROJECT_ID=$(gcloud config list --format 'value(core.project)')

gcloud compute url-maps import grpcwallet-url-map << EOF
defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-account-service
name: grpcwallet-url-map
hostRules:
- hosts:
  - account.grpcwallet.io
  pathMatcher: grpcwallet-account-path-matcher
- hosts:
  - stats.grpcwallet.io
  pathMatcher: grpcwallet-stats-path-matcher
- hosts:
  - wallet.grpcwallet.io
  pathMatcher: grpcwallet-wallet-path-matcher
pathMatchers:
- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-account-service
  name: grpcwallet-account-path-matcher
- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-stats-service
  name: grpcwallet-stats-path-matcher
  routeRules:
  - matchRules:
    - prefixMatch: /
      headerMatches:
      - headerName: membership
        exactMatch: premium
    priority: 0
    service: projects/$PROJECT_ID/global/backendServices/grpcwallet-stats-premium-service
- defaultService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v1-service
  name: grpcwallet-wallet-path-matcher
  routeRules:
  - matchRules:
    - fullPathMatch: /grpc.examples.wallet.Wallet/FetchBalance
    priority: 0
    routeAction:
      weightedBackendServices:
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v2-service
        weight: 40
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v1-service
        weight: 60
  - matchRules:
    - prefixMatch: /grpc.examples.wallet.Wallet/
    priority: 1
    routeAction:
      weightedBackendServices:
      - backendService: projects/$PROJECT_ID/global/backendServices/grpcwallet-wallet-v2-service
        weight: 100
EOF

Créer le proxy cible et la règle de transfert

Dans cette section, vous créez le proxy gRPC cible et une règle de transfert.

Le proxy gRPC cible référence le mappage d'URL que vous avez créé à l'étape précédente. L'option --validate-for-proxyless active les vérifications de configuration afin de ne pas activer accidentellement une fonctionnalité qui n'est pas compatible avec les déploiements gRPC sans proxy.

gcloud

  1. Créez le proxy gRPC cible.

    gcloud compute target-grpc-proxies create grpcwallet-proxy \
      --url-map grpcwallet-url-map \
      --validate-for-proxyless
    

La règle de transfert fait référence au proxy gRPC cible que vous avez créé. Le schéma d'équilibrage de charge est défini sur INTERNAL_SELF_MANAGED pour indiquer que cette règle de transfert est utilisée par Traffic Director. Il doit s'agir d'une règle de transfert globale. L'adresse IP est définie sur 0.0.0.0, car un client gRPC sans proxy résout le hostname:port dans l'URI cible en envoyant une requête LDS à Traffic Director au lieu d'effectuer une résolution DNS Pour en savoir plus, consultez la section Schéma de résolution des noms.

Lorsqu'un port n'est pas spécifié dans l'URI cible, la valeur par défaut est 80. Par exemple, un URI cible xds:///foo.myservice:8080 correspond à une règle de transfert configurée avec le port 8080. Dans cet exemple, la règle de transfert est configurée avec le port 80.

gcloud

  1. Créez la règle de transfert.

    gcloud compute forwarding-rules create grpcwallet-forwarding-rule \
       --global \
       --load-balancing-scheme=INTERNAL_SELF_MANAGED \
       --address=0.0.0.0 --address-region=us-central1 \
       --target-grpc-proxy=grpcwallet-proxy \
       --ports 80 \
       --network default
    

Vérifier la configuration

Une fois le processus de configuration terminé, vérifiez que les services de backend que vous avez configurés sont disponibles en consultant la page Traffic Director dans la console. Vérifiez que les services de backend et les backends associés sont signalés comme étant opérationnels.

Vérifier la configuration du routage

Dans cette section, vous vérifiez que la configuration de routage fonctionne correctement. Utilisez l'outil grpcurl pour tester la configuration.

gcloud

  1. Créez une VM cliente sur laquelle vous exécutez les clients pour tester le service.

    gcloud compute instances create grpc-wallet-client \
      --zone us-central1-a \
      --scopes=https://www.googleapis.com/auth/cloud-platform \
      --image-family=debian-10 \
      --image-project=debian-cloud \
      --metadata-from-file=startup-script=<(echo '#! /bin/bash
    set -e
    export GRPC_XDS_BOOTSTRAP=/run/td-grpc-bootstrap.json
    # Expose bootstrap variable to SSH connections
    echo export GRPC_XDS_BOOTSTRAP=$GRPC_XDS_BOOTSTRAP | sudo tee /etc/profile.d/grpc-xds-bootstrap.sh
    # Create the bootstrap file
    curl -L https://storage.googleapis.com/traffic-director/td-grpc-bootstrap-0.9.0.tar.gz | tar -xz
    ./td-grpc-bootstrap-0.9.0/td-grpc-bootstrap | tee $GRPC_XDS_BOOTSTRAP')
    
  2. Accédez à la VM à l'aide de SSH.

Pour accéder aux services sans proxy side-car, le client gRPC doit utiliser le schéma de résolution de noms xds. Ce schéma indique à la bibliothèque gRPC utilisée dans le client qu'elle doit utiliser un serveur xDS pour résoudre le nom d'hôte. Pour ce faire, une configuration d'amorçage est nécessaire. Le script de démarrage de la section précédente définit la variable d'environnement GRPC_XDS_BOOTSTRAP et utilise un script d'aide pour générer le fichier d'amorçage. Les valeurs de TRAFFICDIRECTOR_GCP_PROJECT_NUMBER, TRAFFICDIRECTOR_NETWORK_NAME et de la zone du fichier d'amorçage généré sont obtenues auprès du serveur de métadonnées qui connaissent ces détails sur vos instances de VM Compute Engine. Vous pouvez fournir manuellement ces valeurs au script d'aide à l'aide des options -gcp-project-number et -vpc-network-name.

Vérifier la configuration à l'aide de l'outil grpcurl

Commencez par installer l'outil grpcurl.

curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.6.1/grpcurl_1.6.1_linux_x86_64.tar.gz | tar -xz
chmod +x grpcurl

Exécutez ensuite les commandes suivantes pour vérifier que les services Account, Stats et Wallet sont en cours d'exécution.

$ ./grpcurl -plaintext xds:///account.grpcwallet.io list
grpc.examples.wallet.account.Account
grpc.health.v1.Health
grpc.reflection.v1alpha.ServerReflection

$ ./grpcurl -plaintext -d '{"token": "2bd806c9"}' xds:///account.grpcwallet.io grpc.examples.wallet.account.Account/GetUserInfo
{
  "name": "Alice",
  "membership": "PREMIUM"
}

$ ./grpcurl -plaintext -H 'authorization:2bd806c9' -H 'membership:premium' xds:///stats.grpcwallet.io grpc.examples.wallet.stats.Stats/FetchPrice
{
  "price": "10295"
}

$ ./grpcurl -plaintext -H 'authorization:2bd806c9' -H 'membership:premium' -d '{"include_balance_per_address": true}' xds:///wallet.grpcwallet.io grpc.examples.wallet.Wallet/FetchBalance
{
  "balance": "5089953"
}

Vérifier avec les clients grpc-wallet

Suivez les instructions par langage ci-dessous pour vérifier la configuration. Les commandes envoient plusieurs RPC, certains avec des métadonnées supplémentaires, pour indiquer que les requêtes sont acheminées vers des services de backend en fonction des règles de correspondance du mappage d'URL. La commande imprime également le nom d'hôte du backend pour chaque réponse, afin d'indiquer le service de backend vers lequel la requête a été acheminée.

C++

  1. Pour vérifier le service avec un client gRPC C++, exécutez la commande suivante :

    sudo apt-get update
    sudo apt-get install -y build-essential git
    
    git clone https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    cd traffic-director-grpc-examples/cpp
    ../tools/bazel build :client
    
    # This command calls FetchBalance from the Wallet service in a loop, to demonstrate that
    # FetchBalance gets responses from wallet-v1 (40%) and wallet-v2 (60%).
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch=true
    
    # This command calls the streaming RPC WatchBalance from the Wallet
    # service. The RPC path matches the service prefix, so all requests are sent to wallet-v2.
    ../bazel-bin/cpp/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true
    
    # This command calls WatchPrice from the Stats service. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to stats-premium, and get faster responses. Alice's requests
    # always go to premium, and Bob goes to regular.
    ../bazel-bin/cpp/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Bob
    ../bazel-bin/cpp/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Alice
    

Go

  1. Pour vérifier le service avec un client gRPC Go, exécutez la commande suivante :

    sudo apt-get update
    sudo apt install -y golang git
    
    git clone https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    cd traffic-director-grpc-examples/go/wallet_client
    go build .
    
    # This command calls FetchBalance from the Wallet service in a loop,
    # to demonstrate that FetchBalance gets responses from wallet-v1 (40%)
    # and wallet-v2 (60%).
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch
    
    # This command calls the streaming RPC WatchBalance from the Wallet
    # service. The RPC path matches the service prefix, so all requests
    # are sent to wallet-v2.
    ./wallet_client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch
    
    # This command calls WatchPrice from the Stats service. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to stats-premium, and get faster responses. Alice's requests
    # always go to premium and Bob goes to regular.
    ./wallet_client price --stats_server="xds:///stats.grpcwallet.io" --watch --user=Bob
    ./wallet_client price --stats_server="xds:///stats.grpcwallet.io" --watch --user=Alice
    

Java

  1. Pour vérifier le service avec un client Java gRPC, exécutez la commande suivante :

    sudo apt-get update
    sudo apt-get install -y openjdk-11-jdk-headless git
    
    git clone https://github.com/GoogleCloudPlatform/traffic-director-grpc-examples.git
    cd traffic-director-grpc-examples/java
    ./gradlew installDist
    
    # This command calls FetchBalance from the Wallet service in a loop,
    # to demonstrate that FetchBalance gets responses from wallet-v1 (40%)
    # and wallet-v2(60%).
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --unary_watch=true
    
    # This command calls the streaming RPC WatchBalance from the Wallet
    # service. The RPC path matches the service prefix, so all requests are
    # sent to wallet-v2.
    ./build/install/wallet/bin/client balance --wallet_server="xds:///wallet.grpcwallet.io" --watch=true
    
    # This command calls WatchPrice from the Stats service. It sends the
    # user's membership (premium or not) in metadata. Premium requests are
    # all sent to stats-premium, and get faster responses. Alice's requests
    # always go to premium and Bob goes to regular.
    ./build/install/wallet/bin/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Bob
    ./build/install/wallet/bin/client price --stats_server="xds:///stats.grpcwallet.io" --watch=true --user=Alice
    

Nettoyer les ressources

Exécutez ce script pour nettoyer les ressources.

bash <(curl -s https://raw.githubusercontent.com/GoogleCloudPlatform/traffic-director-grpc-examples/master/scripts/cleanup.sh)
gcloud compute instances delete grpc-wallet-client --zone us-central1-a -q

Étape suivante

Si vous avez rencontré un comportement inattendu lors du processus de configuration, consultez la page Résoudre les problèmes de déploiement sans proxy de Traffic Director et la page sur les limites de Traffic Director avec les applications gRPC sans proxy.