VPC ピアリングの使用時に TARGET_CONNECT_TIMEOUT により「503 Service Unavailable(サービス利用不可)」エラーが発生する

現在、ApigeeApigee ハイブリッドのドキュメントを表示しています。
このトピックに対応する Apigee Edge のドキュメントはありません。

症状

この問題は、API Monitoringデバッグ、その他のツールで「503 - Service Unavailable」エラーとして表面化します。「TARGET_CONNECT_TIMEOUT」の理由は、VPC ピアリングの使用時に Apigee インスタンスとターゲットの間で接続タイムアウトが発生したことを示します。

このエラーを「504 Gateway Timeout」などの他のタイムアウト エラーと混同しないよう注意してください。

エラー メッセージ

以下に、デバッグ セッションまたはレスポンス ペイロードでの一般的なエラーを示します。理由が TARGET_CONNECT_TIMEOUT になっている点に注目してください。

{"fault":{"faultstring":"The Service is temporarily unavailable",
"detail":{"errorcode":"messaging.adaptors.http.flow.ServiceUnavailable",
"reason":"TARGET_CONNECT_TIMEOUT"}}}

考えられる原因

以下の原因は、VPC ピアリングが設定された Apigee に固有のものです。Apigee ネットワーキング オプションをご覧ください。ターゲットが PSC(エンドポイント アタッチメント)の場合は、代わりに PSC ハンドブックをご覧ください。

原因 説明
ルートの構成ミス ターゲット ルートが Apigee インスタンスとのピアリングにエクスポートされていません。
ターゲットでの接続性の問題 ターゲットが常に TCP 接続を受け入れることができません。
ターゲットの IP 許可リストに一部またはすべての Apigee NAT IP が追加されていない すべての Apigee NAT IP がターゲットの許可リストに登録されていません。
NAT IP ポートの枯渇 NAT ポートが不足していてトラフィックに対応できません。
connect.timeout.millis の設定値が小さすぎる Apigee 側で設定されている接続タイムアウトが短すぎます。

共通の診断手順

デバッグは、この問題に関する以下のような詳細情報を収集して評価するために不可欠なツールです。

  • リクエストの合計時間。通常は、接続がタイムアウトするまで 3 秒かかります(3 秒は connect.timeout.millis のデフォルト値)。リクエストの合計時間が短い場合は、ターゲット エンドポイントの構成を確認します。
  • ターゲットのホスト名と IP アドレス。表示された IP アドレスが間違っている場合は、DNS 関連の問題がある可能性があります。異なるターゲット IP と問題との間に相関関係が認められることもあります。
  • 頻度。問題が断続的か持続的かによって必要なアプローチは異なります。

原因: ルートの構成ミス

診断

問題が持続的な場合は、最近発生し始めたとしても、ルートの構成ミスが原因である可能性があります。

これは、内部(ピアリングされた VPC 内でルーティングされる)ターゲットと外部(インターネット)ターゲットのどちらにも影響する可能性があります。

  1. まず Apigee インスタンスから、解決されたターゲットの IP アドレスを特定します。その方法の一つは、デバッグ セッションを使用することです。デバッグで、[AnalyticsPublisher](クラシック デバッグの場合は [AX])に移動します。

    デバッグ ウィンドウ

    画面の右側で [target.ip] の値を探します。

    この例では、IP は 10.2.0.1 です。これはプライベート IP アドレスの範囲なので、Apigee がターゲットに到達できるように特定のルーティング対策を講じる必要があります。

    ターゲットがインターネット上にある場合でも、Apigee で VPC Service Controls が有効になっている場合はインターネットに接続できないため、このステップを実施する必要があります。

  2. 問題の Apigee インスタンスがデプロイされているリージョンをメモします。Cloud コンソールの Apigee UI で、[インスタンス] をクリックします。[ロケーション] フィールドで、インスタンスの正確なリージョンを確認できます。

    Apigee コンソール インスタンス
  3. Apigee とピアリングされているプロジェクトで、UI の [VPC ネットワーク] -> [VPC ネットワーク ピアリング] セクションに移動します。共有 VPC を使用している場合、これらの手順は Apigee プロジェクトではなくホスト プロジェクトで行う必要があります。

    VPC ネットワーク ピアリング
  4. [servicenetworking-googleapis-com] をクリックし、[エクスポートされたルート] タブを選択して、ステップ 2 でメモしたリージョンによってフィルタします。

    この例では、10.2.0.0/24 ルートがエクスポートされており、10.2.0.1 のターゲット IP はこれに含まれます。ターゲットに対応するルートがリストにない場合は、それが問題の原因です。

    ピアリング接続の詳細

