Anthos Service Mesh ログの解釈

以下のセクションでは、メッシュのステータスを確認する方法と、トラブルシューティングに役立つ情報を含むさまざまなログを確認する方法について説明します。

コントロール プレーンの指標を解釈する

asm-gcp プロファイルを使用して Anthos Service Mesh をインストールしている場合、デフォルトでは、Istiod はモニタリング用の指標を Google Cloud Observability にエクスポートします。Istiod では、これらの指標に istio.io/control という接頭辞が付いており、各コントロール プレーン インスタンスに接続されるプロキシの数、構成イベント、push、検証など、コントロール プレーンの状態の分析情報を提供します。

次の手順でコントロール プレーンを監視またはトラブルシューティングします。

  1. サンプル ダッシュボードを読み込みます。

    git clone https://github.com/GoogleCloudPlatform/monitoring-dashboard-samples && cd monitoring-dashboard-samples && git checkout asm
  2. Anthos Service Mesh ダッシュボードをインストールします。

    gcloud monitoring dashboards create --config-from-file=dashboards/servicemesh/anthos-service-mesh-control-plane-monitoring.json
  3. リストで、Istio Control Plane Dashboard という名前のダッシュボードを探します。詳細については、インストールされたダッシュボードの表示をご覧ください。

    asm-gcp プロファイルを使用していない場合でも、環境変数を Istiod のデプロイに追加することで、コントロール プレーン指標を有効にできます。

    - name: ENABLE_STACKDRIVER_MONITORING
    value: "true"

    さらに、インストール オプション components.pilot.k8s.env を使用して、この環境変数を追加できます。

利用可能な指標の一覧については、エクスポートされた指標をご覧ください。

構成の遅延を診断する

次の手順では、pilot_proxy_convergence_time 指標を使用して、構成の変更とすべてのプロキシ収束の遅延を診断する方法について説明します。

  1. Pod でシェルコマンドを実行します。

    kubectl exec -it $(kubectl get pod -l app=pilot -o jsonpath='{.items[0].metadata.name}' -n istio-system) -n istio-system -c istio-proxy -- curl -s
  2. 指標の convergencelocalhost:15014grep にアクセスします。

    curl http://localhost:15014/metrics | grep convergence

Google Cloud Observability のアクセスログを解釈する

ここでは、Google Cloud Observability のアクセスログを使用して、接続の問題を解決する方法について説明します。

Anthos Service Mesh は、Google Cloud Observability のアクセスログにデータをエクスポートします。この情報は、次の種類の問題のデバッグに役立ちます。

  • トラフィック フローと障害
  • エンドツーエンドのリクエスト ルーティング

asm-gcp プロファイルのデフォルトでは、メッシュ全体で Google Cloud Observability のアクセスログとトラフィック ログが有効になっています。まだ有効になっていない場合は、次のコマンドを使用できます。

istioctl install --set profile=PROFILE_NAME --set revision==ASM_VERSION \
    --set values.telemetry.v2.stackdriver.enabled=true \
    --set values.telemetry.v2.stackdriver.logging=true

アクセスログには次の 2 種類があります。

  • サーバー アクセス ログでは、サーバーサイドのリクエストを確認できます。これらは server-accesslog-stackdriver の下にあり、k8s_container モニタリング対象リソースに接続されます。サーバーサイドのアクセスログを表示するには、次の URL 構文を使用します。

    https://console.cloud.google.com/logs/viewer?advancedFilter=logName="projects/PROJECT_ID/logs/server-accesslog-stackdriver"&project=PROJECT_ID
  • クライアント アクセス ログは、クライアントサイドのリクエストを表示します。これらは client-accesslog-stackdriver の下にあり、k8s_pod モニタリング対象リソースに接続されます。クライアントサイドのアクセスログを表示するには、次の URL 構文を使用します。

    https://console.cloud.google.com/logs/viewer?advancedFilter=logName="projects/PROJECT_ID/logs/client-accesslog-stackdriver"&project=PROJECT_ID

ロギングの費用を抑えるため、デフォルトではクライアント エラーログのみが有効になっています。ただし、次のコマンドを使用すると、すべてのクライアント ログ(成功とエラー)を有効にできます。

istioctl install --set profile=PROFILE_NAME --set revision==ASM_VERSION 
--set values.telemetry.v2.stackdriver.enabled=true
--set values.telemetry.v2.stackdriver.outboundAccessLogging=FULL

アクセスログには次の情報が含まれます。

  • ID、URL、サイズ、レイテンシ、共通ヘッダーなどの HTTP リクエスト プロパティ。
  • 送信元と宛先のワークロードの情報(名前、名前空間、ID、共通ラベルなど)。
  • 送信元と宛先の正規サービスとリビジョン情報。
  • トレースが有効になっている場合、ログにはサンプリング、トレース ID、スパン ID などのトレース情報が含まれます。

