ACK KubeSkoop (旧 ACK Net Exporter) は、Container Service for Kubernetes (ACK) 向けのオープンソースのネットワークモニタリングおよびトラブルシューティングスイートです。これにより、クラスターを監視し、複雑なネットワーク問題を迅速にトラブルシューティングできます。このトピックでは、マネージド ACK クラスターで KubeSkoop を使用して、迅速に開始し、実際の問題を解決する方法を説明します。
背景情報
KubeSkoop は、詳細なネットワークモニタリング、接続性診断、パケットキャプチャ、遅延プロービングなど、eBPF ベースの機能を提供します。Prometheus メトリックと異常イベントを公開します。KubeSkoop は、各ノードでデーモンプロセス Pod として実行されます。eBPF テクノロジーを使用してノードから情報を収集し、特定の Pod のために集約して、高レベルのネットワーク情報を観測するための標準化されたインターフェイスを提供します。次の図は、KubeSkoop のコアアーキテクチャを示しています。
ACK KubeSkoop コンポーネントのインストールと構成
ACK KubeSkoop コンポーネントのインストール
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
クラスター ページで、管理するクラスターを見つけてその名前をクリックします。左側のナビゲーションウィンドウで、[アドオン] をクリックします。
[アドオン] ページで ACK KubeSkoop を検索し、コンポーネントを見つけて [インストール] をクリックします。
[コンポーネント ACK KubeSkoop のインストール] ページで、[確認] をクリックします。
KubeSkoop コンポーネントの構成
ConfigMap を使用して KubeSkoop コンポーネントを構成するには、次のコマンドを実行します。
kubectl edit cm kubeskoop-config -n ack-kubeskoopコンソールで KubeSkoop コンポーネントを構成することもできます。
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
クラスター ページで、目的のクラスターを見つけてその名前をクリックします。左側のペインで、 を選択します。
[ConfigMap] ページで、[名前空間] を ack-kubeskoop に設定し、kubeskoop-config を検索してから、kubeskoop-config の [操作] 列にある [編集] をクリックします。
[編集] パネルでパラメーターを構成し、[OK] をクリックします。次の表に、KubeSkoop でサポートされているパラメーターを示します。
パラメーター
説明
デフォルト値
debugmodeデバッグモードを有効にするかどうかを指定します。有効な値:
false: デバッグモードは無効です。
true: デバッグモードは有効です。有効にすると、このオプションは DEBUG レベルのログ、デバッグインターフェイス、および Go pprof と gops 診断ツールを提供します。
falseportメトリックサービス用のポート。HTTP エンドポイントを提供します。
9102enableControllerController コンポーネントを有効にするかどうかを指定します。Controller は Kubernetes API と対話して、モニタリングまたは管理タスクを実行します。
truecontrollerAddrKubeSkoop Controller コンポーネントのアドレス。
dns:kubeskoop-controller:10263metrics.probes収集するモニタリングメトリックタイプのリスト。各プローブはメトリックカテゴリに対応します。
- name: conntrack - name: qdisc - name: netdev - name: io - name: sock - name: tcpsummary - name: tcp - name: tcpext - name: udp - name: rdmaプローブの詳細については、「プローブ、メトリック、イベント」をご参照ください。
ConfigMap を更新した後、ACK KubeSkoop コンポーネントを再起動する必要はありません。コンポーネントは変更を自動的にホットリロードして、対応するプローブを有効または無効にします。
ARMS Prometheus ダッシュボードの構成
ARMS コンソールにログインします。
左側のナビゲーションウィンドウで、[インテグレーション管理] をクリックします。
[インテグレーション管理] ページで、[インテグレーションの追加] をクリックします。検索ボックスで KubeSkoop を検索し、[ACK KubeSkoop ネットワークモニタリング] をクリックします。
[ACK KubeSkoop ネットワークモニタリング] ダイアログボックスで、統合する ACK クラスターを選択し、[インテグレーション名] を入力してから [OK] をクリックして KubeSkoop モニタリングを有効にします。
ACK コンソールにログインします。左側のナビゲーションウィンドウで、[クラスター] をクリックします。
クラスター ページで、目的のクラスターを見つけてその名前をクリックします。左側のペインで、 を選択します。
[その他] タブをクリックします。ダッシュボードリストで KubeSkoop によって作成されたノードと Pod のモニタリングダッシュボードを見つけることができます。

