linux cgroupsの概要

5081 ワード

転載先:http://xiezhenye.com/2013/10/linux-cgroups-%E6%A6%82%E8%BF%B0.html
2.6.24バージョンから、linuxカーネルはcgroups(制御グループ)という特性を提供している。cgroupsはcontrol groupsの略語であり、一つのプロセスによって占有される資源を制限、統計、分離するために用いられる。現在のライト級仮想化技術lxcの基礎の一つです。各プロセスは一つのコントロールグループ、つまり一つのcgroupです。cgroupsはいくつかのサブシステムに分けられており、各サブシステムは、1つの施設またはリソースコントローラを表し、cpuクロック、メモリ、ブロックデバイスなどのような、ある種類のリソースの使用をスケジュールする。実装では、cgroupsは、新しいシステム呼び出しを追加することなく、cgroupファイルシステムとして機能し、あるディレクトリに一つ以上のサブシステムをマウントすることができる。如き
mount -t cgroup -o cpu cpu /sys/fs/cgroup/cpu
cpuシステムをマウントしました。/sys/fs/cgroup/cpu。一つのディレクトリに複数のサブシステムをマウントしてもいいです。一つのディレクトリに全部マウントしてもいいです。でも、各サブシステムを別のディレクトリにマウントするのはもっと柔軟性があると思います。使う?遣う  mount|awk '$5=="cgroup" {print $0}' 現在マウントされているコントロールグループが見えます。使う?遣う  cat /proc/cgroups 現在のすべてのコントロールグループの状態が見られます。次のスクリプトは、すべてのサブシステムをそれぞれのディレクトリにマウントすることができます。
#!/bin/bash

cgroot="${1:-/sys/fs/cgroup}"
subsys="${2:-blkio cpu cpuacct cpuset devices freezer memory net_cls net_prio ns perf_event}"

mount -t tmpfs cgroup_root "${cgroot}"
for ss in $subsys; do
  mkdir -p "$cgroot/$ss"
  mount -t cgroup -o "$ss" "$ss" "$cgroot/$ss"
