linux

私の中でちょっと問題になった部分を共有します。

kernel: nf_conntrack: table full, dropping packet
このエラーでよく紹介されている解決方法が
sysctl.confに設定を追記してsysctl -pで設定を読み込ませるという方法です。

確かにこれでも問題はありません。わたしもこの方法でやってます。
ただし、iptablesを使っている方には問題がでる可能性があります。

conntrackテーブルはiptablesで利用されているnetfilterモジュールに設定される値ですので、iptablesを再起動など行ってしまうと一度そのモジュールが読み込みなおされることになり、設定が初期化されてしまいます。この事実を知らずにiptablesを再起動しちゃうと、混雑する深夜の時間帯にkernel: nf_conntrack: table full, dropping packetとなり、たたき起こされてしまうことになりかねません。私がそうです。^^;

これを回避するためは
sysctl.confではなくmodprobe.dディレクトリ配下に設定ファイルを置きます。

vi /etc/modprobe.d/conntrack.conf
options nf_conntrack hashsize=25000

例えば上記のように設定しておけばnetfilterモジュールの読み込み時(iptablesの再起動時)にこの設定が読み込まれ、値に合わせたテーブルサイズに変更してくれます。

ちなみにnf_conntrack_maxの値を200000にする場合は
hashsizeで8分の1の値(25000)を設定しておけば20万となります。

hashsizeで設定を行う場合は下記のパラメーターに変更が加えられます。
※下記は6系の例

あと、rhelの5系と6系でも違いがあります。
6系になるとiptablesの起動スクリプトでsysctlも親切に読み込んでくれるようになっています。なのでsysctl.confで設定しておいても値が初期化されることはなくなります。
※5系のiptablesの起動スクリプトではsysctlを読み込んでくれません。

ただし、modprobe.d配下の設定ファイルとsysctl.confのファイルが混在している場合は
modprobe.d配下の設定ファイルが優先されていますので注意が必要です。

sysctl.confで設定を増加させた後、6系なのでと安心しきっていると、
誰かがiptablesを再起動してmodprobe.dの設定が読み込まれて再度問題となるなんてこともあるかもしれませんよ。

DNS, linux

私もよく混乱するのですが、

dnsの問い合わせで遅延が発生するパターンは二つあります。

1.resolv.conf上位のDNSキャッシュサーバがホストダウン中に
2番手のネームサーバへの切り替えるため遅延が発生する。
デフォルト設定では5秒待ってから次のサーバを試す。

2.RHEL6系からAとAAAAレコードが同じソケットでの問い合わせを行うため
対応していないfirewallやブロードバンドルータ配下のホストでは遅延が発生する。
AとAAAAレコードの二つのレコード結果の両方が揃うまで待ち続けるため、
その待ちがタイムアウトするまで5秒遅延が発生する。

どちらも5秒待つことになるので同じ問題なんだと考え深みにはまる。

1については「DNSキャッシュサーバのメンテナンスや障害時の影響と対策」でお話ししましたが、ここでは2について触れます。

2の場合でも混乱ポイントがあって、同じバージョンであっても問題がでる場合とでない場合があるということを留意しておく必要がありますのでご注意ください。

我々の環境ではバックボーン環境やサーバで構築しているNATサーバ、firewallや負荷分散装置配下のRHEL6系のホストでは遅延は発生していません。

一方でオフィスのBフレッツ回線配下に設置するRHEL6系のOSはことごとく遅延してしまいます。

裏は取れていないのですが、上流のブロードバンドルータが同一ソケットでの問い合わせに対応できずパケットを落としてしまうため問題が発生していると推測しています。

ということで、上記を踏まえつつ今件をどのように対応するかについてなんですが、

3つの方法が考えられます。

■ひとつめ

A、AAAAレコードを同一ソケットで問い合わせが出来る機器で構成する。

■ふたつめ

みなさんご存じのresolv.confでの設定

もしくは