Alibaba Cloud の Prometheus モニタリングの詳細については、「Alibaba Cloud Prometheus サービスの使用」をご参照ください。
KubeSkoop の使用
KubeSkoop モニタリングメトリックの手動表示
KubeSkoop は Prometheus フォーマットでモニタリングデータを提供します。KubeSkoop をインストールした後、任意の KubeSkoop Pod インスタンスのサービスポートにアクセスして、すべてのメトリックを取得できます。
次のコマンドを実行して、すべての KubeSkoop インスタンスを取得します。
kubectl get pod -n ack-kubeskoop -o wide | grep kubeskoop-agent期待される出力:
kubeskoop-agent-2chvw 1/1 Running 0 43m 172.16.16.xxx cn-hangzhou.172.16.16.xxx <none> <none> kubeskoop-agent-2qtbf 1/1 Running 0 43m 172.16.16.xxx cn-hangzhou.172.16.16.xxx <none> <none> kubeskoop-agent-72pgf 1/1 Running 0 43m 172.16.16.xxx cn-hangzhou.172.16.16.xxx <none> <none>次のコマンドを実行してメトリックを取得します。前のステップで取得した KubeSkoop インスタンスの IP アドレスで
172.16.16.xxxを置き換えます。curl http://172.16.16.xxx:9102/metrics
KubeSkoop は次のフォーマットでモニタリングメトリックを提供します。
kubeskoop_netdev_rxbytes{k8s_namespace="",k8s_node="cn-hangzhou.172.16.16.xxx",k8s_pod=""} 2.970963745e+09ACK KubeSkoop を使用して断続的なコンテナーネットワークの問題をトラブルシューティングする方法
以下のセクションでは、典型的なクラウドネイティブの問題をトラブルシューティングするためのガイダンスを提供します。ACK KubeSkoop を使用すると、これらの問題に関連する情報を迅速に取得できます。
DNS タイムアウト問題のトラブルシューティング
クラウドネイティブ環境では、DNS サービスのタイムアウト問題により、サービスへのアクセスが失敗することがあります。DNS タイムアウトの一般的な原因は次のとおりです。
DNS サーバーの応答が遅く、アプリケーションがタイムアウトする前に DNS クエリを完了できない。
送信者が DNS クエリパケットを迅速に送信できない。
サーバーは迅速に応答しますが、送信者はメモリ不足などの問題によりパケットをドロップします。
断続的な DNS タイムアウトの問題のトラブルシューティングに役立つ次のメトリックを使用できます。
メトリック名 | 説明 |
| ネットワーク層を介して UDP データを送信するときに発生するエラーの数。 |
| UDP パケットを受信するときに発生するチェックサムエラーの数。 |
|
|
| UDP パケットを受信するときに発生するエラーの数。 |
| UDP によってネットワーク層を介して正常に送信されたパケットの数。 |
| アプリケーション層にデータをコピーするときに、ソケット受信キューが不十分なために発生するエラーの数。 |
クラウドネイティブ環境の多くのサービスは、名前解決のために CoreDNS に依存しているため、DNS の問題が CoreDNS に関連している場合は、CoreDNS 関連の Pod の上記のメトリックも監視する必要があります。
Nginx Ingress HTTP 499/502/503/504 エラーのトラブルシューティング
クラウドネイティブ環境では、Ingress ゲートウェイやその他のプロキシサービスで断続的な例外が発生することがよくあります。Nginx Ingress やその他の Nginx ベースのプロキシサービスでは、499、502、503、504 が最も一般的なエラーです。これらは次のことを示します。
499: Nginx が応答する前に、Nginx を要求するクライアントが TCP 接続を閉じます。一般的な原因は次のとおりです。クライアントは接続を確立しますが、リクエストの送信が遅いため、Nginx が応答している間にクライアント側のタイムアウトに達します。これは、Android クライアントの非同期リクエストフレームワークで一般的です。
接続が確立された後、サーバーは接続をゆっくりと処理します。これにはさらなる調査が必要です。
サーバーは、アップストリームのバックエンドに送信されたリクエストの処理が遅いです。
502: 構成されたバックエンドの DNS 解決に失敗しました。これは、Kubernetes Service をバックエンドとして使用する場合によく発生します。構成されたバックエンドの DNS 解決に失敗しました。これは、Kubernetes Service をバックエンドとして使用する場合によく発生します。
アップストリームとの接続の確立に失敗しました。
アップストリームのリクエストまたは応答が大きすぎるため、メモリ割り当てに失敗し、通常のビジネスインタラクションが中断されます。
503: Nginx では、この状態コードは、すべてのアップストリームサーバーが利用できないことを示すために使用されます。クラウドネイティブシナリオでは、この状態コードにはいくつかの特定の意味があります。一般的な原因は次のとおりです。利用可能なバックエンドがありません。これはまれな状況です。
トラフィックが多すぎて、Ingress の
limit-req設定によってスロットリングされています。
504: このエラーは、Nginx とアップストリーム間のビジネス関連パケットのタイムアウト問題を示します。一般的な原因は、アップストリームからの応答の遅延です。
これらの問題が発生した場合は、まず一般的な情報を収集して問題の範囲を特定し、トラブルシューティングの次のステップを決定します。
Nginx の
access_log情報、特にrequest_time、upstream_connect_time、およびupstream_response_time。Nginx の
error_log情報。問題が発生したときに異常なエラーメッセージがないか確認します。liveness または readiness ヘルスチェックが構成されている場合は、そのステータスを確認します。
上記の情報に基づいて、接続障害が発生した可能性がある場合の次のメトリックの変化に注意してください。
メトリック名 | 説明 |
| LISTEN 状態のソケットの半接続キューがオーバーフローしたときにインクリメントされます。 |
| LISTEN 状態のソケットが SYN_RECV 状態のソケットを作成できなかったときにインクリメントされます。 |
| 送信エラーのためにネットワークインターフェイスカード (NIC) がパケットをドロップした回数。 |
| 受信エラーのために NIC がパケットをドロップした回数。 |
| Pod が SYN パケットで TCP ハンドシェイクを正常に開始した回数。これには SYN 再送は含まれませんが、接続に失敗した場合もこのメトリックは増加します。 |
| Pod が TCP ハンドシェイクを完了し、ソケットを正常に割り当てた累積回数。これは一般的に、正常に確立された接続の数として理解できます。 |
| 単一の Pod 内の再送されたセグメントの総数。値は、TCP Segmentation Offload (TSO) によるセグメンテーション後に計算されます。 |
| 単一の Pod 内で TCP 接続が異常終了した回数。このメトリックは結果のみをカウントします。 |
| 単一の Pod 内で TCP によって送信されたリセットパケットの数。 |
| さまざまな理由で接続追跡 (conntrack) エントリを確立できないが、パケットはドロップされない回数。 |
| conntrack エントリを確立できなかったためにドロップされたパケットの数。 |
Nginx の request_time が短い場合でもタイムアウトが発生するなど、Nginx の応答が遅い場合は、次のメトリックの変化に注意してください。
メトリック名 | 説明 |
| ESTABLISHED 状態にある現在の TCP 接続の数。 |
| TIME_WAIT 状態にある現在の TCP 接続の数。 |
| 現在 ESTABLISHED 状態にある TCP 接続の送信キュー内のデータの合計バイト数。 |
| 現在 ESTABLISHED 状態にある TCP 接続の受信キュー内のデータの合計バイト数。 |
| 再送されたパケットが EBUSY 以外のエラーを返し、再送が失敗したことを示す場合にインクリメントされます。 |
問題発生時のこれらのメトリックの変化に基づいて、調査の範囲を絞り込むことができます。。
TCP リセット問題のトラブルシューティング
TCP リセットパケットは、TCP プロトコルにおける予期しない状況への応答です。通常、ユーザープログラムに次のような影響を与えます。
connection reset by peerエラー。Nginx などの C ライブラリに依存するアプリケーションでよく見られます。Broken pipeエラー。Java や Python など、TCP 接続ラッパーを使用するアプリケーションでよく見られます。
クラウドネイティブのネットワーク環境では、リセットパケットには多くの一般的な原因があります。以下に一般的な原因をいくつか示します。
TCP に構成されたメモリが不十分であるなど、サーバー側の例外が通常のサービスを妨げます。この状況は通常、積極的なリセットをトリガーします。
Service またはロードバランシングを使用する場合、Endpoint の選択や conntrack などのステートフルメカニズムの異常により、トラフィックが予期しないバックエンドに転送されます。
セキュリティ上の理由による接続の解放。
NAT 環境または高い同時実行性シナリオでは、Protection Against Wrapped Sequence Numbers (PAWS) またはシーケンス番号のラップアラウンドが発生します。
TCP Keepalive を使用して接続を維持しますが、長期間通常のビジネス通信はありません。
これらの根本原因を迅速に区別するために、いくつかの基本的な情報とメトリックを収集できます。
リセットパケットが生成されたときのクライアントとサーバー間のネットワークトポロジーを分析します。
次のメトリックの変化に注意してください。
メトリック名
説明
kubeskoop_tcpext_tcpabortontimeoutキープアライブ、ウィンドウプローブ、または再送呼び出しの最大数を超えたためにリセットが送信されたときにインクリメントされます。
kubeskoop_tcpext_tcpabortonlingerTCP Linger2 オプションが有効な場合に、FIN_WAIT2 状態の接続を迅速に再利用するために送信されるリセットの数。
kubeskoop_tcpext_tcpabortonclose状態機械の外部の理由で TCP 接続が閉じられたときにまだ未読データがあるためにリセットパケットが送信されたときにインクリメントされます。
kubeskoop_tcpext_tcpabortonmemorytcp_check_oomによってトリガーされるメモリ不足のために接続を終了するために送信されるリセットの数 (tw_sockやtcp_sockなどのリソースを割り当てる場合)。Linger または Linger2 オプションが有効な場合に、リセットを介して高速な接続再利用のために送信されるリセットの数。
kubeskoop_tcpext_tcpackskippedsynrecvSYN_RECV 状態のソケットが ACK で応答しない回数。
kubeskoop_tcpext_tcpackskippedpawsPAWS メカニズムによって修正がトリガーされたにもかかわらず、Out-of-Window (OOW) レート制限のために ACK パケットが送信されない回数。
kubeskoop_tcp_estabresets単一の Pod 内で TCP 接続が異常終了した回数。このメトリックは結果のみをカウントします。
kubeskoop_tcp_outrsts単一の Pod 内で TCP によって送信されたリセットパケットの数。
断続的なネットワーク遅延ジッターのトラブルシューティング
断続的なネットワーク遅延ジッターは、クラウドネイティブ環境で診断するのが最も一般的で困難な問題の 1 つです。多くの原因があり、前述の 3 種類の問題につながる可能性があります。コンテナーネットワークシナリオでは、ノード内のネットワーク遅延には通常、次の原因があります。
RT スケジューラによって管理されるリアルタイムプロセスが長時間実行され、ビジネスプロセスまたはネットワークカーネルスレッドが長時間キューに入れられたり、処理が遅くなったりします。
プロセス自体が、クラウドディスクからの応答が遅い、RDS のラウンドトリップタイム (RTT) が断続的に増加するなど、時折長い外部呼び出しを経験し、リクエスト処理が遅くなります。
ノード構成の問題により、異なる CPU または NUMA ノード間で負荷が不均一になり、負荷の高いシステムが遅延します。
conntrack の confirm 操作など、カーネルのステートフルメカニズムによって引き起こされる遅延、または多くの孤立ソケットが通常のソケット検索に影響を与えます。
このような問題に直面した場合、ネットワークの問題として現れますが、根本原因は他のオペレーティングシステムの要因に関連していることがよくあります。調査の範囲を絞り込むために、次のメトリックに注意してください。
メトリック名 | 説明 |
| プロセスが |
| プロセスが |
| プロセスがファイルシステムから読み取るバイト数。通常はブロックデバイスからです。 |
| プロセスがファイルシステムに書き込むバイト数。 |
| SYN パケットが確認されずに再送されるときにインクリメントされます。これは、輻輳回避 (CA) 状態が回復、損失、または無秩序に入っていない場合にトリガーされます。 |
| ESTABLISHED 状態にある現在の TCP 接続の数。 |
| TIME_WAIT 状態にある現在の TCP 接続の数。 |
| 現在 ESTABLISHED 状態にある TCP 接続の送信キュー内のデータの合計バイト数。 |
| 現在 ESTABLISHED 状態にある TCP 接続の受信キュー内のデータの合計バイト数。 |
| 単一の Pod 内のすべての CPU によって処理された NIC のバックログからのパケット数。 |
| 単一の Pod 内のすべての CPU によってドロップされたパケット数。 |
顧客のユースケース
以下は、顧客が ACK KubeSkoop を使用して複雑な問題をトラブルシューティングおよび分析したケースです。比較のために参照できます。
ケース 1: 断続的な DNS タイムアウトの問題
問題
ある顧客が断続的な DNS 解決タイムアウトを経験しました。ユーザーのビジネスは PHP で実行されており、DNS サービスは CoreDNS で構成されていました。
トラブルシューティングプロセス
顧客の説明に基づいて、顧客から DNS 関連のモニタリングデータを取得しました。
エラー期間中のデータを分析したところ、次の問題が明らかになりました。
kubeskoop_udp_noportsがエラー期間中に 1 増加しました。全体的なメトリック値は小さかったです。kubeskoop_packetloss_totalメトリックが 1 増加しました。パケット損失の変化は小さかったです。
顧客は、構成された DNS アドレスがパブリックサービスプロバイダーのアドレスであると報告しました。この情報とモニタリングデータを組み合わせると、DNS 応答が遅いことが根本原因であることが示されました。DNS 応答パケットは、ユーザー側のアプリケーションがすでにタイムアウトした後に到着しました。
ケース 2: Java アプリケーションでの断続的な接続障害
問題
ある顧客は、Tomcat が断続的に利用できなくなる異常を発見しました。各発生は約 5〜10 秒間続きました。
トラブルシューティングプロセス
ログ分析により、問題が発生したときに顧客の Java ランタイムがガベージコレクション (GC) 操作を実行していたことが確認されました。
KubeSkoop モニタリングを展開した後、問題発生時に
kubeskoop_tcpext_listendropsメトリックが大幅に増加していることがわかりました。顧客の Java ランタイムが GC を実行すると、リクエスト処理速度が低下し、接続の解放が遅れると結論付けました。しかし、新しい接続リクエストは続き、多数の接続が作成されました。これにより、リッスンソケットのバックログがいっぱいになり、オーバーフローが発生し、
kubeskoop_tcpext_listendropsが増加しました。顧客の接続の蓄積は短時間であり、処理能力自体は問題ではありませんでした。関連する Tomcat パラメーターを調整するよう顧客に推奨したところ、問題は解決しました。
ケース 3: 顧客の断続的なネットワーク遅延ジッター
問題
ある顧客は、アプリケーションと Redis 間のリクエストで断続的な RTT の増加が発生し、ビジネスのタイムアウトにつながることを発見しました。しかし、この問題は再現できませんでした。
トラブルシューティングプロセス
ログ分析によると、顧客は合計応答時間が 300 ms を超える断続的な Redis リクエストを経験していました。
KubeSkoop を展開した後、モニタリングデータは、問題が発生したときに
kubeskoop_virtcmdlatency_latencyメトリックの増加を示しました。増加したle(Prometheus ヒストグラムバケットラベル) の値は 18 と 15 でした。これは、2 つの高遅延仮想化呼び出しが発生したことを示しています。le=15のものは 36 ms を超える遅延を引き起こし、le=18のものは 200 ms を超える遅延を引き起こしました。カーネルの仮想化呼び出しは CPU を占有し、プリエンプトできないため、顧客の断続的な遅延は、Pod のバッチ作成および削除中に一部の仮想化呼び出しの実行に時間がかかりすぎることが原因でした。
ケース 4: Ingress Nginx の断続的なヘルスチェックの失敗
問題
Ingress マシンで断続的なヘルスチェックの失敗が発生し、それに伴いビジネスリクエストの失敗も発生しました。
トラブルシューティングプロセス
モニタリングを展開した後、問題発生時にいくつかのメトリックが異常な変化を示していることがわかりました。
kubeskoop_tcpsummary_tcprxqueueとkubeskoop_tcpsummary_tcptxqueueの両方が増加しました。kubeskoop_tcpext_tcptimeoutsが増加しました。kubeskoop_tcpsummary_tcptimewaitconnが減少し、kubeskoop_tcpsummary_tcpestablishedconnが増加しました。
分析により、カーネルは正常に動作しており、接続も正しく確立されていることが確認されました。しかし、受信ソケットからのパケットの処理や実際のパケット送信など、プロセスの実行は異常でした。ユーザープロセスのスケジューリングまたはリソース制限の問題が疑われました。
ユーザーに Cgroup モニタリングを確認するようアドバイスしたところ、問題発生時に顧客が CPU スロットリング現象を経験していることがわかりました。これにより、Cgroup の制限によりユーザープロセスが断続的にスケジュールされなくなったことが証明されました。
ガイド「CPU バーストパフォーマンス最適化ポリシーを有効にする」に従って、Ingress の CPU バースト機能を構成したところ、この種の問題が解決しました。