プロキシレス gRPC アプリケーションによるオブザーバビリティ

このドキュメントでは、Traffic Director を使用するサービスで gRPC のオブザーバビリティ機能を使用する手順について説明します。これらの機能により、デプロイに関する問題の解決を容易にするモニタリングとトレースの指標にアクセスできるようになります。

また、Cloud TraceCloud Monitoring に情報をエクスポートする方法についても説明します。

前提条件

このドキュメントのサンプルを作成するには、次のことを行います。

一部のオブザーバビリティ機能には、gRPC アプリケーションに追加のコマンドライン パラメータが必要です。これらのパラメータについては、このドキュメントで説明します。このドキュメントで説明する機能はすべて gRPC ライブラリに含まれています。Traffic Director をさらに構成する必要はありません。

指標とトレース

gRPC のクライアントとサーバーは OpenCensus と統合され、指標とトレースを Trace や Monitoring を含むさまざまなバックエンドにエクスポートします。このドキュメントでは、次の gRPC 言語によるサンプルを示します。

  • C++
  • Go
  • Java

他の言語の OpenCensus 実装で、このドキュメントで説明している機能の一部がサポートされている場合もありますが、機能の動作は保証されません。詳細については、OpenCensus のドキュメントをご覧ください。

指標とトレースが有効になっている場合、gRPC クライアントとサーバーはビューをエクスポートします。これは、特定の指標の集合体で、OpenCensus gRPC 指標仕様に具体的に記載されています。

  • grpc.io/{client,server}/sent_bytes_per_rpc
  • grpc.io/{client,server}/received_bytes_per_rpc
  • grpc.io/{client,server}/sent_messages_per_rpc
  • grpc.io/{client,server}/received_messages_per_rpc
  • grpc.io/{client,server}/started_rpcs
  • grpc.io/client/roundtrip_latency
  • grpc.io/server/server_latency

Cloud Monitoring API と Cloud Trace API を有効にする

gRPC による OpenCensus の統合では、指標とトレースをエクスポートするための幅広いバックエンドをサポートしています。以下の例は、この情報を Monitoring と Trace にエクスポートする方法を示しています。このドキュメントで示す依存関係では、これらをまとめて stackdriver としています。

これらの例が機能し、プロジェクトの Google Cloud コンソールで指標とトレースを可視化できるようにするには、手順に沿って Monitoring APICloud Trace API を有効にします。

gRPC アプリケーションをインストルメント化する

gRPC ウォレットのサンプルコードでは、すでに指標とトレース用にインストルメント化されています。指標とトレースを有効にするには、次のコマンドライン フラグを使用して gRPC クライアントとサーバーを実行します。

 --gcp_client_project=PROJECT_ID

PROJECT_ID は、プロジェクトのプロジェクト ID に置き換えます。プロキシレス gRPC サービスで高度なトラフィック管理を構成するで説明されているように、gRPC ウォレットのサンプル リポジトリの create_service.sh script を使用する場合は、このフラグをシェル スクリプトに渡される最後の引数に追加します。

次に例を示します。

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

既存の gRPC アプリケーションにインストルメンテーションを追加するために必要なコードの変更は次のとおりです。独自のアプリケーションにおけるベスト プラクティスは、コマンドライン フラグや環境変数でインストルメンテーション コードの使用を制御することです。これにより、プロキシレス gRPC のデプロイメントで、コードを追加変更することなく、指標とトレースを動的に有効または無効にすることができます。

このサンプルコードでは、指標とトレースを同時に構成する方法を示します。また、指標とトレースは、個別に構成することや、どちらか一方だけを構成することもできます。どちらの手順も似ているため、このコードでは合わせて構成する方法を示しています。

C++

