GDCV for Bare Metal のネットワーキングに関する問題のトラブルシューティング

このページでは、Google Distributed Cloud Virtual for Bare Metal のネットワーキングに関する問題を解決する方法について説明します。一般的なトラブルシューティング情報とガイダンス、および推奨されるツールを紹介します。DNS のトラブルシューティング情報と MetalLB の一般的な問題についても説明します。

さらにサポートを必要とされる場合は、Cloud カスタマーケアにお問い合わせください。

ネットワーク接続のトラブルシューティング

GKE Enterprise のネットワーキングは、物理的なネットワーク インフラストラクチャに依存しています。たとえば、MetalLB は Gratuitous ARP を使用するスイッチに依存し、Border Gateway Protocol(BGP)とのバンドル型ロード バランシングはルーターに依存し、すべてのノードが相互に通信できる必要があります。GKE クラスタでネットワークに問題がある場合は、問題が GKE Enterprise コンポーネントにあるか、独自のインフラストラクチャにあるかを特定する必要があります。

問題の範囲を判断してから、影響を受けるコンポーネントの特定を試みます。問題の範囲は、次の 3 つのカテゴリのいずれかになります。サブジェクト(開始)、ターゲット(終了)、ネットワーク レイヤ

サブジェクトの範囲は次のいずれかになります。

  • クラスタ全体のすべてのノード(または hostNetwork Pod)。
  • クラスタ全体のすべての Pod。
  • 単一のノードまたは一連のノード上のすべての Pod。
  • 同じ Deployment または DaemonSet のすべての Pod。
  • クラスタ外のクライアント。

ターゲットの範囲は次のいずれかになります。

  • 同じクラスタの他のすべての Pod IP アドレス。
  • 同じノードの他のすべての Pod IP アドレス。
  • 同じクラスタの ClusterIP Service VIP。
  • 同じクラスタの LoadBalancer Service VIP。
  • Ingress レイヤ 7 LoadBalancer(Istio)。
  • 同じクラスタの他のノード。
  • 内部 DNS 名(*.svc.cluster.local など)。
  • 外部 DNS 名(google.com など)。
  • クラスタ外のエンティティ。
  • インターネット上のエンティティ。

ネットワーク レイヤは、次のいずれかになります。

  • ネイバー システム、ARP、NDP などのレイヤ 2 リンクレイヤの問題。
  • レイヤ 3 IP アドレスのルーティングの問題。
  • レイヤ 4 TCP または UDP エンドポイントの問題。
  • レイヤ 7 HTTP または HTTPS の問題。
  • DNS の解決に関する問題。

問題の範囲を理解すると、問題に関連するコンポーネントと問題が発生しているレイヤを特定できます。問題の一部は一時的なものであり、システム復旧後のスナップショットには根本原因の分析について十分な情報が含まれていないため、問題発生時に情報を収集することは重要です。

上り(内向き)の問題

サブジェクトがクラスタ外のクライアントで、LoadBalancer Service に接続できない場合は、North-South 接続性の問題です。次の図は、実際の例では受信トラフィックがスタックを通って左から右に向かい、戻りトラフィックがスタックを通って右から左に向かうことを示しています。

上り(内向き)トラフィックは、ユーザーから物理インフラストラクチャ、ロードバランサ、anetd / kube-proxy を経由してバックエンドに送信されます。

このトラフィック フローに問題がある場合は、次のトラブルシューティング フローチャートを使用して問題の発生場所を特定します。

パケットが環境を通過する際の各ステップを確認して、ネットワーク上り(内向き)の問題のトラブルシューティングを行います。途中で適切なアクションと接続が存在するかどうかを確認します。

このフローチャートでは、次のトラブルシューティング ガイダンスが問題の発生場所の特定に役立ちます。

  • パケットはクライアントから送信されていますか?そうでない場合は、ネットワーク インフラストラクチャで問題が発生している可能性があります。
  • MetalLB を使用していますか?使用している場合、パケットが LB ノードに到達し、ARP が正しく送信されますか?そうでない場合は、ネットワーク インフラストラクチャで問題が発生している可能性があります。
  • F5 BIG-IP を使用している場合、F5 の問題を確認しましたか?
  • ネットワーク アドレス変換(NAT)が正しく行われていますか?そうでない場合は、kube-proxy / Dataplane V2 で問題が発生している可能性があります。
  • パケットはワーカーノードに到達していますか?そうでない場合は、Dataplane v2 の Pod 間で問題が発生している可能性があります。
  • パケットは Pod に到達していますか?そうでない場合は、Dataplane v2 のローカル転送で問題が発生している可能性があります。

