Traffic Director のデプロイに関するトラブルシューティング

このガイドでは、Traffic Director の構成に関する問題を解決する際に有用な情報を提供します。

Envoy のログの場所

問題のトラブルシューティングを行うには、Envoy プロキシのログを調べる必要があります。

Google Kubernetes Engine で、Envoy プロキシはアプリケーション Pod で実行されるため、istio-proxy コンテナでフィルタリングすると、アプリケーション Pod のログにエラーが表示されます。クラスタでワークロード ロギングが有効になっている場合は、Cloud Logging でワークロードのログを表示できます。

次のフィルタを使用できます。

resource.type="k8s_container"
resource.labels.project_id="PROJECT-NAME"
resource.labels.location="CLUSTER-ZONE"
resource.labels.cluster_name="CLUSTER-NAME"
resource.labels.namespace_name="WORKLOAD-NAMESPACE"
labels.k8s-pod/app="WORKLOAD-NAME"
resource.labels.container_name="istio-proxy"

クラスタでワークロードのロギングが有効になっていない場合は、次のようなコマンドを使用してエラーを確認できます。

kubectl logs $(kubectl get po -l app=WORKLOAD-NAME -o=jsonpath='{.items[0].metadata.name}') -c istio-proxy --tail 50 #NOTE: This assumes the default namespace.

次のフィルタを使用して、すべてのクラスタとワークロードで実行されているすべての Envoy のログを表示することもできます。

resource.type="k8s_container"
resource.labels.container_name="istio-proxy"

Compute Engine と手動デプロイを使用する場合は、設定ガイドrun.sh スクリプトを実行する前に、LOG_DIR を定義します。

例: LOG_DIR='/var/log/envoy/'

デフォルトでは、エラーは /var/log/envoy/envoy.err.log に表示されます。

ユーザーが Logging にエクスポートするための追加構成を行わなかった場合は、インスタンスに SSH 接続してこのファイルの取得を試みたときにのみ、このエラーが発生します。

自動 Envoy デプロイを使用している場合は、インスタンスに SSH 接続してログファイルを取得できます。ファイルパスは上記の例と同じ場合があります。

プロキシを Traffic Director に接続できない

プロキシを Traffic Director に接続できない場合は、次の手順を行ってください。

  • Envoy プロキシのログで trafficdirector.googleapis.com への接続エラーを確認します。
  • すべてのトラフィックを Envoy プロキシにリダイレクトするように netfilter を設定した場合(iptables を使用)は、プロキシを実行するユーザー(UID)がリダイレクトから除外されていることを確認してください。除外していないと、トラフィックはプロキシに継続的にループバックします。
  • プロジェクトで Traffic Director API を有効にしたことを確認してください。プロジェクトの API とサービスで、Traffic Director API のエラーを探します。
    [API ライブラリ] ページに移動
  • VM の API アクセス スコープが、GCP API への完全アクセス権を許可するように設定されていることを確認します。これを行うには、VM の作成時に --scopes=https://www.googleapis.com/auth/cloud-platform を指定します。
  • サービス アカウントに正しい権限が付与されていることを確認します。詳細については、Traffic Director API にアクセスするためのサービス アカウントの有効化をご覧ください。
  • VM から trafficdirector.googleapis.com:443 にアクセスできることを確認します。このアクセスに問題がある場合は、ファイアウォールが TCP ポート 443 経由での trafficdirector.googleapis.com へのアクセスを阻止している、または trafficdirector.googleapis.com ホスト名の DNS 解決に問題があることが原因として考えられます。
  • サイドカー プロキシに Envoy を使用している場合は、Envoy のバージョンがリリース 1.9.1 以降であることを確認します。

Traffic Director で構成されたサービスにアクセスできない

Traffic Director で構成されたサービスにアクセスできない場合は、サイドカー プロキシが実行中で、Traffic Director に接続できることを確認します。