done
これらのカタログを見てください。lsちょっと/sys/fs/cgroup/cpuのようなものがあります。
cgroup.event_control  cpu.cfs_period_us  cpu.rt_period_us   cpu.shares  notify_on_release  tasks
cgroup.procs          cpu.cfs_quota_us   cpu.rt_runtime_us  cpu.stat    release_agent
その中でも「cpu.」というのはこのサブシステムに特有のものです。他のものは各サブシステムに対応するディレクトリにあります。これらのファイルは資源利用情報を読み取り、資源制限を行うものです。コントロールグループを作成するには、必要なサブシステムにディレクトリを作成すればいいです。如き  mkdir /sys/fs/cgroup/cpu/foo コントロールグループを作成しました。新しいディレクトリに同じファイルが表示されます。このディレクトリでも、ディレクトリを作成することでcgroupを作成することができます。つまり、cgroupはディレクトリ構造と同じレベルであることができます。各サブシステムに点々ディレクトリをマウントすると、ルートディレクトリに相当します。各異なる経路は異なるcgroupを表しています。異なるサブシステムでは、同じ経路で同じ制御グループを表しています。例えば、cpu、memoryにはfoo/barディレクトリがあります。cpu、memoryの2つのサブシステムをその/foo/barで操作することができます。同じサブシステムの場合、各プロセスは一つのcgroupに属し、デフォルトはルートcgroupにある。階層構造は制御グループの組織と管理に便利であり、いくつかの構成項目に対して、階層構造はまた資源配分に関連している。また、あるディレクトリのownerを修正して、非rootユーザーにも特定のセキュリティグループを操作させることができます。
cgroupsの設定と情報の読み取りは、それらのファイルの読み書きによって行われる。例えば
# echo 2048 >/sys/fs/cgroup/cpu/foo/cpu.shares
このコントロールグループのcpu.shresパラメータを2048に設定します。
前に述べましたが、一部の書類は各カタログに共有されています。それらは共通の設定です。ここで、taskとcgroups.procsは、制御グループ内のプロセスを管理するために使用される。プロセスをコントロールグループに追加するには、該当するディレクトリのtaskysファイルにpidを書き込むだけでいいです。如き
# echo 5678 >/sys/fs/cgroup/cpu/foo/tasks
5678プロセスをfooコントロールグループに追加しました。taskysとcgroups.procsはどんな違いがありますか?前に述べた「プロセス」の管理制限は正確ではないです。システムのタスクに対するスケジューリングの単位はスレッドです。ここで、taskで見たのはスレッドidです。cgroups.procsではスレッドグループID、つまりプロセスIDというのが一般的です。一般的なpidをtaskysに書き込むと、このpidだけが対応するスレッドと、それによって生成される他のプロセス、スレッドはこのコントロールグループに属し、元の他のスレッドは存在しません。cgroups.procsに書き込んで、現在のスレッドを全部入れます。cgroups.procsに書き込まれているのがスレッド群idではなく、一般的なスレッドIDである場合、対応するスレッド群idが自動的に見つかります。プロセスはコントロールグループに参加すると、コントロールグループに対応する制限が即時に有効になります。プロセスはどのようなコントロールグループに属していますか?  cat /proc//cgroup 表示します
プロセスをコントロールグループから移動するには、pidをルートcgroupのtaskファイルに書き込むだけでいいです。各プロセスが一つのcgroupに属していますので、新しいcgroupに加入したら元の関係も解除されます。cgroupを削除するには、rmdirで該当ディレクトリを削除できます。しかし、削除する前に、プロセスを全部終了させなければなりません。対応するサブシステムのリソースは全部解放されました。そうでなければ、削除できません。
前は全部ファイルシステムのアクセス方式でcgroupsを操作しています。実際には、コマンドラインツールのセットもあります。lssubsys -am 各サブシステムのマウントポイントを確認することができます。また、「cg」の先頭コマンドのセットを管理することができます。cgexecは、特定のサブシステムにおける指定された制御グループに対して直接にプログラムを実行するために使用することができる。如き  cgexec -g "cpu,blkio:/foo" bash 。他のコマンドや具体的なパラメータはマンで確認できます。
次はbash版のcgexecです。cgroupsの使い方を示しています。コマンドラインツールがインストールされているかどうかは不明です。
#!/bin/bash

# usage: 
# ./cgexec.sh cpu:g1,memory:g2/g21 sleep 100

blkio_dir="/sys/fs/cgroup/blkio"
memory_dir="/sys/fs/cgroup/memory"
cpuset_dir="/sys/fs/cgroup/cpuset"
perf_event_dir="/sys/fs/cgroup/perf_event"
freezer_dir="/sys/fs/cgroup/freezer"
net_cls_dir="/sys/fs/cgroup/net_cls"
cpuacct_dir="/sys/fs/cgroup/cpuacct"
cpu_dir="/sys/fs/cgroup/cpu"
hugetlb_dir="/sys/fs/cgroup/hugetlb"
devices_dir="/sys/fs/cgroup/devices"

groups="$1"
shift

IFS=',' g_arr=($groups)
for g in ${g_arr[@]}; do
  IFS=':' g_info=($g)
  if [ ${#g_info[@]} -ne 2 ]; then
    echo "bad arg $g" >&2
    continue
  fi
  g_name=${g_info[0]}
  g_path=${g_info[1]}
  if [ "$g_path" == "${g_path#/}" ]; then
    g_path="/$g_path"
  fi
  echo $g_name $g_path
  var="${g_name}_dir"
  d=${!var}
  if [ -z "$d" ]; then
    echo "bad cg name $g_name" >&2
    continue
  fi
  path="${d}${g_path}"
  if [ ! -d "$path" ]; then
    echo "cg not exists" >&2
    continue
  fi
  echo "$$" >"${path}/tasks"
done

exec $*

cgroupsにはたくさんのものがあります。一枚だけ書くつもりでしたが、いくつかに分けて話したほうが分かりやすいと思います。あとは具体的に使うものも書きます。
参考資料:cgroups docs–ケネル.orgResource Management Gide–redhat.com How I Used CGroups to Manage System Resource–orace.com