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インスタンスの有効なカーネルパラメータをすべて問い合わせます。次のコードブロックを参照してください:
net.ipv4.tcp_app_win = 31
net.ipv4.tcp_adv_win_scale = 2
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_frto = 2
net.ipv4.tcp_frto_response = 0
net.ipv4.tcp_low_latency = 0
net.ipv4.tcp_no_metrics_save = 0
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_tso_win_divisor = 3
net.ipv4.tcp_congestion_control = cubic
net.ipv4.tcp_abc = 0
net.ipv4.tcp_mtu_probing = 0
net.ipv4.tcp_base_mss = 512
net.ipv4.tcp_workaround_signed_windows = 0
net.ipv4.tcp_challenge_ack_limit = 1000
net.ipv4.tcp_limit_output_bytes = 262144
net.ipv4.tcp_dma_copybreak = 4096
net.ipv4.tcp_slow_start_after_idle = 1
net.ipv4.cipso_cache_enable = 1
net.ipv4.cipso_cache_bucket_size = 10
net.ipv4.cipso_rbm_optfmt = 0
net.ipv4.cipso_rbm_strictvalid = 1
カーネルパラメータを変更:
/sbin/sysctl -w kernel.parameter="example"
を実行して、sysctl -w net.ipv4.tcp_tw_recycle="0"
などの指定されたパラメータ値を変更します。/etc/sysctl.conf
ファイル内のパラメータを変更するにはvi /etc/sysctl.conf
を実行します。/sbin/sysctl -p
を実行して設定を有効にします。
注意:ECSインスタンスを再起動する必要があります。これは、カーネルパラメータを変更した後にカーネルが不安定になるためです。
Linuxカーネルパラメータの一般的な問題のトラブルシューティング
ハッシュテーブルの枯渇によるパケット損失
ここに含まれるカーネルパラメータは次のとおりです。
net.netfilter.nf_conntrack_buckets
net.nf_conntrack_max
症状
ECS Linuxインスタンスで断続的なパケット損失が発生し、インスタンスに接続できません。リンクテストツールの概要のようなリンクテストツールで例外を見つけることはできません。同時に、次のコードブロックに示すように、多数のエラーメッセージ table full、dropping packet .
がシステムログで繰り返されます。
Feb 6 16:05:07 i - ***カーネル:nf_conntrack:テーブルがいっぱいになり、パケットが破棄されました。
Feb 6 16:05:07 i - ***カーネル:nf_conntrack:テーブルがいっぱいになり、パケットが破棄されました。
Feb 6 16:05:07 i - ***カーネル:nf_conntrack:テーブルがいっぱいになり、パケットが破棄されました。
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_buckets
とnf_conntrack_max
の値に依存します。nf_conntrack_max
のデフォルト値はnf_conntrack_buckets
の4倍ですが、Linuxインスタンスの起動後に nf_conntrack_max
の値を変更できないので、nf_conntrack_max
の値を増やすことができます。
注意:オペレーティングシステムはTCP接続を管理するためにメモリを消費するので、
nf_conntrack_max
の値を増やす前にLinuxインスタンスに十分なメモリがあることを確認してください。調整された値は、Linuxインスタンスの状態によって異なります。
解決策
- 管理端末を使用してECSインスタンスにログオンします。
#vi /etc/sysctl.conf
を実行して、カーネル設定を編集します。- ハッシュテーブルの最大パラメータ値を変更します:
net.netfilter.nf_conntrack_max = 655350
。 - タイムアウトパラメータ:
net.netfilter.nf_conntrack_tcp_timeout_established = 1200
を変更します。デフォルト値は432000(秒)です。 #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
に似たエラーメッセージですバケット次のコードブロックを例として参照してください。
Feb 6 16:05:07 i-*** kernel: nf_conntrack: table full, dropping packet.
Feb 6 16:05:07 i-*** kernel: nf_conntrack: table full, dropping packet.
Feb 6 16:05:07 i-*** kernel: nf_conntrack: table full, dropping packet.
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接続を改善することをお勧めします。
解決策
netstat -anp | grep tcp | wc -l
を実行して、TCP接続の合計を数えます。vi /etc/sysctl.conf
を実行してnet.ipv4.tcp_max_tw_buckets
の値を問い合わせます。合計をnet.ipv4.tcp_max_tw_buckets
の値と比較して、余分な接続が存在するかどうかを確認してください。net.ipv4.tcp_max_tw_buckets
の値を増やして制限値を変更します。#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接続を高速化することができます。
解決策
vi /etc/sysctl.conf
を実行して、次のコードブロックを変更または追加します。net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
#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接続はハーフオープン状態になっていますが、ピアと通信できないため、時間内に解放する必要があります。ピアがプログラムロジックに基づいて適時に接続を閉じたかどうかを推定する必要があります。
解決策
プログラミング言語によっては、 read
やwrite
を実行してCLOSE_WAIT TCP接続を調べることができます。
Java :
- I/Oを評価するために
read
を実行します。readメソッドが-1
を返すとき、それはその終わりに達したことを意味します。 - 接続を閉じるには
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_recycle
とnet.ipv4.tcp_timestamps
の両方の値が1である場合、サーバは各メッセージのタイムスタンプをチェックします。メッセージのタイムスタンプが増加していない場合、サーバーはメッセージを傍受しません。しかし、NAT構成のクライアントは同じ送信元IPを持ち、NATを構成する前の各クライアントの時間が異なる可能性があるため、メッセージのタイムスタンプは増加していないため、サーバーはメッセージを受信する可能性があります。
解決策
- リモートサーバがECSの場合、
net.ipv4.tcp_tw_recycle
を0に変更してください。 - リモートサーバーがRDSなどのPaaSサービスの場合RDSはカーネルパラメータを直接変更することはできませんので、クライアント上で
net.ipv4.tcp_tw_recycle
とnet.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 は受信キューの最大長を決定します。 |