以降のセクションでは、各ステージのトラブルシューティングを行ってトラフィックが正しく流れているかどうかを判断する手順を説明します。

パケットはクライアントから送信されていますか?

パケットがクライアントから正しく送信され、物理ネットワーク インフラストラクチャで構成されたルーターを通過しているかどうかを確認します。

  1. tcpdump を使用して、クライアントから宛先サービスに向かうパケットを確認します。

    tcpdump -ni any host SERVICE_VIP and port SERVICE_PORT
    

    出て行くトラフィックが確認できない場合は、ここが問題の発生源です。

パケットは LoadBalancer ノードに到達していますか?

ロードバランサとして MetalLB を使用する場合:

  1. metallb-controller ログを調べて、サービス VIP を提供するロードバランサ ノードを特定します。

    kubectl -n kube-system logs -l app=metallb --all-containers=true | grep SERVICE_VIP
    
  2. SSH を使用してノードに接続します。

  3. MetalLB ノードの場合は、tcpdump を使用してトラフィックを確認します。

    tcpdump -ni any host SERVICE_VIP and port SERVICE_PORT
    

    ManualLB の場合、トラフィックは任意のノードに到達する可能性があります。ロードバランサの構成に応じて、1 つまたは複数のノードを選択できます。tcpdump を使用してトラフィックを確認します。

    tcpdump -ni any host NODE_IP and port NODE_PORT
    

    このコマンドは、ロードバランサの種類によって異なります。MetalLB はパケットをノードに転送する前に NAT を行いません。

    どのノードに向かうトラフィックも確認できない場合は、ここが問題の発生源です。

F5 BIG-IP の問題がありますか?

F5 BIG-IP の問題をトラブルシューティングするには、F5 Service がトラフィックを受信しない件に関して次のいずれかのセクションをご覧ください。

ARP は正しく送信されていますか?

MetalLB のロードバランサ ノードは、ARP を使用してサービス VIP をアドバタイズします。ARP レスポンスが正しく送信されていても、トラフィックが到達しない場合は、物理ネットワーク インフラストラクチャに問題があることを示しています。この問題の一般的な原因は、一部の高度なデータプレーン学習機能では、ソフトウェア定義ネットワーク(SDN)ソリューションの ARP レスポンスが無視されることです。

  1. tcpdump を使用して ARP レスポンスを検出します。

    tcpdump -ni any arp
    

    問題が発生している VIP をアドバタイズしているメッセージを探してください。

  2. MetalLB の場合、Gratuitous ARP は送信されません。レスポンスが確認される頻度は、トップオブラック(ToR)スイッチなどの別のデバイスが ARP リクエストを送信するタイミングによって異なります。

NAT は行われていますか?

Dataplane v2 / kube-proxy は、宛先ネットワーク アドレス変換(宛先 NAT または DNAT)を行って、宛先 VIP をバックエンド Pod の IP アドレスに変換します。ロードバランサのバックエンドのノードがわかっている場合は、SSH を使用してそのノードに接続します。

  1. tcpdump を使用して、Service VIP が正しく変換されているかどうかを確認します。

    tcpdump -ni any host BACKEND_POD_IP and port CONTAINER_PORT
    
  2. Dataplane v2 では、追加で anetd Pod に接続し、組み込みの Cilium デバッグツールを使用することもできます。

    cilium monitor --type=drop
    

詳細については、Dataplane v2 / Cilium の問題に関して次のいずれかのセクションをご覧ください。

パケットはワーカーノードに到達していますか?

ワーカーノードで、パケットは外部インターフェースに到達し、Pod に配信されます。

  1. tcpdump を使用して、パケットが外部インターフェース(通常は eth0 または ens192)に到達しているかどうかを確認します。

    tcpdump -ni any host BACKEND_POD_IP and port CONTAINER_PORT
    