OpenCensus gRPC C++ プラグインでは、Bazel でビルドする必要があります。OpenCensus の依存関係を含めるため 2 つのビルドファイルを変更する必要があります。

  1. 次のコードを WORKSPACE ファイルに追加します。

    load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_language")
    
    http_archive(
        name = "com_google_googleapis",
        sha256 = "150be57ff83646e5652e03683c949f0830d9a0e73ef787786864210e45537fe0",
        strip_prefix = "googleapis-6e3b55e26bf5a9f7874b6ba1411a0cc50cb87a48",
       urls =       ["https://github.com/googleapis/googleapis/archive/6e3b55e26bf5a9f7874b6ba1411a0cc50cb87a48.zip"],
    )
    
    switched_rules_by_language(
        name = "com_google_googleapis_imports",
        cc = True,
        grpc = True,
    )
    
  2. BUILD ファイルのビルド ターゲットに次の依存関係を追加します。

    cc_binary(
       name = "client",
       srcs = ["client.cc"],
       defines = ["BAZEL_BUILD"],
       deps = [
           # New dependencies:
           "@com_github_grpc_grpc//:grpc_opencensus_plugin",
           "@io_opencensus_cpp//opencensus/trace:trace",
           "@io_opencensus_cpp//opencensus/stats:stats",
           "@io_opencensus_cpp//opencensus/exporters/trace/stackdriver:stackdriver_exporter",
           "@io_opencensus_cpp//opencensus/exporters/stats/stackdriver:stackdriver_exporter",
       ],
    )
    
  3. C++ アプリケーションをインストルメント化します。クライアントとサーバーは、プロセス内で次のようにグローバルにインストルメント化されます。

    #include <grpcpp/opencensus.h>
    #include "opencensus/exporters/stats/stackdriver/stackdriver_exporter.h"
    #include "opencensus/exporters/trace/stackdriver/stackdriver_exporter.h"
    
    ABSL_FLAG(std::string, gcp_client_project, "", "Google Cloud project for metric/trace uploads");
    
    int main(int argc, char** argv) {
      // Optionally configure OpenCensus before using gRPC
      if (!absl::GetFlag(FLAGS_gcp_client_project).empty()) {
        grpc::RegisterOpenCensusPlugin();
        grpc::RegisterOpenCensusViewsForExport();
        // For demo purposes, always sample (probability=1.0)
        opencensus::trace::TraceConfig::SetCurrentTraceParams(
            {128, 128, 128, 128, opencensus::trace::ProbabilitySampler(1.0)});
        opencensus::exporters::trace::StackdriverOptions trace_opts;
        trace_opts.project_id = absl::GetFlag(FLAGS_gcp_client_project);
        opencensus::exporters::trace::StackdriverExporter::Register(std::move(trace_opts));
        opencensus::exporters::stats::StackdriverOptions stats_opts;
        stats_opts.project_id = absl::GetFlag(FLAGS_gcp_client_project);
        // This must be unique among all processes exporting to Stackdriver
        stats_opts.opencensus_task = "wallet-server-" + std::to_string(getpid());
        opencensus::exporters::stats::StackdriverExporter::Register(std::move(stats_opts));
      }
    
      // Now use gRPC as usual.
    }
    

Go

Go の場合は次の手順を行います。

  1. ClientHandler を使用してクライアントをインストルメント化します。

    import (
      "go.opencensus.io/plugin/ocgrpc"
      "go.opencensus.io/stats/view"
      "go.opencensus.io/trace"
      "contrib.go.opencensus.io/exporter/stackdriver"
    )
    
    if gcpClientProject != "" {
        view.Register(ocgrpc.DefaultClientViews...)
        sd, err := stackdriver.NewExporter(stackdriver.Options{
            ProjectID:    gcpClientProject,
        })
        defer sd.Flush()
        trace.RegisterExporter(sd)
        sd.StartMetricsExporter()
        defer sd.StopMetricsExporter()
        trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
    
        channel, err := grpc.Dial(serverAddr, grpc.WithInsecure(),
           grpc.WithStatsHandler(new(ocgrpc.ClientHandler)))
    }
    
  2. ServerHandler を使用してサーバーをインストルメント化します。

    import (
      "go.opencensus.io/plugin/ocgrpc"
      "go.opencensus.io/stats/view"
      "go.opencensus.io/trace"
      "contrib.go.opencensus.io/exporter/stackdriver"
    )
    
    if gcpClientProject != "" {
        view.Register(ocgrpc.DefaultServerViews...)
        sd, err := stackdriver.NewExporter(stackdriver.Options{
            ProjectID:    gcpClientProject,
        })
        defer sd.Flush()
        trace.RegisterExporter(sd)
        sd.StartMetricsExporter()
        defer sd.StopMetricsExporter()
        trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()})
    
        srv := grpc.NewServer(grpc.StatsHandler(&ocgrpc.ServerHandler{}))
    }
    

