4.3. CPU およびメモリーリソースのグループ別配分

多数のユーザーが単一のシステムを使用する場合、特定のユーザーにより多くのリソースを提供すると役立ちます。次の例を検討してください: ある会社で、finance (財務)、sales (営業)、engineering (エンジニアリング) の 3 つの部署があるとします 。エンジニアは、他の部署よりもシステムとそのリソースを多く使用するので、全部署で CPU とメモリーを集中的に使用するタスクを実行する場合に、エンジニアにより多くのリソースを提供するのが当然です。
cgroups は、システムユーザーグループ別にリソースを制限する手段を提供します。この例では、システム上で以下のユーザーを作成済みであることを前提とします。
~]$ grep home /etc/passwd
martin:x:500:500::/home/martin:/bin/bash
john:x:501:501::/home/john:/bin/bash
mark:x:502:502::/home/mark:/bin/bash
peter:x:503:503::/home/peter:/bin/bash
jenn:x:504:504::/home/jenn:/bin/bash
mike:x:505:505::/home/mike:/bin/bash
これらのユーザーは、次のシステムグループに割り当てられています。
~]$ grep -e "50[678]" /etc/group
finance:x:506:jenn,john
sales:x:507:mark,martin
engineering:x:508:peter,mike
この例が適切に機能するには、libcgroup パッケージがインストール済みである必要があります。/etc/cgconfig.conf および /etc/cgrules.conf のファイルを使用して階層を作成し、各ユーザー用のリソースの量を決定するルールを設定することができます。この設定は、手順4.3「グループ別の CPU およびメモリーリソースの管理」 に記載した手順にしたがって行ってください。

手順4.3 グループ別の CPU およびメモリーリソースの管理

  1. /etc/cgconfig.conf ファイルで、以下のようなサブシステムをマウントして、cgroup を作成するように設定します。
    mount {
        cpu     = /cgroup/cpu_and_mem;
        cpuacct = /cgroup/cpu_and_mem;
        memory  = /cgroup/cpu_and_mem;
    }
    
    group finance {
            cpu {
                    cpu.shares="250";
            }
            cpuacct {
                    cpuacct.usage="0";
            }
            memory {
                    memory.limit_in_bytes="2G";
                    memory.memsw.limit_in_bytes="3G";
            }
    }
    
    group sales {
            cpu {
                    cpu.shares="250";
            }
            cpuacct {
                    cpuacct.usage="0";
            }
            memory {
                    memory.limit_in_bytes="4G";
                    memory.memsw.limit_in_bytes="6G";
            }
    }
    
    group engineering {
            cpu {
                    cpu.shares="500";
            }
            cpuacct {
                    cpuacct.usage="0";
            }
            memory {
                    memory.limit_in_bytes="8G";
                    memory.memsw.limit_in_bytes="16G";
            }
    }
    
    上記の設定ファイルが読み込まれると、cpucpuacct、および memory のサブシステムが単一の cpu_and_mem cgroup にマウントされます。これらのサブシステムについての詳しい情報は、3章サブシステムと調整可能なパラメーター を参照してください。次に cpu_and_mem に階層が作成されます。これには、sales、finance、engineering の 3 つの cgroup が含まれます。これらの cgroup にはそれぞれ、各サブシステムに対するカスタムパラメーターが設定されます。
    • cpucpu.shares パラメーターは、全 cgroup 内の各プロセスに提供する CPU リソースの配分を決定します。このパラメーターを finance cgroup に 250、sales cgroup に 250、engineering cgroup に 500 と設定すると、これらのグループで起動されたプロセスはリソースを 1:1:2 の割合で分割することになります。実行されているプロセスが 1 つの場合、そのプロセスはどの cgroup に配置されているかに関わらず、 必要なだけ CPU を消費する点に注意してください。CPU の制限は、複数のプロセスが CPU リソースを競い合う場合のみに有効となります。
    • cpuacctcpuacct.usage="0" パラメーターは、cpuacct.usage および cpuacct.usage_percpu のファイルに保存されている値をリセットするのに使用します。これらのファイルは、1 つの cgroup 内の全プロセスが消費する CPU 時間の合計 (ナノ秒単位) をレポートします。
    • memorymemory.limit_in_bytes パラメーターは、特定の cgroup 内の全プロセスに提供されるメモリーの容量を示します。以下の例は、finance cgroup で起動したプロセスに 2 GB のメモリー、sales cgroup には 4 GB のメモリー、engineering cgroup には 8 GB のメモリーが割り当てられます。memory.memsw.limit_in_bytes パラメーターは、スワップ領域のプロセスが使用できるメモリー容量の合計を指定します。finance cgroup 内のプロセスが 2 GB のメモリー上限に達すると、追加で 1 GB のスワップ領域を使用することができるので、合計で 3GB が設定されることになります。
  2. 特定の cgroup にプロセスを移動するために cgrulesengd デーモンが使用するルールを定義するには、/etc/cgrules.conf を以下のように設定します。
    #<user/group>         <controller(s)>         <cgroup>
    @finance              cpu,cpuacct,memory      finance
    @sales                cpu,cpuacct,memory      sales
    @engineering          cpu,cpuacct,memory      engineering
    
    上記の設定により、特定のシステムグループ (例: @finance) に使用可能なリソースコントローラー (例: cpucpuacctmemory) とそのシステムグループから起動される全プロセスを格納する cgroup (例: finance) を割り当てるルールを作成します。
    この例では、service cgred start コマンドによって起動された cgrulesengd デーモンが、finance システムグループに属するユーザー (例: jenn) によって起動されたプロセスを検出すると、そのプロセスは自動的に /cgroup/cpu_and_mem/finance/tasks ファイルに移動し、finance cgroup で設定されているリソース制限の対象となります。
  3. cgconfig サービスを起動し、cgroup の階層を作成して、作成した全 cgroup 内で必要なパラメーターを設定します。
    ~]# service cgconfig start
    Starting cgconfig service:                                 [  OK  ]
    
    cgred サービスを起動して、/etc/cgrules.conf ファイルで設定されたシステムグループ内で起動されたプロセスを cgrulesengd デーモンに検出させます。
    ~]# service cgred start
    Starting CGroup Rules Engine Daemon:                       [  OK  ]
    
    cgred とは、cgrulesengd デーモンを起動するサービスの名前である点に注意してください。
  4. リブート後にも変更をすべて保持するには、cgconfig および cgred のサービスがデフォルトで起動するように設定します。
    ~]# chkconfig cgconfig on
    ~]# chkconfig cgred on