Google Distributed Cloud Virtual for Bare Metal の場合、パケットはトンネルでカプセル化されます。パケットは、カプセル化解除されると、cilium_geneve という名前のネットワーク インターフェースから送信されます。

通常の Service バックエンドには、さまざまなノードにわたる複数の Pod が含まれているため、問題のあるノードのトラブルシューティングが難しくなる場合があります。一般的な回避策は、一部のパケットが最終的に到達するように問題を十分に長くキャプチャするか、バックエンドの数を 1 に制限することです。

パケットがワーカーノードに到達しない場合は、ネットワーク インフラストラクチャに問題があることを示しています。LoadBalancer ノードとワーカーノードの間でパケットがドロップされる理由については、ネットワーキング インフラストラクチャ チームに確認してください。一般的な問題としては、次のようなものがあります。

  • ソフトウェア定義ネットワーク(SDN)のログを確認します。SDN は、セグメンテーション、誤ったチェックサム、なりすまし対策など、さまざまな理由でパケットをドロップすることがあります。
  • Geneve パケットの UDP ポート 6081 をフィルタするファイアウォール ルール。

パケットがノードの外部インターフェースまたはトンネル インターフェースに到達したら、宛先 Pod に転送する必要があります。Pod がホスト ネットワーキング Pod の場合、Pod はネットワーク名前空間をノードと共有するため、この手順は不要です。それ以外の場合は、追加のパケット転送が必要になります。

各 Pod には、パイプのように動作する仮想イーサネット インターフェース ペアがあります。インターフェースの一方の端に送信されたパケットは、インターフェースのもう一方の端から受信されます。一方のインターフェースは Pod のネットワーク名前空間に移動し、名前が eth0 に変更されます。もう一方のインターフェースはホスト名前空間に残ります。CNI が異なればスキーマも異なります。Dataplane v2 の場合、インターフェースの名前は通常、lxcxxxx です。名前には連続するインターフェース番号が付きます(lxc17lxc18 など)。tcpdump を使用してパケットが Pod に到達しているかどうかを確認できます。インターフェースを指定することもできます。

  tcpdump -ni lcxxxx host BACKEND_POD_IP and port CONTAINER_PORT

パケットがノードに到達しても Pod に到達できない場合は、次のようにルーティング テーブルを確認します。

  ip route

通常、各 Pod には、Pod IP アドレスを lxc インターフェースにルーティングするルーティング エントリが必要です。エントリがない場合、通常は CNI データパスにエラーがあります。根本原因を特定するには、CNI DaemonSet ログを確認します。

下り(外向き)の問題

トラフィックが Pod に入ることができる場合は、Pod からの下り(外向き)トラフィックで問題が発生している可能性があります。次の図は、実際の例では受信トラフィックがスタックを通って左から右に向かうことを示しています。

下り(外向き)トラフィックは、Pod からホストの外部インターフェース、物理インフラストラクチャを経由して外部サービスに送信されます。

  1. 送信パケットがノード IP アドレスとして正しくマスカレードされていることを確認するには、外部サービス(レイヤ 4)を確認します。

    パケットの送信元 IP アドレスは、送信元ネットワーク アドレス変換(送信元 NAT または SNAT)を使用して Pod IP アドレスからノード IP アドレスにマッピングする必要があります。Dataplane v2 では、このプロセスは外部インターフェースに読み込まれる ebpf で実現します。

    tcpdump を使用して、送信元 IP アドレスが Pod IP アドレスからノード IP アドレスに正しく変換されているかどうかを確認します。

    tcpdump -ni EXTERNAL_INTERFACE host EXTERNAL_IP and port EXTERNAL_PORT
    

    パケットが正しくマスカレードされていることを tcpdump が示していてもリモート サービスが応答しない場合は、インフラストラクチャの外部サービスへの接続を確認します。

  2. 送信パケットがノード IP アドレスとしてマスカレードされている場合は、tcpdump を使用して外部ホスト(レイヤ 3)の接続性を確認します。

    tcpdump -ni EXTERNAL_INTERFACE host EXTERNAL_IP and icmp
    

    tcpdump を実行すると同時に、いずれかの Pod から ping を実行します。

    kubectl exec POD_NAME ping EXTERNAL_IP
    

    ping レスポンスが表示されない場合は、インフラストラクチャの外部サービスへの接続を確認します。