Java

Java の場合は、build.gradle ファイルに次の依存関係を追加します。

def opencensusVersion = "0.28.0"
def grpcVersion = "1.35.0"

dependencies {
  // New dependencies:
  compile "io.grpc:grpc-census:{$grpcVersion}",
               "io.opencensus:opencensus-api:${opencensusVersion}",
               "io.opencensus:opencensus-contrib-grpc-metrics:${opencensusVersion}",
               "io.opencensus:opencensus-exporter-stats-stackdriver:${opencensusVersion}",
               "io.opencensus:opencensus-exporter-trace-stackdriver:${opencensusVersion}"
 runtime "io.opencensus:opencensus-impl:${opencensusVersion}"
}

Java クライアントとサーバーの場合、io.grpc:grpc-census に依存関係を追加すると、指標とトレースのインストルメンテーションが自動的に RPC に追加されます。ただし、データを取得できるように OpenCensus エクスポータを指定する必要があります。

import io.opencensus.contrib.grpc.metrics.RpcViews;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsConfiguration;
import io.opencensus.exporter.stats.stackdriver.StackdriverStatsExporter;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceConfiguration;
import io.opencensus.exporter.trace.stackdriver.StackdriverTraceExporter;
import io.opencensus.trace.Tracing;
import io.opencensus.trace.config.TraceConfig;
import io.opencensus.trace.samplers.Samplers;

if (gcpClientProject != "") {
  // Configure export to Monitoring and Trace
  RpcViews.registerAllViews();
  TraceConfig traceConfig = Tracing.getTraceConfig();
  traceConfig.updateActiveTraceParams(
      traceConfig.getActiveTraceParams().toBuilder()
          .setSampler(Samplers.alwaysSample())
          .build());

  StackdriverStatsExporter.createAndRegister(
      StackdriverStatsConfiguration.builder().setProjectId(gcpClientProject).build());
  StackdriverTraceExporter.createAndRegister(
      StackdriverTraceConfiguration.builder().setProjectId(gcpClientProject).build());
}

Monitoring ダッシュボードに指標を表示する

アプリケーションがインストルメント化されると、gRPC 指標は Monitoring にエクスポートされ、Google Cloud コンソールの Metrics Explorer に表示できるようになります。

コンソール

指標を表示するには、次のようにします。

  1. Google Cloud Console で、[Monitoring] ページに移動します。

    [Monitoring] に移動

  2. 左側のナビゲーションで、[Metrics Explorer] をクリックします。

  3. [Build Your Query] でリソースタイプとして [VM Instance] または [GKE Container] を選択します。

  4. [Metric] フィールドで、指標とトレースに示されている任意の OpenCensus/grpc.io/client/roundtrip_latency 名を選択します。

  5. [Aggregator] プルダウン リストで、タイプとして [mean] を選択します。次のようなグラフが表示されます。

    Metrics Explorer。
    Metrics Explorer(クリックして拡大)

    OpenCensus によって送信された指標には、対応する gRPC メソッド名でアノテーションが付加されているため、特定のインスタンス グループの統計情報のみをフィルタリングして表示するなど、標準の Monitoring の詳細ビューだけでなく、統計情報は、grpc_client_methodgrpc_server_method で分類できます。

    こうした指標ビューは、Monitoring のダッシュボードとグラフに組み込んで、自動アラートの根拠として使用できます。

Trace でトレースを表示する

