ロードバランサの設定を変更したときの話
LVS(Ultramonkey)を使ってロードバランサを作成し
LB ⇒ Web01、Web02 へRoundRobinでの転送を行ってました。
当初は、LB、Web01、Web02の3台すべてが同一セグメントにいたため、
転送の方式は「ダイレクトルーティング(Direct Rooting)」としてました。
ここでさらにWebサーバを追加することになったのですが、新しいWebサーバは別のセグメントに設置する必要が
あったため、ロードバランサの転送方式を「IPトンネリング(IP Tunneling)」に変更しました。
テストを行った感じ、特に問題なく、無事にサービスインを迎えることができた。
が。。。。
一部のユーザから、「画像のアップが出来ない」などの問合わせが増えてきました・・・
ログなどを見てしらべたところ、HTTPヘッダーのContent-Lengthにはガッチリした値が入っているのだが、実際に受信したBODYのデータが取れていない感じ。
小さいRequestデータなら無問題っぽいのですが、ある程度大きめのRequestデータを受信するときに。 しかも決まったユーザのみサーバでデータ受信できない現象になってました。
で結局なんだったかというと、
IPトンネリング方式にする場合、クライアントから来たIPパケットに対して、
更にカプセル化部分のIPヘッダーを付加してWebサーバに追加するのですが、
「カプセル化部分のIPヘッダー」を追加したことにより、イーサーパケットのサイズがMTUの上限を超えてしまっていたのが原因。
そこで、WebサーバのMSSの値を減らすことにより、本問題の解消となりました。
■MTU : Maximum Transmission Unit
1回の転送で送信できるデータ量(L2)
イーサーネットでは、上限で1500と決まっている。
■MSS : (Maximum Segment Size)
TCPで通信を行なう際に指定する、データの送信単位(セグメント)の最大値。
デフォルトでは、MTUの値−40バイト(TCPヘッダ20バイト+IPヘッダ20バイト)が利用される。
MSSの値については、OSの設定にて変更可能(MTUの値設定ってやつは存在しない)
なので、MSSの値を変更することにより対応 って感じ
ちなみにそのときのコマンドはこちら。
iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1400
/etc/init.d/iptables save
/etc/init.d/iptables restart
結果の確認
・tcpdump -n -i tunl0 port 80
・tcpdump -n -i eth0 port 80
同僚は上記コマンドで解決させたのですが、下記コマンドでもOKな気がします。。。
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1400

1