systemdで管理しているserviceがopenできるfile descriptorの上限数を増やす
systemdのバージョン
# systemd --version systemd 237
TL;DR
Service
にLimitNOFILE
を設定すると良い.他の特定のリソースについての制限もどうようにかけることが可能です.
ドキュメントは man systemd.exec
で参照できます (ウェブ上はこれが正しいリソース? http://man7.org/linux/man-pages/man5/systemd.exec.5.html).
挙動の検証
現状確認
テストのためにfileを開きまくるperlのscript.ついでにprocのlimit (/proc/{PID}/limits
の中身) も出力する:
#!/usr/bin/env perl use strict; use warnings; use feature qw/say/; open my $fh, '<', "/proc/$$/limits"; say do { local $/; <$fh> }; my @fhs; for (my $i = 0; $i <= 2000; $i++) { my $filename = "/tmp/test.${i}"; open my $fh, ">", $filename or die "$filename: $!"; push @fhs, $fh; }
特に何も考えずにsystemdのservice fileを書いてみます.
[Unit] Description=test [Service] Type=oneshot WorkingDirectory=/tmp/test ExecStart=/usr/bin/perl run.pl [Install] WantedBy=multi-user.target
で,実行してみます
Starting test... Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 3841 3841 processes Max open files 1024 1048576 files Max locked memory 16777216 16777216 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 3841 3841 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us /tmp/test.1020: Too many open files at run.pl line 13, <$fh> line 1. test.service: Main process exited, code=exited, status=24/n/a test.service: Failed with result 'exit-code'. Failed to start test.
Too many open files
で死にます.Max open files
は1024のようですね.ulimit -n
で表示される現状のデフォの値っぽい.
LimitNOFILE
を設定してみる
[Unit] Description=test [Service] Type=oneshot WorkingDirectory=/tmp/test ExecStart=/usr/bin/perl run.pl LimitNOFILE=65536 [Install] WantedBy=multi-user.target
LimitNOFILE=65536
をserviceの設定に追加してみます.それでscriptを実行:
Starting test... Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 3841 3841 processes Max open files 65536 65536 files Max locked memory 16777216 16777216 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 3841 3841 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us
Max open files
が65536になってますね.おかげで実行にも失敗しない! 良かった良かった.
Starting test... Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 8388608 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 3841 3841 processes Max open files 10 10 files Max locked memory 16777216 16777216 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 3841 3841 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us /tmp/test.6: Too many open files at run.pl line 13, <$fh> line 1. test.service: Main process exited, code=exited, status=24/n/a test.service: Failed with result 'exit-code'. Failed to start test.
試しにLimitNOFILE=10
にしてみた様子.逆方向にもちゃんと絞れていることがわかります.