設定プロセスを完了すると、インストルメント化された gRPC クライアントとサーバーはトレースを Trace に送信するようになります。Google Cloud コンソールの [Trace の概要] ページには、最近のトレースのリストが表示されます。次のセクションで説明するように、個々のトレースを選択するとトラフィックの内訳を確認できます。

Envoy プロキシとの Trace の互換性

Envoy によるオブザーバビリティに説明されているように Traffic Director と Envoy プロキシを使用して Trace にトレースをエクスポートすると、Envoy の OpenCensus トレーサ構成が使用されます。これにより、サービス メッシュ内では、プロキシレス gRPC アプリケーションや Envoy プロキシからエクスポートされたトレースを完全互換にできます。プロキシレス gRPC との互換性を確保するため、Envoy ブートストラップでは、トレース コンテキストが GRPC_TRACE_BIN トレース形式を OpenCensusConfig で含むように構成する必要があります。次に例を示します。

tracing:
  http:
      name: envoy.tracers.opencensus
      typed_config:
        "@type": type.googleapis.com/envoy.config.trace.v2.OpenCensusConfig
        stackdriver_exporter_enabled: "true"
        stackdriver_project_id: "PROJECT_ID"
        incoming_trace_context: ["CLOUD_TRACE_CONTEXT", "GRPC_TRACE_BIN"]
        outgoing_trace_context: ["CLOUD_TRACE_CONTEXT", "GRPC_TRACE_BIN"]

管理インターフェースを公開する

指標とトレースデータでは、問題の解決に十分でないことがあります。その場合、アプリケーションの gRPC ライブラリの構成やランタイム状態の確認が必要になります。たとえば、リゾルバ情報、ピアとの接続状態、チャネルの RPC 統計情報、Traffic Director から受信した構成などの情報が必要になります。

このような情報を取得するために、gRPC アプリケーションでは特定のポートに管理インターフェースを公開できます。これにより、アプリケーションをクエリして、サービスの構成と実行状況を把握できます。このセクションでは、アプリケーションの管理インターフェースをサポートされている各言語で記述して構成する方法について説明します。

gRPC サーバーは、別途アプリケーション内に作成して、この目的のために予約されているポートをリッスンすることをおすすめします。こうすることで、構成ミスやネットワークの問題でデータポートにアクセスできない場合でも、gRPC アプリケーションへはアクセスできるようになります。管理インターフェースは、localhost か Unix ドメイン ソケットにのみ公開することをおすすめします。

管理インターフェースの作成方法を、次のコード スニペットに示します。

C++

C++ では、次のコードを使用して管理インターフェースを作成します。

#include <grpcpp/ext/admin_services.h>

grpc::ServerBuilder builder;
grpc::AddAdminServices(&builder);
builder.AddListeningPort(":50051", grpc::ServerCredentials(...));
std::unique_ptr<grpc::Server> server(builder.BuildAndStart());

Go

Go では、次のコードを使用して管理インターフェースを作成します。

import "google.golang.org/grpc/admin"

lis, err := net.Listen("tcp", ":50051")
if err != nil {
        log.Fatalf("failed to listen: %v", err)
}
defer lis.Close()
grpcServer := grpc.NewServer(...opts)
cleanup, err := admin.Register(grpcServer)
if err != nil {
        log.Fatalf("failed to register admin services: %v", err)
}
defer cleanup()

if err := grpcServer.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
}

Java

Java では、次のコードを使用して管理インターフェースを作成します。

import io.grpc.services.AdminInterface;

server = ServerBuilder.forPort(50051)
        .useTransportSecurity(certChainFile, privateKeyFile)
        .addServices(AdminInterface.getStandardServices())
        .build()
        .start();
server.awaitTermination();

Python

Python では、次のコードを使用して管理インターフェースを作成します。

import grpc_admin

