【インフラエンジニア入門】Linuxのプロセス管理をわかりやすく解説|リソース制限

はじめに

Linuxは多くのサーバやシステムの基盤として使われており、インフラエンジニアにとって欠かせない技術です。その中でも「プロセス管理」は、システムが安定して動作するために重要な知識のひとつですが、Linux OSがどのような方法でプロセスを管理しているのか、詳細に理解できていない方も多いのではないでしょうか。

本記事では、Linuxのプロセス管理におけるリソース制限機能をわかりやすく解説します。ぜひ最後までお読みいただき、日々の業務に役立ててください。

リソース割り当て制限

CPU実行に割り当てるリソース上限や時間を明示的に指定する方法をご紹介します。

ulimitによる一時的な制限

現在ログインしているシェルプロセスにおいて、ulimitコマンドを実行することで、CPU実行に対して一時的な制限を設定することができます。代表的な制限項目およびulimitコマンドのオプション下記となります。

項目名ulimitコマンドのオプション
シェルが書き込み可能なファイルサイズの最大値(ブロック数)-f
利用できる最大のメモリサイズ(KB)-m
同時にオープンできるファイル数-n
プロセスごとに利用できるCPU時間の最大値(秒数)-t
実行可能なユーザプロセス数の最大数-u
シェルが利用可能な仮想メモリの最大サイズ(KB)-v

試しに、プロセスごとに利用できるCPU時間の最大値を指定してみましょう。まず、ulimitの現在の設定値を確認します。cpu timeはunlimitedとなっており、デフォルトでは制限がかかっていない状態です。

root@ubuntu20:~# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 15294
max locked memory       (kbytes, -l) 65536
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 15294
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
root@ubuntu20:~#

「ulimit -t」コマンドでCPUタイムを5秒に設定してみます。「ulimit -a」コマンドで「cpu time」の項目が5になっていることを確認して下さい。

root@ubuntu20:~# ulimit -t 5
root@ubuntu20:~# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 15294
max locked memory       (kbytes, -l) 65536
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) 5
max user processes              (-u) 15294
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
root@ubuntu20:~#

ループ処理を記載したシェルを実行してしばらく経過すると、Killedというメッセージがでてプロセスが終了することが確認できるかと思います。

root@ubuntu20:~# /tmp/loop.sh
Killed
root@ubuntu20:~#

limits.confによる制限

ユーザごと、グループごとに恒久的な制限を設定することができます。シェルログインやPAM(Pluggable Authentication Modules)セッションに適用されます。設定後に再起動は不要で、シェルの再ログインPAM経由のログイン時から適用されます。
※PAMを介さないsystemdやinitスクリプトにて起動されるデーモンサービスには適用されませんのでご留意ください。

limits.confへの記載フォーマットは下記となります。
<ドメイン> <タイプ> <項目> <値>

