コンテナにおけるパフォーマンス調
査でハマった話
TDCソフト株式会社
島田雄太
- Container’s monitoring is hard way -
発表者について
名前: 島田 雄太 (@yuta1979)
所属:TDCソフト株式会社 ITアーキテクト
最近の業務経歴:AWS構築支援、顧客業務システムのCI/CD環境構築・運用
資格:PMP、AWSソリューションアーキテクト アソシエイト
好きなAWSサービス:Route53・CLI
最近の楽しみ:子供と過ごす時間
2
本日の発表について
- コンテナのメトリクス収集に苦労した話
以下は触れません
- Saas型のモニタリングサービスについて(ex Datadog,Mackerel)
- デプロイ周りの話
- コンテナ入門について(特徴のみ説明)
3
コンテナの特徴
- コンテナはホストOS上の独立したアプリケーションの実行環
境
- コンテナランタイムによって作成された、ホスト
OSのリソース
を隔離・制限したプロセス
- コンテナをイメージ化することで、開発、ステージ、本番環境
での差異を解消(設定値は環境変数で割当可能
)
4
コンテナを導入している現場で
実際にあった話
5
背景:STG環境で負荷試験を実施
コンテナ上でリソースの見え方ってそもそもどうなっているんだっけ??
- 複数のコンテナ(実際にはk8sのpod)にアプリケーションをデプロイ
- リリース前に負荷試験を行ったら、メモリの張り付きが発生した
6
Step1:とりあえず調べてみた
7
簡単に調べるなら?
オンプレ時代から使っているLinuxのコマンドを利用
- メモリ: free コマンドで使用量を確認
- CPU:psコマンドでプロセスで利用しているCPU利用率を確認
<環境について>
AWS: t2.medium (2vCPU / 4GiB Memory)
OS: Amazon Linux 2
→左図のような構成を用意
 コンテナA  コンテナB
EC2インスタンス
CentOS
7-1
CentOS
7-2
8
2台のコンテナを起動
コンテナの起動コマンド (docker run --name “コンテナ名” -it -d イメージ名)
2台のコンテナが起動していることを確認 (docker ps -a)
9
メモリ調査(free)
ホスト
コンテナ
ホストと同じ値
ここの値は正確か?
10
メモリ調査(free)
コンテナ上でfreeコマンドを使った考察
- freeコマンドは、ホストの/proc/meminfoの値を見ている可能性が高い
- ホストのメモリと同値のため、実際にコンテナで利用可能な値を示していない可
能性が高い
ホストの割り当てメモリ
11
CPU調査(ps)
stressコマンドを使って1つのコンテナで負荷をかけた後、psコマンドで確認
CPUの値が上昇
別のコンテナに影響なし
# stress -c 1 -q &
12
CPU調査(ps)
コンテナ上でpsコマンドを使った考察
コンテナはそれぞれ名前空間(PID)を分けて起動していることから、psコマンド
を利用することでコンテナ毎のCPU使用率を取得することが出来た
名前空間:実行中のプロセスに対する隔離を提供し、システムリソースに対する
アクセスを制限する
13
Step2:コンテナのメトリクスについて
深掘りする
14
コンテナのメトリクスについて
コンテナはアクセス可能なシステムのリソース(CPUやメモリなど)を厳密に制限
するために、Linuxカーネルの機能であるcgroupを利用する
cgroup:タスクをグループ化したり、グループ内のタスクに様々なリソース制御
を行う仕組み。先程の名前空間はホスト名やPIDなどのリソースを制御する。
cgroupはCPUやメモリなどの物理的なリソースを制御する。
15
リソースの制御について
実際に起動するコンテナのメモリ上限値を100Mしてみる
cgroupの“memory.limits_in_bytes”で100MBと表示される
ホストからdocker statsコマンドでもLIMITの設定が有効であることを確認
kaka
16
負荷をかけてみる
再度stressコマンドで64MBの負荷をかけ、psコマンドで確認する
RSS(物理メモリ)合計値:2,784+3,020+856+66,176+3,460=76,296KB≒74.5MB
ホストからdocker stats コマンドのMEM USAGEを確認する 66.72MiB 
メモリに関する値が上昇
# stress -m 1 --vm-bytes 64M --vm-hang 0 &
17
負荷をかけてみる
厳密にイコールにならないと推測するが、差分がそれなりにある??
cgroupの”memory.usage_in_bytes”の値も確認する
memory.usage_in_bytesの値:77,041,664byte≒73.47MB
18
公式ドキュメントを確認する
Linuxでは、Docker CLIは合計メモリ使用量からページキャッシュ使用量を差し引いてメモリ使用量を報告します。
APIはこのような
計算を実行せず、クライアントが必要に応じてデータを使用できるように、合計メモリ使用量とページキャッシュからの量を提供しま
す。
https://docs.docker.com/engine/reference/commandline/stats/
Linuxでは、Docker CLIは合計メモリ使用量からページキャッシュ使用量を差し引いてメモリ使用量を
報告します。APIはこのような計算を実行せず、クライアントが必要に応じてデータを使用できるように、
合計メモリ使用量とページキャッシュからの量を提供します。
https://docs.docker.com/engine/reference/commandline/stats/
→docker statsコマンドではページキャッシュが含まれていない
usage_in_bytes:他のカーネルコンポーネントと同様に、メモリcgroupは、最適化を使用して不
要なキャッシュラインの誤った共有を回避します。 usage_in_bytesはメソッドの影響を受け、メモ
リ(およびスワップ)使用の「正確な」値を表示しません。効率的なアクセスのためのファズ値です。
(もちろん、必要な場合は同期されます。)より正確なメモリ使用量を知りたい場合は、
memory.statのRSS + CACHE(+ SWAP)値を使用する必要があります(5.2を参照)。
https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt
→memory.statはRSS+ページキャッシュの合計値を利用する 19
参考: memory.statの値
rss+cache=74,907,648≒71.43MB
20
考察
- CPUはpsやdocker statsコマンドで使用率をみることができた (cpu
測定時のdocker statsコマンドについては割愛)
- メモリは用途に応じてpsやdocker stats / cgroup を使い分ける 
(freeでは求める結果は得られない)
- リソースの値は絶えず変化するため、横串でみるのは少し難しい(測定
するときは軸を決めましょう)
docker stats: 実メモリの利用率を確認
cgroup.memory.stat:キャッシュを含めたメモリ利用量を確認 21
Appendix
補足事項
- 本番環境ではSaas型のモニタリングサービスの利用がオススメ
(GUIを提供/ドキュメントやライブラリが充実)
- 次はk8sのリソース制御についても同様にまとめて発表したい!
22
Appendix
謝辞
今回のコンテンツを作成するにあたり、案件で参画しているチームの方とディスカッ
ションをさせていただいたことで整理することが出来ました。
本当にありがとうございました!!
23
Appendix
参考にさせていただいたサイト
Docker公式:
- https://docs.docker.com/engine/reference/commandline/stats/
- https://docs.docker.com/config/containers/runmetrics/#metrics-from-cgroups-memory-cpu-block-io
- http://docs.docker.jp/engine/articles/runmetrics.html
  メモリについて:
- https://qiita.com/kunihirotanaka/items/70d43d48757aea79de2d
cgroup について:
- https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt
- https://www.itbook.info/network/docker06.html
- https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/resource_management_guide/ch01
24
ご清聴ありがとうございました!
25

コンテナにおけるパフォーマンス調査でハマった話