cgroup

cgroup はプロセスをグループ化し、そのグループに属するプロセスに対してリソースの制限を行う仕組みです。
cgroup は cgroupfs と呼ばれるファイルシステムを通して操作します。多くは /sys/fs/cgroup にマウントされています。

制限できるリソースのことをサブシステムと呼び、CPU のコア数やメモリ使用量、プロセス数などを制限できます。
サブシステムについては man をご参照ください1

CPU の利用を制限する

無限ループのプロセスを作成し、そのプロセスに対して CPU 利用率を100%にしてみます。
cgroup 管理下にない状態で top で確認すると 100% 利用していることが確認できます。

$ while true; do : ; done &
[1] 16541

$ top

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  16541 ubuntu    20   0   10252   1960      0 R 100.0   0.0   0:18.27 bash

このプロセスを cgroup 管理下に置きます。

$ sudo mkdir /sys/fs/cgroup/cpu/test
$ echo 16541 | sudo tee -a /sys/fs/cgroup/cpu/test/tasks

続いてCPU利用率を50%にするように調整します。すると 50% 前後に落ち着くことが確認できます。

$ echo 50000 | sudo tee -a /sys/fs/cgroup/cpu/test/cpu.cfs_quota_us
50000
$ top
    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  16541 ubuntu    20   0   10252   1960      0 R  49.8   0.0   9:48.24 bash

メモリ使用量を制限する

続いてメモリ使用量も200MBに制限してみます。

$ stress --vm 1 --vm-bytes 500M
stress: info: [17223] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd

$ top
   PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
  17273 root      20   0  515860 291760    208 R 100.0   7.2   0:23.89 stress

プロセスを cgroup 管理下に置きます。

$ sudo mkdir /sys/fs/cgroup/memory/test
$ echo 17272 | sudo tee -a /sys/fs/cgroup/memory/test/tasks
17273

メモリ使用量を 200MB に制限します。

ubuntu@docker:~$ echo 200M | sudo tee -a /sys/fs/cgroup/memory/test/memory.limit_in_bytes
200M

すると stress が OOM Killer によって kill されます。

stress: FAIL: [17272] (415) <-- worker 17273 got signal 9
stress: WARN: [17272] (417) now reaping child worker processes
stress: FAIL: [17272] (451) failed run completed in 55s

$ dmesg
[23834.514678] oom-kill:constraint=CONSTRAINT_MEMCG,nodemask=(null),cpuset=/,mems_allowed=0,oom_memcg=/test,task_memcg=/test,task=stress,pid=17273,uid=0
[23834.514683] Memory cgroup out of memory: Killed process 17273 (stress) total-vm:515860kB, anon-rss:204432kB, file-rss:336kB, shmem-rss:0kB, UID:0 pgtables:444kB oom_score_adj:0
[23834.519784] oom_reaper: reaped process 17273 (stress), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

docker で cgroup を使う

docker では run サブコマンドに対して -c フラグや -m フラグを指定することで制限できます。詳しくは docker run --help で確認してください。

$ docker run --rm -it -m 100m --memory-swappiness=0 ubuntu:20.04 bash
root@36570f483e85:/# stress --vm 2 --vm-bytes 100M
stress: info: [255] dispatching hogs: 0 cpu, 0 io, 2 vm, 0 hdd
stress: FAIL: [255] (415) <-- worker 257 got signal 9
stress: WARN: [255] (417) now reaping child worker processes
stress: FAIL: [255] (415) <-- worker 256 got signal 9
stress: WARN: [255] (417) now reaping child worker processes
stress: FAIL: [255] (451) failed run completed in 0s

$ dmesg
[24555.596613] Memory cgroup out of memory: Killed process 17691 (stress) total-vm:106260kB, anon-rss:45456kB, file-rss:320kB, shmem-rss:0kB, UID:0 pgtables:136kB oom_score_adj:0
[24555.596719] oom_reaper: reaped process 17692 (stress), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
[24555.600384] oom_reaper: reaped process 17691 (stress), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

$ cat /sys/fs/cgroup/memory/docker/36570f483e8510887b7be178fba3830f1088aa694131c89a18043ef3db220658/memory.limit_in_bytes
104857600

1. https://man7.org/linux/man-pages/man7/cgroups.7.html

results matching ""

    No results matching ""