で対応していくことになるかと思います。

このオプション使用前と後でのtcpdumpで改善したかどうか確認してみましょう。

■オプション使用前

AとAAAAレコードが同じソケット(35504)で問い合わせを行い
Aレコードは返答が来ているがAAAAレコードを待っているため5秒待っているのが分かる。

■オプション使用後

こちらは別ソケット(Aレコードは48690、AAAAレコードは52755)で
順番に問い合わせしているので遅延は発生していないのがわかる。

■みっつめ

OS側でipv6をdisableとすると改善します。

上記のいずれかの対応を自身の環境に合わせて適用していけばよさそうです。

それにしても、ほんと混乱します。

システムコールやコマンドごとに挙動が違うことも問題を複雑化させているように思います。

traceroute、curlは遅延しますし、

ping、digやnslookupなどは遅延しません。

例えばpingで確認してしまうと直ったと勘違いしてしまうことになります。^^;

とりあえずは、標準化の策定の中でsingle-requestを入れておくというのが正解なんだと思います。

最後に小ネタをひとつ

curlコマンドはオプションで[-4]を利用すると遅延が改善します。

DNS, linux

DNSキャッシュサーバのメンテナンスや障害時の影響と対策

みなさん、サーバ構築する際/etc/resolv.confでnameserverの設定をされているかと思います。

ここに指定しているDNSキャッシュサーバで障害が発生しホストダウンとなると
resolv.confで設定した次のネームサーバへ問い合わせるまである一定の時間待たされ影響が出ることがあります。

標準のタイムアウト値は5秒なんですが復旧するまでの名前解決はそれぞれずっと5秒間遅延することになりますのでdmmでは意外と影響が大きくなります。

IPは生きていてdnsサービス自体が落ちている場合はすぐに次のDNSキャッシュサーバに切り替わるのですが、
IPの接続性がなくなるホストダウンとなるとタイムアウト値まで待たされることになりますので注意が必要です。

存在しないIPアドレス:10.255.255.255
存在するがDNSサーバではない:10.163.0.226
動作中のローカルDNSキャッシュ:127.0.0.1

の組み合わせでテストしてみました。結果は下記です。

■5秒待たされる場合のstrace結果

10.255.255.255を試し、タイムアウト(5秒)まで待たされて127.0.0.1へ問い合わせしているのがわかります。

 

■すぐに切り替わる場合のstrace結果

10.163.0.226を試してすぐにPOLLERRとなりすぐに127.0.0.1へ問い合わせしているのがわかります。

ということでこれらの影響を最小限とするため下記のような対策が必要になってくると思っています。

1.タイムアウト値を調整し障害発生時でも影響を最小限に

resolv.confでのタイムアウト値を規定の5秒から1秒へ変更
options timeout:1

2.そもそもDNSキャッシュサーバを落とさない構成

lvs配下にDNSキャッシュサーバを2台以上配置。
その構成を2セット用意してそもそも落とさない
3.各サーバでdnsmasqやunboundを導入し切り替え時間を高速化する。

resolv.confに
nameserver 127.0.0.1

として
一番上にローカルにインストールされたDNSキャッシュサーバを指定しておく。

※ローカルのIPは落ちることがないのでローカルにインストールされた
DNSキャッシュが停止したとしてもすぐに切り替わる。
4.hostsを利用しそもそもDNSキャッシュサーバに頼らない。

分かり切った相手先への通信を行うサーバについてはhostsを利用し、
そもそもDNSキャッシュサーバを利用しない。
5.DNSキャッシュアプライアンスを導入する。

6.外部のDNSキャッシュサービスを利用する。
上記6つの対策はどれも正解でそれぞれを適材適所で利用することになるんだと思います。

dmmでは

DNSキャッシュサーバを落とさない設計

プラス

各サーバのローカル環境にDNSキャッシュサーバをインストールし、さらに一部hostsも利用し低レイテンシーを実現する方向で対策を行います。