Envoy をサイドカー プロキシとして使用している場合は、次のコマンドを実行して確認できます。

  1. コマンドラインから、Envoy プロセスが実行されていることを確認します。

    ps aux | grep envoy
    
  2. Envoy のランタイム構成を調べて、ダイナミック リソースが Traffic Director によって構成されていることを確認します。構成を表示するには、次のコマンドを実行します。

    curl http://localhost:15000/config_dump
    
  3. サイドカー プロキシのトラフィック インターセプトが正しく設定されていることを確認します。

iptables を使用したリダイレクト設定の場合は、iptables コマンドを実行してから grep を実行し、出力結果にルールが含まれることを確認します。

sudo iptables -t nat -S | grep ISTIO

次に、iptables が VIP 10.0.0.1/32 をインターセプトし、ポート 15001 で実行されている Envoy プロキシに UID 1006 として転送する出力の例を示します。

-N ISTIO_IN_REDIRECT
-N ISTIO_OUTPUT
-N ISTIO_REDIRECT
-A OUTPUT -p tcp -j ISTIO_OUTPUT
-A ISTIO_IN_REDIRECT -p tcp -j REDIRECT --to-ports 15001
-A ISTIO_OUTPUT -m owner --uid-owner 1006 -j RETURN
-A ISTIO_OUTPUT -d 127.0.0.1/32 -j RETURN
-A ISTIO_OUTPUT -d 10.0.0.1/32 -j ISTIO_REDIRECT
-A ISTIO_OUTPUT -j RETURN

VM インスタンスが GCP Console で作成された場合、一部の IPV6 関連モジュールは再起動するまでインストールされず使用できません。これにより依存関係が欠落するため、iptables が失敗します。この場合は、VM を再起動して設定プロセスを再実行すると問題が解決します。gcloud コマンドを使用して作成した Compute Engine VM では、この問題は発生しないと考えられます。

Envoy アクセス ロギングが構成されている場合にサービスにアクセスできなくなる

サイドカー プロキシの追加属性の構成で説明したとおり、TRAFFICDIRECTOR_ACCESS_LOG_PATH を使用して Envoy アクセスログを構成した場合は、Envoy プロキシを実行しているシステム ユーザーに指定されたアクセスログのロケーションに対する書き込み権限が付与されていることを確認します。

必要な権限を付与しないと、リスナーがプロキシにプログラミングされません。これは、Envoy プロキシログで次のエラー メッセージを確認することで検出できます。

gRPC config for type.googleapis.com/envoy.api.v2.Listener rejected:
Error adding/updating listener(s) TRAFFICDIRECTOR_INTERCEPTION_LISTENER:
unable to open file '/var/log/envoy.log': Permission denied

この問題を解決するには、選択したファイルのアクセスログの権限を変更して、Envoy ユーザーが書き込めるようにします。

Traffic Director で構成されていないサービスにアプリケーションから接続できない

Traffic Director で構成されているサービスの IP アドレスに対してのみトラフィック インターセプトを設定していることを確認します。すべてのトラフィックがインターセプトされると、Traffic Director で構成されていないサービスへの接続は、サイドカー プロキシによって自動的に破棄されます。

ノード内でトラフィックがループしている、またはノードがクラッシュする

すべてのトラフィックをインターセプトするように netfilter(iptables)を設定している場合は、サイドカー プロキシの実行に使用するユーザー(UID)がトラフィック インターセプトから除外されていることを確認します。除外されていないと、サイドカー プロキシによって送信されたトラフィックは、プロキシに対して無限にループバックされます。その結果、サイドカー プロキシのプロセスがクラッシュする可能性があります。参照構成では、netfilter ルールはプロキシ ユーザーからのトラフィックをインターセプトしません。

大部分のエンドポイントが正常でない場合の Traffic Director の動作

99% のエンドポイントが正常でない場合は、サービスポートが引き続き機能している可能性があることから、信頼性を高めるために、Traffic Director はエンドポイントのヘルス ステータスを無視するようにデータプレーンを構成して、すべてのエンドポイントでトラフィックを分散します。

構成に問題があることを示す Envoy ログのエラー メッセージ