Istio 構成でログを有効にすると、Google Cloud Observability のアクセスログの情報は Envoy アクセスログから生成されます。これには次のヘッダーが含まれています。

  • route_name
  • upstream_cluster
  • X-Envoy-Original-Path
  • X-Envoy-Original-Host

これはログエントリの例です。

{
  "insertId": "1j84zg8g68vb62z",
  "httpRequest": {
    "requestMethod": "GET",
    "requestUrl": "http://35.235.89.201:80/productpage",
    "requestSize": "795",
    "status": 200,
    "responseSize": "7005",
    "remoteIp": "10.168.0.26:0",
    "serverIp": "10.36.3.153:9080",
    "latency": "0.229384205s",
    "protocol": "http"
  },
  "resource": {
    "type": "k8s_container",
    "labels": {
      "cluster_name": "istio-e2e22",
      "namespace_name": "istio-bookinfo-1-68819",
      "container_name": "productpage",
      "project_id": "***",
      "location": "us-west2-a",
      "pod_name": "productpage-v1-64794f5db4-8xbtf"
    }
  },
  "timestamp": "2020-08-13T21:37:42.963881Z",
  "severity": "INFO",
  "labels": {
    "protocol": "http",
    "upstream_host": "127.0.0.1:9080",
    "source_canonical_service": "istio-ingressgateway",
    "source_namespace": "istio-system",
    "x-envoy-original-path": "",
    "source_canonical_revision": "latest",
    "connection_id": "32",
    "upstream_cluster": "inbound|9080|http|productpage.istio-bookinfo-1-68819.svc.cluster.local",
    "requested_server_name": "outbound_.9080_._.productpage.istio-bookinfo-1-68819.svc.cluster.local",
    "destination_version": "v1",
    "destination_workload": "productpage-v1",
    "source_workload": "istio-ingressgateway",
    "destination_canonical_revision": "v1",
    "mesh_uid": "cluster.local",
    "source_principal": "spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account",
    "x-envoy-original-dst-host": "",
    "service_authentication_policy": "MUTUAL_TLS",
    "destination_principal": "spiffe://cluster.local/ns/istio-bookinfo-1-68819/sa/bookinfo-productpage",
    "response_flag": "-",
    "log_sampled": "false",
    "destination_service_host": "productpage.istio-bookinfo-1-68819.svc.cluster.local",
    "destination_name": "productpage-v1-64794f5db4-8xbtf",
    "destination_canonical_service": "productpage",
    "destination_namespace": "istio-bookinfo-1-68819",
    "source_name": "istio-ingressgateway-6845f6d664-lnfvp",
    "source_app": "istio-ingressgateway",
    "destination_app": "productpage",
    "request_id": "39013650-4e62-9be2-9d25-78682dd27ea4",
    "route_name": "default"
  },
  "logName": "projects/***/logs/server-accesslog-stackdriver",
  "trace": "projects/***t/traces/466d77d15753cb4d7749ba5413b5f70f",
  "receiveTimestamp": "2020-08-13T21:37:48.758673203Z",
  "spanId": "633831cb1fda4fd5",
  "traceSampled": true
}

このログはさまざまな方法で使用できます。

  • Anthos Service Mesh のオプションの機能である Cloud Trace と統合する。
  • トラフィック ログを BigQuery にエクスポートする。すべてのリクエストを選択すると 5 秒以上かかるようなクエリを実行できます。
  • ログベースの指標を作成する。
  • 404 エラーと 503 エラーのトラブルシューティング

404 エラーと 503 エラーのトラブルシューティング

次の例は、このレスポンスを使用して、404 または 503 のレスポンス コードでリクエストが失敗した場合のトラブルシューティングを行う方法を示しています。

  1. クライアント アクセスログで、次のようなエントリを検索します。

    httpRequest: {
    requestMethod: "GET"
    requestUrl: "://IP_ADDRESS/src/Util/PHP/eval-stdin.php"
    requestSize: "2088"
    status: 404
    responseSize: "75"
    remoteIp: "10.168.0.26:34165"
    serverIp: "10.36.3.149:8080"
    latency: "0.000371440s"
    protocol: "http"
    }
  2. アクセス ログエントリ内のラベルに移動します。次のような response_flag フィールドを探します。

    response_flag: "NR"

    NR 値は NoRoute の頭字語です。これは、宛先のルートが見つからなかったか、ダウンストリーム接続に一致するフィルタ チェーンがなかったことを意味します。同様に、response_flag ラベルを使用して 503 エラーのトラブルシューティングを行うこともできます。

  3. クライアント ログとサーバー アクセスログの両方に 503 エラーが表示された場合は、各サービスに設定されたポート名が、サービス間で使用されているプロトコルの名前と一致していることを確認してください。たとえば、Golang バイナリ クライアントが HTTP を使用して golang サーバーに接続されているが、ポート名は http2 の場合、プロトコルは自動的にネゴシエートされません。