最近は各社さんとの連携のため多くの通信が発生し、その通信に低レイテンシーさが求められるようになってきているためhostsを使ったりunboundやdnsmasqなどのDNSキャッシュを利用する構成をとります。

みなさんはどのような対策を行っていますでしょうか?

コメントorツイートいただけると嬉しいです。

linux, 超解釈

cronとanacronとRHEL5系6系についてですが

結構、適当に設定し、
はまることが多々あったので自分なりに簡単に解釈してみましたのでお話しします。

anacronについては同じものではあるのですが
5系と6系で解釈を変えるとすんなりと頭に入り込んでくるようになると思います。

では、始めます。

RHEL5系

cron
特定のプログラムなどの処理を定期的に実行してくれるプログラム

anacron
サーバ停止中のためcronが実行できなかった場合にジョブを再実行させるためのcronのヘルパープログラム

定期ジョブは下記の二つのうちのいずれかで設定を行う。

■/etc/crontab
cron処理の実行スケジュールを設定する。

■/etc/cron.{hourly,daily,weekly,monthly}
スケジュールごとに指定のディレクトリでプログラムを登録する。
上記の設定だけで定期スケジュールとプログラムの設置が完了する

■/etc/cron.d
自分ではさわらない。

ヘルパーのanacronを利用したい場合はcron.dailyなどのディレクトリでプログラムを登録し、
/etc/init.d/anacronで定期的にstartしてあげる。
設定ファイルは/etc/anacrontabを読み込みます。
標準で/etc/cron.{daily,weekly,monthly}配下に登録されたプログラムがanacronで動作していなかった場合に再実行してくれます。

RHEL6系

cron
特定のプログラムなどの処理を定期的に実行してくれるプログラム

anacron
仮想環境などのゲスト環境でcron処理が特定の時間に集中しないように定期ジョブをうまいこと分散してくれるプログラム
なので、サーバが稼働し続けていなくともRHELの5系の時のanacronのように、サーバが稼働した時点でジョブを実行してくれるようになります。

■/etc/crontab
確実にcronを指定時間に動かしたい場合はこちらを利用する。

■/etc/anacrontab
実行時間は変動するが確実にcronを実行させたい場合はこちらを利用する。

■/etc/cron.{daily,weekly,monthly}
こちらのディレクトリでプログラムを登録するとanacronのほうで実行されます。
※cron.hourlyを使いたい場合はanacrontabで設定を忘れずに

■/etc/cron.d
自分ではさわらない。

5系と同じようにcronを利用したい場合はcronie-nonanacronをインストールしてcronie-anacronをremoveするといいみたい。

p.s.
タイトルは「部屋とYシャツと私」を字余りで歌いながら書き込んでました^^;

linux

非常に忙しいサーバやNATやプロクシサーバなどを運用している環境だと上記のようなエラーによく遭遇するかと思います。

iptablesを利用している環境では利用するステートフルなパケットのエントリを管理するためのテーブルが必要で、
管理するエントリが多すぎるとエントリテーブルのサイズが上限に達してしまい上記のエラーとともにパケットをドロップしましたよというエラーが表示されるようになります。
※iptablesが動作していない環境では問題とはなりません。

この問題を解決するためにはエントリのテーブルサイズの上限を引き上げる必要があります。

みなさんと同じように我々も下記のように設定しています。
※CentOS6系

vi /etc/sysctl.conf
net.nf_conntrack_max = 1000000

そして、

当然、「この値は監視しなくてはならない」となると思います。

dmmではmuninのip_conntrackというプラグインを利用してこの値を監視することになるのですが、

どうもネットワーク系のエラーが多発して調子が悪い。

muninのグラフを見てみるとインターフェースで多くのエラーが発生してしまいます。

if_err2_vnet1-day

if_err2_eth1-day (2)

調査していくとこのプラグインはスクリプトの中で