クラスタ内の問題

Pod 間の接続の問題については、問題をノードにスコープしてみてください。多くの場合、ノードグループは別のノードグループと通信できません。

  1. Dataplane v2 で、現在のノードから同じクラスタ内の他のすべてのノードへのノード接続性を確認します。anetd Pod 内から、ヘルス ステータスを確認します。

    cilium status --all-health
    

ネットワーク層の問題

接続性の問題が発生しているネットワーク層を特定することは、重要なステップです。「ソースから宛先への接続の問題」のようなエラー メッセージは、アプリケーション エラー、ルーティングの問題、DNS の問題など、問題の解決に十分な情報ではありません。どのレイヤで問題が発生しているかを把握することで、適切なコンポーネントを修正できます。

多くの場合、エラー メッセージは問題が発生しているレイヤを直接示します。ネットワーク レイヤに関する疑問のトラブルシューティングに役立つ例を以下に紹介します。

  • HTTP エラーは、レイヤ 7 の問題であることを示します。
    • HTTP コード 40x50x、TLS handshake のエラーは、レイヤ 4 ですべてが正常に機能していることを意味します。
  • 「ピアによって接続がリセットされた」エラーは、レイヤ 4 問題であることを示します。
    • 多くの場合、リモート ソケットは接続の現在の状態に一致しないため、RESET パケットを送信します。このような動作は、接続トラッキングや NAT の間違いである可能性があります。
  • 「ホストへのルートがない」エラーと「接続タイムアウト」エラーは通常、レイヤ 3 またはレイヤ 2 の問題です。
    • これらのエラーは、パケットを宛先に正しくルーティングできないことを示しています。

便利なトラブルシューティング ツール

ネットワーク関連の DaemonSet はノード上で実行されるため、接続の問題の原因となる可能性があります。ただし、ノード、トップオブラック(ToR)スイッチ、スパイン ルーター、ファイアウォールの構成ミスも問題を引き起こす可能性があります。次のツールを使用して、問題の範囲またはレイヤを特定し、GKE Enterprise ノードまたは物理インフラストラクチャのどちらに問題があるのかを判断することができます。

Ping

ping はレイヤ 3(IP レイヤ)で動作し、送信元と宛先の間のルートを確認します。ping が宛先に到達できない場合、通常はレイヤ 3 に問題があります。

ただし、すべての IP アドレスが ping できるわけではありません。たとえば、一部のロードバランサの VIP は、純粋なレイヤ 4 ロードバランサである場合、ping できません。VIP が ping レスポンスを返さない可能性がある一例は、ClusterIP Service です。レイヤ 4 では、VIP:port などのポート番号が指定された場合にのみ、この Service から ping レスポンスが返されます。

Google Distributed Cloud Virtual for Bare Metal の BGPLB ロードバランサと MetalLB ロードバランサはすべてレイヤ 3 で動作します。ping を使用して接続性を確認できます。F5 は異なりますが、ICMP もサポートしています。ping を使用して F5 VIP への接続性を確認できます。

arping

arping は ping と似ていますが、レイヤ 2 で動作する点が異なります。レイヤ 2 とレイヤ 3 の問題は多くの場合、アプリケーションからのエラー メッセージが似ています。arping と ping は問題を区別するのに役立ちます。たとえば、送信元と宛先が同じサブネット内にあり、宛先に arping できない場合、レイヤ 2 の問題です。

arping <ip> が成功すると、宛先の MAC アドレスが返されます。レイヤ 2 では多くの場合、このアドレスは物理インフラストラクチャの問題を示します。多くの場合、この問題はノード間の物理的な切り替えです。

arping は、IP アドレスの競合も検出できます。IP アドレスの競合は、2 つのマシンが同じサブネット上で同じ IP アドレスを使用するように構成されている場合、または VIP が別の物理マシンによって使用されている場合に発生します。IP アドレスの競合により、トラブルシューティングしにくい断続的な問題が発生する可能性があります。arping <ip> が複数の MAC アドレス エントリを返した場合は、IP アドレスの競合があることを示しています。