この設定が機能するかどうかをテストするには、CPU またはメモリーを集中的に使用するプロセスを実行して、結果を観察します。たとえば、top ユーティリティを使用します。CPU リソース管理をテストするには、各ユーザー下で以下の dd コマンドを実行します。
~]$ dd if=/dev/zero of=/dev/null bs=1024k
上記のコマンドは /dev/zero を読み取り、その内容を 1024 KB 単位で /dev/null に出力します。top ユーティリティが起動すると、以下のような結果を確認することができます。
 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
8201 peter     20   0  103m 1676  556 R 24.9  0.2   0:04.18 dd
8202 mike      20   0  103m 1672  556 R 24.9  0.2   0:03.47 dd
8199 jenn      20   0  103m 1676  556 R 12.6  0.2   0:02.87 dd
8200 john      20   0  103m 1676  556 R 12.6  0.2   0:02.20 dd
8197 martin    20   0  103m 1672  556 R 12.6  0.2   0:05.56 dd
8198 mark      20   0  103m 1672  556 R 12.3  0.2   0:04.28 dd
⋮
全プロセスが cgroup に正しく割り当てられ、提供された CPU リソースのみを表示することができるようになります。finance と engineering の cgroup に属する 2 つのプロセス以外がすべて停止された場合、残りのリソースは両プロセス間で均等に分割されます。
 PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
8202 mike      20   0  103m 1676  556 R 66.4  0.2   0:06.35 dd
8200 john      20   0  103m 1672  556 R 33.2  0.2   0:05.08 dd
⋮

その他の方法

cgrulesengd デーモンは、 /etc/cgrules.conf に設定された該当する条件が満たされた後でしかプロセスを cgroup に移動しないので、そのプロセスが誤った cgroup で数ミリ秒間実行される場合があります。指定の cgroup にプロセスを移動する別の方法として、pam_cgroup.so PAM モジュールを使用する方法があります。このモジュールは、/etc/cgrules.conf ファイルで定義されているルールにしたがって使用可能な cgroup にプロセスを移動します。手順4.4「PAM モジュールを使用した、cgroup へのプロセス移行」 に記載した手順にしたがって pam_cgroup.so PAM モジュールを設定してください。

手順4.4 PAM モジュールを使用した、cgroup へのプロセス移行

  1. オプションの Red Hat Enterprise Linux Yum リポジトリから libcgroup-pam パッケージをインストールします。
    ~]# yum install libcgroup-pam --enablerepo=rhel-6-server-optional-rpms
  2. PAM モジュールがインストール済みで、存在していることを確認します。
    ~]# ls /lib64/security/pam_cgroup.so
    /lib64/security/pam_cgroup.so
    
    32 ビットのシステムでは、モジュールは /lib/security ディレクトリに配置される点に注意してください。
  3. /etc/pam.d/su ファイルに以下の行を追記して、su コマンドが事項されるたびに pam_cgroup.so モジュールを使用するようにします。
    session         optional        pam_cgroup.so
    
  4. 手順4.4「PAM モジュールを使用した、cgroup へのプロセス移行」 に示したように、/etc/cgconfig.conf および /etc/cgrules.conf のファイルを設定します。
  5. /etc/cgrules.conf ファイルの cgroup 設定の影響を受けるユーザーをすべてログアウトし、上記の設定を適用します。
pam_cgroup.so PAM モジュールを使用する際には、cgred サービスを無効にすることができます。