上記のコマンドを呼び出しているようです。
このプロセスが動作している時だけロードアベレージが跳ね上がるので、
root権限でのコマンドのせいで競合が発生しこの値の取得に多くの時間を要しているのかもしれません。
※混雑する時間帯は15秒もかかる場合も。

あまり混雑していない15時くらいの時間でも下記のように多くの時間を要していました。

sudo time cat /proc/net/ip_conntrack|wc -l

24028

real 0m2.616s
user 0m0.005s
sys 0m2.621s

因果関係はわかっていませんがこの状況のためエラーが高くなっているのではないかと推測。

該当するプラグインを停止してみました。
その時の画像が下記の3枚となります。※先ほどと同じではあるのですが。
12時すぎに該当のmuninプラグインを停止したのですが、その後エラーが発生していないことが分かるかと思います。

if_err2_eth1-day (2)

if_err2_vnet1-day

また、下記はロードアベレージの値ですが、muninが動作する5分毎にギザギザになっていたものが、
なめらかになったのがわかるかと思います。

load-day

自分でプラグインを作ればなんとかなるかなとプラグインのソースを眺めていると

my $conntrack = '/usr/sbin/conntrack';
my $nf_conntrack_file = '/proc/net/nf_conntrack';
my $ip_conntrack_file = '/proc/net/ip_conntrack';
my $command;
if ( -x $conntrack) {
$command = "$conntrack -L -o extended 2&>/dev/null";
} elsif ( -r $nf_conntrack_file ) {
$command = "cat $nf_conntrack_file";
} elsif (-r $ip_conntrack_file ) {
$command = "cat $ip_conntrack_file";
} else {
die "Can't find conntrack information\n";
}

という部分がありました。

まずはconntrackというコマンドが実効可能かどうかを確認し可能であればそのコマンドを使うようになっています。

/usr/sbin/conntrackコマンド???

はい、知らなかったです。調べてみました。

conntrackコマンドはconntrack-toolsに含まれているコマンドでredhat系の標準レポジトリでは含まれていません。

我々の環境でもconntrackコマンドが入っていないため、当然catコマンドが呼び出される状態だった。

リッチな機能を搭載したユーザ空間で動作するコマンドで/proc/net/nf_conntrackを置き換えるべく作られたようなので、
兎にも角にも、早速、インストールして違いを確認してみました。

インストール方法

wget http://sourceforge.net/projects/flexbox/files/flexbox-release-1-1.noarch.rpm/download
rpm -ivh flexbox-release-1-1.noarch.rpm
yum -y install conntrack-tools

コマンド結果

$ sudo time cat /proc/net/ip_conntrack|wc -l
27311

real 0m3.324s
user 0m0.002s
sys 0m3.322s

$ time conntrack -L|wc -l
conntrack v0.9.15 (conntrack-tools): 27062 flow entries have been shown.
27062

real 0m0.142s
user 0m0.101s
sys 0m0.047s

15時30分の時間帯でもかなりの差がついています。

なるほど、
だから、conntrackコマンドがあれば優先して利用し、なるべくcatを利用しないような設計になっているんだと。

とりあえずは自分でプラグインを作成する必要はなさそうで、

今後は高負荷なサーバでconntrackテーブルを監視する場合はconntrackコマンドをインストールしようかなと思っています。

追記です。

23時30分時点でのコマンド結果

$ time conntrack -L|wc -l
conntrack v0.9.15 (conntrack-tools): 53225 flow entries have been shown.
53225<
real 0m0.265s
user 0m0.191s
sys 0m0.087s

ユーザ空間で動作するコマンドなのでユーザで利用時間が多くなっています。

$ sudo time cat /proc/net/ip_conntrack|wc -l
51947

real 0m14.574s
user 0m0.009s
sys 0m14.611s

こちらのroot権限で動作するcatコマンドはシステムの利用時間が多くなっています。

こんなに違うんですね。

PAGE TOP