解決策

ネットワーク アーキテクチャを見直し、ルートが Apigee との VPC ピアリングにエクスポートされていることを確認します。たいていの場合、見つからないルートは静的ルートか動的ルートです。必要な動的ルートがない場合は、対応する機能(Cloud Interconnect など)に問題があることを示します。

なお、推移的ピアリングはサポートされていません。たとえば、VPC ネットワーク N1 が N2 と N3 にピアリングされ、N2 と N3 が直接接続されていない場合、VPC ネットワーク N2 が VPC ネットワーク ピアリングを介して VPC ネットワーク N3 と通信することはできません。

詳細については、サウスバウンド ネットワーキング パターンをご覧ください。

原因: ターゲットでの接続性の問題

診断

VPC からターゲットに到達できないか、ターゲットが接続を受け入れられない可能性があります。この問題を診断する方法は 2 通りあります。

接続テスト(プライベート ターゲット IP アドレス)

ターゲットがプライベート ネットワーク内にある場合は、接続テスト機能を使用して一般的な原因を診断できます。

  1. Apigee インスタンスから、解決されたターゲットの IP アドレスを特定します。その方法の一つは、デバッグ セッションを使用することです。

    デバッグで、[AnalyticsPublisher](クラシック デバッグの場合は [AX])に移動します。 画面の右側で [target.ip] の値を探します。

    この例では、IP は 10.2.0.1 です。これはプライベート IP アドレスなので、接続テストを使用できます。

    AnalyticsPublisher
  2. ターゲットに接続できない Apigee インスタンスの IP アドレスをメモします。Apigee コンソールの [インスタンス] をクリックし、[IP アドレス] フィールドで Apigee インスタンスの IP アドレスを確認します。

    IP アドレスを示すインスタンス
  3. [接続テスト] に移動し、[接続テストを作成] をクリックします。以下の情報を入力します。
    1. 送信元 IP アドレス: 上記のステップ 2 でメモした Apigee インスタンスの IP を使用します。厳密に言うと、これは Apigee がターゲットにリクエストを送信する際に使用する送信元 IP とは異なりますが、同じサブネット内にあるため、接続テストにはこれで十分です。
    2. これは Google Cloud で使用される IP アドレスです: 入力したアドレスがいずれかの Google Cloud プロジェクトで使用されている場合を除き、オフのままにしておきます。このボックスをオンにする場合は、プロジェクトとネットワークも指定します。
    3. ターゲット アドレス(ステップ 1)とポートをそれぞれ [宛先 IP アドレス] と [宛先ポート] に入力します。
    接続テストの作成
  4. [作成] をクリックし、最初の実行が完了するまで待ちます。
  5. 接続テストのリストで [表示] をクリックして、実行結果を確認します。
  6. 結果が「到達不可能」の場合は、構成に問題があることを意味します。提示されたリンクから接続テストの状態に関するドキュメントを開いて、問題に対処します。ステータスが「到達可能」の場合、構成の問題の多くが除外されます。ただし、これはターゲットに到達可能であることを保証するものではありません。実際には、ターゲットとの TCP 接続の確立は試行されていません。これをテストするには、次の診断方法を使用する必要があります。

    接続テストの結果


VM 接続テスト(すべてのターゲット)

  1. Apigee とピアリングされている同じ VPC 内に、Linux の VM インスタンスを作成します。
  2. 可能であれば、Apigee から問題を再現できるそのときに、VM から接続テストを行います。接続の確立には telnet や curl などのユーティリティを使用できます。以下の curl の例では、3 秒のタイムアウトで接続試行をループさせています。3 秒以内に TCP 接続を確立できない場合、このコマンドは失敗します。
    for i in {1..100}; do curl -m 3 -v -i https://[TARGET_HOSTNAME] ; sleep 0.5 ; done
  3. 出力全体を見て、次のエラーを探します。
    * Closing connection 0
     curl: (28) Connection timed out after 3005 milliseconds

    このエラーが存在する場合は、Apigee の外部で問題を再現できることを示します。

    TLS 関連のエラーや不良ステータス コードなどの他のエラーが表示されている場合、それらは接続タイムアウトを確定するものではなく、この問題とは無関係です。

  4. ターゲットで IP 許可リストが必要な場合は、VM インスタンスの送信元 IP アドレスも許可リストに登録しないと、VM からテストできない場合があります。

