Kemampuan observasi dengan aplikasi gRPC tanpa proxy

Alat Kemampuan observasi microservice memberi Anda kemampuan untuk melengkapi aplikasi Anda guna mengumpulkan dan menyajikan data telemetri di Cloud Monitoring, Cloud Logging, dan Cloud Trace dari workload gRPC yang di-deploy di Google Cloud, termasuk workload gRPC di Cloud Service Mesh.

Klien dan server gRPC terintegrasi dengan OpenCensus untuk mengekspor metrik dan trace ke berbagai backend, termasuk Trace dan Monitoring. Anda dapat melakukannya dengan bahasa gRPC berikut:

  • C++
  • Go
  • Java

Baca Ringkasan kemampuan observasi Microservice, lalu gunakan petunjuk dalam Menyiapkan kemampuan observasi Microservice untuk melengkapi workload gRPC Anda untuk hal berikut:

Gunakan petunjuk dalam dokumen ini untuk tugas berikut:

Melihat rekaman aktivitas di Trace

Setelah Anda menyelesaikan proses penyiapan, klien dan server gRPC berinstrumen akan mengirim trace ke Trace. Halaman Ringkasan Trace di Konsol Google Cloud menampilkan daftar trace terbaru. Anda dapat memilih trace satu per satu untuk melihat perincian traffic, seperti yang dijelaskan di bagian berikut.

Kompatibilitas pelacakan dengan proxy Envoy

Mengekspor rekaman aktivitas ke Trace dengan Cloud Service Mesh dan proxy Envoy, seperti yang dijelaskan dalam Kemampuan observasi dengan Envoy, menggunakan konfigurasi tracer OpenCensus Envoy, yang memungkinkan trace yang diekspor dari aplikasi gRPC tanpa proxy dan proxy Envoy sepenuhnya kompatibel dalam mesh layanan. Untuk kompatibilitas dengan gRPC tanpa proxy, bootstrap Envoy perlu mengonfigurasi konteks rekaman aktivitas untuk menyertakan format rekaman aktivitas GRPC_TRACE_BIN dalam OpenCensusConfig-nya. Contoh:

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

Mengekspos antarmuka admin

Terkadang, data metrik dan pelacakan tidak cukup untuk menyelesaikan masalah. Anda mungkin perlu melihat konfigurasi atau status runtime library gRPC di aplikasi Anda. Informasi ini mencakup informasi resolver, status konektivitas ke pembanding, statistik RPC pada saluran, dan konfigurasi yang diterima dari Cloud Service Mesh.

Untuk mendapatkan informasi tersebut, aplikasi gRPC dapat menampilkan antarmuka admin pada port tertentu. Selanjutnya, Anda dapat membuat kueri aplikasi untuk memahami cara layanan dikonfigurasi, dan cara layanannya berjalan. Di bagian ini, Anda dapat menemukan petunjuk cara mengonfigurasi antarmuka admin untuk aplikasi yang ditulis dalam setiap bahasa yang didukung.

Sebaiknya buat server gRPC terpisah di aplikasi Anda yang memproses port yang disediakan untuk tujuan ini. Hal ini memungkinkan Anda mengakses aplikasi gRPC meskipun port data tidak dapat diakses karena kesalahan konfigurasi atau masalah jaringan. Sebaiknya perlihatkan antarmuka admin hanya di localhost atau pada soket domain Unix.

Cuplikan kode berikut menunjukkan cara membuat antarmuka admin.

C++

Di C++, gunakan kode ini untuk membuat antarmuka admin:

#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

Di Go, gunakan kode ini untuk membuat antarmuka admin:

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

Di Java, gunakan kode ini untuk membuat antarmuka admin:

import io.grpc.services.AdminInterface;

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

Python

Di Python, gunakan kode ini untuk membuat antarmuka admin:

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

Menggunakan SSH untuk terhubung ke VM

Contoh gRPC Wallet sudah mengaktifkan antarmuka admin. Anda dapat mengubah port antarmuka admin dengan memberikan tanda berikut:

 --admin-port=PORT

Port admin default adalah localhost:28881.

Untuk men-debug aplikasi gRPC, Anda dapat menggunakan SSH untuk terhubung ke salah satu VM yang menayangkan wallet-service. Tindakan ini memberi Anda akses ke 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

Menginstal alat grpcdebug

Untuk mengakses antarmuka admin, Anda memerlukan klien gRPC yang dapat berkomunikasi dengan layanan admin di aplikasi gRPC Anda. Pada contoh berikut, Anda menggunakan alat bernama grpcdebug yang dapat didownload dan diinstal di VM atau Pod tempat aplikasi gRPC Anda berjalan. Repositori untuk grpcdebug berada di grpc-ecosystem/grpcdebug.

Dukungan minimum versi Golang adalah 1.12. Panduan pemasangan Golang resmi dapat ditemukan di situs Golang. Jika mengikuti panduan pembuatan VM Linux untuk wallet-service, Anda dapat menginstal Golang 1.16 menggunakan perintah berikut:

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

Anda menginstal alat grpcdebug dengan perintah berikut:

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

Anda sekarang memiliki akses ke antarmuka command line grpcdebug. Output bantuan berisi informasi tentang perintah yang didukung:

$ 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

Untuk memperoleh informasi selengkapnya tentang perintah tertentu, gunakan hal berikut:

 grpcdebug <target address> [command] --help

Menggunakan alat grpcdebug untuk men-debug aplikasi

Anda dapat menggunakan alat grpcdebug untuk men-debug aplikasi. Alat grpcdebug menyediakan konfigurasi seperti ssh_config yang mendukung aliasing, penulisan ulang nama host, dan setelan keamanan koneksi (tidak aman/TLS). Untuk mengetahui informasi selengkapnya tentang fitur lanjutan ini, lihat grpcdebug/Connect&Security.

Bagian berikut menjelaskan layanan yang ditampilkan oleh antarmuka admin dan cara mengaksesnya.

Menggunakan Channelz

Layanan Channelz memberikan akses ke informasi runtime tentang koneksi di berbagai level dalam library gRPC aplikasi Anda. Anda dapat menggunakan ini untuk analisis langsung aplikasi yang mungkin memiliki masalah terkait konfigurasi atau jaringan. Contoh berikut mengasumsikan bahwa Anda men-deploy contoh gRPC Wallet dengan menggunakan petunjuk di Mengonfigurasi pengelolaan traffic lanjutan dengan layanan gRPC tanpa proxy dan bahwa Anda memberikan tanda berikut:

 --admin-port=PORT

Setelah Anda mengirim beberapa RPC dari klien pengujian, seperti yang ditunjukkan dalam Memverifikasi konfigurasi, gunakan perintah berikut untuk mengakses data Channelz untuk layanan gRPC:

  1. Gunakan SSH untuk terhubung ke VM yang menjalankan wallet-service.
  2. Siapkan grpcdebug agar terhubung ke aplikasi gRPC yang berjalan.

Output default grpcdebug adalah dalam format tabel yang cocok untuk konsol. Jika Anda memberikan flag --json, output akan dienkode sebagai JSON.

Perintah grpcdebug channelz digunakan untuk mengambil dan menampilkan informasi proses debug dari layanan Channelz. Perintah ini berfungsi untuk klien gRPC dan server gRPC.

Untuk klien gRPC, perintah grpcdebug channelz channels menyediakan daftar saluran yang ada dan beberapa informasi dasar:

$ 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

Jika memerlukan informasi tambahan tentang saluran tertentu, Anda dapat menggunakan grpcdebug channelz channel [CHANNEL_ID] untuk memeriksa informasi detail untuk saluran tersebut. ID saluran dapat berupa ID saluran atau alamat target, jika hanya ada satu alamat target. Saluran gRPC dapat berisi beberapa subsaluran, yang merupakan abstraksi gRPC di atas koneksi TCP.

$ 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

Anda juga dapat memeriksa informasi mendetail untuk subchannel:

$ 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

Anda dapat mengambil informasi tentang soket 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

Di sisi server, Anda dapat menggunakan Channelz untuk memeriksa status aplikasi server. Misalnya, Anda bisa mendapatkan daftar server dengan menggunakan perintah 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

Untuk mendapatkan informasi selengkapnya tentang server tertentu, gunakan perintah grpcdebug channelz server. Anda dapat memeriksa soket server dengan cara yang sama seperti memeriksa soket klien.

$ 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

Menggunakan Layanan Penemuan Status Klien

Client Status Discovery Service (CSDS) API adalah bagian dari xDS API. Dalam aplikasi gRPC, layanan CSDS menyediakan akses ke konfigurasi (juga disebut konfigurasi xDS) yang diterima dari Cloud Service Mesh. Hal ini memungkinkan Anda mengidentifikasi dan menyelesaikan masalah terkait konfigurasi di mesh Anda.

Contoh berikut mengasumsikan bahwa Anda men-deploy contoh gRPC Wallet dengan menggunakan petunjuk di Mengonfigurasi pengelolaan traffic lanjutan dengan layanan gRPC tanpa proxy.

Untuk menggunakan CSDS guna memeriksa konfigurasi:

  1. Gunakan SSH untuk terhubung ke VM yang menjalankan wallet-service. Gunakan petunjuk di Menggunakan SSH untuk terhubung ke VM.
  2. Jalankan klien grpcdebug.

Untuk mendapatkan ringkasan status konfigurasi, jalankan perintah berikut:

grpcdebug localhost:28881 xds status

Anda akan melihat hasil yang mirip dengan yang berikut ini:

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

Anda dapat menemukan definisi status konfigurasi dalam dokumentasi untuk proxy Envoy. Singkatnya, status resource xDS adalah salah satu dari REQUESTED, DOES_NOT_EXIST, ACKED, atau NACKED.

Untuk mendapatkan dump konfigurasi xDS mentah, jalankan perintah berikut:

grpcdebug localhost:28881 xds config

Anda akan melihat daftar JSON objek PerXdsConfig:

{
  "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":  [
              {
...

Jika output konfigurasi mentah terlalu panjang, grpcdebug memungkinkan Anda memfilter berdasarkan jenis xDS tertentu. Contoh:

$ 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",
...

Anda juga dapat membuang konfigurasi jenis xDS seberal secara bersamaan:

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

Langkah selanjutnya