arping で MAC アドレスを取得したら、https://maclookup.app/ を使用してその MAC アドレスのメーカーを検索できます。各メーカーが MAC プレフィックスを所有しているため、この情報を使用して、同じ IP アドレスを使用しようとしているデバイスを特定できます。たとえば、VMware は 00:50:56 ブロックを所有しているため、MAC アドレス 00:50:56:xx:yy:zz は vSphere 環境の VM です。

iproute2

iproute2ip CLI には、次のような便利なサブコマンドがあります。

  • ip r: ルートテーブルを出力します。
  • ip n: IP アドレスから MAC アドレスへのマッピングのネイバー テーブルを出力します。
  • ip a: マシン上のすべてのインターフェースを出力します。

ネイバー テーブルにルートがないか、エントリがないと、ノードから接続の問題が発生する可能性があります。anetd は、ルートテーブルとネイバー テーブルを管理します。これらのテーブルの構成ミスで、接続の問題が発生する可能性があります。

Dataplane V2 の Cilium / Hubble CLI

anetd Pod には、接続性の問題に役立つデバッグツールがいくつか用意されています。

  • cilium monitor --type=drop
    • anetd / Cilium によってドロップされたすべてのパケットのログを出力します。
  • hubble observe
    • anetd の ebpf スタックを経由するすべてのパケットを出力します。
  • cilium status --all-health
    • ノード間の接続ステータスを含む Cilium のステータスを出力します。各 anetd Pod は、クラスタ内の他のすべてのノードの状態をチェックします。これはノード間の接続の問題を特定するのに役立ちます。

iptables

iptables は、多くの Kubernetes コンポーネントとサブシステムで使用されています。kube-proxy は iptables を使用してサービスの解決を実装します。

  1. iptables レベルでネットワークの問題をトラブルシューティングするには、次のコマンドを使用します。

    iptables -L -v | grep DROP
    

    ドロップルールを調べて、パケット数とバイト数が時間とともに増加しているかどうかを確認します。

tcpdump

tcpdump は、大量のネットワーク トラフィック データを生成する強力なパケット キャプチャ ツールです。一般に、送信元と宛先の両方から tcpdump を実行します。パケットが送信元ノードから出るときにキャプチャされ、宛先ノードではキャプチャされない場合、その間でパケットがドロップされます。この動作は通常、物理インフラストラクチャの何かでパケットが誤ってドロップされたことを示します。

DNS のトラブルシューティング

DNS の解決の問題は、次の 2 つの主要カテゴリに分類されます。

  • クラスタ内の DNS サーバーを使用する通常の Pod。
  • クラスタ内の DNS サーバーを使用しないホスト ネットワークの Pod またはノード。

以降のセクションでは、クラスタ DNS アーキテクチャについて説明し、これらのカテゴリのいずれかのトラブルシューティングを開始する前に役立つヒントを紹介します。

クラスタ DNS アーキテクチャ

クラスタ DNS サービスは、クラスタ内の Pod の DNS リクエストを解決します。CoreDNS は、Google Distributed Cloud Virtual for Bare Metal のすべてのバージョンにこのサービスを提供します。

各クラスタには 2 つ以上の coredns Pod と、クラスタサイズに基づいて DNS Pod の数を調整するオートスケーラーがあります。また、すべてのバックエンド coredns Pod 間でリクエストのロード バランシングを行う kube-dns というサービスもあります。

ほとんどの Pod はアップストリーム DNS が kube-dns Service IP アドレスに構成されます。Pod は DNS リクエストをいずれかの coredns Pod に送信します。DNS リクエストは、次のいずれかの宛先にグループ化できます。

  • cluster.local ドメインに対するリクエストの場合、これはクラスタ内の Service または Pod を参照するクラスタ内の DNS 名です。
    • CoreDNS は、クラスタ内のすべての Service と Pod に対して api-server を監視し、有効な cluster.local ドメインへのリクエストに応答します。
  • cluster.local ドメイン以外のリクエストの場合は、外部ドメイン用です。
    • CoreDNS は、リクエストをアップストリーム ネームサーバーに転送します。デフォルトでは、CoreDNS は稼働しているノードに構成されているアップストリーム ネームサーバーを使用します。