項目名説明
ドメインユーザー名、グループ名(@group)を指定
タイプ制限の種類
soft: ユーザーが変更可能なソフトリミット
hard: 超えられないハードリミット
項目※主な項目はした表を参照ください。
制限値(数値またはunlimited

主な項目を下表に示します。

項目名説明単位
rssユーザー実行プロセスのメモリサイズKB
memlockロックできるメモリのサイズKB
cpu最大CPU時間
nproc同時実行可能なプロセス数プロセス数
maxlogins同時ログイン数ログインセッション数

それでは実機で試してみましょう。eeengineerユーザに対してCPU時間の上限を設定してみます。事前に「ulimit -m」コマンドで現状の設定を確認すると、デフォルトの無制限(unlimited)となっています。

root@ubuntu20:~# su - eeengineer
eeengineer@ubuntu20:~$ ulimit -t
unlimited
eeengineer@ubuntu20:~$

続いて、rootユーザになって下記の通りlimits.confに設定を追加します。eeengineerユーザに対して、CPU時間の上限を1分で設定しています。

eeengineer@ubuntu20:~$ sudo su -
[sudo] password for eeengineer:
root@ubuntu20:~#
root@ubuntu20:~# vi /etc/security/limits.conf
root@ubuntu20:~# grep eeengineer /etc/security/limits.conf
eeengineer    hard    cpu    1
root@ubuntu20:~#

再びeeengineerユーザにスイッチして確認をすると、CPU時間の上限がumlimitedから60秒に変更されていることが確認できました。

oot@ubuntu20:~# su - eeengineer
eeengineer@ubuntu20:~$ ulimit -t
60
eeengineer@ubuntu20:~$

cgroupsによる制限

cgroupsとはControl Groupsの略で、プロセスをグループ化し、グループごとに各種リソース(CPU、メモリ、I/O、ネットワーク等)を制限することができる機能です。最近のLinuxにおいては、cgroupsとsystemdを組み合わせた管理が推奨されており、デーモンサービスにも適用することが可能です。

試しに、apacheに対してCPU処理に対して制限をかけてみましょう。systemctl showコマンドでデフォルト状態を確認します。CPUQuotaPerSecUSec(1秒当たりのCPU使用時間)がinfinityとなっており制限がかかっていない状態です。

root@ubuntu20:~# systemctl show apache2.service --property=CPUQuotaPerSecUSec
CPUQuotaPerSecUSec=infinity

続いてユニットファイルを編集しCPUて使用率の上限の設定を追加します。ここでは、CPUQuotaという項目に使用率50%を指定して制限をかけています。

root@ubuntu20:~# vi /lib/systemd/system/apache2.service
root@ubuntu20:~# cat /lib/systemd/system/apache2.service
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=https://httpd.apache.org/docs/2.4/
[Service]
Type=forking
Environment=APACHE_STARTED_BY_SYSTEMD=true
ExecStart=/usr/sbin/apachectl start
ExecStop=/usr/sbin/apachectl stop
ExecReload=/usr/sbin/apachectl graceful
PrivateTmp=true
Restart=on-abort
##Add CPU Usage restriction setting
CPUQuota=50%
[Install]
WantedBy=multi-user.target
root@ubuntu20:~#

systemctl daemon-reexecコマンドでsystemdを再起動し、systemctl daemon-reloadコマンドでユニットファイルを再読み込みします。その後、systemctl showで制限値を確認するとCPUQuotaPerSecUSecの上限値が500msに設定されていることが確認できます。

root@ubuntu20:~# systemctl daemon-reexec
root@ubuntu20:~# systemctl daemon-reload
root@ubuntu20:~# systemctl show apache2.service --property=CPUQuotaPerSecUSec
CPUQuotaPerSecUSec=500ms

さいごに

Linuxのプロセス管理についての説明は以上となります。本内容を理解していなくても普段の業務に支障はないかもしれませんが、いざトラブルが起きた時には非常に役立つ知識になります。本記事を通じて理解を深めていただけると幸いです。最後まで読んでいただき、ありがとうございました。

Linuxのプロセス管理に関する他の記事は下記にまとめているので、もっと知りたくなった方はぜひ参考にしてみてください。
【インフラエンジニア入門】Linuxのプロセス管理をわかりやすく解説|プロセス管理概要
【インフラエンジニア入門】Linuxのプロセス管理をわかりやすく解説|スケジューラ機能

また、Linuxの処理概要については下記の記事でまとめてるので、興味ある方はこちらも参照ください。
インフラエンジニア入門|Linuxの歴史・機能概要・特徴をわかりやすく解説

参考文献

[試して理解]Linuxのしくみ | 技術評論社
ITシステムやソフトウェアの基盤OSとして幅広く使われているLinux。エンジニアとしてLinuxに関する知識はいまや必須とも言えますが、あなたはそのしくみや動作を具体的にイメージすることができるでしょうか。本書では、Linux OS にお...
4.2. CPU のスケジューリング | パフォーマンスチューニングガイド | Red Hat Enterprise Linux | 6 | Red Hat Documentation
4.2. CPU のスケジューリング | パフォーマンスチューニングガイド | Red Hat Enterprise Linux | 6 | Red Hat Documentation

コメント