edit-icon download-icon

ECS Linuxインスタンスの共通カーネルネットワークパラメータと問題のトラブルシューティング

最終更新日: Mar 06, 2019

ECS Linuxインスタンスの共通カーネルネットワークパラメータと問題のトラブルシューティング

このドキュメントでは、いくつかのLinuxカーネルパラメータを紹介し、関連する問題の解決方法を示します。カーネルパラメータを変更する前に、次の項目に注意してください。

  • 実際の稼働を考慮し、確認のために関連データを入手し、カーネルパラメータを容易に変更しないことをお勧めします。
  • 各パラメーターの特定の機能を理解し、カーネルパラメーターは、同じタイプまたはオペレーティングシステムのバージョンで異なる可能性があります。
  • ECSインスタンス内の重要なデータをバックアップします。指示については、スナップショットの作成を参照してください。

Linuxインスタンスのカーネル・パラメーターの照会と変更

/proc/sys/ディレクトリ

カーネルパラメータのクエリcatを実行して、対応するファイルの内容を確認します。 たとえば、 cat /proc/sys/net/ipv4/tcp_tw_recycleを実行してnet.ipv4.tcp_tw_recycleの値を確認します。

カーネルパラメータを変更するechoを実行してカーネルパラメータの対応するファイルを変更する。たとえば、 echo" 0 "> /proc/sys/net/ipv4/tcp_tw_recycleを実行してnet.ipv4.tcp_tw_recycleの値を0に変更します。