詳細については、DNS の仕組みと Kubernetes における構成の概要に関するページをご覧ください。

DNS のトラブルシューティングのヒント

DNS の問題のトラブルシューティングを行うには、dig ツールと nslookup ツールを使用します。これらのツールを使用すると、DNS リクエストを送信して、DNS の解決が正常に機能するかどうかをテストできます。次の例は、dignslookup を使用して DNS の解決の問題を確認する方法を示しています。

  • dig または nslookup を使用して google.com のリクエストを送信します。

    dig google.com
    nslookup google.com
    
  • dig を使用して、kubernetes.default.svc.cluster.local のリクエストをサーバー 192.168.0.10 に送信します。

    dig @192.168.0.10 kubernetes.default.svc.cluster.local
    
  • nslookup を使用して、前の dig コマンドと同じ DNS ルックアップを行うこともできます。

    nslookup kubernetes.default.svc.cluster.local 192.168.0.10
    

    dig コマンドまたは nslookup コマンドの出力を確認します。正しくないレスポンスが返された場合、またはレスポンスがない場合は、DNS の解決に問題があることを示しています。

通常の Pod

DNS の問題をデバッグする最初のステップは、リクエストが coredns Pod に対して行われたかどうかを判断することです。多くの場合、DNS リクエストはワークロードが送信するトラフィックの最初のタイプであるため、一般的なクラスタの接続の問題は DNS の問題として表示されます。

アプリケーションからのエラー メッセージを確認します。io timeout などのエラーは、レスポンスがなく、一般的なネットワーク接続の問題があることを示しています。

NXDOMAINSERVFAIL などの DNS エラーコードを含むエラー メッセージは、クラスタ内の DNS サーバーに接続していてもサーバーがドメイン名を解決できなかったことを示しています。

  • NXDOMAIN エラーは、ドメインが存在しない旨を DNS サーバーが報告していることを示しています。アプリケーションがリクエストしているドメイン名が有効であることを確認します。
  • SERVFAIL または REFUSED エラーは、DNS サーバーがレスポンスを送信したものの、ドメインを解決できなかったか、ドメインの存在を検証できなかったことを示します。詳細については、coredns Pod のログを確認してください。

次のコマンドを使用すると、kube-dns サービスの IP アドレスを確認できます。

kubectl -n kube-system get svc kube-dns

前のセクションで説明したように、DNS が機能していない Pod から、dig または nslookup を使用してこの IP アドレスに DNS リクエストを送信してみます。

  • これらのリクエストが機能しない場合は、各 coredns Pod の IP アドレスにリクエストを送信してみてください。
  • 一部の Pod が機能しても他の Pod が機能しない場合は、DNS の解決が coredns Pod と同じノードの Pod には機能するが、ノード間では機能しないなど、識別可能なパターンがあるかどうかを確認します。この動作は、クラスタ内の接続の問題を示している可能性があります。

CoreDNS が外部のドメイン名を解決できない場合は、次のセクションでホスト ネットワークの Pod のトラブルシューティングを行ってください。CoreDNS は、ホスト ネットワークの Pod のように動作し、名前解決にノードのアップストリーム DNS サーバーを使用します。

ホスト ネットワークの Pod またはノード

ホスト ネットワークの Pod とノードは、DNS の解決のためにノードに構成されたネームサーバーを使用します。クラスタ内の DNS サービスは使用しません。このネームサーバーは、OS に応じて /etc/resolv.conf または /run/systemd/resolve/resolv.conf のいずれかで構成されます。このような構成では、cluster.local ドメイン名は解決できません。

ホスト ネットワークの名前解決で問題が発生した場合は、前のセクションのトラブルシューティング手順を使用して、アップストリーム ネームサーバーで DNS が正しく機能しているかどうかをテストします。

すべてのノードに同じ一連のサーバーが構成されていることを確認します。異なるネームサーバーが構成されている場合、異なるノード上の DNS の解決に不整合が生じる可能性があります。dig または nslookup を使用して各ネームサーバーにリクエストを送信し、各ネームサーバーが個別に動作することを確認します。一部のネームサーバーは機能しても他のネームサーバーは機能しない場合、このような DNS の解決の不一致が発生します。

