ファイルディスクリプタの上限を増やす

dockerlinux

ファイルディスクリプタとは

プロセスの外部とやりとりするための識別子。POSIXではint型で、0がstdin、1がstdout、2がstderrとなっている。 ファイルやデバイスに対するopen()や、 ネットワーク(INETドメインソケット)やホスト内(UNIXドメインソケット)で 通信するためのソケットを生成するsocket()などのシステムコールで割り当てられる。

ファイルディスクリプタの上限

一つのプロセスがリソースを食いつぶさないように使えるファイルディスクリプタの上限が決まっていて、現在のプロセスの値はulimit -nで確認できる。

$ ulimit -n
1024

各プロセスの上限と、使っているファイルディスクリプタは次のようにして確認できる。

$ cat /proc/<プロセスID>/limits
...
Max open files            1024                 4096                 files     
...

$ ls -l /proc/<プロセスID>/fd

webサーバーのような同時に大量の通信をするプロセスではこの上限に達してしまい、Too many open filesになってしまうことがあるので増やす必要がある。 上限を変更する方法として次の方法がある。

/etc/security/limits.confで変更する

ログインの際などに行われるPAM認証時に適用されるので、サーバーの起動時に立ち上がったデーモンには適用されない。

$ cat /etc/pam.d/sshd
...
session    required     pam_limits.so
...

全てのユーザー(*)のプロセスが使えるファイルディスクリプタの、ユーザーが設定できるsoftとrootが設定できるhard limitを共に64000にする。

$ echo "* hard nofile 64000" >> /etc/security/limits.conf
$ echo "* soft nofile 64000" >> /etc/security/limits.conf
$ ulimit -n
64000

ulimit -nで変更する

シェルと、そこから起動したプロセスでのみ有効。

$ ulimit -n 64000

(dockerの場合) run時の–ulimitで変更する

$ docker run -itd --ulimit nofile=11111 ubuntu
$ docker exec -it <id> /bin/bash -c "ulimit -n"
11111

参考

/etc/security/limits.confに関するメモ | OpenGroove

ファイルディスクリプタ数の上限変更とlimits.confの罠

Linuxのファイルディスクリプタ数を変更・確認する方法: 小粋空間

ファイル記述子 - Wikipedia

調べなきゃ寝れない!と調べたら余計に寝れなくなったソケットの話 - Qiita