Traffic Director の構成に問題がある場合は、Envoy のログに次のようなエラー メッセージが記録されることがあります。

  • warning envoy config StreamAggregatedResources gRPC config stream closed: 5, Traffic Director configuration was not found for network "VPC_NAME" in project "PROJECT_NUMBER".
  • warning envoy upstream StreamLoadStats gRPC config stream closed: 5, Traffic Director configuration was not found for network "VPC_NAME" in project "PROJECT_NUMBER".
  • warning envoy config StreamAggregatedResources gRPC config stream closed: 5, Requested entity was not found.
  • warning envoy upstream StreamLoadStats gRPC config stream closed: 5, Requested entity was not found.
  • Traffic Director configuration was not found.

このエラー メッセージは通常、Envoy が Traffic Director の構成をリクエストし、一致する構成が見つからないことを示しています。Envoy が Traffic Director に接続すると、VPC ネットワーク名(my-network など)が提示されます。Traffic Director は、(1)INTERNAL_SELF_MANAGED という負荷分散スキームを使用し、(2)同じネットワーク名(my-network など)を参照している転送ルールを探します。

  1. ネットワークに負荷分散スキーム INTERNAL_SELF_MANAGED の転送ルールがあることを確認します。転送ルールの VPC ネットワークをメモしておきます。

  2. Compute Engine での Envoy の自動デプロイで Traffic Director を使用している場合は、--service-proxy:network フラグの値が転送ルールのネットワーク名と一致していることを確認します。

  3. Compute Engine の Envoy の手動デプロイで Traffic Director を使用している場合は、Envoy ブートストラップ ファイルを確認します。

    1. TRAFFICDIRECTOR_NETWORK_NAME 変数の値をチェックし、その値が転送ルールのネットワーク名と一致することを確認します。
    2. Envoy ブートストラップ ファイルの TRAFFICDIRECTOR_GCP_PROJECT_NUMBER 変数でプロジェクト番号が設定されていることを確認します。
  4. GKE にデプロイし、自動インジェクタを使用している場合は、自動 Envoy インジェクションによる Google Kubernetes Engine Pod での Traffic Director の設定の手順に沿って、プロジェクト番号とネットワーク名が正しく構成されていることを確認します。

Envoy の自動デプロイのトラブルシューティング

このセクションでは、Envoy の自動デプロイのトラブルシューティングについて説明します。

トラブルシューティング用の通信チャネル

Envoy と VM のブートストラップ プロセスとその後のライフサイクル管理オペレーションは、一時的な接続の問題、リポジトリの破損、ブートストラップ スクリプトや VM 上のエージェントのバグ、予期しないユーザー アクションなど、多くの理由で失敗する可能性があります。

Google Cloud には、ブートストラップ プロセスと VM 内に存在するコンポーネントの現在の状態を理解する際に役立つ通信チャネルが用意されています。

仮想シリアルポート出力のロギング

VM のオペレーティング システム、BIOS、その他のシステムレベルのエンティティは通常、シリアルポートに出力を書き込みます。この出力は、システムのクラッシュ、起動の失敗、起動時の問題、シャットダウン時の問題などのトラブルシューティングに役立ちます。

Compute Engine ブートストラップ エージェントは、インスタンスのメタデータ サーバー、iptables 構成、Envoy のインストール ステータスからデータを取得することにより、基本的なパッケージのインストールから実行されたすべてのアクションを、システム イベントとともにシリアルポート 1 に記録します。

VM 上のエージェントは、Envoy プロセスのヘルス ステータス、新しく検出された Traffic Director サービスと、VM の問題を調査するときに役立つ可能性のあるその他の情報を記録します。

Cloud Monitoring のロギング

シリアルポート出力で公開されるデータは、Monitoring にも記録されます。Monitoring は、Golang ライブラリを使用してログを別のログにエクスポートし、ノイズを軽減します。これはインスタンス レベルのログであるため、サービス プロキシのログは他のインスタンス ログと同じページに表示されることがあります。

VM のゲスト属性

ゲスト属性は、インスタンスでの実行中にアプリケーションから書き込み可能な特定の型のカスタム メタデータです。インスタンスのすべてのアプリケーションまたはユーザーは、ゲスト属性メタデータ値にデータを書き込み、読み取ることができます。