ネットワークの一般的な問題

以降のセクションでは、ネットワークで発生する可能性のある一般的な問題について説明します。問題を解決するには、適切なトラブルシューティング ガイダンスに沿って対応してください。さらにサポートを必要とされる場合は、Cloud カスタマーケアにお問い合わせください。

Dataplane v2 / Cilium

一般的なエラー: [PUT /endpoint/{id}][429] putEndpointIdTooManyRequests

このエラーは、レート制限が原因で Pod 作成イベントが Cilium エージェントによって拒否されたことを意味します。ノードごとに、Cilium の PUT エンドポイントへの同時リクエストの上限は 4 です。1 つのノードへのリクエストがバーストした場合、この動作は想定されたものです。Cilium エージェントが遅延したリクエストに追いつく必要があります。

GKE Enterprise 1.14 以降では、レート制限はノードの容量に合わせて自動的に調整されます。レート制限機能はより合理的な数に収束し、より強力なノードに対するレート制限が高くなります。

一般的なエラー: Ebpf map size is full

Dataplane v2 は eBFP マップに状態を保存します。状態には、Service、接続トラッキング、Pod の ID、ネットワーク ポリシーのルールが含まれます。マップがいっぱいの場合、エージェントはエントリを挿入できません。これにより、コントロール プレーンとデータプレーンの間に不一致が生じます。たとえば、Service マップのエントリ数の上限は 64k です。

  1. eBFP マップエントリとその現在のサイズを確認するには、bpftool を使用します。次の例では、ロードバランサのマップを確認しています。

    bpftool map dump pinned \
    /sys/fs/bpf/tc/globals/cilium_lb4_services_v2 | tail -n -1
    
    bpftool map dump pinned \ /sys/fs/bpf/tc/globals/cilium_lb4_backends_v2 | tail -n -1
    
  2. マップが 64k の上限に近づいている場合は、マップをクリーンアップします。次の例では、ロードバランサ マップをクリーンアップしています。

    bpftool map dump pinned /sys/fs/bpf/tc/globals/cilium_lb4_services_v2 | \
        awk '{ print "0x"$2, "0x"$3, "0x"$4, "0x"$5, "0x"$6, "0x"$7, "0x"$8, "0x"$9, "0x"$10, "0x"$11, "0x"$12, "0x"$13}' | \
        head -n -1 | \
        xargs -L 1 bpftool map delete pinned /sys/fs/bpf/tc/globals/cilium_lb4_services_v2 key
    
    bpftool map dump pinned /sys/fs/bpf/tc/globals/cilium_lb4_backends_v2 | \
        awk '{ print "0x"$2, "0x"$3, "0x"$4, "0x"$5 }' | \
        head -n -1 | \
        xargs -L 1 bpftool map delete pinned /sys/fs/bpf/tc/globals/cilium_lb4_backends_v2 key
    
  3. 状態を eBFP マップに補充するには、anetd を再起動してください。

NetworkPluginNotReady エラーが原因でノードが未準備になる

CNI Pod がノードで実行されていない場合、次のようなエラーが表示されることがあります。

  "Container runtime network not ready" networkReady="NetworkReady=false reason:NetworkPluginNotReady message:Network plugin returns error: cni plugin not initialized

ノードが未準備状態になり、次の例のようなエラーが発生することがあります。

  "Network plugin not installed"

ノードが初期化されると、kubelet はノードが Ready とマークされる前に、複数のイベントが発生するのを待ちます。kubelet が確認するイベントとしては、Container Network Interface(CNI)プラグインがインストールされていることが挙げられます。CNI プラグインは、CNI バイナリと CNI 構成の両方を必要なホスト ディレクトリにインストールするために、init コンテナを使用し、anetd によってインストールする必要があります。

