Como configurar serviços do gRPC sem proxy com o gerenciamento de tráfego avançado

Neste documento, fornecemos instruções completas para configurar o Traffic Director com estes recursos de roteamento:

  • Correspondência de rota
  • Divisão de tráfego

Para informações conceituais sobre esses recursos, consulte Gerenciamento de tráfego avançado.

Para ilustrar esses recursos, implante um exemplo de gRPC do Wallet. Conforme mostrado no diagrama abaixo, você cria serviços de back-end para wallet-service, stats-service e account-service.

Exemplo de configuração de roteamento de tráfego do Wallet para gRPC (clique para ampliar)
Exemplo de configuração de roteamento de tráfego do Wallet para gRPC (clique para ampliar)

No exemplo, você implanta várias versões de cada serviço para ilustrar o roteamento de solicitações com base nas regras configuradas. Para simular a criação e a implantação de diferentes versões de um serviço, use sinalizações de servidor para alterar o comportamento dos binários criados uma vez.

  • A sinalização --port especifica a porta em que o serviço na VM de back-end realiza a detecção.
  • A sinalização --hostname_suffix especifica um valor anexado ao nome do host da VM que responde a uma solicitação. O valor resultante é adicionado como os metadados hostname na resposta. Isso ajuda a identificar qual instância de um serviço de back-end respondeu à solicitação do cliente.
  • A sinalização --premium_only com o valor true especifica que se trata de uma versão premium do serviço stats.
  • A sinalização --v1_behavior com o valor true especifica que o binário da carteira atua como uma versão v1.
Serviço Grupo de instâncias Instância(s) Sinalizações do servidor
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"

Depois, configure o Traffic Director a fim de rotear solicitações para esses serviços de um cliente de teste com base nas regras de roteamento a seguir:

Host Corresponder às regras Ação de rota
wallet.grpcwallet.io Padrão wallet-v1
Caminho completo: /grpc.examples.wallet.Wallet/FetchBalance wallet-v1: 40%
wallet-v2: 60%
Prefixo do caminho: /grpc.examples.wallet.Wallet/ wallet-v2
stats.grpcwallet.io Padrão stats
Prefixo do caminho: "/"
Cabeçalho: {"membership": "premium"}
stats-premium
account.grpcwallet.io Padrão account

Como criar a verificação de integridade e a regra de firewall do gRPC

Nesta seção, você cria uma verificação de integridade e uma regra de firewall do gRPC que permite que as solicitações de verificação de integridade do gRPC alcancem sua rede. Futuramente, a verificação de integridade do gRPC será associada a serviços de back-end para verificar a integridade dos back-ends nesses serviços de back-end.

gcloud

  1. Crie a verificação de integridade.

    gcloud compute health-checks create grpc grpcwallet-health-check \
      --use-serving-port
    
  2. Crie a regra de firewall para a verificação de integridade.

    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
    

Como criar o modelo de instância

Nesta seção, você cria um modelo de instância para implantar o serviço gRPC account que é exposto na porta 50053.

gcloud

  1. Crie o modelo da instância.

    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')
    

Como criar o grupo de instâncias gerenciadas

Os grupos de instâncias gerenciadas usam o escalonamento automático para criar novas VMs de back-end, conforme necessário. Nesta seção, você cria um grupo de instâncias gerenciadas usando o modelo de instância criado na seção anterior.

gcloud

  1. Crie o grupo de instâncias.

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

Como configurar a porta nomeada

Nesta seção, você configura a porta nomeada do serviço gRPC. A porta nomeada é aquela em que o serviço gRPC detecta solicitações. Neste exemplo, a porta nomeada é a porta 50053.

gcloud

  1. Crie a porta nomeada.

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

Como criar o serviço de back-end

Nesta seção, você cria um serviço de back-end global com o esquema de balanceamento de carga de INTERNAL_SELF_MANAGED e o protocolo GRPC, além de associar a verificação de integridade e o grupo de instâncias ao serviço de back-end Neste exemplo, use o grupo de instâncias gerenciadas criado em Como criar o grupo de instâncias gerenciadas. Esse grupo de instâncias gerenciadas executa o serviço gRPC account. A porta na sinalização --port-name é a porta nomeada que você criou em Como configurar a porta nomeada.

gcloud

  1. Crie o serviço de back-end e associe a verificação de integridade ao a esse novo serviço.

    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. Adicione o grupo de instâncias gerenciadas como o back-end.

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

As etapas para criar os serviços de back-end restantes usados no exemplo do Wallet para gRPC são semelhantes às etapas acima. Execute um script de shell para criar os serviços restantes. O script implanta os seguintes serviços de back-end:

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

Execute o script de shell que cria os serviços de back-end adicionais:

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

Como criar as regras de roteamento

Nesta seção, você cria um mapa de URL que especifica os nomes dos hosts virtuais dos serviços neste exemplo, bem como as regras de roteamento associadas. Para saber mais, consulte Como rotear mapas de regras.

No mapa de URL, hostRules especifica os nomes de host virtuais dos serviços no exemplo. Esses são os nomes que um cliente usa no URI de canal para se conectar a um serviço específico. Por exemplo, para enviar uma solicitação ao serviço account, um cliente usa xds:///account.grpcwallet.io no URI do canal. Você precisa configurar uma entrada hosts com valor account.grpcwallet.io no hostRules.