解決策

接続テストによって問題が特定された場合は、記載されている解決手順に進みます。

VM 接続テストでタイムアウトが再現される場合、ターゲット側での問題の解決方法に関する明確なガイダンスはありません。Apigee の外部で接続タイムアウトが再現可能になったら、VPC からさらに問題を追求します。ターゲットのできるだけ近くで接続テストを試みます。

ターゲットが VPN 接続の背後にある場合は、ローカル ネットワークからテストできる場合があります。

ターゲットがインターネット上にある場合は、Google Cloud コンソールの外部で問題の再現を試みることができます。

この問題がピーク時間帯に発生する場合、ターゲットが接続で過負荷状態になっている可能性があります。

その段階で Google Cloud サポートケースを提出する場合、VPC から直接問題を再現できるため、Apigee コンポーネントを選択する必要はありません。

原因: ターゲットの IP 許可リストに一部またはすべての Apigee NAT IP が追加されていない

診断

これは、IP 許可リストが有効になっている外部ターゲット(インターネット)に関係します。問題のターゲット側ですべての Apigee NAT IP が追加されていることを確認します。ターゲットに許可リストがない場合、このセクションはスキップできます。

エラーが断続的な場合は、特定の NAT IP とエラーとの相関関係が見つかる可能性があるため、問題の所在を突き止めやすくなります。

問題が持続的な場合(すべての呼び出しが失敗する場合)は、Apigee で NAT IP が有効になっていることを確認し、以下の手順で NAT IP を取得します。

インスタンスの NAT IP のリストを取得します。

curl -H "Authorization: Bearer $TOKEN" \
"https://apigee.googleapis.com/v1/organizations/$ORG_ID/instances/$INSTANCE_NAME/natAddresses"
レスポンスの例:
{
  "natAddresses": [
    {
      "name": "nat-1",
      "ipAddress": "35.203.160.18",
      "state": "ACTIVE"
    },
    {
      "name": "nat-2",
      "ipAddress": "35.230.14.174",
      "state": "RESERVED"
    }
  ]
}
出力にアドレスが含まれていない場合、Apigee 側で NAT IP は追加されていません。アドレスは含まれているものの、状態が「ACTIVE」になっているアドレスがない場合、使用されているどのアドレスもインターネットへのアクセスを許可していません。これも問題です。

ACTIVE なアドレスが少なくとも 1 つある場合は、そのアドレスをターゲットの許可リストに登録できるため、Apigee 側に構成ミスはありません。この場合、それらのアドレスがターゲットの許可リストに含まれていない可能性があります。

問題が断続的な場合、NAT IP の一部だけがターゲットの許可リストに登録されている可能性があります。これを確認するには:

  1. 問題のターゲットを TargetEndpoint として指定した新しいリバース プロキシを作成します。代わりに既存のプロキシを再利用して、次のステップに進むこともできます。

    リバース プロキシを作成する
  2. リクエスト PreFlow に ServiceCallout ポリシーを追加します。この ServiceCallout から、https://icanhazip.com、https://mocktarget.apigee.net/ip、または呼び出し元の IP アドレスをレスポンスとして返すその他のパブリック エンドポイントを呼び出します。レスポンスを response 変数に保存して、デバッグツールで内容を確認できるようにします。ServiceCallout ポリシーの構成例を以下に示します。
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <ServiceCallout continueOnError="false" enabled="true" name="Service-Callout-1">
        <DisplayName>Service Callout-1</DisplayName>
        <Properties/>
        <Request clearPayload="true" variable="myRequest">
            <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
        </Request>
        <Response>response</Response>
        <HTTPTargetConnection>
            <Properties/>
            <URL>https://icanhazip.com</URL>
        </HTTPTargetConnection>
    </ServiceCallout>

    レスポンスをカスタム変数に保存することもできますが、カスタム変数をデバッグツールで確認するには、AssignMessage ポリシーを使用してその変数の「.content」を読み取る必要があります。

    ターゲットが問題のプロキシとまったく同じように構成されていることを確認します。

  3. デバッグ セッションを実行し、ServiceCallout のステップをクリックします。

    ServiceCallout を使用してデバッグする
  4. 右下にある [Response content] セクションの [Body] に、リクエストを発行した Apigee インスタンスの NAT IP が表示されます。あるいは、ServiceCallout のレスポンスを別の場所に格納した場合は、その行に NAT IP が表示されます。

    フローの後半でプロキシがターゲットを呼び出し、[Response content] はエラーまたはターゲットからのレスポンスで上書きされることに注意してください。
  5. NAT IP と問題の間に相関関係があるか調べます。特定の IP のみが接続に失敗する場合は、一部の IP がターゲットの許可リストに登録されていないことを示します。
  6. NAT IP とエラーの間に相関関係がない場合(たとえば、同じ IP からの接続があるリクエストでは失敗し、別のリクエストでは成功する場合)は、許可リストが原因ではないと考えられます。これは NAT の枯渇を示している可能性があります。原因: NAT IP ポートの枯渇をご覧ください。

