「コントロールグループ」の版間の差分

提供: ArchWiki
ナビゲーションに移動 検索に移動
26行目: 26行目:
 
* {{AUR|libcgroup}}、{{AUR|libcgroup-git}} - スタンドアロンツールのセット ({{ic|cgcreate}}、{{ic|cgclassify}}、永続的な設定は {{ic|cgconfig.conf}})。
 
* {{AUR|libcgroup}}、{{AUR|libcgroup-git}} - スタンドアロンツールのセット ({{ic|cgcreate}}、{{ic|cgclassify}}、永続的な設定は {{ic|cgconfig.conf}})。
   
  +
== systemd を使う ==
== Systemd でリソースグループを管理する ==
 
  +
systemd を使って ''cgconfig'' サービスを[[systemd#ユニットを使う|有効にする]]ことができます:
 
  +
=== 階層 ===
# systemctl enable cgconfig.service
 
  +
以下のコマンドを使えば {{ic|cgconfig.conf}} ファイルにエラーがないか簡単に調べることができます:
 
  +
現在の cgroup 階層は {{ic|systemctl status}} コマンドか {{ic|systemd-cgls}} コマンドを使って見ることができます。
$ systemctl status cgconfig.service
 
  +
  +
{{hc|$ systemctl status|<nowiki>
  +
● myarchlinux
  +
State: running
  +
Jobs: 0 queued
  +
Failed: 0 units
  +
Since: Wed 2019-12-04 22:16:28 UTC; 1 day 4h ago
  +
CGroup: /
  +
├─user.slice
  +
│ └─user-1000.slice
  +
│ ├─user@1000.service
  +
│ │ ├─gnome-shell-wayland.service
  +
│ │ │ ├─ 1129 /usr/bin/gnome-shell
  +
│ │ ├─gnome-terminal-server.service
  +
│ │ │ ├─33519 /usr/lib/gnome-terminal-server
  +
│ │ │ ├─37298 fish
  +
│ │ │ └─39239 systemctl status
  +
│ │ ├─init.scope
  +
│ │ │ ├─1066 /usr/lib/systemd/systemd --user
  +
│ │ │ └─1067 (sd-pam)
  +
│ └─session-2.scope
  +
│ ├─1053 gdm-session-worker [pam/gdm-password]
  +
│ ├─1078 /usr/bin/gnome-keyring-daemon --daemonize --login
  +
│ ├─1082 /usr/lib/gdm-wayland-session /usr/bin/gnome-session
  +
│ ├─1086 /usr/lib/gnome-session-binary
  +
│ └─3514 /usr/bin/ssh-agent -D -a /run/user/1000/keyring/.ssh
  +
├─init.scope
  +
│ └─1 /sbin/init
  +
└─system.slice
  +
├─systemd-udevd.service
  +
│ └─285 /usr/lib/systemd/systemd-udevd
  +
├─systemd-journald.service
  +
│ └─272 /usr/lib/systemd/systemd-journald
  +
├─NetworkManager.service
  +
│ └─656 /usr/bin/NetworkManager --no-daemon
  +
├─gdm.service
  +
│ └─668 /usr/bin/gdm
  +
└─systemd-logind.service
  +
└─654 /usr/lib/systemd/systemd-logind
  +
</nowiki>}}
  +
  +
=== プロセスの cgroup を見つける ===
  +
  +
あるプロセスの cgroup 名は、{{ic|/proc/''PID''/cgroup}} で見ることができます。
  +
  +
例えば、現在のシェルの cgroup は:
  +
  +
{{hc|$ cat /proc/self/cgroup|
  +
0::/user.slice/user-1000.slice/session-3.scope
  +
}}
  +
  +
=== cgroup のリソース使用量 ===
  +
  +
{{ic|systemd-cgtop}} コマンドを使用して、cgroup のリソース使用量を見ることができます:
  +
  +
{{hc|$ systemd-cgtop|
  +
Control Group Tasks %CPU Memory Input/s Output/s
  +
user.slice 540 152,8 3.3G - -
  +
user.slice/user-1000.slice 540 152,8 3.3G - -
  +
user.slice/u…000.slice/session-1.scope 425 149,5 3.1G - -
  +
system.slice 37 - 215.6M - -
  +
}}
  +
  +
=== カスタムの cgroup ===
  +
  +
{{man|5|systemd.slice}} systemd ユニットファイルを使うことで、カスタムの cgroup 設定を定義できます。このユニットファイルは、systemd のディレクトリ内 ({{ic|/etc/systemd/system/}} など) に配置しなければなりません。リソースの割り当て可能な管理オプションは、{{man|5|systemd.resource-control}} にてドキュメント化されています。
  +
  +
以下は、1つの CPU の 30% のみの使用を許可する slice ユニットの例です:
  +
  +
{{hc|/etc/systemd/system/my.slice|2=
  +
[Slice]
  +
CPUQuota=30%
  +
}}
   
 
== シンプルな使い方 ==
 
== シンプルな使い方 ==

2022年9月22日 (木) 07:34時点における版

関連記事

コントロールグループ (一般的には cgroup と知られています) とは、プロセスのグループを管理、制限、監査するための、Linux カーネルによって提供されている機能です。cgroup はプロセスの集合 (およびその部分集合) に対して操作することができる (また、異なるシステムユーザを用いることもできる) ので 、nice(1) コマンドや /etc/security/limits.conf のような他のアプローチと比べて、cgroup はより柔軟です。

コントロールグループは様々なツールによってアクセスできます:

  • systemd ユニットファイルでディレクティブを使ってサービスやスライスに対する制限を指定する。
  • cgroup ファイルシステムに直接アクセスする。
  • cgcreatecgexeccgclassify (libcgroupAURlibcgroup-gitAUR の一部です) のようなツールを使う。
  • "Rules Engine Daemon" を使って、特定のユーザ/グループ/コマンドをグループに自動的に移動する (/etc/cgrules.confcgconfig.service) (libcgroupAURlibcgroup-gitAUR の一部です)。
  • Linux Containers (LXC) 仮想化などのような他のソフトウェアを使う。

Arch Linux の場合は、systemd がデフォルトのインストールの一部なので、cgroup を起動・管理する方法として systemd が最も簡単で推奨されます。

インストール

cgroup を自動的に管理するために、以下のパッケージのうち1つをインストールしていることを確認してください:

  • systemd - systemd サービスのリソースを管理するために必要です。
  • libcgroupAURlibcgroup-gitAUR - スタンドアロンツールのセット (cgcreatecgclassify、永続的な設定は cgconfig.conf)。

systemd を使う

階層

現在の cgroup 階層は systemctl status コマンドか systemd-cgls コマンドを使って見ることができます。

$ systemctl status
● myarchlinux
    State: running
     Jobs: 0 queued
   Failed: 0 units
    Since: Wed 2019-12-04 22:16:28 UTC; 1 day 4h ago
   CGroup: /
           ├─user.slice 
           │ └─user-1000.slice 
           │   ├─user@1000.service 
           │   │ ├─gnome-shell-wayland.service 
           │   │ │ ├─ 1129 /usr/bin/gnome-shell
           │   │ ├─gnome-terminal-server.service 
           │   │ │ ├─33519 /usr/lib/gnome-terminal-server
           │   │ │ ├─37298 fish
           │   │ │ └─39239 systemctl status
           │   │ ├─init.scope 
           │   │ │ ├─1066 /usr/lib/systemd/systemd --user
           │   │ │ └─1067 (sd-pam)
           │   └─session-2.scope 
           │     ├─1053 gdm-session-worker [pam/gdm-password]
           │     ├─1078 /usr/bin/gnome-keyring-daemon --daemonize --login
           │     ├─1082 /usr/lib/gdm-wayland-session /usr/bin/gnome-session
           │     ├─1086 /usr/lib/gnome-session-binary
           │     └─3514 /usr/bin/ssh-agent -D -a /run/user/1000/keyring/.ssh
           ├─init.scope 
           │ └─1 /sbin/init
           └─system.slice 
             ├─systemd-udevd.service 
             │ └─285 /usr/lib/systemd/systemd-udevd
             ├─systemd-journald.service 
             │ └─272 /usr/lib/systemd/systemd-journald
             ├─NetworkManager.service 
             │ └─656 /usr/bin/NetworkManager --no-daemon
             ├─gdm.service 
             │ └─668 /usr/bin/gdm
             └─systemd-logind.service 
               └─654 /usr/lib/systemd/systemd-logind

プロセスの cgroup を見つける

あるプロセスの cgroup 名は、/proc/PID/cgroup で見ることができます。

例えば、現在のシェルの cgroup は:

$ cat /proc/self/cgroup
0::/user.slice/user-1000.slice/session-3.scope

cgroup のリソース使用量

systemd-cgtop コマンドを使用して、cgroup のリソース使用量を見ることができます:

$ systemd-cgtop
Control Group                            Tasks   %CPU   Memory  Input/s Output/s
user.slice                                 540  152,8     3.3G        -        -
user.slice/user-1000.slice                 540  152,8     3.3G        -        -
user.slice/u…000.slice/session-1.scope     425  149,5     3.1G        -        -
system.slice                                37      -   215.6M        -        -

カスタムの cgroup

systemd.slice(5) systemd ユニットファイルを使うことで、カスタムの cgroup 設定を定義できます。このユニットファイルは、systemd のディレクトリ内 (/etc/systemd/system/ など) に配置しなければなりません。リソースの割り当て可能な管理オプションは、systemd.resource-control(5) にてドキュメント化されています。

以下は、1つの CPU の 30% のみの使用を許可する slice ユニットの例です:

/etc/systemd/system/my.slice
[Slice]
CPUQuota=30%

シンプルな使い方

手動で使用する

次のセクションで説明している cgm を使う方法の代わりに、このセクションでは手動でメモリ使用量を制限する方法を説明します。

groupname という名前の新しい cgroup を作成:

# mkdir /sys/fs/cgroup/memory/groupname

最大メモリ使用制限を 100MB に設定:

# echo 100000000 > /sys/fs/cgroup/memory/groupname/memory.limit_in_bytes

プロセスを cgroup に移動 (一度に指定できる PID はひとつだけで、複数指定することはできません):

# echo pid > /sys/fs/cgroup/memory/groupname/cgroup.procs

一時的なグループ

cgroups を使って即座に"一時的な"グループを作成することができます。実際に、通常ユーザーにカスタムグループを作成する権限を与えることも可能です。次のコマンドを root で実行してください (user はあなたのユーザー名に、groupname は cgroup に付けたい名前に置き換えてください):

# cgcreate -a user -t user -g memory,cpu:groupname

もしくは cgmanager を使用 (ユーザー ID `1000` とシステムグループ root (GID 0) は適当な値に置き換えてください):

# cgm create memory groupname
# cgm chown memory groupname 1000 0
# cgm create cpu groupname
# cgm chown cpu groupname 1000 0
# chown user /sys/fs/cgroup/{memory,cpu}/groupname/*

ユーザーによってグループ groupname の全ての設定を書き換えることができます:

$ ls -l /sys/fs/cgroup/memory/groupname
total 0
-rwxrwxr-x 1 user root 0 Sep 25 00:39 cgroup.event_control
-rwxrwxr-x 1 user root 0 Sep 25 00:39 cgroup.procs
-rwxrwxr-x 1 user root 0 Sep 25 00:39 cpu.rt_period_us
-rwxrwxr-x 1 user root 0 Sep 25 00:39 cpu.rt_runtime_us
-rwxrwxr-x 1 user root 0 Sep 25 00:39 cpu.shares
-rwxrwxr-x 1 user root 0 Sep 25 00:39 notify_on_release
-rwxrwxr-x 1 user root 0 Sep 25 00:39 tasks

Cgroups は階層式なので、好きなだけサブグループを作成することができます。例えば、通常ユーザーとして、bash シェルを新しいサブグループ 'foo' 下で動作させたい場合:

$ cgcreate -g memory,cpu:groupname/foo
$ cgexec -g memory,cpu:groupname/foo bash

同じことを cgmanager で設定するには:

$ cgm create memory groupname/foo
$ cgm create cpu groupname/foo
$ bash
$ cgm movepid memory groupname/foo $pid_of_bash
$ cgm movepid cpu groupname/foo $pid_of_bash

さあ、確認してみましょう:

$ cat /proc/self/cgroup
11:memory:/groupname/foo
6:cpu:/groupname/foo

このグループの新しいサブディレクトリが作成されています。このグループ内の全てのプロセスのメモリ使用量を 10 MB に制限するには、次を実行します:

$ echo 10000000 > /sys/fs/cgroup/memory/groupname/foo/memory.limit_in_bytes

cgmanager を使用する場合:

$ cgm setvalue memory groupname/foo memory.limit_in_bytes 10000000

メモリ制限は RAM の使用にしか適用されないので注意してください -- タスクが制限に達すると、スワップを始めます。しかしながら他のプロセスのパフォーマンスにはあまり影響を与えません。

同じようにこのグループの CPU 優先度 ("shares") を変更することもできます。デフォルトでは全てのグループは 1024 shares になっています。100 shares のグループは CPU 時間の ~10% だけを使うようになります:

$ echo 100 > /sys/fs/cgroup/cpu/groupname/foo/cpu.shares

cgroup ディレクトリを表示することで他の設定や統計を見ることができます。

また、既に実行中のプロセスの cgroup を変更することも可能です。全ての 'bash' コマンドをこのグループに移動するには:

$ pidof bash
13244 13266
$ cgclassify -g memory,cpu:groupname/foo `pidof bash`
$ cat /proc/13244/cgroup
11:memory:/groupname/foo
6:cpu:/groupname/foo

永続的なグループ設定

ノート: systemd 205 以上を使って cgroups を管理する場合、このファイルは完全に無視することができます。

起動時に cgroup が作成されるようにしたい場合、代わりに /etc/cgconfig.conf でグループを定義することができます。例えば、"groupname" に制限を管理しタスクを追加する $USER のパーミッションとグループ $GROUPusers を定義します。サブグループの "groupname/foo" グループの定義は以下のようになります。

/etc/cgconfig.conf 
group groupname {
  perm {
# who can manage limits
    admin {
      uid = $USER;
      gid = $GROUP;
    }
# who can add tasks to this group
    task {
      uid = $USER;
      gid = $GROUP;
    }
  }
# create this group in cpu and memory controllers
  cpu { }
  memory { }
}

group groupname/foo {
  cpu {
    cpu.shares = 100;
  }
  memory {
    memory.limit_in_bytes = 10000000;
  }
}
ノート:
  • コメントは行の初めに置いて下さい。そうしないと、cgconfigparser が解析するときに問題が発生しますが、cgconfigSystemd で起動しない限り、エラーとしては cgroup change of group failed しか報告されません。
  • permissions セクションは任意です。
  • /sys/fs/cgroup/ ディレクトリ階層には controllers サブディレクトリが全て含まれ、起動時に仮想ファイルシステムとして作成・マウントされます。$CONTROLLER-NAME { } コマンドを使って新しいグループエントリを作成することが可能です。何らかの理由で他の場所に階層を作成・マウントしたいときは、/etc/cgconfig.conf に以下のようにふたつ目のエントリを書く必要があります:
mount {    
   cpuset = /your/path/groupname;
}

これは以下のシェルコマンドと同等です:

# mkdir /your/path/groupname
# mount -t /your/path -o cpuset groupname /your/path/groupname

活用例

Matlab

Matlab にはマシンのメモリや CPU が全て使われるのに対するプロテクトがありません。膨大な計算を始めてしまうとシステムが使えなくなる可能性があります。以下はそれを防止するために /etc/cgconfig.conf に配置するファイルです ($USER はあなたのユーザー名に置き換えてください):

/etc/cgconfig.conf 
# Prevent Matlab from taking all memory
group matlab {
    perm {
        admin {
            uid = $USER;
        }
        task {
            uid = $USER;
        }
    }

    cpuset {
        cpuset.mems="0";
        cpuset.cpus="0-5";
    }
    memory {
# 5 GiB limit
        memory.limit_in_bytes = 5368709120;
    }
}
ノート: $USER を実際に Matlab を動かすユーザーの名前に変えるのを忘れないで下さい。

この cgroup は Matlab が使えるコアをコア0から5までに (Matlab には6つのコアだけが認識されます) そしてメモリの使用量を 5 GiB に制限します。"cpu" リソースの強制を使って CPU 使用量の制限も定義することが可能ですが、"cpuset" で十分だと思われます。

matlab を次のようにして起動します:

$ cgexec -g memory,cpuset:matlab /opt/MATLAB/2012b/bin/matlab -desktop

正しい実行可能ファイルのパスを使って下さい。

ドキュメント

  • コントローラーや特定のスイッチ・オプションに関する情報はカーネルのドキュメント (v1v2) を参照してください (または linux-docs をインストールして /usr/src/linux/Documentation/cgroup を見て下さい)。
  • 詳細かつ完全なリソース管理ガイドが fedora プロジェクトのドキュメント にあります。

コマンドや設定ファイルについては、man cgcreateman cgrules.conf などの該当する man ページを見て下さい。