O pathMatcher associado a uma entrada hosts especifica o nome de um pathMatcher que contém todas as regras de roteamento desse host virtual. Uma configuração de pathMatcher consiste em regras de correspondência e regras de ação correspondentes. Neste exemplo, o resultado é a seguinte configuração:

  • Quando uma solicitação for enviada para account.grpcwallet.io, envie a solicitação ao serviço de back-end grpcwallet-account-service.
  • Quando uma solicitação é enviada para stats.grpcwallet.io:
    • Se a solicitação contiver o cabeçalho membership com valor premium, envie a solicitação para o serviço de back-end grpcwallet-stats-premium-service.
    • Caso contrário, envie a solicitação para o serviço de back-end padrão grpcwallet-stats-service.
  • Quando uma solicitação é enviada para wallet.grpcwallet.io:

    • se o ServiceName/MethodName corresponder a /grpc.examples.wallet.Wallet/FetchBalance, envie 40% dessas solicitações para o serviço de back-end grpcwallet-wallet-v2-service e as solicitações restantes para o serviço de back-end grpcwallet-wallet-v1-service.
    • Caso contrário, se ServiceName corresponder a /grpc.examples.wallet.Wallet/, independentemente do método chamado, envie a solicitação ao serviço de back-end grpcwallet-wallet-v1-service.

gcloud

Execute este comando para criar o mapa de 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

Como criar o proxy de destino e a regra de encaminhamento

Nesta seção, você criará o proxy gRPC de destino e uma regra de encaminhamento.

O proxy gRPC de destino faz referência ao mapa de URL que você criou na etapa anterior. A sinalização --validate-for-proxyless permite realizar verificações de configuração para que você não ative acidentalmente um recurso que não seja compatível com implantações de gRPC sem proxy.

gcloud

  1. Crie o proxy de destino do gRPC.

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

A regra de encaminhamento faz referência ao proxy gRPC de destino criado. O esquema de balanceamento de carga é definido como INTERNAL_SELF_MANAGED para indicar que essa regra de encaminhamento é usada pelo Traffic Director. Ela precisa ser uma regra de encaminhamento global. O endereço IP é definido como 0.0.0.0 porque um cliente gRPC sem proxy resolve o hostname:port no URI de destino ao enviar uma solicitação de LDS ao Traffic Director, em vez de fazer uma busca DNS. Para mais informações, consulte Esquema de resolução de nomes.

Quando uma porta não é especificada no URI de destino, o valor padrão é 80. Por exemplo, um URI de destino xds:///foo.myservice:8080 corresponde a uma regra de encaminhamento configurada com a porta 8080. Neste exemplo, a regra de encaminhamento é configurada com a porta 80.

gcloud

  1. Crie a regra de encaminhamento.

    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
    

Como verificar a configuração

Quando o processo de configuração estiver concluído, verifique se os serviços de back-end configurados estão disponíveis. Para isso, acesse a página do Traffic Director no Console. Confirme se os serviços de back-end e os back-ends associados são informados como em bom estado.

Como verificar a configuração de roteamento

Nesta seção, você verifica se a configuração de roteamento está funcionando corretamente. Use a ferramenta grpcurl para testar a configuração.

gcloud

  1. Crie uma VM cliente em que você executará os clientes para testar o serviço.

    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. Acesse a VM usando SSH.

Para acessar os serviços sem um proxy sidecar, o cliente gRPC precisa usar o esquema de resolução de nomes xds. Esse esquema instrui a biblioteca gRPC usada no cliente a usar um servidor xDS para resolver o nome do host. Para isso, é necessária uma configuração de inicialização. O script de inicialização na seção anterior define a variável de ambiente GRPC_XDS_BOOTSTRAP e usa um script auxiliar para gerar o arquivo de inicialização. Os valores de TRAFFICDIRECTOR_GCP_PROJECT_NUMBER, TRAFFICDIRECTOR_NETWORK_NAME e da zona no arquivo de inicialização gerado são recebidos do servidor de metadados que conhece esses detalhes sobre suas instâncias de VM do Compute Engine. É possível fornecer manualmente esses valores para o script auxiliar usando as opções -gcp-project-number e -vpc-network-name.

Como verificar a configuração usando a ferramenta grpcurl

Primeiro, instale a ferramenta 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

Em seguida, execute os seguintes comandos para verificar se os serviços Account, Stats e Wallet estão em execução.

$ ./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"
}

Como fazer a verificação com clientes grpc-wallet

Use as seguintes instruções específicas da linguagem para verificar a configuração. Os comandos enviam várias RPCs, algumas com metadados extras, para mostrar que as solicitações são roteadas para serviços de back-end com base nas regras correspondentes do mapa de URL. O comando também imprime o nome do host do back-end de cada resposta para mostrar para qual serviço de back-end a solicitação foi encaminhada.

C++

  1. Para verificar o serviço com um cliente gRPC em C++, execute o seguinte:

    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. Para verificar o serviço com um cliente Go do gRPC, execute o seguinte:

    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. Para verificar o serviço com um cliente Java do gRPC, execute o seguinte:

    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
    

Como limpar os recursos

Execute este script para limpar os recursos.

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

A seguir

Se você observar um comportamento inesperado durante o processo de configuração, consulte Solução de problemas nas implantações do Traffic Director sem proxy e Limitações do Traffic Director com aplicativos gRPC sem proxy.