解決策

NAT IP がプロビジョニングされて有効になっていることを確認し、それらの IP がすべてターゲット側で追加されていることを確認します。

原因: NAT IP ポートの枯渇

診断

問題が Apigee からのみ再現可能で、NAT IP が組織にプロビジョニングされていて、なおかつ異なるターゲットで問題が同時に発生する場合は、NAT 送信元ポートが枯渇している可能性があります。

  1. 問題が発生した時間帯をメモします。例: 毎日午後 5 時 58 分~午後 6 時 8 分。
  2. 同じ時間帯に別のターゲットがその問題の影響を受けているかどうかを確認します。その別のターゲットは、インターネット経由でアクセス可能で、ホストされているロケーションが元の(問題が発生した)ターゲットとは異なっている必要があります。
  3. エラーが、ある一定のトラフィック量(TPS)を超えたときにのみ発生しているかどうかを確認します。そのためには、問題の発生時間帯をメモし、[Proxy Performance] ダッシュボードに移動します。
  4. エラーの時間帯と 1 秒あたりの平均トランザクション数(tps)の増加との間に相関関係があるか調べます。
API 指標

この例では、午後 5 時 58 分に tps が 1,000 に増加しています。この午後 5 時 58 分はまさに問題が発生した時刻です。この問題が 2 つ以上の無関係なターゲットに影響していれば、NAT の枯渇が原因であることを示します。

解決策

静的 NAT IP 要件の計算の手順に沿って、NAT IP の要件を計算し直します。

NAT IP を追加して、問題が解決するかどうかを確認することもできます。IP を追加する際、まずすべてのターゲットでそれらの IP を許可リストに登録しなければならない場合があります。

原因: connect.timeout.millis の設定値が小さすぎる

診断

プロキシでタイムアウト値が正しく設定されていない可能性があります。

これを確認するには、対象のプロキシに移動し、問題の TargetEndpoint を調べます。connect.timeout.millis プロパティとその値に注目します。以下の例では、設定値は 50 になっています。これは 50 ミリ秒であり、通常は短すぎて TCP 接続の確立を保証できません。値が 1,000 未満の場合、それが問題の原因である可能性があります。connect.timeout.millis プロパティが表示されていない場合はデフォルト値が設定されており、原因は確定されません。

プロキシでのタイムアウトの設定

解決策

connect.timeout.millis の値を修正します。時間単位はミリ秒であることにご注意ください。デフォルト値は 3,000(3,000 ミリ秒)です。詳細については、Endpoints プロパティのリファレンスをご覧ください。

サポートに連絡して支援を受ける

上記の手順を行っても問題が解決しない場合は、Google Cloud サポートに連絡するため、以下の診断情報を収集してください。

  1. プロジェクト ID と Apigee 組織名
  2. プロキシ名と環境
  3. 問題が発生する時間帯
  4. 問題の頻度
  5. ターゲット ホスト名
  6. 問題を示すデバッグ セッション
  7. 上記の考えられる原因に対して実施したチェックの結果。たとえば、VM からの curl コマンドの出力など。