詳細については、レスポンス フラグをご覧ください。

Envoy ログを解釈する

以下の手順では、Envoy プロキシ アクセスログを使用して、接続の両側でトラフィックを確認する方法を説明します。

Envoy アクセスログは、次のような問題の診断に役立ちます。

  • トラフィック フローと障害
  • エンドツーエンドのリクエスト ルーティング

Anthos Service Mesh のデフォルトでは、アクセスログは有効になっていません。このログは、メッシュ全体でグローバルに有効にできます。

HTTP リクエストをトリガーするアクティビティをアプリケーション内で生成し、関連するログをソースログまたは宛先ログで調査することで、接続 / リクエストのエラーをトラブルシューティングできます。

トリガーされたリクエストがソース プロキシログに表示されている場合は、iptables トラフィックのリダイレクトが正常に動作しており、Envoy プロキシがトラフィックを処理していることを示します。ログにエラーが表示されたら、Envoy 構成ダンプを生成し、Envoy クラスタの構成が正しいことを確認してください。リクエストが表示されてログにエラーがない場合は、代わりに宛先プロキシのログを確認してください。

リクエストが宛先プロキシログに表示されている場合は、メッシュ自体が正常に動作していることを示しています。代わりにエラーが表示された場合は、Envoy 構成ダンプを実行し、リスナー構成で設定されているトラフィック ポートの正しい値を確認します。

上述の手順で問題が解決しない場合は、Envoy がサイドカーとそのアプリケーション Pod 間でプロトコルを自動的にネゴシエートできない可能性があります。Kubernetes Service のポート名(http-80 など)がアプリケーションで使用するプロトコルと一致していることを確認します。

ログ エクスプローラを使用してログをクエリする

ログ エクスプローラ インターフェースを使用して、特定のアクセスログを照会できます。たとえば、MULTUAL_TLS が有効で、grpc プロトコルを使用するすべてのリクエストをクエリで取得するには、サーバー アクセスログのクエリの末尾に以下を追加します。

labels.protocol="grpc" labels.service_authentication_policy="MULTUAL_TLS"

アクセスログ ポリシーを設定する

収集する情報の種類を決定するプロキシ ロギング ポリシーを設定できます。これは、問題のトラブルシューティングに使用するログのスコープを制御するのに役立ちます。たとえば、ロギングでエラーが自動的にキャプチャされますが、logWindowDuration を設定すると、特定の期間内に成功したすべてのイベントをキャプチャできます。また、ウィンドウ期間を 0 に設定して、すべてのアクセスをロギングすることもできます。このポリシーは、メッシュまたはクラスタレベルで設定されます。

アクセスログ ポリシーを有効にするには、次のコマンドを使用します。

istioctl install --set profile=PROFILE_NAME \
    --set values.telemetry.v2.stackdriver.enabled=true \
    --set values.telemetry.v2.stackdriver.logging=true \
    --set values.telemetry.accessLogPolicy.enabled=true

logWindowDuration などのアクセスログ構成オプションの詳細については、AccessLogPolicy Config をご覧ください。

サービスまたはワークロード固有の情報を表示する

メッシュ全体ではなく、特定のサービスやワークロードに問題がある場合は、個々の Envoy プロキシを調査し、関連する情報を収集します。特定のワークロードとそのプロキシに関する情報を収集するには、pilot-agent を使用します。

kubectl exec POD_NAME -c istio-proxy -- pilot-agent request GET SCOPE

この例では、SCOPE は次のいずれかです。

  • certs - Envoy インスタンス内の証明書
  • clusters - Envoy が構成されているクラスタ
  • config_dump - Envoy 構成をダンプする
  • listeners - Envoy が構成されているリスナー
  • logging - ロギング設定を表示して変更する
  • stats - Envoy 統計情報
  • stats/prometheus - Prometheus レコードとしての Envoy 統計情報

プロキシ ソケットの状態を表示する

次のプロセスを使用すると、Envoy プロキシ ソケットの状態を直接調べることが可能です。

  1. 確立されたソケットのリストを表示します(TIME_WAIT 状態のソケットを含む)。数が多いと、スケーラビリティに悪影響を与える可能性があります。

    kubectl exec POD_NAME -c istio-proxy -- ss -anopim
  2. ソケットの統計情報の概要を表示します。

    kubectl exec POD_NAME -c istio-proxy -- ss -s

詳細については、ss コマンドの概要をご覧ください。

istio-proxy ログと istio-init ログ

また、istio-proxy ログを取得し、その内容を確認して、問題の原因を示しているエラーがないか確認します。

kubectl logs POD_NAME -c istio-proxy

init コンテナについても同じことができます。

kubectl logs POD_NAME -c istio-init