LoginSignup
34

More than 5 years have passed since last update.

docker上のCPU負荷を計測する方法

Last updated at Posted at 2014-06-30

概要

dockerで動かしているサーバのCPU負荷を計測しようとして、「docker上のサーバからtopとかで見れるんでしょ?」って思ってたら実はそれで取得できるのはホストサーバの負荷だったということでじゃあどないすんねんっていうお話

方法

コンテナごとにcpuやらメモリやらのメトリクスがファイルに出力されているのでその情報をもとにしてCPU負荷を算出する。

cpu使用時間 (動作確認環境では100ミリ秒というよくわからない単位に・・)
$ cat /pathto/cgroup/lxc/$container/cpuacct.stat
user 163
system 137

サーバ稼働時間(ナノ秒)
$ cat /pathto/cgroup/lxc/$container/cpuacct.usage
10130485311

これらそれぞれの差分を割り算することで単位時間あたりのCPU負荷を計算する。
($cur_user_cpu - $prev_user_cpu) / ($cur_time - $prev_time)
シェルでやると以下のようになった。
ただし、LXC_CPU_DIRの部分は環境によって違うかもしれないのでそこは適宜変えてもらいたいです。

cpu.sh
#!/bin/sh

# usage: cpu.sh [-d] [container]
#
# cpu使用率を出力.
#

LXC_CPU_DIR=/cgroup/cpu/cpuacct/lxc
USAGE="usage: cpu.sh [-d] [container]"

cpu(){
  container=$1
  dir=$LXC_CPU_DIR/$container
  cpu_file=$dir/cpuacct.stat
  time_file=$dir/cpuacct.usage
  if [ ! -e $cpu_file -o ! -e $time_file ]; then
    return 1
  fi

  #経過時間の差分を計算
  cur_time=`cat $time_file` 
  egrep [0-9]+ /tmp/$container.usage > /dev/null 
  if [ $? -eq 0 ]; then
    prev_time=`cat /tmp/$container.usage` > /dev/null 
  else
    prev_time=0
  fi 
  diff_time=`expr $cur_time - $prev_time | xargs -i echo "scale=5;{} / 1000 / 1000 / 1000" | bc`

  #CPU使用時間の差分を計算
  user_cpu=`grep user $cpu_file`
  cur_cpu_time=`echo $user_cpu | cut -d " " -f 2`
  egrep [0-9]+ /tmp/$container.stat > /dev/null 
  if [ $? -eq 0 ]; then
    prev_cpu_time=`cat /tmp/$container.stat` > /dev/null
  else
    prev_cpu_time=0
  fi 
  diff_cpu_time=`expr $cur_cpu_time - $prev_cpu_time | xargs -i echo "scale=5; {} / 100" | bc`
  if [ -n "$DEBUG_FLG" ]; then
    echo $container
  fi
  res_cpu=`echo "scale=5; $diff_cpu_time / $diff_time * 100" | bc`
  echo $res_cpu
  #現在経過時間の格納
  echo $cur_time > /tmp/$container.usage
  echo $cur_cpu_time > /tmp/$container.stat
}

all(){
for dir in `find $LXC_CPU_DIR/* -type d`; do
  container=`basename $dir`
  cpu $container
done
}

while getopts d opt
do
  case ${opt} in
    d)
      DEBUG_FLG=1
      ;;
    \?)
      echo $USAGE
      exit 1
      ;;
  esac
done

shift $((OPTIND - 1))

if [ $# -eq 0 ]; then
  all
  exit 0
fi

if [ $# -eq 1 ];then
  container=$1
  cpu $container
  if [ $? -eq 1 ]; then
    exit 1;
  fi
  exit 0
else
  echo $USAGE 
  exit 1
fi

動かすとこんな感じ

$ sh ~/autoscaling/cpu.sh -d
f57a5e6c6d827362d458b712a1fc66cb75f273a84a4436edeabc978ba70a797b
0
# docker上のサーバでyesコマンド打ってちょっと負荷を挙げてみた
$ sh ~/autoscaling/cpu.sh -d
f57a5e6c6d827362d458b712a1fc66cb75f273a84a4436edeabc978ba70a797b
20.25800

たまに0になったりありえないくらい大きな数字になったりするけど概ね合ってそう。
watchすると楽しい。

[追記]
メモリに関しても同じ要領でできるのかな?とか言ってたけどメモリの場合は/pathto/cgroup/memory/lxc/${container}/memory.usage_in_bytesを見ればいいだけだった。楽だね。

まとめ

docker上のサーバのcpu負荷を計測する方法とそのためのスクリプトを載せてみた。試してないけどメモリも同じ要領でできるのかな?
10ストックいったらやってみる。

参考

http://wtatsuru.hatenadiary.com/entry/2013/12/23/190644
https://access.redhat.com/site/documentation/ja-JP/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/sec-cpuacct.html

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34