ECSの仕様で気になっていたことがあったので軽く調査しました。
というわけで早速ながら調査内容を共有させていただきます。
問題の内容
Agent versions <= 1.1.0:Nullと0のCPU値はDockerに0として渡され、Dockerはそれを1,024個のCPU配分に変換します。
1のCPU値はDockerに1として渡され、Linuxカーネルはそれを2個のCPU配分に変換します。Agent versions >= 1.2.0:Null、0、1のCPU値はDockerに2個のCPU配分として渡されます。
引用:https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definition_parameters.html
気になったところというのはズバリ、ECSタスク定義のCPUユニットの割り当てについてです。
タスク定義で言う所の上記の画像部分ですね。
CPUユニットの設定では、コンテナが最低限担保したいリソースを割り当てることができます。
ただし実際にはECSのホストインスタンスにCPUリソースが余っている場合には、コンテナに割り当てているCPUユニット以上のリソースをCPU使用率100%を越えて扱うことができます。
CPUユニットの設定を小さな値にしておくことで、ECSのタスク配置についてCPUユニットをあまり気にしなくて済むようになるため、「絶対にこのくらいのCPU割り当ては必要だ!!」みたいなのがない限りはなるべく低くめに設定したいところです。
さて、引用を見ていただくとわかる通り、よほど古いECS-Agentを使用していない限りは、CPUユニットの値を2以下で定義した場合には実際の割り当ては2として扱われるように見えます。
そのため、今まではCPUユニットの割り当てを0にしていたのですが、0も2も同じになるのであれば2にしておこうと考えました。
CPUユニット割り当てを2にした場合
変化があったのはCloudWatchのCPU使用率のメトリクスです。
このメトリクスはECSサービス単位の物なのですが、CPU使用率が平常時から43.9%と高めになっています。
そりゃ、CPUユニットを2しか割り当てていないから当たり前なのですが・・・。
CPUユニット割り当てを0にした場合
続いて同じDockerイメージを用いた状態でCPUユニットの割り当てを0に変更してみました。
すると今度はサービス単位のCPU使用率が0.097%まで落ちています。
何が起こったのか
これは推測なのですが、おそらくCPUユニットの割り当てを0に定義した場合には、サービス側のCPU使用率のメトリクスの上限値をホストインスタンスのCPUの上限値で扱っているのではないかと思われます。
実際にCPUユニットの割り当てを0にした時のサービスのメトリクスとホストインスタンスのCPU使用率のメトリクスは連動していました。もしもそうであれば、サービス単位のCPU使用率をトリガーとしたServiceAutoScalingの設定が簡単そうだなと個人的には思っています。(単純に「このサービスのCPU使用率だけでホストインスタンスのCPUを◯◯%も食いつぶしてる!」って分かりやすそう?)
逆にCPUユニットの割り当てを普段から2にしている場合には、「CPU使用率5000%」なんてのを日常的に見ることになるわけです。
保守の面を考えたら前者の方が簡単になりそうですね。
また、CPUユニットの値を小さく設定しているため、デプロイ時のホストインスタンスのリソースはメモリだけを考えればよいことになります。もちろんこれは使用しているサービスが一定値以上のCPUユニットを担保しなければならない場合では使えませんが。。。
Spotインスタンスとオンデマンドインスタンスが混在していて、さらにインスタンスタイプもバラバラなケースではCPUリソースの計算が面倒になりますので、これが使えればありがたそうだなーと思い記事にしました。
ちなみにWebサービスでCPU使用率が低い物に関しては、実際にCPUユニット0で割り当てて運用しているものもあります。
この辺りは展開するサービスと相談して決めたいですね。
以上、小ネタ記事でした!
追記:
AWSのサポートにて問い合わせたところ、コンテナへのCPUリソースの割り当てをNULLまたは0にしている場合には、サービスのメトリクスはホストインスタンスのvCPUをベースに表示されるとのことでした。
つまり予想通りの仕様です。ドキュメントをあさってもこの記述は見つけられませんでしたが、とりあえずAutoScale設定を組むときには便利ではないでしょうか。
コメントを残す