server = grpc.server(futures.ThreadPoolExecutor())
grpc_admin.add_admin_servicers(server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()

SSH を使用して VM に接続する

gRPC ウォレットの例では、管理インターフェースがすでに有効になっています。管理インターフェースのポートを変更するには、次のフラグを指定します。

 --admin-port=PORT

デフォルトの管理ポートは localhost:28881 です。

gRPC アプリケーションをデバッグするには、wallet-service を提供する VM のいずれかに SSH で接続します。これにより、localhost にアクセスできるようになります。

# List the Wallet VMs
$ gcloud compute instances list --filter="zone:(us-central1-a)" --filter="name~'grpcwallet-wallet-v2'"
NAME                                       ZONE            MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP    EXTERNAL_IP     STATUS
grpcwallet-wallet-v2-mig-us-central1-ccl1  us-central1-a   n1-standard-1               10.240.0.38    35.223.42.98    RUNNING
grpcwallet-wallet-v2-mig-us-central1-k623  us-central1-a   n1-standard-1               10.240.0.112   35.188.133.75   RUNNING
# Pick one of the Wallet VMs to debug
$ gcloud compute ssh grpcwallet-wallet-v2-mig-us-central1-ccl1 --zone=us-central1-a

grpcdebug ツールをインストールする

管理インターフェースにアクセスするには、gRPC アプリケーションの管理サービスと通信できる gRPC クライアントが必要です。次の例では、gRPC アプリケーションが実行されている VM または Pod にダウンロードできる grpcdebug というツールを使用します。grpcdebug のリポジトリは、grpc-ecosystem/grpcdebug にあります。

Golang の最小サポート バージョンは 1.12 です。Golang の公式ガイドは Golang のサイトにあります。ガイドに沿って wallet-service 用の Linux VM を作成する場合は、次のコマンドを使用して Golang 1.16 をインストールできます。

sudo apt update && sudo apt install -y wget
wget https://golang.org/dl/go1.16.3.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.16.3.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
sudo ln -sf /usr/local/go/bin/go /usr/bin/go
go version
# go version go1.16.3 linux/amd64

次のコマンドで grpcdebug ツールをインストールします。

go install -v github.com/grpc-ecosystem/grpcdebug@latest
export PATH=$PATH:$(go env GOPATH)/bin

これで、grpcdebug コマンドライン インターフェースにアクセスできるようになりました。ヘルプ出力には、サポートされているコマンドについての情報が含まれます。

$ grpcdebug -h
grpcdebug is a gRPC service admin command-line interface

Usage:
  grpcdebug <target address> [flags]  <command>

Available Commands:
  channelz    Display gRPC states in human readable way.
  health      Check health status of the target service (default "").
  help        Help about any command
  xds         Fetch xDS related information.

Flags:
      --credential_file string        Sets the path of the credential file; used in [tls] mode
  -h, --help                          Help for grpcdebug
      --security string               Defines the type of credentials to use [tls, google-default, insecure] (default "insecure")
      --server_name_override string   Overrides the peer server name if non empty; used in [tls] mode
  -t, --timestamp                     Print timestamp as RFC 3339 instead of human readable strings
  -v, --verbose                       Print verbose information for debugging

特定のコマンドに関する詳細を確認するには、次のコマンドを使用します。

 grpcdebug <target address> [command] --help

grpcdebug ツールを使用してアプリケーションをデバッグする

grpcdebug ツールを使用してアプリケーションをデバッグできます。grpcdebug ツールには、ssh_config に似た構成があり、エイリアス、ホスト名の書き換え、接続のセキュリティ設定(Insecure / TLS)がサポートされます。この高度な機能の詳細については、grpcdebug/Connect&Security をご覧ください。

このセクションでは、管理インターフェースによって公開されるサービスとそのアクセス方法について説明します。

Channelz を使用する

Channelz サービスでは、アプリケーションで使用されている gRPC ライブラリのさまざまなレベルで、接続に関するランタイム情報にアクセスできます。これにより、構成関連の問題やネットワーク関連の問題があると考えられるアプリケーションを実行しながら調査できます。次の例では、プロキシレス gRPC サービスを使用して高度なトラフィック管理を構成するの手順に沿って gRPC Wallet のサンプルをデプロイし、次のフラグを指定したことを前提としています。

 --admin-port=PORT

構成の確認で説明されているように、テスト クライアントから RPC を送信した後、次のコマンドを使用して gRPC サービスの Channelz データにアクセスします。

  1. SSH を使用して、wallet-service を実行している VM に接続します。
  2. grpcdebug を設定して、実行中の gRPC アプリケーションに接続します。

grpcdebug のデフォルトの出力は、コンソール対応のテーブル形式です。--json フラグを指定すると、出力が JSON としてエンコードされます。

grpcdebug channelz コマンドは、Channelz サービスからデバッグ情報を取得して表示するために使用します。このコマンドは、gRPC クライアントと gRPC サーバーの両方で機能します。

gRPC クライアントでは、コマンド grpcdebug channelz channels を実行すると、既存のチャネルのリストと基本情報の一部が出力されます。

$ grpcdebug localhost:28881 channelz channels
Channel ID   Target                               State     Calls(Started/Succeeded/Failed)   Created Time
1            xds:///account.grpcwallet.io:10080   READY     0/0/0                             59 seconds ago
2            trafficdirector.googleapis.com:443   READY     2/0/0                             59 seconds ago
4            xds:///stats.grpcwallet.io:10080     READY     0/0/0                             59 seconds ago

特定のチャネルに関する追加情報が必要な場合は、grpcdebug channelz channel [CHANNEL_ID] を使用してそのチャネルの詳細情報を調べます。CHANNEL_ID は、チャネル ID か、ターゲット アドレス(1 つしかない場合)になります。gRPC チャネルには、TCP コネクションの上に gRPC を抽象化した複数のサブチャネルを含めることができます。

$ grpcdebug localhost:28881 channelz channel 2
Channel ID:        2
Target:            trafficdirector.googleapis.com:443
State:             READY
Calls Started:     2
Calls Succeeded:   0
Calls Failed:      0
Created Time:      10 minutes ago
---
Subchannel ID   Target                               State     Calls(Started/Succeeded/Failed)   CreatedTime
3               trafficdirector.googleapis.com:443   READY     2/0/0                             10 minutes ago
---
Severity   Time             Child Ref                      Description
CT_INFO    10 minutes ago                                  Channel Created
CT_INFO    10 minutes ago                                  parsed scheme: ""
CT_INFO    10 minutes ago                                  scheme "" not registered, fallback to default scheme
CT_INFO    10 minutes ago                                  ccResolverWrapper: sending update to cc: {[{trafficdirector.googleapis.com:443  <nil> 0 <nil>}] <nil> <nil>}
CT_INFO    10 minutes ago                                  Resolver state updated: {Addresses:[{Addr:trafficdirector.googleapis.com:443 ServerName: Attributes:<nil> Type:0 Metadata:<nil>}] ServiceConfig:<nil> Attributes:<nil>} (resolver returned new addresses)
CT_INFO    10 minutes ago                                  ClientConn switching balancer to "pick_first"
CT_INFO    10 minutes ago                                  Channel switches to new LB policy "pick_first"
CT_INFO    10 minutes ago   subchannel(subchannel_id:3 )   Subchannel(id:3) created
CT_INFO    10 minutes ago                                  Channel Connectivity change to CONNECTING
CT_INFO    10 minutes ago                                  Channel Connectivity change to READY

サブチャネルの詳細を調べることもできます。

$ grpcdebug localhost:28881 channelz subchannel 3
Subchannel ID:     3
Target:            trafficdirector.googleapis.com:443
State:             READY
Calls Started:     2
Calls Succeeded:   0
Calls Failed:      0
Created Time:      12 minutes ago
---
Socket ID   Local->Remote                           Streams(Started/Succeeded/Failed)   Messages(Sent/Received)
9           10.240.0.38:60338->142.250.125.95:443   2/0/0                               214/132

TCP ソケットに関する情報を取得できます。

$ grpcdebug localhost:28881 channelz socket 9
Socket ID:                       9
Address:                         10.240.0.38:60338->142.250.125.95:443
Streams Started:                 2
Streams Succeeded:               0
Streams Failed:                  0
Messages Sent:                   226
Messages Received:               141
Keep Alives Sent:                0
Last Local Stream Created:       12 minutes ago
Last Remote Stream Created:      a long while ago
Last Message Sent Created:       8 seconds ago
Last Message Received Created:   8 seconds ago
Local Flow Control Window:       65535
Remote Flow Control Window:      966515
---
Socket Options Name   Value
SO_LINGER             [type.googleapis.com/grpc.channelz.v1.SocketOptionLinger]:{duration:{}}
SO_RCVTIMEO           [type.googleapis.com/grpc.channelz.v1.SocketOptionTimeout]:{duration:{}}
SO_SNDTIMEO           [type.googleapis.com/grpc.channelz.v1.SocketOptionTimeout]:{duration:{}}
TCP_INFO              [type.googleapis.com/grpc.channelz.v1.SocketOptionTcpInfo]:{tcpi_state:1  tcpi_options:7  tcpi_rto:204000  tcpi_ato:40000  tcpi_snd_mss:1408  tcpi_rcv_mss:1408  tcpi_last_data_sent:8212  tcpi_last_data_recv:8212  tcpi_last_ack_recv:8212  tcpi_pmtu:1460  tcpi_rcv_ssthresh:88288  tcpi_rtt:2400  tcpi_rttvar:3012  tcpi_snd_ssthresh:2147483647  tcpi_snd_cwnd:10  tcpi_advmss:1408  tcpi_reordering:3}
---
Security Model:   TLS
Standard Name:    TLS_AES_128_GCM_SHA256

サーバー側では、Channelz を使用してサーバー アプリケーションのステータスを調べることができます。たとえば、サーバーのリストを取得するには、grpcdebug channelz servers コマンドを使用します。

$ grpcdebug localhost:28881 channelz servers
Server ID   Listen Addresses    Calls(Started/Succeeded/Failed)   Last Call Started
5           [127.0.0.1:28881]   9/8/0                             now
6           [[::]:50051]        159/159/0                         4 seconds ago

特定サーバーの詳細情報を取得するには、grpcdebug channelz server コマンドを使用します。サーバー ソケットは、クライアント ソケットの場合と同じ方法で検査できます。

$ grpcdebug localhost:28881 channelz server 6
Server Id:           6
Listen Addresses:    [[::]:50051]
Calls Started:       174
Calls Succeeded:     174
Calls Failed:        0
Last Call Started:   now
---
Socket ID   Local->Remote                            Streams(Started/Succeeded/Failed)   Messages(Sent/Received)
25          10.240.0.38:50051->130.211.1.39:44904    68/68/0                             68/68
26          10.240.0.38:50051->130.211.0.167:32768   54/54/0                             54/54
27          10.240.0.38:50051->130.211.0.22:32768    52/52/0                             52/52

クライアント ステータス ディスカバリ サービスを使用する

Client Status Discovery Service(CSDS)API は、xDS API の一部です。gRPC アプリケーションの場合、CSDS サービスは Traffic Director から受け取る構成(xDS 構成とも呼ばれます)にアクセスします。これにより、メッシュの構成に関する問題を特定し、解決できます。

下の例では、プロキシレス gRPC サービスで高度なトラフィック管理を構成するの手順で gRPC ウォレットのサンプルをデプロイしていることを前提としています。

CSDS を使用して構成を調べるには、次のようにします。

  1. SSH を使用して、wallet-service を実行している VM に接続します。SSH を使用して VM に接続するの手順を使行います。
  2. grpcdebug クライアントを実行します。

構成ステータスの概要を取得するには、次のコマンドを実行します。

grpcdebug localhost:28881 xds status

次のような結果が表示されます。

Name                                                                    Status    Version               Type                                                                 LastUpdated
account.grpcwallet.io:10080                                             ACKED     1618529574783547920   type.googleapis.com/envoy.config.listener.v3.Listener                3 seconds ago
stats.grpcwallet.io:10080                                               ACKED     1618529574783547920   type.googleapis.com/envoy.config.listener.v3.Listener                3 seconds ago
URL_MAP/830293263384_grpcwallet-url-map_0_account.grpcwallet.io:10080   ACKED     1618529574783547920   type.googleapis.com/envoy.config.route.v3.RouteConfiguration         3 seconds ago
URL_MAP/830293263384_grpcwallet-url-map_1_stats.grpcwallet.io:10080     ACKED     1618529574783547920   type.googleapis.com/envoy.config.route.v3.RouteConfiguration         3 seconds ago
cloud-internal-istio:cloud_mp_830293263384_3566964729007423588          ACKED     1618529574783547920   type.googleapis.com/envoy.config.cluster.v3.Cluster                  3 seconds ago
cloud-internal-istio:cloud_mp_830293263384_7383783194368524341          ACKED     1618529574783547920   type.googleapis.com/envoy.config.cluster.v3.Cluster                  3 seconds ago
cloud-internal-istio:cloud_mp_830293263384_3363366193797120473          ACKED     1618529574783547920   type.googleapis.com/envoy.config.cluster.v3.Cluster                  3 seconds ago
cloud-internal-istio:cloud_mp_830293263384_3566964729007423588          ACKED     86                    type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment   2 seconds ago
cloud-internal-istio:cloud_mp_830293263384_3363366193797120473          ACKED     86                    type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment   2 seconds ago
cloud-internal-istio:cloud_mp_830293263384_7383783194368524341          ACKED     86                    type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment   2 seconds ago

構成ステータスの定義については、Envoy プロキシのドキュメントをご覧ください。xDS リソースのステータスは、REQUESTEDDOES_NOT_EXISTACKEDNACKED のいずれかです。

未加工の xDS 構成ダンプを取得するには、次のコマンドを実行します。

grpcdebug localhost:28881 xds config

PerXdsConfig オブジェクトの JSON リストが表示されます。

{
  "config":  [
    {
      "node":  {
        "id":  "projects/830293263384/networks/default/nodes/6e98b038-6d75-4a4c-8d35-b0c7a8c9cdde",
        "cluster":  "cluster",
        "metadata":  {
          "INSTANCE_IP":  "10.240.0.38",
          "TRAFFICDIRECTOR_GCP_PROJECT_NUMBER":  "830293263384",
          "TRAFFICDIRECTOR_NETWORK_NAME":  "default"
        },
        "locality":  {
          "zone":  "us-central1-a"
        },
        "userAgentName":  "gRPC Go",
        "userAgentVersion":  "1.37.0",
        "clientFeatures":  [
          "envoy.lb.does_not_support_overprovisioning"
        ]
      },
      "xdsConfig":  [
        {
          "listenerConfig":  {
            "versionInfo":  "1618529930989701137",
            "dynamicListeners":  [
              {
...

未加工の構成出力では量が多すぎる場合は、grpcdebug を使用すると特定の xDS タイプでフィルタリングできます。たとえば、次のように使用します。

$ grpcdebug localhost:28881 xds config --type=cds
{
  "versionInfo":  "1618530076226619310",
  "dynamicActiveClusters":  [
    {
      "versionInfo":  "1618530076226619310",
      "cluster":  {
        "@type":  "type.googleapis.com/envoy.config.cluster.v3.Cluster",
        "name":  "cloud-internal-istio:cloud_mp_830293263384_7383783194368524341",
        "altStatName":  "/projects/830293263384/global/backendServices/grpcwallet-stats-service",
        "type":  "EDS",
        "edsClusterConfig":  {
          "edsConfig":  {
            "ads":  {},
            "initialFetchTimeout":  "15s",
...

複数の xDS タイプの構成を同時にダンプすることもできます。

$ grpcdebug localhost:28881 xds config --type=lds,eds
{
  "versionInfo":  "1618530076226619310",
  "dynamicListeners":  [...]
}
{
  "dynamicEndpointConfigs":  [...]
}

次のステップ