⚠️ 記事内に広告を含みます。

cgroupでリソース制御を行う

cgroupでリソース制御方法

cgroupはプロセスのリソースを割り当てられるカーネルの機能

cgroup(コントロールグループ)はカーネルの機能の一つです。

グループ化したプロセスのリソース(CPUやメモリ)を制御できます。

あるプロセスがCPUやメモリを使い果たさないように、CPUのコアを割り当てられます。

プロセスのCPUリソースの制御方法としては

  • nice値の変更 (-20 > 19) 優先順位を変更 (cpu使用率は相対的に変化する)
  • ulimit (systemdではユニット定義ファイルで変更)
  • cpulimit 指定CPU使用率に制限 (指定使用率になるようにプロセスを開始停止する)
  • cgroups

があります。

niceやcpulimitは手軽に設定できますが、複数プロセスの設定やサービス単位で停止・起動した時の制御には最近のLinuxではsystemdで制御がよさそうです。

systemdのユニットファイルでリソース制御する

cgroupの設定はlibcgrouop (cgconfig, cgcreate, cgset)や/etc/cgconfig.confを設定する方法がありますが、libcgroupはRHEL7で非推奨で今後削除予定なので利用しない方が良いさそうです。

systemd実行環境下ではsystemctlコマンドかsystemdユニットファイルを変更してcgroupを制御できます。

systemdのユニットファイルのうちcgroupの制御に関するものはサービス、スコープ、スライスです。

  • service
    • ユニットファイルで定義した1〜数個のプロセスのグループをサービスとして起動・停止できます。
  • scope
    • コンテナや仮想マシンなどのプロセスのグループ
  • slice
    • サービスやスライスが階層構造になったユニットのグループ

実際にcgroupの階層を見る
systemdをトップとして階層になっており、user.sliceとsystem.sliceがあるのが確認できる。
userスライスはsshなどユーザのセッションに関するもので、systemスライスはapacheやcronといったシステムのサービスが属しています。

# systemd-cgls 
├─1 /usr/lib/systemd/systemd --system --deserialize 17
├─user.slice
│ └─user-1001.slice
│   ├─session-48361.scope
│   │ ├─ 1350 systemd-cgls
│   │ ├─ 1351 less
│   │ ├─29547 sshd: sshuser [priv]  
│   │ ├─29550 sshd: sshuser@pts/0   
│   │ ├─29552 -bash
│   │ ├─29585 sudo su -
│   ├─session-21761.scope
│   │ ├─10254 tmux
│   │ ├─10255 -bash
│   │ └─10295 -bash
│   └─session-4800.scope
│     └─2546 /usr/bin/python2 -Es /sbin/firewalld
└─system.slice
  ├─snapd.service
  │ └─30214 /usr/libexec/snapd/snapd
  ├─httpd.service
  │ ├─ 1338 /usr/sbin/rotatelogs /var/log/httpd/example.com/access_log_8085.%Y%m%d 86400 540
  │ ├─ 3753 /usr/sbin/httpd -DFOREGROUND
  ├─crond.service
  │ └─3204 /usr/sbin/crond -n
  ├─sshd.service
  │ └─1027 /usr/sbin/sshd -D
  ├─NetworkManager.service
  │ ├─575 /usr/sbin/NetworkManager --no-daemon
  │ └─701 /sbin/dhclient -d -q -sf /usr/libexec/nm-dhcp-helper -pf /var/run/dhclient-eth0.pid -lf /var/lib/NetworkManager/dhclient-3134daea-6
  ├─dbus.service

### systemctl statusでも可能
# systemctl status
● vm-machine
    State: degraded
     Jobs: 0 queued
   Failed: 2 units
    Since: Sun 2022-01-16 13:38:10 JST; 9 months 11 days ago
   CGroup: /
           ├─1 /usr/lib/systemd/systemd --system --deserialize 17
           ├─user.slice
           │ └─user-1001.slice
           │   ├─session-48361.scope
           │   │ ├─ 1809 systemctl status
           │   │ ├─ 1810 less

スライスの中にサービスやスコープがあります
プロセス側から確認するには/proc/以下のプロセスIDの場所のcgroupを見ればわかります。

# cat /proc/30214/cgroup 
11:blkio:/system.slice/snapd.service
10:pids:/system.slice/snapd.service
9:net_prio,net_cls:/
8:freezer:/
7:perf_event:/
6:devices:/system.slice/snapd.service
5:hugetlb:/
4:cpuacct,cpu:/system.slice/snapd.service
3:cpuset:/
2:memory:/system.slice/snapd.service
1:name=systemd:/system.slice/snapd.service

systemctl status で指定もできる

# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2022-09-01 20:08:20 JST; 1 months 26 days ago
     Docs: man:httpd(8)
           man:apachectl(8)
  Process: 3737 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=0/SUCCESS)
 Main PID: 4363 (httpd)
   Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"
    Tasks: 33
   Memory: 74.4M
   CGroup: /system.slice/httpd.service
           ├─ 3468 /usr/sbin/rotatelogs /var/log/httpd/example.com/access_log_8085.%Y%m%d 86400 540
           ├─ 3743 /usr/sbin/rotatelogs 
           ├─ 3753 /usr/sbin/httpd -DFOREGROUND

cgroupで制御できるリソース

  • blkio. ブロックデバイスのIO制限
  • cpu.
  • cpuacct.
  • cpuset
  • devices
  • freezer
  • memory
  • net_cls
  • pref_event
  • HugeTLB

設定方法

一時的な変更はsystemd-runコマンド、永続的な変更にはsystemdユニットファイルを変更します。

  • systemd-run
  • /etc/systemd/system/

systemd-runコマンド

# systems-run --unit=httpd --scope --slice=system.sclice

ユニットファイルで制限

例えばapacheは/usr/lib/systemd/system/httpd.serviceにユニットファイルがあるがこちらは編集せずに/etc/systemd/system/httpd/service.d/cpu.confを作成して適用させる。
(/user/lib/systemd/以下の直接編集は推奨されない)

以下の方法は/etc/systemd/system/{ユニット名}.d/*,confを作成して設定を追加する方法です。(/usr/lib/systemdよりも/etc/systemd/が優先されるのでこちらに同名のユニットファイルを作成して全上書きも可能)

# vim /etc/systemd/system/httpd.service.d/cpu.conf

[Service]
CPUQuota=20%
MemoryLimit=1G

# systemctl deamon-reload
# systemctl restart httpd

参考

  1. https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/resource_management_guide
  2. https://wiki.archlinux.jp/index.php/Cgroups#libcgroup_.E3.82.92.E4.BD.BF.E3.81.86
  3. https://www.belbel.or.jp/opensuse-manuals_ja/cha-tuning-cgroups.html
  4. https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/resource_management_guide/sec-modifying_control_groups#sec-Modifying_Unit_Files

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です