注意

  • /proc/sys/ディレクトリは、Linuxインスタンスに関する情報を提供するだけでなく、システム管理者がカーネル機能をただちに有効または無効にすることを可能にします。ディレクトリ内の netフォルダには、現在のLinuxインスタンスで有効なすべてのカーネルパラメータが格納されます。そのディレクトリツリー構造は、対応するファイル /proc/ sys/net/ipv4/tcp_tw_recycleを伴うパラメータnet.ipv4.tcp_tw_recycleやファイルの内容としてのパラメータ値など、パラメータのフルネームに関連しています。

  • /proc/sys/ディレクトリのパラメータ(#method1)の値を変更すると、現在の操作でのみ有効になり、Linuxインスタンスの再起動後に以前の値に復元されます。このメソッドを使用して効果を確認したり、パラメータを永久に変更することができます(sysctl.conf`ファイル内)。

sysctl.confファイル

カーネルパラメータのクエリsysctl -aを実行して、ECSインスタンスの有効なカーネルパラメータをすべて問い合わせます。次のコードブロックを参照してください:

  1. net.ipv4.tcp_app_win = 31
  2. net.ipv4.tcp_adv_win_scale = 2
  3. net.ipv4.tcp_tw_reuse = 0
  4. net.ipv4.tcp_frto = 2
  5. net.ipv4.tcp_frto_response = 0
  6. net.ipv4.tcp_low_latency = 0
  7. net.ipv4.tcp_no_metrics_save = 0
  8. net.ipv4.tcp_moderate_rcvbuf = 1
  9. net.ipv4.tcp_tso_win_divisor = 3
  10. net.ipv4.tcp_congestion_control = cubic
  11. net.ipv4.tcp_abc = 0
  12. net.ipv4.tcp_mtu_probing = 0
  13. net.ipv4.tcp_base_mss = 512
  14. net.ipv4.tcp_workaround_signed_windows = 0
  15. net.ipv4.tcp_challenge_ack_limit = 1000
  16. net.ipv4.tcp_limit_output_bytes = 262144
  17. net.ipv4.tcp_dma_copybreak = 4096
  18. net.ipv4.tcp_slow_start_after_idle = 1
  19. net.ipv4.cipso_cache_enable = 1
  20. net.ipv4.cipso_cache_bucket_size = 10
  21. net.ipv4.cipso_rbm_optfmt = 0
  22. net.ipv4.cipso_rbm_strictvalid = 1

カーネルパラメータを変更

  1. /sbin/sysctl -w kernel.parameter="example"を実行して、 sysctl -w net.ipv4.tcp_tw_recycle="0"などの指定されたパラメータ値を変更します。
  2. /etc/sysctl.confファイル内のパラメータを変更するにはvi /etc/sysctl.confを実行します。
  3. /sbin/sysctl -pを実行して設定を有効にします。

注意:ECSインスタンスを再起動する必要があります。これは、カーネルパラメータを変更した後にカーネルが不安定になるためです。

Linuxカーネルパラメータの一般的な問題のトラブルシューティング

ハッシュテーブルの枯渇によるパケット損失

ここに含まれるカーネルパラメータは次のとおりです。

  • net.netfilter.nf_conntrack_buckets
  • net.nf_conntrack_max

症状

ECS Linuxインスタンスで断続的なパケット損失が発生し、インスタンスに接続できません。リンクテストツールの概要のようなリンクテストツールで例外を見つけることはできません。同時に、次のコードブロックに示すように、多数のエラーメッセージ table full、dropping packet .がシステムログで繰り返されます。

  1. Feb 6 16:05:07 i - ***カーネル:nf_conntrack:テーブルがいっぱいになり、パケットが破棄されました。
  2. Feb 6 16:05:07 i - ***カーネル:nf_conntrack:テーブルがいっぱいになり、パケットが破棄されました。
  3. Feb 6 16:05:07 i - ***カーネル:nf_conntrack:テーブルがいっぱいになり、パケットが破棄されました。
  4. Feb 6 16:05:07 i - ***カーネル:nf_conntrack:テーブルがいっぱいになり、パケットが破棄されました。

分析

ip_conntrackは、LinuxインスタンスのNATのconntrackの数を示すモジュールです。ip_conntrackモジュールは、ハッシュテーブルを使用してTCP接続の確立されたレコードを記録します。ハッシュテーブルの枯渇は nf_conntrack:table full、dropped packetエラーを引き起こします。Linuxインスタンスは各TCP接続を維持する余地を確保しています。この部屋のサイズは nf_conntrack_bucketsnf_conntrack_maxの値に依存します。nf_conntrack_maxのデフォルト値はnf_conntrack_bucketsの4倍ですが、Linuxインスタンスの起動後に nf_conntrack_maxの値を変更できないので、nf_conntrack_maxの値を増やすことができます。

注意:オペレーティングシステムはTCP接続を管理するためにメモリを消費するので、 nf_conntrack_maxの値を増やす前にLinuxインスタンスに十分なメモリがあることを確認してください。調整された値は、Linuxインスタンスの状態によって異なります。

解決策

  1. 管理端末を使用してECSインスタンスにログオンします。
  2. #vi /etc/sysctl.confを実行して、カーネル設定を編集します。
  3. ハッシュテーブルの最大パラメータ値を変更します: net.netfilter.nf_conntrack_max = 655350
  4. タイムアウトパラメータ: net.netfilter.nf_conntrack_tcp_timeout_established = 1200を変更します。デフォルト値は432000(秒)です。
  5. #sysctl -pを実行して設定を有効にします。

time wait バケットテーブルオーバーフローのエラー

ここで関与するカーネルパラメータは次のとおりです。

  • net.ipv4.tcp_max_tw_buckets

症状

netstat -ant | grep TIME_WAIT | wc -lを実行してTCP接続の合計を数えると、TIME_WAIT接続が多数見つかります。

/var/log/messageのログは、kernel: TCP: time wait bucket table overflowに似たエラーメッセージですバケット次のコードブロックを例として参照してください。

  1. Feb 6 16:05:07 i-*** kernel: nf_conntrack: table full, dropping packet.
  2. Feb 6 16:05:07 i-*** kernel: nf_conntrack: table full, dropping packet.
  3. Feb 6 16:05:07 i-*** kernel: nf_conntrack: table full, dropping packet.
  4. Feb 6 16:05:07 i-*** kernel: nf_conntrack: table full, dropping packet.

分析

net.ipv4.tcp_max_tw_bucketsパラメータは、カーネル内のTIME_WAIT状態のTCP接続の合計を管理します。TIME_WAIT TCP接続とTIME_WAITの直前のTCP接続の合計が net.ipv4.tcp_max_tw_bucketsの値を超えると、カーネルはメッセージログにエラーメッセージを出力し、net.ipv4以外のTCP接続を閉じます。tcp_max_tw_buckets値をTIME_WAIT TCP接続にすることなく変更できます。

注意:実際の状況に合わせて net.ipv4.tcp_max_tw_bucketsの値を増やし、その間にビジネス層からのTCP接続を改善することをお勧めします。

解決策

  1. netstat -anp | grep tcp | wc -lを実行して、TCP接続の合計を数えます。

  2. vi /etc/sysctl.confを実行してnet.ipv4.tcp_max_tw_bucketsの値を問い合わせます。合計を net.ipv4.tcp_max_tw_bucketsの値と比較して、余分な接続が存在するかどうかを確認してください。

  3. net.ipv4.tcp_max_tw_bucketsの値を増やして制限値を変更します。

  4. #sysctl -pを実行して設定を有効にします。

LinuxインスタンスのTCP接続が多すぎます

ここで関与するカーネルパラメータは次のとおりです。

  • net.ipv4.tcp_fin_timeout

症状

FIN_WAIT2状態のTCP接続が多すぎます。

原因分析

  • HTTPサービスでは、KEEPALIVEタイムアウトが発生したときにサーバーがTCP接続を閉じ、結果としてサーバーがFIN_WAIT2状態に入ります。
  • TCP / IPサービスで semi-join が許可されているため、FIN_WAIT2 TCP接続はタイムアウトではありません(TIME_WAIT状態とは異なります)。クライアントがそれを閉じないと、Linuxインスタンスが再起動されるまで、TCP接続はFIN_WAIT2状態のままです。したがって、より多くのFIN_WAIT2 TCP接続がカーネルクラッシュを引き起こします。
  • net.ipv4.tcp_fin_timeoutの値を適切に減らして、LinuxインスタンスのリサイクルFIN_WAIT2 TCP接続を高速化することができます。

解決策

  1. vi /etc/sysctl.confを実行して、次のコードブロックを変更または追加します。

    1. net.ipv4.tcp_syncookies = 1
    2. net.ipv4.tcp_fin_timeout = 30
    3. net.ipv4.tcp_max_syn_backlog = 8192
    4. net.ipv4.tcp_max_tw_buckets = 5000
  2. #sysctl -pを実行して設定を有効にします。

注意FIN_WAIT2状態のTCP接続がTIME_WAIT状態に遷移します。バケットテーブルオーバーフローエラーセクションを参照ください。

LinuxインスタンスでCLOSE_WAIT TCP接続が多すぎます

症状

Linuxインスタンスで netstat -atn | grep CLOSE_WAIT | wc -lを実行すると、大量のCLOSE_WAIT TCP接続が見つかります。

分析

ピアとローカルの両方のエンドは、TCP接続を閉じる要求を開始します。ピア・エンドが要求を開始したがローカル・エンドが接続をクローズしない場合、接続は「CLOSE_WAIT」になります。TCP接続はハーフオープン状態になっていますが、ピアと通信できないため、時間内に解放する必要があります。ピアがプログラムロジックに基づいて適時に接続を閉じたかどうかを推定する必要があります。

解決策

プログラミング言語によっては、 readwriteを実行してCLOSE_WAIT TCP接続を調べることができます。

Java

  1. I/Oを評価するために readを実行します。readメソッドが -1を返すとき、それはその終わりに達したことを意味します。
  2. 接続を閉じるには closeを実行します。

C readの戻り値を確認します:

  • 0の場合は接続を閉じ、
  • 0より小さい場合はerrnoをチェックし、そうでない場合は接続をクローズします。

NAT構成のクライアントがECSまたはRDSにアクセスできない

ここに含まれるカーネルパラメータは次のとおりです。

  • net.ipv4.tcp_tw_recycle
  • net.ipv4.tcp_timestamps

症状

NATで設定されたクライアントは、VPCネットワークタイプのSNATで設定されたECSインスタンスを含め、ECSまたはRDSへのアクセスに失敗します。一方、パケットロス率の検出ツールは、クライアントからサーバーに送信されたSYNパケットが応答しないことを検出します。

分析

net.ipv4.tcp_tw_recyclenet.ipv4.tcp_timestampsの両方の値が1である場合、サーバは各メッセージのタイムスタンプをチェックします。メッセージのタイムスタンプが増加していない場合、サーバーはメッセージを傍受しません。しかし、NAT構成のクライアントは同じ送信元IPを持ち、NATを構成する前の各クライアントの時間が異なる可能性があるため、メッセージのタイムスタンプは増加していないため、サーバーはメッセージを受信する可能性があります。

解決策

  • リモートサーバがECSの場合、 net.ipv4.tcp_tw_recycleを0に変更してください。
  • リモートサーバーがRDSなどのPaaSサービスの場合RDSはカーネルパラメータを直接変更することはできませんので、クライアント上で net.ipv4.tcp_tw_recyclenet.ipv4.tcp_timestampsを0に修正する必要があります。

ドキュメント内の関連するLinuxカーネルパラメータ

パラメータ 説明
net.ipv4.tcp_max_syn_backlog net.ipv4.tcp_max_syn_backlog このパラメータは SYN_RECV TCP接続の最大量を決定します。SYN_RECV状態はスリーウェイハンドシェイクの最後のACKフェーズを意味し、LinuxインスタンスがSYNを受信した後に起こり、SYN + ACKに応答し、相手方が応答するのを待ちます。
net.ipv4.tcp_syncookies このパラメータは、TCP SYN_COOKIESが有効かどうかを決定します。カーネルはCONFIG_SYN_COOKIESを有効にしてコンパイルする必要があります。SYN_COOKIESは、過度のTCP接続要求が存在するときにソケットが過負荷にならないようにします。パラメータが1に設定され、SYN_RECVキューが枯渇すると、カーネルはSYNパケットの応答を変更します。つまり、SYN + ACK応答パケットの元のシリアル番号は、ソースIP、ソースポート、ターゲットIP、ターゲットポートと時刻です。SYN + ACK応答パケットのシリアル番号が正常に計算されていない場合、攻撃者はそれに応答することはできませんが、呼び出し側はSYN + ACKを受信すると正しく応答します。
注意tcp_syncookiesが有効になっていると、net.ipv4.tcp_max_syn_backlogの値は無視されます。
net.ipv4.tcp_synack_retries このパラメータはSYN + ACKパケットが SYN_RECV状態で再送される回数を決定します。
net.ipv4.tcp_abort_on_overflow このパラメータを1に設定すると、ECSインスタンスが短時間に大量の要求を受信し、関連するアプリケーションが処理に失敗した場合、ECSインスタンスはリセットパケットを送信してリンクを直接終了します。
アプリケーションを最適化して、 リセットよりも処理能力を向上させることができます。net.ipv4.tcp_abort_on_overflowのデフォルト値は0です。
net.core.somaxconn このパラメータは、各ポートのリスニングキューの最大長を決定します。これはグローバルパラメータです。この値は、 net.ipv4.tcp_max_syn_backlogに関連付けられています。これは、スリーウェイハンドシェイクのセミジョインの上限を表し、net.core.somaxconnは、ESTABLISHED接続の上限を表します。インスタンスが負荷の高いビジネスを実行している場合は、パラメータを増やす必要があります。listen(2)のbacklogパラメータは、ESTABLISHEDリスニングポートの上限も示します。バックログの値が net.core.somaxconnより大きい場合、Linuxインスタンスはカーネル内のnet.core.somaxconn値を選択します。
net.core.netdev_max_backlog カーネルの処理速度がネットワークインタフェースのパケット受信速度よりも遅い場合、ネットワークインタフェースはパケットを受信キューに格納します。net.core.netdev_max_backlogは受信キューの最大長を決定します。

参考文献

  1. Linux man-pages
  2. kernel/git/torvalds/linux.git_proc
  3. kernel/git/torvalds/linux.git_proc_net_tcp
  4. kernel/git/torvalds/linux.git_ip-sysctl
  5. kernel/git/torvalds/linux.git_netfilter-sysctl
  6. kernel/git/torvalds/linux.git_nf_conntrack-sysctl