Compute Engine Envoy ブートストラップ スクリプトと VM 上のエージェントは、ブートストラップ プロセスと Envoy の現在のステータスに関する情報を含む属性を公開します。すべてのゲスト属性は gce-service-proxy 名前空間で公開されます。

gcloud compute instances get-guest-attributes INSTANCE_NAME \
    --query-path=gce-service-proxy/ --zone ZONE

問題が見つかった場合は、ゲスト属性 bootstrap-statusbootstrap-last-failure の値を確認することをおすすめします。FINISHED 以外の bootstrap-status 値は、Envoy 環境がまだ構成されていないことを意味します。bookstrap-last-failure の値は、問題の原因を示します。

サービス プロキシ対応のインスタンス テンプレートを使用して作成された VM から Traffic Director サービスに到達できない

次の手順に沿って問題を解決してください。

  1. VM へのサービス プロキシ コンポーネントのインストールが完了していないか、失敗している可能性があります。

    次のコマンドを使用して、すべてのコンポーネントが正しくインストールされているかどうかを確認します。

    gcloud compute instances get-guest-attributes INSTANCE_NAME \
        --query-path=gce-service-proxy/ --zone=ZONE
    

    bootstrap-status ゲスト属性は次のいずれかに設定されます。

    • [none] は、インストールがまだ開始していないことを示します。VM がまだ起動中である可能性があります。数分後にもう一度ステータスを確認してください。
    • IN PROGRESS は、サービス プロキシ コンポーネントのインストールと構成がまだ完了していないことを示します。プロセスの更新についてステータス チェックを繰り返します。
    • FAILED は、コンポーネントのインストールまたは構成が失敗したことを示します。gce-service-proxy/bootstrap-last-failure1 属性をクエリして、エラー メッセージを確認します。
    • FINISHED は、インストールと構成のプロセスがエラーなしで終了したことを示します。以下の手順を使用して、トラフィック インターセプトと Envoy プロキシが正しく構成されていることを確認します。
  2. VM 上のトラフィック インターセプトが Traffic Director ベースのサービスに対して正しく構成されていません。

    VM にログインし、iptables 構成を確認します。

    gcloud compute ssh INSTANCE_NAME --zone=ZONE
    sudo iptables -L -t nat
    

    次のような SERVICE_PROXY_REDIRECT エントリのチェーン SERVICE_PROXY_SERVICE_CIDRS を調べます。

    Chain SERVICE_PROXY_SERVICE_CIDRS (1 references)
    target           prot opt source              destination  ...
    SERVICE_PROXY_REDIRECT  all  --  anywhere             10.7.240.0/20
    

    サービスごとに、destination 列に一致する IP アドレスまたは CIDR が必要です。VIP のエントリがない場合、Traffic Director から Envoy プロキシ構成にデータを入力する際に問題が発生したか、VM 上のエージェントが失敗しました。

  3. Envoy プロキシが、Traffic Director からの構成をまだ受信していません。

    VM にログインして、Envoy プロキシの構成を確認します。

    gcloud compute ssh INSTANCE_NAME --zone=ZONE
    sudo curl localhost:15000/config_dump
    

    Traffic Director から受信したリスナー構成を調べます。例:

    "dynamic_active_listeners": [
      ...
      "filter_chains": [{
        "filter_chain_match": {
          "prefix_ranges": [{
            "address_prefix": "10.7.240.20",
            "prefix_len": 32
          }],
          "destination_port": 80
        },
      ...
        "route_config_name": "URL_MAP/[PROJECT_NUMBER].td-routing-rule-1"
      ...
    ]
    

    address_prefix は Traffic Director サービスの VIP です。これは、td-routing-rule-1 という URL マップを指します。接続するサービスがリスナー構成にすでに含まれているかどうかを確認します。

  4. VM 上のエージェントが実行されていません。

    新しい Traffic Director サービスが作成されると、VM 上のエージェントはトラフィック インターセプトを自動的に構成します。エージェントが実行されていない場合、新しいサービスへのすべてのトラフィックは Envoy Proxy をバイパスして VIP に直接送信され、タイムアウトします。

    VM 上のエージェントのステータスを確認するには、次のコマンドを実行します。

    gcloud compute instances get-guest-attributes INSTANCE_NAME \
        --query-path=gce-service-proxy/ --zone=ZONE
    
  5. VM 上のエージェントの属性を確認できます。agent-heartbeat 属性の値は、エージェントで最後にアクションを実行したか確認した時刻です。この値が 5 分以上経過している場合は、エージェントが停止し、gcloud compute instance-groups managed recreate-instance コマンドを使用して VM を再作成する必要があります。

  6. agent-last-failure 属性は、エージェントで最後に発生したエラーを公開します。これは、エージェントが次にチェックするときにまでに解決される一時的な問題の可能性があります(たとえば、エラーが Cannot reach the Traffic Director API server の場合もあれば、永続的なエラーである場合もあります)。数分待ってから、エラーを再度確認してください。

受信トラフィック インターセプトがワークロード ポートに構成されているが、VM の外部からポートに接続することができない

次の手順に沿って問題を解決してください。

  1. VM へのサービス プロキシ コンポーネントのインストールが完了していないか、失敗している可能性があります。

    次のコマンドを使用して、すべてのコンポーネントが正しくインストールされているかどうかを確認します。

    gcloud compute instances get-guest-attributes INSTANCE_NAME \
        --query-path=gce-service-proxy/ --zone=ZONE
    

    bootstrap-status ゲスト属性は次のいずれかに設定されます。

    • [none] は、インストールがまだ開始していないことを示します。VM がまだ起動中である可能性があります。数分後にもう一度ステータスを確認してください。
    • IN PROGRESS は、サービス プロキシ コンポーネントのインストールと構成がまだ完了していないことを示します。プロセスの更新についてステータス チェックを繰り返します。
    • FAILED は、コンポーネントのインストールまたは構成が失敗したことを示します。gce-service-proxy/bootstrap-last-failure1 属性をクエリして、エラー メッセージを確認します。
    • FINISHED は、インストールと構成のプロセスがエラーなしで終了したことを示します。以下の手順を使用して、トラフィック インターセプトと Envoy プロキシが正しく構成されていることを確認します。
  2. VM 上のトラフィック インターセプトが、受信トラフィックに対して正しく構成されていません。

    VM にログインし、iptables 構成を確認します。

    gcloud compute ssh INSTANCE_NAME --zone=ZONE
    sudo iptables -L -t nat
    

    次のような SERVICE_PROXY_IN_REDIRECT エントリのチェーン SERVICE_PROXY_INBOUND を調べます。

    Chain SERVICE_PROXY_INBOUND (1 references)
    target     prot opt source               destination
    ...
    SERVICE_PROXY_IN_REDIRECT  tcp  --  anywhere  anywhere  tcp dpt:mysql
    

    service-proxy:serving-ports で定義されているポートごとに、destination 列に一致するポートがあるはずです。ポートのエントリがない場合は、すべての受信トラフィックが Envoy プロキシをバイパスして、このポートに直接送信されます。

    このポートまたは特定の 1 つのポートを除くすべてのポートにトラフィックをドロップする他のルールがないことを確認します。

  3. Envoy プロキシが、Traffic Director からの受信ポートの構成をまだ受信していません。

    VM にログインして、Envoy プロキシの構成を確認します。

    gcloud compute ssh INSTANCE_NAME --zone=ZONE
    sudo curl localhost:15000/config_dump
    

    Traffic Director から受信した 受信 リスナー構成を探します。

    "dynamic_active_listeners": [
      ...
      "filter_chains": [{
        "filter_chain_match": {
          "prefix_ranges": [{
            "address_prefix": "10.0.0.1",
            "prefix_len": 32
          }],
          "destination_port": 80
        },
      ...
        "route_config_name": "inbound|default_inbound_config-80"
      ...
    ]
    

    inbound で始まる route_config_name は、受信トラフィックのインターセプトを目的として作成された特別なサービスを示します。接続するポートが、すでに destination_port のリスナー構成に含まれているかどうかを確認します。

次のステップ