ども、 cloudpackかっぱ (@inokara) です。

はじめに

cgroup を使って CPU リソース制限を試してみたいと思います。また、せっかくなので Datadog を使って CPU リソースがどのように変化するかを見ながら試してみたいと思います。

尚、自分は cgroup を実務を含め意識して利用したことはありません。LXC は利用することがありますので気付かないうちに利用していた程度の cgroup レベルとなります。

参考

以下を読んで cgroup とは何ぞやを学びます。

CPU のリソース制限

cgconfig を利用した CPU のリソース制限

こちらを参考にさせて頂いて CPU のリソース制限を掛けてみます。

以下のように cgconfig が利用出来るように libcgroup をインストールします。

sudo yum install libcgroup

尚、今回、検証に利用したインスタンスは t2.micro インスタンスになりますが…

# cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 62
model name      : Intel(R) Xeon(R) CPU E5-2670 v2 @ 2.50GHz
stepping        : 4
microcode       : 0x415
cpu MHz         : 2494.028
cache size      : 25600 KB
physical id     : 0
siblings        : 1
core id         : 0
cpu cores       : 1
apicid          : 0
initial apicid  : 0
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm xsaveopt fsgsbase smep erms
bogomips        : 4988.05
clflush size    : 64
cache_alignment : 64
address sizes   : 46 bits physical, 48 bits virtual
power management:

上記のように CPU の model name こそジーク・ジオンですが OS から見える CPU コア数は 1 個となります。

yes

まずは yes コマンドを実行してひたすら CPU に負荷をかけます。

yes

別の端末を開いて top を実行すると以下のように順調に yes の CPU 使用率が高いのが解ります。
cgroup による CPU リソース制限:  yes の CPU 使用率が高いのが解る
しばらく放置していると、以下のように stolen が発生しています。
cgroup による CPU リソース制限:  しばらく後に stolen が発生

この stolen(steel) は仮想マシンにおいてホストマシンから CPU リソースを割り当ててもらえなかった時間の割合を表しています。つまり、仮想マシンとしてホストマシンから性能を制限されている状態が続いてしまっていることを表しています…orz。

cgconfig でリソース制限

では、先ほどインストールした cgconfig を設定して yes コマンドが利用出来る CPU リソースに制限をかけてみたいと思いますので、/etc/cgconfig.conf に以下を設定します。

group yes {
 cpu {
   cpu.cfs_quota_us = 250000;
   cpu.cfs_period_us = 1000000;
 }
 cpuacct {
 }
}

上記のようにリソース制限の対象となるアプリケーション名(今回は yes)を group に定義して(追記:アプリケーション名はあくまでも目印みたいなものなので必ずしもアプリケーション名と同じにする必要はありません)各リソースに関する制限の定義を行うようです。それぞれのパラメータはこちらを転載させて頂き、下記の通りです。

cpu.cfs_period_us は…

cgroup による CPU リソースへのアクセスを再割り当てする一定間隔をマイクロ秒単位 (µs、ただしここでは “us” と表示) で指定します。

cpu.cfs_quota_us は…

cgroup 内の全タスクが (cpu.cfs_period_us で定義された) 一定の期間に実行される合計時間をマイクロ秒単位 (µs、ただしここでは “us” と表示) で指定します。

1000000 マイクロ秒内に 250000 マイクロ秒だけ CPU を利用するという風に読み取れば良いのでしょうか…。とりあえず、上記のように設定をした上で cgconfig を起動します。

sudo /etc/init.d/cgconfig restart

そして、改めて yesを以下のように起動します。起動際に /etc/cgconfig.conf で指定したグループ名(yes)を指定して起動します。(これ重要です)

sudo cgexec -g cpu:yes yes

しばらくして datadog のメトリクスを見ると…
cgroup による CPU リソース制限:  Datadog のメトリクスを確認

おお、stolen も減少して idle の割合が大きくなっているのが解ります。リソース制限の効果がありました。

どのくらい制限をかけるべき?

cpu.cfs_quota_us300000 マイクロ秒に変更した場合には以下のようになりました。
cgroup による CPU リソース制限:  cpu.cfs_quota_us を 300000 マイクロ秒に制限した場合

おお、ちょっと CPU の使用率が上がりましたし、stolen も同様に増えています。

では、100000 マイクロ秒にしたら…以下のようになりました。
cgroup による CPU リソース制限:  cpu.cfs_quota_us を 100000 マイクロ秒に制限した場合

おお、CPU の使用率は下がりました…がっ…

今回はひたすら yes なので処理速度等を測定することは出来ませんでしたが、CPU の使用率が下がって処理速度も極端に下がってしまっては意味はありませんので、このあたりの加減は実際にリソースの制限をかけるアプリケーションの性能要件に見合うかどうかは微調整する必要があると思います。また、 CPU 使用率だけに目を奪われてしまっていますが、負荷を語るならばロードアベレージ等、ホストの各種リソースを多角的に判断して判断するべきだと思います。

今日の知見

以下のような知見を得ました。

  • cgroup により CPU 使用率の制限を cgconfig を利用して設定しました
  • CPU 使用率の制限は cpu.cfs_period_uscpu.cfs_quota_us を利用して cpu.cfs_period_us 内で cpu.cfs_quota_us だけ利用するという設定を行う(日本語下手過ぎ)
  • 制限のかけすぎに注意(実際の適用にはリソースの変化だけではなくアプリケーションのパフォーマンスについても確認する)
  • CPU 使用率を下げられたからって安心しない(使用率を下げた分だけしわ寄せがどこかにあるので CPU 使用率のみを見るのではなく vmstat 等で多角的監視すること)

元記事はこちらです。
可視化して解る cgroup による CPU リソース制限