この問題のトラブルシューティングを行うには、こうした Pod がノードで実行されていない理由を確認します。通常、このエラーはネットワークの問題によるものではありません。これらの Pod はホスト ネットワークで実行されるため、ネットワークの依存関係はありません。

  1. anetd Pod の状態を確認します。次のトラブルシューティング手順を確認すると、問題の原因の特定に役立ちます。

    • Pod が Crashlooping 状態の場合は、ログを調べて、Pod が正しく動作しない理由を確認します。
    • Pod が Pending 状態の場合は、kubectl describe を使用して Pod イベントを確認します。たとえば、Pod に Volume などのリソースがない場合があります。
    • Pod が Running 状態の場合は、ログと構成を確認します。Cilium など、一部の CNI 実装には CNI のインストールを無効にするオプションが用意されています。
    • anetd には custom-cni-conf という構成オプションがあります。この設定が true として構成されている場合、anetd は CNI バイナリをインストールしません。

F5 Service がトラフィックを受信しない

F5 Service にトラフィックが届かない場合は、次のトラブルシューティング手順を確認してください。

  1. F5 BIG-IP のすべてのパーティションが、管理クラスタまたはユーザー クラスタの 1 つのクラスタに構成されていることを確認します。1 つのパーティションが複数のクラスタで共有されている場合、接続が断続的に中断します。これは、2 つのクラスタが同じパーティションに対する制御を占め、他のクラスタから Service を削除しようとするためです。

  2. 次の 2 つの Pod が実行されていることを確認します。実行されていない Pod は、エラーを示します。

    Load-balancer-f5
    K8s-bigip-ctlr-deployment-577d57985d-vk9wj
    

    GKE Enterprise が所有する Load-balancer-f5。すべての LoadBalancer タイプの Service に ConfigMap を作成します。ConfigMap は、最終的に bigip コントローラによって使用されます。

  3. 各 Service の各ポートに ConfigMap が存在することを確認します。たとえば、次のポートがあるとします。

    Kube-server-443-tcp     2   31h
    Kube-server-8132-tcp        2   31h
    

    kube-server Service は次の例のようになります。

    Kube-server LoadBalancer  10.96.232.96  21.1.7.16   443:30095/TCP,8132:32424/TCP  31h
    

    次の例に示すように、ConfigMap のデータ セクションには、フロントエンド VIP とポートが必要です。

    data: '{"virtualServer":{"backend":{"serviceName":"kube-apiserver","servicePort":443,"healthMonitors":[{"protocol":"tcp","interval":5,"timeout":16}]},"frontend":{"virtualAddress":{"bindAddr":"21.1.7.16","port":443},"partition":"herc-b5bead08c95b-admin","balance":"ratio-member","mode":"tcp"}}}'
      schema: f5schemadb://bigip-virtual-server_v0.1.7.json
    
  4. BIG-IP インスタンスのログと指標を確認します。ConfigMap が正しく構成されていても BIG-IP インスタンスが構成を適用できない場合は、F5 の問題である可能性があります。BIG-IP インスタンス内で発生する問題については、F5 のサポートに連絡して、問題の診断とトラブルシューティングを行います。

並列接続が多すぎる NAT のエラー

クラスタ内の特定のノードでは、ノードの IP アドレスによって、クラスタ外のアドレスにルーティングされるパケットに対してネットワーク アドレス変換(NAT)が提供されます。同様に、受信パケットがバンドル型ロード バランシング(spec.loadBalancer.mode: bundled)を使用するように構成された負荷分散ノードに入ると、送信元ネットワーク アドレス変換(SNAT)により、バックエンド Pod に転送される前にノード IP アドレスにパケットがルーティングされます。

GDCV for Bare Metal で使用される NAT のポート範囲は 32768-65535 です。この範囲により、並列接続の数はそのノードのプロトコルあたり 32,767 に制限されます。各接続には、conntrack テーブルのエントリが必要です。有効期間が短い接続数が多すぎると、conntrack テーブルが NAT のポートを使い果たします。ガベージ コレクタは古いエントリをクリーンアップしますが、クリーンアップは直ちには行われません。

ノード上の接続数が 32,767 に近づくと、NAT を必要とする接続のパケット ドロップが発生し始めます。

この問題の影響を受けたかどうかを判断するには:

  1. 問題のあるノードの anetd Pod で次のコマンドを実行します。

    kubectl -n kube-system anetd-XXX -- hubble observe \
        --from-ip $IP --to-ip $IP -f
    

    次の形式のエラーが表示されます。

    No mapping for NAT masquerade DROPPED
    

この問題の回避方法として、他のノードにトラフィックを再分散してください。

次のステップ

さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。